; #include <stdlib.h>
;
; void leaf_call(int b, int c, int d, int e, int f, int g, int h)
; {
; }
;
; void nonleaf_call(int a, int b, int c, int d, int e, int f, int g, int h)
; {
; /* use some local data */
; *(char*)alloca(220) = 'L';
; leaf_call(b, c, d, e, f, g, h);
; }
;
; int main()
; {
; nonleaf_call(0, 1, 2, 3, 4, 5, 6, 7);
; return 0;
; }
; output from psptoolchain-20111215-psp w/ gcc 4.9.3
00000000 <leaf_call>:
0: 27bdffd8 addiu sp,sp,-40
4: afbe0024 sw s8,36(sp)
8: 03a0f021 move s8,sp
c: afc40000 sw a0,0(s8)
10: afc50004 sw a1,4(s8)
14: afc60008 sw a2,8(s8)
18: afc7000c sw a3,12(s8)
1c: afc80010 sw t0,16(s8)
20: afc90014 sw t1,20(s8)
24: afca0018 sw t2,24(s8)
28: 03c0e821 move sp,s8
2c: 8fbe0024 lw s8,36(sp)
30: 27bd0028 addiu sp,sp,40
34: 03e00008 jr ra
38: 00000000 nop
0000003c <nonleaf_call>:
3c: 27bdffd8 addiu sp,sp,-40 ; |
40: afbf0024 sw ra,36(sp) ; |
44: afbe0020 sw s8,32(sp) ; | prolog
48: 03a0f021 move s8,sp ; / frame pointer (note: with offset to frame start, but static compared to sp)
4c: afc40000 sw a0,0(s8) ; \
50: afc50004 sw a1,4(s8) ; |
54: afc60008 sw a2,8(s8) ; |
58: afc7000c sw a3,12(s8) ; |
5c: afc80010 sw t0,16(s8) ; | in args 0,1,2,3,4,5,6,7 -> temp space in local area
60: afc90014 sw t1,20(s8) ; |
64: afca0018 sw t2,24(s8) ; |
68: afcb001c sw t3,28(s8) ; |
6c: 27bdff18 addiu sp,sp,-232 ; alloca(220) - with padding to guarantee alignment
70: 03a01021 move v0,sp ; |
74: 24420007 addiu v0,v0,7 ; |
78: 000210c2 srl v0,v0,0x3 ; | start of alloca()'d memory -> v1, by ...
7c: 000210c0 sll v0,v0,0x3 ; | ... using v0 as helper to align to 8b
80: 00401821 move v1,v0 ; |
84: 2402004c li v0,76 ; 'L' -> v0, and...
88: a0620000 sb v0,0(v1) ; ... store in local area (of alloca()'d space)
8c: 8fc40004 lw a0,4(s8) ; |
90: 8fc50008 lw a1,8(s8) ; |
94: 8fc6000c lw a2,12(s8) ; |
98: 8fc70010 lw a3,16(s8) ; | arg 0,1,2,3,4,5,6 (fetched from local area stored to above)
9c: 8fc80014 lw t0,20(s8) ; | (t0 = a4)
a0: 8fc90018 lw t1,24(s8) ; | (t1 = a5)
a4: 8fca001c lw t2,28(s8) ; | (t2 = a6)
a8: 0c000000 jal 0 <leaf_call> ; call and ret addr -> ra
ac: 00000000 nop ; branch delay slot
b0: 03c0e821 move sp,s8 ; |
b4: 8fbf0024 lw ra,36(sp) ; |
b8: 8fbe0020 lw s8,32(sp) ; |
bc: 27bd0028 addiu sp,sp,40 ; | epilog
c0: 03e00008 jr ra ; |
c4: 00000000 nop ; | branch delay slot
000000c8 <main>:
c8: 27bdfff8 addiu sp,sp,-8 ; |
cc: afbf0004 sw ra,4(sp) ; |
d0: afbe0000 sw s8,0(sp) ; | prolog
d4: 03a0f021 move s8,sp ; | frame pointer (note: with offset to frame start, but static compared to sp)
d8: 00002021 move a0,zero ; arg 0
dc: 24050001 li a1,1 ; arg 1
e0: 24060002 li a2,2 ; arg 2
e4: 24070003 li a3,3 ; arg 3
e8: 24080004 li t0,4 ; arg 4 (t0 = a4)
ec: 24090005 li t1,5 ; arg 5 (t1 = a5)
f0: 240a0006 li t2,6 ; arg 6 (t2 = a6)
f4: 240b0007 li t3,7 ; arg 7 (t3 = a7)
f8: 0c000000 jal 0 <leaf_call> ; call and ret addr -> ra
fc: 00000000 nop ; branch delay slot
100: 00001021 move v0,zero ; return value
104: 03c0e821 move sp,s8 ; |
108: 8fbf0004 lw ra,4(sp) ; |
10c: 8fbe0000 lw s8,0(sp) ; |
110: 27bd0008 addiu sp,sp,8 ; | epilog
114: 03e00008 jr ra ; |
118: 00000000 nop ; | branch delay slot
; ------------- as above but more args to use stack params ----------->
; #include <stdlib.h>
;
; void leaf_call(int b, int c, int d, int e, int f, int g, int h, int i, int j)
; {
; }
;
; void nonleaf_call(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j)
; {
; /* use some local data */
; *(char*)alloca(220) = 'L';
; leaf_call(b, c, d, e, f, g, h, i, j);
; }
;
; int main()
; {
; nonleaf_call(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
; return 0;
; }
; output from psptoolchain-20111215-psp w/ gcc 4.9.3
00000000 <leaf_call>:
0: 27bdffd8 addiu sp,sp,-40
4: afbe0024 sw s8,36(sp)
8: 03a0f021 move s8,sp
c: afc40000 sw a0,0(s8)
10: afc50004 sw a1,4(s8)
14: afc60008 sw a2,8(s8)
18: afc7000c sw a3,12(s8)
1c: afc80010 sw t0,16(s8)
20: afc90014 sw t1,20(s8)
24: afca0018 sw t2,24(s8)
28: afcb001c sw t3,28(s8)
2c: 03c0e821 move sp,s8
30: 8fbe0024 lw s8,36(sp)
34: 27bd0028 addiu sp,sp,40
38: 03e00008 jr ra
3c: 00000000 nop
00000040 <nonleaf_call>:
40: 27bdffd0 addiu sp,sp,-48 ; |
44: afbf002c sw ra,44(sp) ; |
48: afbe0028 sw s8,40(sp) ; | prolog
4c: 03a0f021 move s8,sp ; / frame pointer (note: with offset to frame start, but static compared to sp)
50: afc40008 sw a0,8(s8) ; \
54: afc5000c sw a1,12(s8) ; |
58: afc60010 sw a2,16(s8) ; |
5c: afc70014 sw a3,20(s8) ; |
60: afc80018 sw t0,24(s8) ; | in args 0,1,2,3,4,5,6,7 -> temp space in local area
64: afc9001c sw t1,28(s8) ; |
68: afca0020 sw t2,32(s8) ; |
6c: afcb0024 sw t3,36(s8) ; |
70: 27bdff18 addiu sp,sp,-232 ; alloca(220) - with padding to guarantee alignment
74: 27a20008 addiu v0,sp,8 ; |
78: 24420007 addiu v0,v0,7 ; |
7c: 000210c2 srl v0,v0,0x3 ; | start of alloca()'d memory -> v1, by ...
80: 000210c0 sll v0,v0,0x3 ; | ... using v0 as helper to align to 8b
84: 00401821 move v1,v0 ; |
88: 2402004c li v0,76 ; 'L' -> v0, and...
8c: a0620000 sb v0,0(v1) ; ... store in local area (of alloca()'d space)
90: 8fc20034 lw v0,52(s8) ; arg 8 (fetched from prev frame's param area), and ...
94: afa20000 sw v0,0(sp) ; ... "pushed" onto stack
98: 8fc4000c lw a0,12(s8) ; |
9c: 8fc50010 lw a1,16(s8) ; |
a0: 8fc60014 lw a2,20(s8) ; |
a4: 8fc70018 lw a3,24(s8) ; | arg 0,1,2,3,4,5,6 (fetched from local area stored to above)
a8: 8fc8001c lw t0,28(s8) ; | (t0 = a4)
ac: 8fc90020 lw t1,32(s8) ; | (t1 = a5)
b0: 8fca0024 lw t2,36(s8) ; | (t2 = a6)
b4: 8fcb0030 lw t3,48(s8) ; | (t3 = a7)
b8: 0c000000 jal 0 <leaf_call> ; call and ret addr -> ra
bc: 00000000 nop ; branch delay slot
c0: 03c0e821 move sp,s8 ; |
c4: 8fbf002c lw ra,44(sp) ; |
c8: 8fbe0028 lw s8,40(sp) ; |
cc: 27bd0030 addiu sp,sp,48 ; | epilog
d0: 03e00008 jr ra ; |
d4: 00000000 nop ; | branch delay slot
000000d8 <main>:
d8: 27bdfff0 addiu sp,sp,-16 ; |
dc: afbf000c sw ra,12(sp) ; |
e0: afbe0008 sw s8,8(sp) ; | prolog
e4: 03a0f021 move s8,sp ; | frame pointer (note: with offset to frame start, but static compared to sp)
e8: 24020008 li v0,8 ; arg 8
ec: afa20000 sw v0,0(sp) ; ... "pushed" onto stack
f0: 24020009 li v0,9 ; arg 9
f4: afa20004 sw v0,4(sp) ; ... "pushed" onto stack
f8: 00002021 move a0,zero ; arg 0
fc: 24050001 li a1,1 ; arg 1
100: 24060002 li a2,2 ; arg 2
104: 24070003 li a3,3 ; arg 3
108: 24080004 li t0,4 ; arg 4 (t0 = a4)
10c: 24090005 li t1,5 ; arg 5 (t1 = a5)
110: 240a0006 li t2,6 ; arg 6 (t2 = a6)
114: 240b0007 li t3,7 ; arg 7 (t3 = a7)
118: 0c000000 jal 0 <leaf_call> ; call and ret addr -> ra
11c: 00000000 nop ; branch delay slot
120: 00001021 move v0,zero ; return value
124: 03c0e821 move sp,s8 ; |
128: 8fbf000c lw ra,12(sp) ; |
12c: 8fbe0008 lw s8,8(sp) ; |
130: 27bd0010 addiu sp,sp,16 ; | epilog
134: 03e00008 jr ra ; |
138: 00000000 nop ; | branch delay slot
; ------------- with var args to see spilling ----------->
; #include <stdlib.h>
; #include <stdarg.h>
;
; void leaf_call(int b, int c, int d, int e, int f, int g, int h, int i, int j)
; {
; }
;
; void nonleaf_call(int a, ...)
; {
; int b, c, d, e, f, g, h, i, j;
; va_list ap;
; va_start(ap, a);
; b = va_arg(ap, int);
; c = va_arg(ap, int);
; d = va_arg(ap, int);
; e = va_arg(ap, int);
; f = va_arg(ap, int);
; g = va_arg(ap, int);
; h = va_arg(ap, int);
; i = va_arg(ap, int);
; j = va_arg(ap, int);
; /* use some local data */
; *(char*)alloca(220) = 'L';
; leaf_call(b, c, d, e, f, g, h, i, j);
; }
;
; int main()
; {
; nonleaf_call(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
; return 0;
; }
; output from psptoolchain-20111215-psp w/ gcc 4.9.3
00000000 <leaf_call>:
0: 27bdffd8 addiu sp,sp,-40
4: afbe0024 sw s8,36(sp)
8: 03a0f021 move s8,sp
c: afc40000 sw a0,0(s8)
10: afc50004 sw a1,4(s8)
14: afc60008 sw a2,8(s8)
18: afc7000c sw a3,12(s8)
1c: afc80010 sw t0,16(s8)
20: afc90014 sw t1,20(s8)
24: afca0018 sw t2,24(s8)
28: afcb001c sw t3,28(s8)
2c: 03c0e821 move sp,s8
30: 8fbe0024 lw s8,36(sp)
34: 27bd0028 addiu sp,sp,40
38: 03e00008 jr ra
3c: 00000000 nop
00000040 <nonleaf_call>:
40: 27bdffa0 addiu sp,sp,-96 ; | leaving 32b extra space adjacent to prev frame's param area for spilling
44: afbf003c sw ra,60(sp) ; |
48: afbe0038 sw s8,56(sp) ; | prolog
4c: 03a0f021 move s8,sp ; / frame pointer (note: with offset to frame start, but static compared to sp)
50: afc50044 sw a1,68(s8) ; \
54: afc60048 sw a2,72(s8) ; |
58: afc7004c sw a3,76(s8) ; |
5c: afc80050 sw t0,80(s8) ; | in args 1,2,3,4,5,6,7 -> spill area in current frame (adjacent to prev frame's param area)
60: afc90054 sw t1,84(s8) ; |
64: afca0058 sw t2,88(s8) ; |
68: afcb005c sw t3,92(s8) ; |
6c: afc40030 sw a0,48(s8) ; in arg 0 -> temp space in local area
70: 27c20060 addiu v0,s8,96 ; v0 initialized to point ...
74: 2442ffe4 addiu v0,v0,-28 ; ... to start of spill area (96 - 28 = 68, where we spilled a1)
78: afc2002c sw v0,44(s8) ; store read ptr in local area
7c: 8fc2002c lw v0,44(s8) ; | get read pointer in v0 (pointless here, but part of following pattern) ...
80: 24430004 addiu v1,v0,4 ; | ... advance ...
84: afc3002c sw v1,44(s8) ; | in arg 1 ... store again ...
88: 8c420000 lw v0,0(v0) ; | ... arg -> v0 (using pre-inc read location), then ...
8c: afc20008 sw v0,8(s8) ; / ... write to local area on stack for later
90: 8fc2002c lw v0,44(s8) ; \
94: 24430004 addiu v1,v0,4 ; |
98: afc3002c sw v1,44(s8) ; | in arg 2
9c: 8c420000 lw v0,0(v0) ; |
a0: afc2000c sw v0,12(s8) ; /
a4: 8fc2002c lw v0,44(s8) ; \
a8: 24430004 addiu v1,v0,4 ; |
ac: afc3002c sw v1,44(s8) ; | in arg 3
b0: 8c420000 lw v0,0(v0) ; |
b4: afc20010 sw v0,16(s8) ; /
b8: 8fc2002c lw v0,44(s8) ; \
bc: 24430004 addiu v1,v0,4 ; |
c0: afc3002c sw v1,44(s8) ; | in arg 4
c4: 8c420000 lw v0,0(v0) ; |
c8: afc20014 sw v0,20(s8) ; /
cc: 8fc2002c lw v0,44(s8) ; \
d0: 24430004 addiu v1,v0,4 ; |
d4: afc3002c sw v1,44(s8) ; | in arg 5
d8: 8c420000 lw v0,0(v0) ; |
dc: afc20018 sw v0,24(s8) ; /
e0: 8fc2002c lw v0,44(s8) ; \
e4: 24430004 addiu v1,v0,4 ; |
e8: afc3002c sw v1,44(s8) ; | in arg 6
ec: 8c420000 lw v0,0(v0) ; |
f0: afc2001c sw v0,28(s8) ; /
f4: 8fc2002c lw v0,44(s8) ; \
f8: 24430004 addiu v1,v0,4 ; |
fc: afc3002c sw v1,44(s8) ; | in arg 7
100: 8c420000 lw v0,0(v0) ; |
104: afc20020 sw v0,32(s8) ; /
108: 8fc2002c lw v0,44(s8) ; \
10c: 24430004 addiu v1,v0,4 ; |
110: afc3002c sw v1,44(s8) ; | in arg 8
114: 8c420000 lw v0,0(v0) ; |
118: afc20024 sw v0,36(s8) ; /
11c: 8fc2002c lw v0,44(s8) ; \
120: 24430004 addiu v1,v0,4 ; |
124: afc3002c sw v1,44(s8) ; | in arg 9
128: 8c420000 lw v0,0(v0) ; |
12c: afc20028 sw v0,40(s8) ; /
130: 27bdff18 addiu sp,sp,-232 ; alloca(220) - with padding to guarantee alignment
134: 27a20008 addiu v0,sp,8 ; |
138: 24420007 addiu v0,v0,7 ; |
13c: 000210c2 srl v0,v0,0x3 ; | start of alloca()'d memory -> v1, by ...
140: 000210c0 sll v0,v0,0x3 ; | ... using v0 as helper to align to 8b
144: 00401821 move v1,v0 ; |
148: 2402004c li v0,76 ; 'L' -> v0, and...
14c: a0620000 sb v0,0(v1) ; ... store in local area (of alloca()'d space)
150: 8fc20028 lw v0,40(s8) ; arg 8 (fetched from local area stored to above) and ...
154: afa20000 sw v0,0(sp) ; ... "pushed" onto stack
158: 8fc40008 lw a0,8(s8) ; |
15c: 8fc5000c lw a1,12(s8) ; |
160: 8fc60010 lw a2,16(s8) ; |
164: 8fc70014 lw a3,20(s8) ; | arg 0,1,2,3,4,5,6 (fetched from local area stored to above)
168: 8fc80018 lw t0,24(s8) ; | (t0 = a4)
16c: 8fc9001c lw t1,28(s8) ; | (t1 = a5)
170: 8fca0020 lw t2,32(s8) ; | (t2 = a6)
174: 8fcb0024 lw t3,36(s8) ; | (t3 = a7)
178: 0c000000 jal 0 <leaf_call> ; call and ret addr -> ra
17c: 00000000 nop ; branch delay slot
180: 03c0e821 move sp,s8 ; |
184: 8fbf003c lw ra,60(sp) ; |
188: 8fbe0038 lw s8,56(sp) ; |
18c: 27bd0060 addiu sp,sp,96 ; | epilog
190: 03e00008 jr ra ; |
194: 00000000 nop | branch delay slot
00000198 <main>:
198: 27bdfff0 addiu sp,sp,-16 ; |
19c: afbf000c sw ra,12(sp) ; |
1a0: afbe0008 sw s8,8(sp) ; | prolog
1a4: 03a0f021 move s8,sp ; | frame pointer (note: with offset to frame start, but static compared to sp)
1a8: 24020008 li v0,8 ; arg 8
1ac: afa20000 sw v0,0(sp) ; ... "pushed" onto stack
1b0: 24020009 li v0,9 ; arg 9
1b4: afa20004 sw v0,4(sp) ; ... "pushed" onto stack
1b8: 00002021 move a0,zero ; arg 0
1bc: 24050001 li a1,1 ; arg 1
1c0: 24060002 li a2,2 ; arg 2
1c4: 24070003 li a3,3 ; arg 3
1c8: 24080004 li t0,4 ; arg 4 (t0 = a4)
1cc: 24090005 li t1,5 ; arg 5 (t1 = a5)
1d0: 240a0006 li t2,6 ; arg 6 (t2 = a6)
1d4: 240b0007 li t3,7 ; arg 7 (t3 = a7)
1d8: 0c000000 jal 0 <leaf_call> ; call and ret addr -> ra
1dc: 00000000 nop ; branch delay slot
1e0: 00001021 move v0,zero ; return value
1e4: 03c0e821 move sp,s8 ; |
1e8: 8fbf000c lw ra,12(sp) ; |
1ec: 8fbe0008 lw s8,8(sp) ; |
1f0: 27bd0010 addiu sp,sp,16 ; | epilog
1f4: 03e00008 jr ra ; |
1f8: 00000000 nop ; | branch delay slot
; ------------- var args with ints and floats to see spilling (which remains only a?-a7 regs), b/c doubles are passed via them and floats are promoted to doubles in (...) ----------->
; #include <stdlib.h>
; #include <stdarg.h>
;
; void leaf_call(int b, int c, int d, int e, float f, float g, int h, int i, float j)
; {
; }
;
; void nonleaf_call(int a, ...)
; {
; int b, c, d, e, h, i;
; float f, g, j;
; va_list ap;
; va_start(ap, a);
; b = va_arg(ap, int);
; c = va_arg(ap, int);
; d = va_arg(ap, int);
; e = va_arg(ap, int);
; f = (float)va_arg(ap, double);
; g = (float)va_arg(ap, double);
; h = va_arg(ap, int);
; i = va_arg(ap, int);
; j = (float)va_arg(ap, double);
; /* use some local data */
; *(char*)alloca(220) = 'L';
; leaf_call(b, c, d, e, f, g, h, i, j);
; }
;
; int main()
; {
; nonleaf_call(0, 1, 2, 3, 4, 5.f, 6.f, 7, 8, 9.f);
; return 0;
; }
; output from psptoolchain-20111215-psp w/ gcc 4.9.3
00000000 <leaf_call>:
0: 27bdffd0 addiu sp,sp,-48
4: afbe002c sw s8,44(sp)
8: 03a0f021 move s8,sp
c: afc40000 sw a0,0(s8)
10: afc50004 sw a1,4(s8)
14: afc60008 sw a2,8(s8)
18: afc7000c sw a3,12(s8)
1c: e7cc0010 swc1 $f12,16(s8)
20: e7cd0014 swc1 $f13,20(s8)
24: afc80018 sw t0,24(s8)
28: afc9001c sw t1,28(s8)
2c: e7ce0020 swc1 $f14,32(s8)
30: 03c0e821 move sp,s8
34: 8fbe002c lw s8,44(sp)
38: 27bd0030 addiu sp,sp,48
3c: 03e00008 jr ra
40: 00000000 nop
00000044 <nonleaf_call>:
44: 27bdffa8 addiu sp,sp,-88 ; | leaving 32b extra space adjacent to prev frame's param area for spilling
48: afbf0034 sw ra,52(sp) ; |
4c: afbe0030 sw s8,48(sp) ; | prolog
50: 03a0f021 move s8,sp ; / frame pointer (note: with offset to frame start, but static compared to sp)
54: afc5003c sw a1,60(s8) ; \
58: afc60040 sw a2,64(s8) ; |
5c: afc70044 sw a3,68(s8) ; |
60: afc80048 sw t0,72(s8) ; | in args 1,2,3,4,5 (spread out over 7 param regs) -> spill area in current frame (adjacent to prev frame's param area)
64: afc9004c sw t1,76(s8) ; | this one is just padding
68: afca0050 sw t2,80(s8) ; | |
6c: afcb0054 sw t3,84(s8) ; | | this is arg 5, passed as a double, spilled like integers
70: afc40028 sw a0,40(s8) ; in arg 0 -> temp space in local area
74: 27c20058 addiu v0,s8,88 ; v0 initialized to point ...
78: 2442ffe4 addiu v0,v0,-28 ; ... to start of spill area (88 - 28 = 60, where we spilled a1)
7c: afc20024 sw v0,36(s8) ; store read ptr in local area
80: 8fc20024 lw v0,36(s8) ; | get read pointer in v0 (pointless here, but part of following pattern) ...
84: 24430004 addiu v1,v0,4 ; | ... advance ...
88: afc30024 sw v1,36(s8) ; | in arg 1 ... store again ...
8c: 8c420000 lw v0,0(v0) ; | ... arg -> v0 (using pre-inc read location), then ...
90: afc20000 sw v0,0(s8) ; / ... write to local area on stack for later
94: 8fc20024 lw v0,36(s8) ; \
98: 24430004 addiu v1,v0,4 ; |
9c: afc30024 sw v1,36(s8) ; | in arg 2
a0: 8c420000 lw v0,0(v0) ; |
a4: afc20004 sw v0,4(s8) ; /
a8: 8fc20024 lw v0,36(s8) ; \
ac: 24430004 addiu v1,v0,4 ; |
b0: afc30024 sw v1,36(s8) ; | in arg 3
b4: 8c420000 lw v0,0(v0) ; |
b8: afc20008 sw v0,8(s8) ; /
bc: 8fc20024 lw v0,36(s8) ; \
c0: 24430004 addiu v1,v0,4 ; |
c4: afc30024 sw v1,36(s8) ; | in arg 4
c8: 8c420000 lw v0,0(v0) ; |
cc: afc2000c sw v0,12(s8) ; /
d0: 8fc20024 lw v0,36(s8) ; \ get read ptr in v0
d4: 24430007 addiu v1,v0,7 ; | |
d8: 2402fff8 li v0,-8 ; | | align
dc: 00621024 and v0,v1,v0 ; | |
e0: 24430008 addiu v1,v0,8 ; | advance read ptr to point to double
e4: afc30024 sw v1,36(s8) ; | restore read ptr
e8: 8c430004 lw v1,4(v0) ; | in arg 5 |
ec: 8c420000 lw v0,0(v0) ; | | load both parts of double ...
f0: 00402021 move a0,v0 ; | | ... and store in a{0,1} pair (used to pass doubles, used in next call)
f4: 00602821 move a1,v1 ; | /
f8: 0c000000 jal 0 <leaf_call> ; | \ call to cast double to float, returned in f0
fc: 00000000 nop ; | | NOTE: not a call to leaf_call() (objdump done from .o file, not finally linked executable)
100: e7c00010 swc1 $f0,16(s8) ; / write float to local area on stack for later
104: 8fc20024 lw v0,36(s8) ; \
108: 24430007 addiu v1,v0,7 ; |
10c: 2402fff8 li v0,-8 ; |
110: 00621024 and v0,v1,v0 ; |
114: 24430008 addiu v1,v0,8 ; |
118: afc30024 sw v1,36(s8) ; |
11c: 8c430004 lw v1,4(v0) ; | in arg 6
120: 8c420000 lw v0,0(v0) ; |
124: 00402021 move a0,v0 ; |
128: 00602821 move a1,v1 ; |
12c: 0c000000 jal 0 <leaf_call> ; |
130: 00000000 nop ; |
134: e7c00014 swc1 $f0,20(s8) ; /
138: 8fc20024 lw v0,36(s8) ; \
13c: 24430004 addiu v1,v0,4 ; |
140: afc30024 sw v1,36(s8) ; | in arg 7
144: 8c420000 lw v0,0(v0) ; |
148: afc20018 sw v0,24(s8) ; /
14c: 8fc20024 lw v0,36(s8) ; \
150: 24430004 addiu v1,v0,4 ; |
154: afc30024 sw v1,36(s8) ; | in arg 8
158: 8c420000 lw v0,0(v0) ; |
15c: afc2001c sw v0,28(s8) ; /
160: 8fc20024 lw v0,36(s8) ; \
164: 24430007 addiu v1,v0,7 ; |
168: 2402fff8 li v0,-8 ; |
16c: 00621024 and v0,v1,v0 ; |
170: 24430008 addiu v1,v0,8 ; |
174: afc30024 sw v1,36(s8) ; |
178: 8c430004 lw v1,4(v0) ; | in arg 9
17c: 8c420000 lw v0,0(v0) ; |
180: 00402021 move a0,v0 ; |
184: 00602821 move a1,v1 ; |
188: 0c000000 jal 0 <leaf_call> ; |
18c: 00000000 nop ; |
190: e7c00020 swc1 $f0,32(s8) ; /
194: 27bdff18 addiu sp,sp,-232 ; alloca(220) - with padding to guarantee alignment
198: 03a01021 move v0,sp ; |
19c: 24420007 addiu v0,v0,7 ; |
1a0: 000210c2 srl v0,v0,0x3 ; | start of alloca()'d memory -> v1, by ...
1a4: 000210c0 sll v0,v0,0x3 ; | ... using v0 as helper to align to 8b
1a8: 00401821 move v1,v0 ; |
1ac: 2402004c li v0,76 ; 'L' -> v0, and...
1b0: a0620000 sb v0,0(v1) ; ... store in local area (of alloca()'d space)
1b4: 8fc40000 lw a0,0(s8) ; |
1b8: 8fc50004 lw a1,4(s8) ; |
1bc: 8fc60008 lw a2,8(s8) ; | arg 0,1,2,3 (int args, fetched from local area stored to above)
1c0: 8fc7000c lw a3,12(s8) ; |
1c4: c7cc0010 lwc1 $f12,16(s8) ; arg 4 (float, fetched from local area stored to above)
1c8: c7cd0014 lwc1 $f13,20(s8) ; arg 5 (float, fetched from local area stored to above)
1cc: 8fc80018 lw t0,24(s8) ; arg 6 (int, fetched from local area stored to above, t0 = a4)
1d0: 8fc9001c lw t1,28(s8) ; arg 7 (int, fetched from local area stored to above, t1 = a5)
1d4: c7ce0020 lwc1 $f14,32(s8) ; arg 9 (float, fetched from local area stored to above)
1d8: 0c000000 jal 0 <leaf_call> ; call and ret addr -> ra
1dc: 00000000 nop ; branch delay slot
1e0: 03c0e821 move sp,s8 ; |
1e4: 8fbf0034 lw ra,52(sp) ; |
1e8: 8fbe0030 lw s8,48(sp) ; |
1ec: 27bd0058 addiu sp,sp,88 ; | epilog
1f0: 03e00008 jr ra ; |
1f4: 00000000 nop ; | branch delay slot
000001f8 <main>:
1f8: 27bdffe0 addiu sp,sp,-32 ; |
1fc: afbf001c sw ra,28(sp) ; |
200: afbe0018 sw s8,24(sp) ; | prolog
204: 03a0f021 move s8,sp ; / frame pointer (note: with offset to frame start, but static compared to sp)
208: 8f8a0000 lw t2,0(gp) ; \
20c: 8f8b0004 lw t3,4(gp) ; / arg 5 (t1,t2 = a4,a5), as double b/c of vararg, effectively skipping t1 (=a5)
210: 8f820008 lw v0,8(gp) ; \
214: 8f83000c lw v1,12(gp) ; | arg 6, as double b/c of vararg, via v0 and v1 ...
218: afa20000 sw v0,0(sp) ; |
21c: afa30004 sw v1,4(sp) ; | ... "pushed" onto stack
220: 24020007 li v0,7 ; arg 7
224: afa20008 sw v0,8(sp) ; ... "pushed" onto stack
228: 24020008 li v0,8 ; arg 8
22c: afa2000c sw v0,12(sp) ; ... "pushed" onto stack
230: 8f820010 lw v0,16(gp) ; |
234: 8f830014 lw v1,20(gp) ; | arg 9, as double b/c of vararg ...
238: afa20010 sw v0,16(sp) ; |
23c: afa30014 sw v1,20(sp) ; | ... "pushed" onto stack
240: 00002021 move a0,zero ; arg 0
244: 24050001 li a1,1 ; arg 1
248: 24060002 li a2,2 ; arg 2
24c: 24070003 li a3,3 ; arg 3
250: 24080004 li t0,4 ; arg 4 (t0 = a4)
254: 0c000000 jal 0 <leaf_call> ; call and ret addr -> ra
258: 00000000 nop ; branch delay slot
25c: 00001021 move v0,zero ; return value
260: 03c0e821 move sp,s8 ; |
264: 8fbf001c lw ra,28(sp) ; |
268: 8fbe0018 lw s8,24(sp) ; |
26c: 27bd0020 addiu sp,sp,32 ; | epilog
270: 03e00008 jr ra ; |
274: 00000000 nop ; | branch delay slot
; --------------------- further notes ------------------->
; when passing less arguments than stack params, involving an ellipsis, spill area still spills all registers,
; excluding named ones, e.g.:
;
; void c(int a, ...) { ... }
; c(0, 1, 2, 3, 4);
;
; contains as spilling code same as above:
84: afc5002c sw a1,44(s8)
88: afc60030 sw a2,48(s8)
8c: afc70034 sw a3,52(s8)
90: afc80038 sw t0,56(s8)
94: afc9003c sw t1,60(s8)
98: afca0040 sw t2,64(s8)
9c: afcb0044 sw t3,68(s8)
; ---------- structs by value ---------->
;
; struct A { int i, j; long long l; };
;
; void leaf_call(int b, int c, int d, int e, struct A f, int g, int h)
; {
; }
;
; void nonleaf_call(int a, int b, int c, int d, int e, struct A f, int g, int h)
; {
; /* use some local data */
; char l[100] ={ 'L'};
; leaf_call(b, c, d, e, f, g, h);
; }
;
; int main()
; {
; nonleaf_call(0, 1, 2, 3, 4, (struct A){5, 6, 7ll}, 8, 9);
; return 0;
; }
; output from psptoolchain-20111215-psp w/ gcc 4.9.3
00000000 <leaf_call>:
0: 27bdffd0 addiu sp,sp,-48
4: afbe002c sw s8,44(sp)
8: afb00028 sw s0,40(sp)
c: 03a0f021 move s8,sp
10: afc40010 sw a0,16(s8)
14: afc50014 sw a1,20(s8)
18: afc60018 sw a2,24(s8)
1c: afc7001c sw a3,28(s8)
20: 01008021 move s0,t0
24: afc90020 sw t1,32(s8)
28: afca0024 sw t2,36(s8)
2c: 8e050000 lw a1,0(s0)
30: 8e040004 lw a0,4(s0)
34: 8e030008 lw v1,8(s0)
38: 8e02000c lw v0,12(s0)
3c: afc50000 sw a1,0(s8)
40: afc40004 sw a0,4(s8)
44: afc30008 sw v1,8(s8)
48: afc2000c sw v0,12(s8)
4c: 03c0e821 move sp,s8
50: 8fbe002c lw s8,44(sp)
54: 8fb00028 lw s0,40(sp)
58: 27bd0030 addiu sp,sp,48
5c: 03e00008 jr ra
60: 00000000 nop
00000064 <nonleaf_call>:
64: 27bdff58 addiu sp,sp,-168
68: afbf00a4 sw ra,164(sp)
6c: afbe00a0 sw s8,160(sp)
70: afb0009c sw s0,156(sp)
74: 03a0f021 move s8,sp
78: afc40078 sw a0,120(s8)
7c: afc5007c sw a1,124(s8)
80: afc60080 sw a2,128(s8)
84: afc70084 sw a3,132(s8)
88: afc80088 sw t0,136(s8)
8c: 01208021 move s0,t1
90: afca008c sw t2,140(s8)
94: afcb0090 sw t3,144(s8)
98: 8e050000 lw a1,0(s0)
9c: 8e040004 lw a0,4(s0)
a0: 8e030008 lw v1,8(s0)
a4: 8e02000c lw v0,12(s0)
a8: afc50000 sw a1,0(s8)
ac: afc40004 sw a0,4(s8)
b0: afc30008 sw v1,8(s8)
b4: afc2000c sw v0,12(s8)
b8: 27c30010 addiu v1,s8,16
bc: 24020064 li v0,100
c0: 00602021 move a0,v1
c4: 00002821 move a1,zero
c8: 00403021 move a2,v0
cc: 0c000000 jal 0 <leaf_call>
d0: 00000000 nop
d4: 2402004c li v0,76
d8: a3c20010 sb v0,16(s8)
dc: 8fc4007c lw a0,124(s8)
e0: 8fc50080 lw a1,128(s8)
e4: 8fc60084 lw a2,132(s8)
e8: 8fc70088 lw a3,136(s8)
ec: 03c04021 move t0,s8
f0: 8fc9008c lw t1,140(s8)
f4: 8fca0090 lw t2,144(s8)
f8: 0c000000 jal 0 <leaf_call>
fc: 00000000 nop
100: 03c0e821 move sp,s8
104: 8fbf00a4 lw ra,164(sp)
108: 8fbe00a0 lw s8,160(sp)
10c: 8fb0009c lw s0,156(sp)
110: 27bd00a8 addiu sp,sp,168
114: 03e00008 jr ra
118: 00000000 nop
0000011c <main>:
11c: 27bdffe8 addiu sp,sp,-24
120: afbf0014 sw ra,20(sp)
124: afbe0010 sw s8,16(sp)
128: 03a0f021 move s8,sp
12c: 24020005 li v0,5
130: afc20000 sw v0,0(s8)
134: 24020006 li v0,6
138: afc20004 sw v0,4(s8)
13c: 24020007 li v0,7
140: 00001821 move v1,zero
144: afc20008 sw v0,8(s8)
148: afc3000c sw v1,12(s8)
14c: 00002021 move a0,zero
150: 24050001 li a1,1
154: 24060002 li a2,2
158: 24070003 li a3,3
15c: 24080004 li t0,4
160: 03c04821 move t1,s8
164: 240a0008 li t2,8
168: 240b0009 li t3,9
16c: 0c000000 jal 0 <leaf_call>
170: 00000000 nop
174: 00001021 move v0,zero
178: 03c0e821 move sp,s8
17c: 8fbf0014 lw ra,20(sp)
180: 8fbe0010 lw s8,16(sp)
184: 27bd0018 addiu sp,sp,24
188: 03e00008 jr ra
18c: 00000000 nop
; ---------- structs by value, complex example (multiple structs) ---------->
;
; struct A { int i, j; float f; };
; struct B { double d; long long l; };
;
; void leaf_call(int b, struct A c, struct B d, int e, int f, struct A g, struct B h, int i, int j)
; {
; }
;
; void nonleaf_call(int a, int b, struct A c, struct B d, int e, int f, struct A g, struct B h, int i, int j)
; {
; /* use some local data */
; char l[100] ={ 'L'};
; leaf_call(b, c, d, e, f, g, h, i, j);
; }
;
; int main()
; {
; nonleaf_call(0, 1, (struct A){2, 3, 4.f}, (struct B){5., 6ll}, 7, 8, (struct A){9, 10, 11.f}, (struct B){12., 13ll}, 14, 15);
; return 0;
; }
; output from psptoolchain-20111215-psp w/ gcc 4.9.3
00000000 <leaf_call>:
0: 27bdff98 addiu sp,sp,-104
4: afbe0064 sw s8,100(sp)
8: afb30060 sw s3,96(sp)
c: afb2005c sw s2,92(sp)
10: afb10058 sw s1,88(sp)
14: afb00054 sw s0,84(sp)
18: 03a0f021 move s8,sp
1c: afc40040 sw a0,64(s8)
20: 00a09821 move s3,a1
24: 00c08821 move s1,a2
28: afc70044 sw a3,68(s8)
2c: afc80048 sw t0,72(s8)
30: 01209021 move s2,t1
34: 01408021 move s0,t2
38: afcb004c sw t3,76(s8)
3c: 8e640000 lw a0,0(s3)
40: 8e630004 lw v1,4(s3)
44: 8e620008 lw v0,8(s3)
48: afc40030 sw a0,48(s8)
4c: afc30034 sw v1,52(s8)
50: afc20038 sw v0,56(s8)
54: 8e250000 lw a1,0(s1)
58: 8e240004 lw a0,4(s1)
5c: 8e230008 lw v1,8(s1)
60: 8e22000c lw v0,12(s1)
64: afc50020 sw a1,32(s8)
68: afc40024 sw a0,36(s8)
6c: afc30028 sw v1,40(s8)
70: afc2002c sw v0,44(s8)
74: 8e440000 lw a0,0(s2)
78: 8e430004 lw v1,4(s2)
7c: 8e420008 lw v0,8(s2)
80: afc40010 sw a0,16(s8)
84: afc30014 sw v1,20(s8)
88: afc20018 sw v0,24(s8)
8c: 8e050000 lw a1,0(s0)
90: 8e040004 lw a0,4(s0)
94: 8e030008 lw v1,8(s0)
98: 8e02000c lw v0,12(s0)
9c: afc50000 sw a1,0(s8)
a0: afc40004 sw a0,4(s8)
a4: afc30008 sw v1,8(s8)
a8: afc2000c sw v0,12(s8)
ac: 03c0e821 move sp,s8
b0: 8fbe0064 lw s8,100(sp)
b4: 8fb30060 lw s3,96(sp)
b8: 8fb2005c lw s2,92(sp)
bc: 8fb10058 lw s1,88(sp)
c0: 8fb00054 lw s0,84(sp)
c4: 27bd0068 addiu sp,sp,104
c8: 03e00008 jr ra
cc: 00000000 nop
000000d0 <nonleaf_call>:
d0: 27bdff30 addiu sp,sp,-208
d4: afbf00cc sw ra,204(sp)
d8: afbe00c8 sw s8,200(sp)
dc: afb300c4 sw s3,196(sp)
e0: afb200c0 sw s2,192(sp)
e4: afb100bc sw s1,188(sp)
e8: afb000b8 sw s0,184(sp)
ec: 03a0f021 move s8,sp
f0: afc400a8 sw a0,168(s8)
f4: afc500ac sw a1,172(s8)
f8: 00c09821 move s3,a2
fc: 00e08821 move s1,a3
100: afc800b0 sw t0,176(s8)
104: afc900b4 sw t1,180(s8)
108: 01409021 move s2,t2
10c: 01608021 move s0,t3
110: 8e640000 lw a0,0(s3)
114: 8e630004 lw v1,4(s3)
118: 8e620008 lw v0,8(s3)
11c: afc40038 sw a0,56(s8)
120: afc3003c sw v1,60(s8)
124: afc20040 sw v0,64(s8)
128: 8e250000 lw a1,0(s1)
12c: 8e240004 lw a0,4(s1)
130: 8e230008 lw v1,8(s1)
134: 8e22000c lw v0,12(s1)
138: afc50028 sw a1,40(s8)
13c: afc4002c sw a0,44(s8)
140: afc30030 sw v1,48(s8)
144: afc20034 sw v0,52(s8)
148: 8e440000 lw a0,0(s2)
14c: 8e430004 lw v1,4(s2)
150: 8e420008 lw v0,8(s2)
154: afc40018 sw a0,24(s8)
158: afc3001c sw v1,28(s8)
15c: afc20020 sw v0,32(s8)
160: 8e050000 lw a1,0(s0)
164: 8e040004 lw a0,4(s0)
168: 8e030008 lw v1,8(s0)
16c: 8e02000c lw v0,12(s0)
170: afc50008 sw a1,8(s8)
174: afc4000c sw a0,12(s8)
178: afc30010 sw v1,16(s8)
17c: afc20014 sw v0,20(s8)
180: 27c30044 addiu v1,s8,68
184: 24020064 li v0,100
188: 00602021 move a0,v1
18c: 00002821 move a1,zero
190: 00403021 move a2,v0
194: 0c000000 jal 0 <leaf_call>
198: 00000000 nop
19c: 2402004c li v0,76
1a0: a3c20044 sb v0,68(s8)
1a4: 27c50038 addiu a1,s8,56
1a8: 27c60028 addiu a2,s8,40
1ac: 27c30018 addiu v1,s8,24
1b0: 8fc200d4 lw v0,212(s8)
1b4: afa20000 sw v0,0(sp)
1b8: 8fc400ac lw a0,172(s8)
1bc: 8fc700b0 lw a3,176(s8)
1c0: 8fc800b4 lw t0,180(s8)
1c4: 00604821 move t1,v1
1c8: 27c20008 addiu v0,s8,8
1cc: 00405021 move t2,v0
1d0: 8fcb00d0 lw t3,208(s8)
1d4: 0c000000 jal 0 <leaf_call>
1d8: 00000000 nop
1dc: 03c0e821 move sp,s8
1e0: 8fbf00cc lw ra,204(sp)
1e4: 8fbe00c8 lw s8,200(sp)
1e8: 8fb300c4 lw s3,196(sp)
1ec: 8fb200c0 lw s2,192(sp)
1f0: 8fb100bc lw s1,188(sp)
1f4: 8fb000b8 lw s0,184(sp)
1f8: 27bd00d0 addiu sp,sp,208
1fc: 03e00008 jr ra
200: 00000000 nop
00000204 <main>:
204: 27bdffb0 addiu sp,sp,-80
208: afbf004c sw ra,76(sp)
20c: afbe0048 sw s8,72(sp)
210: 03a0f021 move s8,sp
214: 24020002 li v0,2
218: afc20038 sw v0,56(s8)
21c: 24020003 li v0,3
220: afc2003c sw v0,60(s8)
224: 8f820000 lw v0,0(gp)
228: afc20040 sw v0,64(s8)
22c: 8f820008 lw v0,8(gp)
230: 8f83000c lw v1,12(gp)
234: afc20028 sw v0,40(s8)
238: afc3002c sw v1,44(s8)
23c: 24020006 li v0,6
240: 00001821 move v1,zero
244: afc20030 sw v0,48(s8)
248: afc30034 sw v1,52(s8)
24c: 24020009 li v0,9
250: afc20018 sw v0,24(s8)
254: 2402000a li v0,10
258: afc2001c sw v0,28(s8)
25c: 8f820010 lw v0,16(gp)
260: afc20020 sw v0,32(s8)
264: 8f820018 lw v0,24(gp)
268: 8f83001c lw v1,28(gp)
26c: afc20008 sw v0,8(s8)
270: afc3000c sw v1,12(s8)
274: 2402000d li v0,13
278: 00001821 move v1,zero
27c: afc20010 sw v0,16(s8)
280: afc30014 sw v1,20(s8)
284: 27c60038 addiu a2,s8,56
288: 27c70028 addiu a3,s8,40
28c: 27c30018 addiu v1,s8,24
290: 2402000e li v0,14
294: afa20000 sw v0,0(sp)
298: 2402000f li v0,15
29c: afa20004 sw v0,4(sp)
2a0: 00002021 move a0,zero
2a4: 24050001 li a1,1
2a8: 24080007 li t0,7
2ac: 24090008 li t1,8
2b0: 00605021 move t2,v1
2b4: 27c20008 addiu v0,s8,8
2b8: 00405821 move t3,v0
2bc: 0c000000 jal 0 <leaf_call>
2c0: 00000000 nop
2c4: 00001021 move v0,zero
2c8: 03c0e821 move sp,s8
2cc: 8fbf004c lw ra,76(sp)
2d0: 8fbe0048 lw s8,72(sp)
2d4: 27bd0050 addiu sp,sp,80
2d8: 03e00008 jr ra
2dc: 00000000 nop
; ---------- returning structs by value ---------->
;
; struct Small { char x; };
; struct Big { long long i,j,k,l; long m; }; /* bigger than 16b */
;
; struct Small f0()
; {
; struct Small s = { 132 };
; return s;
; }
;
; struct Big f1()
; {
; struct Big b = { 7171LL, 99LL, -99LL, -3102LL, 32 };
; return b;
; }
;
; int main()
; {
; struct Small s = f0();
; struct Big b = f1();
; return b.j + b.k + b.m + s.x;
; }
; output from psptoolchain-20111215-psp w/ gcc 4.9.3
00000000 <f0>:
0: 27bdfff0 addiu sp,sp,-16
4: afbe000c sw s8,12(sp)
8: 03a0f021 move s8,sp
c: 2402ff84 li v0,-124
10: a3c20000 sb v0,0(s8)
14: 93c20000 lbu v0,0(s8)
18: 03c0e821 move sp,s8
1c: 8fbe000c lw s8,12(sp)
20: 27bd0010 addiu sp,sp,16
24: 03e00008 jr ra
28: 00000000 nop
0000002c <f1>:
2c: 27bdffc8 addiu sp,sp,-56
30: afbf0034 sw ra,52(sp)
34: afbe0030 sw s8,48(sp)
38: 03a0f021 move s8,sp
3c: afc40028 sw a0,40(s8)
40: 3c020000 lui v0,0x0
44: 03c02021 move a0,s8
48: 24430000 addiu v1,v0,0
4c: 24020028 li v0,40
50: 00602821 move a1,v1
54: 00403021 move a2,v0
58: 0c000000 jal 0 <f0>
5c: 00000000 nop
60: 8fc20028 lw v0,40(s8)
64: 00402021 move a0,v0
68: 03c01821 move v1,s8
6c: 24020028 li v0,40
70: 00602821 move a1,v1
74: 00403021 move a2,v0
78: 0c000000 jal 0 <f0>
7c: 00000000 nop
80: 8fc20028 lw v0,40(s8)
84: 03c0e821 move sp,s8
88: 8fbf0034 lw ra,52(sp)
8c: 8fbe0030 lw s8,48(sp)
90: 27bd0038 addiu sp,sp,56
94: 03e00008 jr ra
98: 00000000 nop
0000009c <main>:
9c: 27bdffc8 addiu sp,sp,-56
a0: afbf0034 sw ra,52(sp)
a4: afbe0030 sw s8,48(sp)
a8: 03a0f021 move s8,sp
ac: 0c000000 jal 0 <f0>
b0: 00000000 nop
b4: a3c20000 sb v0,0(s8)
b8: 27c20008 addiu v0,s8,8
bc: 00402021 move a0,v0
c0: 0c000000 jal 0 <f0>
c4: 00000000 nop
c8: 8fc20010 lw v0,16(s8)
cc: 8fc30014 lw v1,20(s8)
d0: 00402021 move a0,v0
d4: 8fc20018 lw v0,24(s8)
d8: 8fc3001c lw v1,28(s8)
dc: 00821021 addu v0,a0,v0
e0: 8fc30028 lw v1,40(s8)
e4: 00431021 addu v0,v0,v1
e8: 83c30000 lb v1,0(s8)
ec: 00431021 addu v0,v0,v1
f0: 03c0e821 move sp,s8
f4: 8fbf0034 lw ra,52(sp)
f8: 8fbe0030 lw s8,48(sp)
fc: 27bd0038 addiu sp,sp,56
100: 03e00008 jr ra
104: 00000000 nop
; ---------- returning long long ---------->
;
; long long f()
; {
; return 7171LL;
; }
;
; int main()
; {
; return (int)f();
; }
; output from psptoolchain-20111215-psp w/ gcc 4.9.3
00000000 <f>:
0: 27bdfff8 addiu sp,sp,-8
4: afbe0004 sw s8,4(sp)
8: 03a0f021 move s8,sp
c: 24021c03 li v0,7171
10: 00001821 move v1,zero
14: 03c0e821 move sp,s8
18: 8fbe0004 lw s8,4(sp)
1c: 27bd0008 addiu sp,sp,8
20: 03e00008 jr ra
24: 00000000 nop
00000028 <main>:
28: 27bdfff8 addiu sp,sp,-8
2c: afbf0004 sw ra,4(sp)
30: afbe0000 sw s8,0(sp)
34: 03a0f021 move s8,sp
38: 0c000000 jal 0 <f>
3c: 00000000 nop
40: 03c0e821 move sp,s8
44: 8fbf0004 lw ra,4(sp)
48: 8fbe0000 lw s8,0(sp)
4c: 27bd0008 addiu sp,sp,8
50: 03e00008 jr ra
54: 00000000 nop
; ---------- passing structs with only fp parts ---------->
;
; struct A { float a; };
; struct B { float a, b; };
; struct C { float a, b, c; };
; struct D { double a; };
; struct E { double a, b; };
; struct F { double a, b, c; };
;
; void leaf_call(struct A a, struct B b, struct C c, struct D d, struct E e, struct F f)
; {
; }
;
; int main()
; {
; leaf_call((struct A){1.f}, (struct B){2.f,3.f}, (struct C){4.f,5.f,6.f}, (struct D){1.}, (struct E){2.,3.}, (struct F){4.,5.,6.});
; return 0;
; }
; output from psptoolchain-20111215-psp w/ gcc 4.9.3
00000000 <leaf_call>:
0: 27bdff98 addiu sp,sp,-104
4: afbe0064 sw s8,100(sp)
8: afb30060 sw s3,96(sp)
c: afb2005c sw s2,92(sp)
10: afb10058 sw s1,88(sp)
14: afb00054 sw s0,84(sp)
18: 03a0f021 move s8,sp
1c: e7cc0040 swc1 $f12,64(s8)
20: 00809821 move s3,a0
24: 00a09021 move s2,a1
28: afc60048 sw a2,72(s8)
2c: afc7004c sw a3,76(s8)
30: 01008821 move s1,t0
34: 01208021 move s0,t1
38: 8e630000 lw v1,0(s3)
3c: 8e620004 lw v0,4(s3)
40: afc30034 sw v1,52(s8)
44: afc20038 sw v0,56(s8)
48: 8e440000 lw a0,0(s2)
4c: 8e430004 lw v1,4(s2)
50: 8e420008 lw v0,8(s2)
54: afc40028 sw a0,40(s8)
58: afc3002c sw v1,44(s8)
5c: afc20030 sw v0,48(s8)
60: 8e250000 lw a1,0(s1)
64: 8e240004 lw a0,4(s1)
68: 8e230008 lw v1,8(s1)
6c: 8e22000c lw v0,12(s1)
70: afc50018 sw a1,24(s8)
74: afc4001c sw a0,28(s8)
78: afc30020 sw v1,32(s8)
7c: afc20024 sw v0,36(s8)
80: 8e070000 lw a3,0(s0)
84: 8e060004 lw a2,4(s0)
88: 8e050008 lw a1,8(s0)
8c: 8e04000c lw a0,12(s0)
90: 8e030010 lw v1,16(s0)
94: 8e020014 lw v0,20(s0)
98: afc70000 sw a3,0(s8)
9c: afc60004 sw a2,4(s8)
a0: afc50008 sw a1,8(s8)
a4: afc4000c sw a0,12(s8)
a8: afc30010 sw v1,16(s8)
ac: afc20014 sw v0,20(s8)
b0: 03c0e821 move sp,s8
b4: 8fbe0064 lw s8,100(sp)
b8: 8fb30060 lw s3,96(sp)
bc: 8fb2005c lw s2,92(sp)
c0: 8fb10058 lw s1,88(sp)
c4: 8fb00054 lw s0,84(sp)
c8: 27bd0068 addiu sp,sp,104
cc: 03e00008 jr ra
d0: 00000000 nop
000000d4 <main>:
d4: 27bdffb0 addiu sp,sp,-80
d8: afbf004c sw ra,76(sp)
dc: afbe0048 sw s8,72(sp)
e0: 03a0f021 move s8,sp
e4: 8f820000 lw v0,0(gp)
e8: afc20044 sw v0,68(s8)
ec: 8f820004 lw v0,4(gp)
f0: afc2003c sw v0,60(s8)
f4: 8f820008 lw v0,8(gp)
f8: afc20040 sw v0,64(s8)
fc: 8f82000c lw v0,12(gp)
100: afc20030 sw v0,48(s8)
104: 8f820010 lw v0,16(gp)
108: afc20034 sw v0,52(s8)
10c: 8f820014 lw v0,20(gp)
110: afc20038 sw v0,56(s8)
114: 8f820018 lw v0,24(gp)
118: 8f83001c lw v1,28(gp)
11c: afc20028 sw v0,40(s8)
120: afc3002c sw v1,44(s8)
124: 8f820020 lw v0,32(gp)
128: 8f830024 lw v1,36(gp)
12c: afc20018 sw v0,24(s8)
130: afc3001c sw v1,28(s8)
134: 8f820028 lw v0,40(gp)
138: 8f83002c lw v1,44(gp)
13c: afc20020 sw v0,32(s8)
140: afc30024 sw v1,36(s8)
144: 8f820030 lw v0,48(gp)
148: 8f830034 lw v1,52(gp)
14c: afc20000 sw v0,0(s8)
150: afc30004 sw v1,4(s8)
154: 8f820038 lw v0,56(gp)
158: 8f83003c lw v1,60(gp)
15c: afc20008 sw v0,8(s8)
160: afc3000c sw v1,12(s8)
164: 8f820040 lw v0,64(gp)
168: 8f830044 lw v1,68(gp)
16c: afc20010 sw v0,16(s8)
170: afc30014 sw v1,20(s8)
174: 27c4003c addiu a0,s8,60
178: 27c30030 addiu v1,s8,48
17c: 27c20018 addiu v0,s8,24
180: c7cc0044 lwc1 $f12,68(s8)
184: 00602821 move a1,v1
188: 8fc60028 lw a2,40(s8)
18c: 8fc7002c lw a3,44(s8)
190: 00404021 move t0,v0
194: 03c04821 move t1,s8
198: 0c000000 jal 0 <leaf_call>
19c: 00000000 nop
1a0: 00001021 move v0,zero
1a4: 03c0e821 move sp,s8
1a8: 8fbf004c lw ra,76(sp)
1ac: 8fbe0048 lw s8,72(sp)
1b0: 27bd0050 addiu sp,sp,80
1b4: 03e00008 jr ra
1b8: 00000000 nop
; ---------- single-field structs by values (and small array fields) ---------->
;
; struct C { char c; };
; struct S { short s; };
; struct I { int i; };
; struct F { float f; };
; struct D { double d; };
;
; struct C2 { char c[2]; };
; struct C3 { char c[3]; };
;
; void leaf_call(struct C2 a, struct C b, struct S c, struct I d, struct F e, struct D f, struct C3 g)
; {
; }
;
; int main()
; {
; leaf_call((struct C2){{0,1}}, (struct C){2}, (struct S){3}, (struct I){4}, (struct F){5.f}, (struct D){6.}, (struct C3){{7,8,9}});
; return 0;
; }
; output from psptoolchain-20111215-psp w/ gcc 4.9.3
00000000 <leaf_call>:
0: 27bdffd8 addiu sp,sp,-40
4: afbe0024 sw s8,36(sp)
8: 03a0f021 move s8,sp
c: a7c40000 sh a0,0(s8)
10: a3c50004 sb a1,4(s8)
14: a7c60008 sh a2,8(s8)
18: afc7000c sw a3,12(s8)
1c: e7cc0010 swc1 $f12,16(s8)
20: afc80018 sw t0,24(s8)
24: afc9001c sw t1,28(s8)
28: afca0014 sw t2,20(s8)
2c: 03c0e821 move sp,s8
30: 8fbe0024 lw s8,36(sp)
34: 27bd0028 addiu sp,sp,40
38: 03e00008 jr ra
3c: 00000000 nop
00000040 <main>:
40: 27bdffd0 addiu sp,sp,-48
44: afbf002c sw ra,44(sp)
48: afbe0028 sw s8,40(sp)
4c: 03a0f021 move s8,sp
50: a3c00020 sb zero,32(s8)
54: 24020001 li v0,1
58: a3c20021 sb v0,33(s8)
5c: 24020002 li v0,2
60: a3c2001c sb v0,28(s8)
64: 24020003 li v0,3
68: a7c20018 sh v0,24(s8)
6c: 24020004 li v0,4
70: afc20014 sw v0,20(s8)
74: 8f820000 lw v0,0(gp)
78: afc20010 sw v0,16(s8)
7c: 8f820008 lw v0,8(gp)
80: 8f83000c lw v1,12(gp)
84: afc20008 sw v0,8(s8)
88: afc3000c sw v1,12(s8)
8c: 24020007 li v0,7
90: a3c20000 sb v0,0(s8)
94: 24020008 li v0,8
98: a3c20001 sb v0,1(s8)
9c: 24020009 li v0,9
a0: a3c20002 sb v0,2(s8)
a4: 8fc40020 lw a0,32(s8)
a8: 93c5001c lbu a1,28(s8)
ac: 97c60018 lhu a2,24(s8)
b0: 8fc70014 lw a3,20(s8)
b4: c7cc0010 lwc1 $f12,16(s8)
b8: 8fc80008 lw t0,8(s8)
bc: 8fc9000c lw t1,12(s8)
c0: 8fca0000 lw t2,0(s8)
c4: 0c000000 jal 0 <leaf_call>
c8: 00000000 nop
cc: 00001021 move v0,zero
d0: 03c0e821 move sp,s8
d4: 8fbf002c lw ra,44(sp)
d8: 8fbe0028 lw s8,40(sp)
dc: 27bd0030 addiu sp,sp,48
e0: 03e00008 jr ra
e4: 00000000 nop
; ---------- C++ trivial and non-trivial aggrs passed to C funcs ---------->
;
; struct Trivial { int a; };
; struct NonTrivial { int a; NonTrivial() : a(0) {} NonTrivial(const NonTrivial& rhs) : a(rhs.a) { } };
;
; extern "C" {
;
; void f1(struct Trivial s) { }
; void f2(struct NonTrivial s) { }
;
; void f()
; {
; struct Trivial t;
; struct NonTrivial n;
; int a=1;
; a += 123;
; f1(t);
; a -= 123;
; f2(n);
; a -= 12;
; }
; }
; output from psptoolchain-20111215-psp w/ gcc 4.9.3
00000000 <f1>:
0: 27bdfff0 addiu sp,sp,-16
4: afbe000c sw s8,12(sp)
8: 03a0f021 move s8,sp
c: afc40000 sw a0,0(s8)
10: 03c0e821 move sp,s8
14: 8fbe000c lw s8,12(sp)
18: 27bd0010 addiu sp,sp,16
1c: 03e00008 jr ra
20: 00000000 nop
00000024 <f2>:
24: 27bdfff0 addiu sp,sp,-16
28: afbe000c sw s8,12(sp)
2c: 03a0f021 move s8,sp
30: afc40000 sw a0,0(s8)
34: 03c0e821 move sp,s8
38: 8fbe000c lw s8,12(sp)
3c: 27bd0010 addiu sp,sp,16
40: 03e00008 jr ra
44: 00000000 nop
00000048 <f>:
48: 27bdffe8 addiu sp,sp,-24 ;
4c: afbf0014 sw ra,20(sp) ;
50: afbe0010 sw s8,16(sp) ;
54: 03a0f021 move s8,sp ;
58: 27c2000c addiu v0,s8,12 ;
5c: 00402021 move a0,v0 ; |
60: 0c000000 jal 0 <f1> ; | NonTrivial::NonTrivial() / ctor
64: 00000000 nop ;
68: 24020001 li v0,1 ; a = 1
6c: afc20000 sw v0,0(s8) ;
70: 8fc20000 lw v0,0(s8) ;
74: 2442007b addiu v0,v0,123 ; a += 123
78: afc20000 sw v0,0(s8) ;
7c: 8fc40008 lw a0,8(s8) ; |
80: 0c000000 jal 0 <f1> ; | call f1(struct Trivial)
84: 00000000 nop ;
88: 8fc20000 lw v0,0(s8) ;
8c: 2442ff85 addiu v0,v0,-123 ; a -= 123
90: afc20000 sw v0,0(s8) ;
94: 27c30004 addiu v1,s8,4 ;
98: 27c2000c addiu v0,s8,12 ;
9c: 00602021 move a0,v1 ; | ptr to dest of copy of n
a0: 00402821 move a1,v0 ; | copy n ptr to n
a4: 0c000000 jal 0 <f1> ; | | NonTrivial::NonTrivial(const NonTrivial&) / copy ctor
a8: 00000000 nop ;
ac: 27c20004 addiu v0,s8,4 ; get ptr to copy of n -> v0
b0: 00402021 move a0,v0 ; f2 arg 0 (ptr to copy of struct NonTrivial), via ptr as non-trivial
b4: 0c000000 jal 0 <f1> ; call f2(struct NonTrivial)
b8: 00000000 nop ;
bc: 8fc20000 lw v0,0(s8) ;
c0: 2442fff4 addiu v0,v0,-12 ; a -= 12
c4: afc20000 sw v0,0(s8) ;
c8: 03c0e821 move sp,s8 ;
cc: 8fbf0014 lw ra,20(sp) ;
d0: 8fbe0010 lw s8,16(sp) ;
d4: 27bd0018 addiu sp,sp,24 ;
d8: 03e00008 jr ra ;
dc: 00000000 nop ;
; ... snip, removed code of ctor and copy ctor ...
; ---------- C++ trivial and non-trivial aggrs as return values ---------->
;
; struct Trivial { int a; };
; struct NonTrivial { int a; NonTrivial() : a(0) {} NonTrivial(const NonTrivial& rhs) : a(rhs.a) { } };
;
; extern "C" {
; struct Trivial f1() { return Trivial(); }
; }
;
; struct NonTrivial f2() { return NonTrivial(); }
;
; extern "C" {
; void f()
; {
; int a=1;
; a += 123;
; struct Trivial t = f1();
; a -= 123;
; struct NonTrivial n = f2();
; a -= 12;
; }
; }
; output from psptoolchain-20111215-psp w/ gcc 4.9.3
00000000 <f1>:
0: 27bdfff8 addiu sp,sp,-8
4: afbe0004 sw s8,4(sp)
8: 03a0f021 move s8,sp
c: 00001021 move v0,zero
10: 03c0e821 move sp,s8
14: 8fbe0004 lw s8,4(sp)
18: 27bd0008 addiu sp,sp,8
1c: 03e00008 jr ra
20: 00000000 nop
00000024 <_Z2f2v>:
24: 27bdfff0 addiu sp,sp,-16 ;
28: afbf000c sw ra,12(sp) ;
2c: afbe0008 sw s8,8(sp) ;
30: 03a0f021 move s8,sp ;
34: afc40000 sw a0,0(s8) ;
38: 8fc40000 lw a0,0(s8) ;
3c: 0c000000 jal 0 <f1> ;
40: 00000000 nop ;
44: 8fc20000 lw v0,0(s8) ; retval, return (hidden) passed-in ptr to space for retval
48: 03c0e821 move sp,s8 ;
4c: 8fbf000c lw ra,12(sp) ;
50: 8fbe0008 lw s8,8(sp) ;
54: 27bd0010 addiu sp,sp,16 ;
58: 03e00008 jr ra ;
5c: 00000000 nop ;
00000060 <f>:
60: 27bdffe8 addiu sp,sp,-24 ;
64: afbf0014 sw ra,20(sp) ;
68: afbe0010 sw s8,16(sp) ;
6c: 03a0f021 move s8,sp ;
70: 24020001 li v0,1 ; a = 1
74: afc20000 sw v0,0(s8) ;
78: 8fc20000 lw v0,0(s8) ;
7c: 2442007b addiu v0,v0,123 ; a += 123
80: afc20000 sw v0,0(s8) ;
84: 0c000000 jal 0 <f1> ; call f1(), struct returned via as trivial and <= 64bit
88: 00000000 nop ;
8c: afc20004 sw v0,4(s8) ;
90: 8fc20000 lw v0,0(s8) ;
94: 2442ff85 addiu v0,v0,-123 ; a -= 123
98: afc20000 sw v0,0(s8) ;
9c: 27c20008 addiu v0,s8,8 ;
a0: 00402021 move a0,v0 ; hidden first arg (ptr to space for ret val)
a4: 0c000000 jal 0 <f1> ; call f2(), result returned indirectly as struct nontrivial
a8: 00000000 nop ;
ac: 8fc20000 lw v0,0(s8) ;
b0: 2442fff4 addiu v0,v0,-12 ; a -= 12
b4: afc20000 sw v0,0(s8) ;
b8: 03c0e821 move sp,s8 ;
bc: 8fbf0014 lw ra,20(sp) ;
c0: 8fbe0010 lw s8,16(sp) ;
c4: 27bd0018 addiu sp,sp,24 ;
c8: 03e00008 jr ra ;
cc: 00000000 nop ;
; ... snip, removed code of ctor ...
; vim: ft=asm