<div dir="ltr">I think clang behaves differently than gcc.<br><br>When the first argument is 'struct' and the second argument is 'int', gcc put the second argument 'int' in register edx, but clang sometimes in edx, and sometimes in ecx.<br> e.g. void __attribute__((fastcall)) test(struct, int)<br><br>I tested with follow structures<br> typedef struct _sti { // gcc: edx, clang: edx
<br> int i;<br> } sti;<br><br> typedef struct _sts { // gcc: edx, clang: ecx
<br> short s;<br> } sts;<br><br> typedef struct __attribute__((__packed__)) _stss { // gcc: edx, clang: ecx<br> short s1;<br> short s2;<br> } stss;<br><br> typedef struct _st1 { // gcc: edx, clang: ecx
<br> char str[1];<br> } st1;<div> ~</div><div> typedef struct _st4 { // gcc: edx, clang: ecx
<br> char str[4];<br> } st4; <br><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">2019년 9월 21일 (토) 오전 5:16, Reid Kleckner <<a href="mailto:rnk@google.com">rnk@google.com</a>>님이 작성:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>1. probably for GCC compatibility</div><div>2. probably the same</div><div>3. Hard to say, this could be a bug, compare with GCC</div><div>4. This behavior was implemented in this change: <a href="https://reviews.llvm.org/rC166538" target="_blank">https://reviews.llvm.org/rC166538</a> You can find the logic for this in clang today.</div><div><br></div><div>I also noticed that fastcall behaves differently when we target MSVC compatibility.</div><div><br></div><div> <br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Sep 20, 2019 at 3:29 AM jy ban via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Hello.<br>I'm trying to understand how fastcall works.<br><br>As far as I know, first two integer type arguments are passed in ecx and edx.<br>I tested several test, but the result was different from what I expected<br><br>#1<br> typedef struct _data_t {<br> int d;<br> } data_t;<br><br> void __attribute__((fastcall)) test_suuu(data_t s, unsigned int a, unsigned int b, unsigned int c);<br> <br>unsigned int a is passed in edx, and the rest are passed in stack (in s, b, c order).<br><br>#2 : order of arguments is diff from #1<br> void __attribute__((fastcall)) test_usuu(unsigned int a, data_t s, unsigned int b, unsigned int c);<br><br>unsigned int a is passed in ecx, and the rest are passed in stack (in s, b, c order)<br><br>#3 : __attribute__((__packed__)) is diff from #1<br> typedef struct __attribute__((__packed__)) _data_t3 {<br> int d;<br> } data_t3;<br> <br> void __attribute__((fastcall)) test_s3uu(data_t3 s3, unsigned int a, unsigned int b);<br><br>unsigned int a is passed in ecx, and the rest are passed in stack (in s, b, c order)<br><br><div>My questions are as follow <br>- why struct s in first test is passed in edx not ecx?<br>- why unsigned b is in second test is passed in stack not edx?</div><div>- why 'packed' makes a difference?<br>- where can I find relevant code in llvm?<br><br>I'm using i586, linux, llvm 5.02<br>Build with "clang++ -std=c++11 -ggdb -O0 -gdwarf-4 -fno-omit-frame-pointer -fno-optimize-sibling-calls -o ref_test ref_test.cpp"</div><div>(All arguments are used in the function so that they are not optimized out)<br>Tested with gdb<br> (gdb) break* test_suuu<br> (gdb) x/6wx $esp<br> (gdb) i r<br></div></div>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div>
</blockquote></div>