July 16, 2014
On 7/15/2014 9:30 PM, Mike wrote:
> On Tuesday, 15 July 2014 at 19:48:23 UTC, Walter Bright wrote:
>
>> The one thing peek/poke doesn't offer is transitivity. C/C++ don't offer
>> volatile transitivity either. I'm not at all sure that anyone builds a data
>> structure in memory-mapped registers, so I'm not convinced this is a need.
>
> Here's an example from the STM32F4 ARM Cortex-M peripheral library:
>
> #define __IO volatile
>
> /**
>    * @brief DMA Controller
>    */
>
> typedef struct
> {
>    __IO uint32_t CR;     /*!< DMA stream x configuration register     */
>    __IO uint32_t NDTR;   /*!< DMA stream x number of data register     */
>    __IO uint32_t PAR;    /*!< DMA stream x peripheral address register */
>    __IO uint32_t M0AR;   /*!< DMA stream x memory 0 address register   */
>    __IO uint32_t M1AR;   /*!< DMA stream x memory 1 address register   */
>    __IO uint32_t FCR;    /*!< DMA stream x FIFO control register     */
> } DMA_Stream_TypeDef;
>
> typedef struct
> {
>    __IO uint32_t LISR;   /*!< DMA low interrupt status register,    Address
> offset: 0x00 */
>    __IO uint32_t HISR;   /*!< DMA high interrupt status register,    Address
> offset: 0x04 */
>    __IO uint32_t LIFCR;  /*!< DMA low interrupt flag clear register,  Address
> offset: 0x08 */
>    __IO uint32_t HIFCR;  /*!< DMA high interrupt flag clear register, Address
> offset: 0x0C */
> } DMA_TypeDef;
>
> There are several hundreds lines of this stuff in the library. It is used to
> model register banks.  Each register bank roughly corresponds to one of the
> embedded peripherals.

There are no pointers to pointers there, so there is no transitivity issue. A single volatile reference to the whole struct will suffice.

July 16, 2014
On 7/15/2014 11:32 PM, Iain Buclaw via Digitalmars-d wrote:
> On 16 July 2014 07:12, Walter Bright via Digitalmars-d
> <digitalmars-d@puremagic.com> wrote:
>> On 7/15/2014 9:29 PM, Brad Roberts via Digitalmars-d wrote:
>>>
>>> I don't have any skin in this particular discussion, but it's worth
>>> pointing out
>>> here that while it's cute that builtin's can be added, when they're not
>>> part of
>>> the language definition, they're not really part of a portable solution.
> > They're as portable as we want them to be.
> I read that as, not portable at all then. :o)


C'mon, guys. It's our spec and we can make it work.
July 16, 2014
On 7/15/2014 11:23 PM, Iain Buclaw via Digitalmars-d wrote:
> GDC doesn't support it as compiler intrinsics.

I know.


> Also, isn't inp/outp all x86-specific?

Yes. This is not an argument that x86 compilers shouldn't support them. After all, D is supposed to be a systems programming language.


> I've never come across a similar thing in other architectures (at
> least, of the same name)

I have. Special I/O ports and associated special instructions used to be commonplace in microprocessors.

Remember, D is supposed to be a systems programming language, not a language restricted to the least common denominator of every CPU now and in the future. One needs access to the system parts of the CPU.

July 16, 2014
On Wednesday, 16 July 2014 at 05:17:56 UTC, Johannes Pfau wrote:
> I think if we decide that Volatile!T is the solution I'd probably hack
> an attribute @TypeWrapper for gdc which simply recognized Volatile!T
> and does the right thing.

I'd recommend @fantom name, because not only type wrappers can benefit from these optimizations. Should be also applicable to functions and maybe modules.
July 16, 2014
Kagamin:

> I'd recommend @fantom name, because not only type wrappers can benefit from these optimizations. Should be also applicable to functions and maybe modules.

This sounds like something fit for D too, not just gdc. You can use it for std.typecons.Typedef too.

Bye,
bearophile
July 16, 2014
On 16 July 2014 08:08, Walter Bright via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> On 7/15/2014 11:32 PM, Iain Buclaw via Digitalmars-d wrote:
>>
>> On 16 July 2014 07:12, Walter Bright via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>>>
>>> On 7/15/2014 9:29 PM, Brad Roberts via Digitalmars-d wrote:
>>>>
>>>>
>>>> I don't have any skin in this particular discussion, but it's worth
>>>> pointing out
>>>> here that while it's cute that builtin's can be added, when they're not
>>>> part of
>>>> the language definition, they're not really part of a portable solution.
>>
>> > They're as portable as we want them to be.
>> I read that as, not portable at all then. :o)
>
>
>
> C'mon, guys. It's our spec and we can make it work.

And we are trying to make it work.

I actually have quite a bit to be planned out after removing the 'volatility' from shared.

>From the following spec:

'''
Unlike the shared attribute, __gshared provides no safe-guards against
data races or other multi-threaded synchronization issues. It is the
responsibility of the programmer to ensure that access to variables
marked __gshared is synchronized correctly.
'''

GDC will likely in future emit atomic loads, stores, and possibly fences around the use of shared data.

As there is no specific meaning to what 'safe-guards' come with shared.  I interpret that to keep in line with a happens-before style relationship with sequential reads/writes to shared data.

Regards
Iain
July 16, 2014
Walter Bright:

> struct VolatilePointerToUint {
>   private:
>     size_t ptr;
>   public:
>     this(size_t ptr) { this.ptr = ptr; }
>     uint read() { return peek(cast(uint*)ptr); }
>     void write(uint value) { poke(cast(uint*)ptr, value); }
> }
>
> You'd probably wish to flesh this out a bit more, but it's the general idea.

To be added to Phobos?


> It's a zero cost abstraction. D has very capable abilities to create types that are restricted versions of other types - this should be explored and exhausted before considering language extensions.

See also the @fantom suggested by Kagamin.

Bye,
bearophile
July 16, 2014
Then we can have phantom functions for porting C macros instead of templates :) (oh it's spelled with 'ph').
July 16, 2014
On Wednesday, 16 July 2014 at 05:17:56 UTC, Johannes Pfau wrote:
> There's TypeInfo and there's the assert(this)

The optimizer should be able to eliminate this assert after inlining as it knows it's not null. It should be looked into, why the optimizer didn't remove it.
July 16, 2014
On 16 July 2014 08:16, Walter Bright via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> On 7/15/2014 11:23 PM, Iain Buclaw via Digitalmars-d wrote:
>>
>> GDC doesn't support it as compiler intrinsics.
>
>
> I know.
>
>
>
>> Also, isn't inp/outp all x86-specific?
>
> Yes. This is not an argument that x86 compilers shouldn't support them. After all, D is supposed to be a systems programming language.
>

It certainly isn't! And it is never my intention to prevent optimisations on one platform if another doesn't benefit.

I think my argument comes down to this, consider the following compiler intrisinsic.
---
ubyte inp(uint port_address);


It should instead be written as.
---
ubyte inp()(uint port_address)
{
    version(ARM)
    {
        asm { /* ... */ }
    }
    else
        static assert(false, "Not Implemented");
}


What's going on here?

1) If the compiler recognises the function as an intrinsic, it
discards the body and does whatever it knows to be correct.
2) If its not an intrinsic, it falls back to the library implementation.
3) So not to hurt targets that do not support inp/outp, it only errors
at compile-time if *actually* used.



As an alternative, instead of a template, we could use core.internal to do the same thing in this way.

core/internal/bitops.d
---
module core.bitops;

version(ARM)
{
    ubyte inp(uint port_address)
    {
        /* ... */
    }
}


core/bitops.d
---
module core.bitops;

ubyte inp(uint port_address);


But then it falls down to a linker error if
1) The compiler didn't expand inp() in the backend
2) core.internal.bitops doesn't implement inp()

Which would you prefer?

Regards
Iain.