Object file questions

Artur Skawina via D.gnu d.gnu at puremagic.com
Sun Aug 17 04:35:21 PDT 2014


On 08/17/14 11:24, Timo Sintonen via D.gnu wrote:
> On Sunday, 17 August 2014 at 07:57:15 UTC, Timo Sintonen wrote:
>>
>>
>> This seems to work.
>>
> 
> This does not work with member functions
> 
> struct uartreg {
>     Volatile!int sr;
>     Volatile!int dr;
>     Volatile!int brr;
>     Volatile!int cr1;
>     Volatile!int cr2;
>     Volatile!int cr3;
>     Volatile!int gtpr;
> 
>     // send a byte to the uart
>     void send(int t) {
>       while ((sr&0x80)==0)
>       {  }
>       dr=t;
>     }
> 
> }
> 
> In this function the fetch of sr is omitted but compare is still
> made against an invalid register value. Then address of dr is
> omitted and store is made from wrong register to invalid address.
> So the generated code is totally invalid.
> 
> If I move this function out of the struct then it is ok.
> I use -O2, not tested what it woud do without optimization.

It works for me:

   import volat; // module w/ the last Volatile(T) implementation.

   struct uartreg {
       Volatile!int sr;
       Volatile!int dr;
       Volatile!int brr;
       Volatile!int cr1;
       Volatile!int cr2;
       Volatile!int cr3;
       Volatile!int gtpr;

       // send a byte to the uart
       void send(int t) {
         while ((sr&0x80)==0)
         {  }
         dr=t;
       }
   }

   enum uart = cast(uartreg*)0xDEADBEAF;

   void main() {
      uart.send(42);
   }

=>

0000000000403620 <_Dmain>:
  403620:       b8 af be ad de          mov    $0xdeadbeaf,%eax
  403625:       0f 1f 00                nopl   (%rax)
  403628:       b9 af be ad de          mov    $0xdeadbeaf,%ecx
  40362d:       8b 11                   mov    (%rcx),%edx
  40362f:       81 e2 80 00 00 00       and    $0x80,%edx
  403635:       74 f1                   je     403628 <_Dmain+0x8>
  403637:       bf b3 be ad de          mov    $0xdeadbeb3,%edi
  40363c:       31 c0                   xor    %eax,%eax
  40363e:       c7 07 2a 00 00 00       movl   $0x2a,(%rdi)
  403644:       c3                      retq   

Except for some obviously missed optimizations (dead eax load,
unnecessary ecx reload), the code seems fine. What platform
are you using and what does the emitted code look like?

> Also if I have:
> cr1=cr2=0;
> I get: expression this.cr2.opAssign(0) is void and has no value

That's because the opAssign returns void, which prevents this
kind of chaining. This was a deliberate choice, as I /wanted/ to
disallow that; it's already a bad idea for normal assignments;
for volatile ones, which can require a specific order, it's an
even worse one.
But it's trivial to "fix", just change

   void opAssign(A)(A a) { volatile_store(raw, a); }

to

   T opAssign(A)(A a) { volatile_store(raw, a); return a; }

artur



More information about the D.gnu mailing list