2009-05-23 17:07:10     Wiki update, and a question

Document created by Aaronwu Employee on Aug 15, 2013
Version 1Show Document
  • View in full screen mode

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

Attachments

    Outcomes