Undefined reference to 'r11'/Compiler failed in iaux.c

Technical questions regarding the XTC tools and programming with XMOS.
User avatar
Jamie
Experienced Member
Posts: 99
Joined: Mon Dec 14, 2009 1:01 pm

Undefined reference to 'r11'/Compiler failed in iaux.c

Post by Jamie »

I'm getting these (pretty unspecified) errors when I'm trying to link an object compiled from XC code with loads of inline assembly in it. The line which seems to be causing the error is:

Code: Select all

asm("ldw %0, cp[%1]" : "=r"(procAddr) : "r"(procIndex));
Which produces:

Code: Select all

kernel/functions.xc: Error: Undefined reference to 'r11'
And when I express this line slightly differently:

Code: Select all

asm("mov r11, %0" :: "r"(procIndex) : "r11");
asm("ldw %0, cp[r11]" : "=r"(procAddr) :: "r11");
The compiler gives the error:

Code: Select all

Compiler failed in iaux.c, line 66
o != ((void *)0)
It could well be something that I'm doing wrong or a problem to do with register allocation but I've got no idea about how to go about fixing this based on these strange error messages?!


User avatar
segher
XCore Expert
Posts: 844
Joined: Sun Jul 11, 2010 1:31 am

Post by segher »

ldwcp takes an immediate argument as the offset from cp, not a register.

You might want an ldawcp / ldw combo?


Segher
richard
Respected Member
Posts: 318
Joined: Tue Dec 15, 2009 12:46 am

Post by richard »

The offset of ldwcp must be an immediate. There is no version of ldwcp which takes a register offset from the cp. When you write:

Code: Select all

asm("ldw %0, cp[%1]" : "=r"(procAddr) : "r"(procIndex));
After substitution the assembler will see something like:

Code: Select all

ldw r0, cp[r11]
Because there is no register offset version of ldwcp the assembler assumes r11 in this context refers to a symbol. When no definition of this symbol is found at link time the mapper errors. I think the following (untested) piece of inline asm should work:

Code: Select all

asm("ldaw r11, cp[0]; ldw %0, r11[%1]" : "=r"(procAddr) : "r"(procIndex) : "r11");
when I express this line slightly differently:

Code: Select all

asm("mov r11, %0" :: "r"(procIndex) : "r11");
asm("ldw %0, cp[r11]" : "=r"(procAddr) :: "r11");
The compiler gives the error:

Code: Select all

Compiler failed in iaux.c, line 66
o != ((void *)0)
This also won't work for the reasons given above, but the compiler shouldn't fail like that. I've haven't been able to recreate this behaviour from just that snippet of code. Are you able to submit a ticket with the source code necessary to recreate the compiler failure?
User avatar
Jamie
Experienced Member
Posts: 99
Joined: Mon Dec 14, 2009 1:01 pm

Post by Jamie »

dwcp takes an immediate argument as the offset from cp, not a register.

You might want an ldawcp / ldw combo?
Whoops! Good spot - I guess it shouldn't have got passed the assembler though.

Even after correcting this, the 'Compiler failed' error is still occuring.

Code: Select all

asm("ldaw r11, cp[0]" ::: "r11");
asm("ldw %0, r11[%1]" : "=r"(procAddr) : "r"(procIndex) : "r11");
User avatar
Jamie
Experienced Member
Posts: 99
Joined: Mon Dec 14, 2009 1:01 pm

Post by Jamie »

This also won't work for the reasons given above, but the compiler shouldn't fail like that. I've haven't been able to recreate this behaviour from just that snippet of code. Are you able to submit a ticket with the source code necessary to recreate the compiler failure?
I've submitted a ticket for it. Although the ammended version still prodcues the error, it only does so with compiler optimisations enabled.
User avatar
segher
XCore Expert
Posts: 844
Joined: Sun Jul 11, 2010 1:31 am

Post by segher »

Jamie wrote: Even after correcting this, the 'Compiler failed' error is still occuring.

Code: Select all

asm("ldaw r11, cp[0]" ::: "r11");
asm("ldw %0, r11[%1]" : "=r"(procAddr) : "r"(procIndex) : "r11");
The clobber on the first asm is wrong: it should be an output instead, since you use
r11 later.
The clobber on the second asm is wrong: it should be an input.

Alternatively, write the whole thing as a single asm, e.g.

Code: Select all

asm("ldaw r11,cp[0] ; ldw %0,r11[%1]" : "=r"(procAddr) : "r"(procIndex) : "r11");
Or, probably best, just write this in C code instead of asm; or if you really want to use asm,
write the whole thing in assembler, i.e. a .s file.


Segher
User avatar
Jamie
Experienced Member
Posts: 99
Joined: Mon Dec 14, 2009 1:01 pm

Post by Jamie »

The clobber on the first asm is wrong: it should be an output instead, since you use
r11 later.
The clobber on the second asm is wrong: it should be an input.
So how do you write "r11" as an output in the first asm and as an input on the second one? Or have I missed the point a bit and the correct way to write it is as a single asm as you have suggested?
User avatar
segher
XCore Expert
Posts: 844
Joined: Sun Jul 11, 2010 1:31 am

Post by segher »

I don't know if there is a register contstraint to say "r11". Writing it as a single
asm() is certainly easier.
JohnR
Experienced Member
Posts: 93
Joined: Fri Dec 11, 2009 1:39 pm

Post by JohnR »

Hi
Or, probably best, just write this in C code instead of asm; or if you really want to use asm,
write the whole thing in assembler, i.e. a .s file.
Or write initially in XC, compile to a .S file and see what's generated.

John.