[llvm-dev] About detailed rule of fastcall

jy ban via llvm-dev llvm-dev at lists.llvm.org
Fri Sep 20 03:29:38 PDT 2019


Hello.
I'm trying to understand how fastcall works.

As far as I know, first two integer type arguments are passed in ecx and
edx.
I tested several test, but the result was different from what I expected

#1
    typedef struct _data_t {
        int d;
    } data_t;

    void __attribute__((fastcall)) test_suuu(data_t s, unsigned int a,
unsigned int b, unsigned int c);

unsigned int a is passed in edx, and the rest are passed in stack (in s, b,
c order).

#2 : order of arguments is diff from #1
   void __attribute__((fastcall)) test_usuu(unsigned int a, data_t s,
unsigned int b, unsigned int c);

unsigned int a is passed in ecx, and the rest are passed in stack (in s, b,
c order)

#3 : __attribute__((__packed__)) is diff from #1
    typedef struct __attribute__((__packed__)) _data_t3 {
        int d;
    } data_t3;

    void __attribute__((fastcall)) test_s3uu(data_t3 s3, unsigned int a,
unsigned int b);

unsigned int a is passed in ecx, and the rest are passed in stack (in s, b,
c order)

My questions are as follow
- why struct s in first test is passed in edx not ecx?
- why unsigned b is in second test is passed in stack not edx?
- why 'packed' makes a difference?
- where can I find relevant code in llvm?

I'm using i586, linux, llvm 5.02
Build with "clang++ -std=c++11 -ggdb -O0 -gdwarf-4 -fno-omit-frame-pointer
-fno-optimize-sibling-calls -o ref_test ref_test.cpp"
(All arguments are used in the function so that they are not optimized out)
Tested with gdb
    (gdb) break* test_suuu
    (gdb) x/6wx $esp
    (gdb) i r
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190920/326a8774/attachment.html>


More information about the llvm-dev mailing list