2009-05-23 17:07:10 Wiki update, and a question
Frank Van Hooft (CANADA)
Message: 74478
I've been working on an assembler routine and was following the parameter passing conventions described here:
docs.blackfin.uclinux.org/doku.php
However my code was not working. After much debugging, I found the parameters were being passed differently. The wiki page above shows that parameters 4 & 5 can be accessed via [FP+8] and [FP+12]. My parameters 4 & 5 are accessed via [FP+20] and [FP+24].
I believe this is a compiler difference. I suspect the wiki page assumes the bfin-uclinux-gcc compiler in its description, whereas I'm using the bfin-linux-uclibc-gcc (FDPIC) compiler.
So a couple of questions:
1) May I suggest the wiki page have a note added to this effect, perhaps just below the very nice stack memory drawings, to prevent others from also tripping over this.
2) Is there a way to detect which compiler is being used? Right now with my parameter reads are hardcoded at [FP+20] & [FP+24] so I'm thinking it'll break if someone compiled it using bfin-uclinux-gcc.
Thanks.
QuoteReplyEditDelete
2009-05-23 18:11:30 Re: Wiki update, and a question
Mike Frysinger (UNITED STATES)
Message: 74479
there shouldnt be any difference between the two compilers. are you sure you're doing it right ? the FP register wont be setup automatically for you if you dont use the LINK instruction ...
$ cat test.c
main(){f(1,2,3,4,5,6);}
$ bfin-elf-gcc -O3 test.c -o - -S
...
LINK 24;
R0 = 4 (X);
[SP+12] = R0;
R0 = 5 (X);
[SP+16] = R0;
R0 = 6 (X);
[SP+20] = R0;
R1 = 2 (X);
R0 = 1 (X);
R2 = 3 (X);
call _f;
UNLINK;
...
$ bfin-uclinux-gcc -O3 test.c -o - -S
...
LINK 24;
R0 = 4 (X);
[SP+12] = R0;
R0 = 5 (X);
[SP+16] = R0;
R0 = 6 (X);
[SP+20] = R0;
R1 = 2 (X);
R0 = 1 (X);
R2 = 3 (X);
call _f;
UNLINK;
...
$ bfin-linux-uclibc-gcc -O3 test.c -o - -S
...
LINK 24;
R0 = 4 (X);
[SP+12] = R0;
R0 = 5 (X);
[SP+16] = R0;
R0 = 6 (X);
[SP+20] = R0;
R1 = 2 (X);
R0 = 1 (X);
R2 = 3 (X);
call _f;
UNLINK;
...
QuoteReplyEditDelete
2009-05-23 19:07:01 Re: Wiki update, and a question
Frank Van Hooft (CANADA)
Message: 74482
I won't claim to be 100% sure, but take a look at this:
// test.c
// test program for examining parameter passing
#include <stdio.h>
int fn (int a, int b, int c, int d, int e);
int main ()
{
int n;
n = fn (11, 12, 13, 14, 15);
printf("Result is %d\n", n);
}
// really tricky function
int fn (int a, int b, int c, int d, int e)
{
return (3*a + 5*b + 6*c + 7*d + 9*e);
}
Compile it with:
$ bfin-linux-uclibc-gcc -O2 -S test.c
.file "test.c";
.text;
.align 4
.global _fn;
.type _fn, STT_FUNC;
_fn:
P1 = R0;
P0 = R1;
P2 = R2;
LINK 0;
R1 = [FP+20];
P1 = P1 + (P1 << 1);
P0 = P0 + (P0 << 2);
P1 = P1 + P0;
P2 = P2 + (P2 << 1);
R0 = R1 << 3 ||
R2 = [FP+24] ||
nop;
P2 = P1 + (P2 << 1);
R0 = R0 - R1;
R1 = P2;
R0 = R0 + R1;
R1 = R2 << 3;
R1 = R1 + R2;
R0 = R0 + R1;
UNLINK;
rts;
.size _fn, .-_fn
.section .rodata.str1.4,"aMS",@progbits,1
.align 4
.LC0:
.string "Result is %d\n"
.text;
.align 4
.global _main;
.type _main, STT_FUNC;
_main:
[--sp] = ( r7:7 );
LINK 20;
R0 = 14 (X);
[SP+12] = R0;
R0 = 15 (X);
R7 = P3;
[SP+16] = R0;
R1 = 12 (X);
R0 = 11 (X);
R2 = 13 (X);
call _fn;
P2 = R7;
P3 = R7;
UNLINK;
R1 = R0;
( r7:7 ) = [sp++];
R0 = [P2+.LC0@GOT17M4];
jump.l _printf;
.size _main, .-_main
.ident "GCC: (GNU) 4.1.2 (ADI svn)"
You can see the [FP+20] and [FP+24] in the function "fn" for yourself.
QuoteReplyEditDelete
2009-05-23 19:21:29 Re: Wiki update, and a question
Mike Frysinger (UNITED STATES)
Message: 74483
you get the same assembly with all the toolchains which indicates the docs are outdated
QuoteReplyEditDelete
2009-05-23 19:29:59 Re: Wiki update, and a question
Frank Van Hooft (CANADA)
Message: 74484
Interesting - I hadn't tried the other toolchains yet (guess I'm a little narrow minded... <grin>). Well, at least that makes it a little easier.
QuoteReplyEditDelete