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