Mercurial > pub > dyncall > dyncall
view doc/disas_examples/mips.o32.disas @ 499:fc614cb865c6
- doc and disasexample additions specific to non-trivial C++ aggregates as return values (incl. fixes to doc and additional LSB specific PPC32 section)
author | Tassilo Philipp |
---|---|
date | Mon, 04 Apr 2022 15:50:52 +0200 |
parents | fd9ba3a6d348 |
children |
line wrap: on
line source
; #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 freebsd-12.0_r333647-malta_mipselhf w/ gcc 4.2.1 -----> 00000000 <leaf_call>: 0: 3c1c0000 lui gp,0x0 4: 279c0000 addiu gp,gp,0 8: 0399e021 addu gp,gp,t9 c: 27bdfff8 addiu sp,sp,-8 10: afbe0000 sw s8,0(sp) 14: 03a0f021 move s8,sp 18: afc40008 sw a0,8(s8) 1c: afc5000c sw a1,12(s8) 20: afc60010 sw a2,16(s8) 24: afc70014 sw a3,20(s8) 28: 03c0e821 move sp,s8 2c: 8fbe0000 lw s8,0(sp) 30: 03e00008 jr ra 34: 27bd0008 addiu sp,sp,8 00000038 <nonleaf_call>: 38: 3c1c0000 lui gp,0x0 ; | 3c: 279c0000 addiu gp,gp,0 ; | 40: 0399e021 addu gp,gp,t9 ; | 44: 27bdffc8 addiu sp,sp,-56 ; | prolog 48: afbf0034 sw ra,52(sp) ; | 4c: afbe0030 sw s8,48(sp) ; | 50: 03a0f021 move s8,sp ; | frame pointer (note: with offset to frame start, but static compared to sp) 54: afbc0020 sw gp,32(sp) ; / 58: afc40038 sw a0,56(s8) ; \ 5c: afc5003c sw a1,60(s8) ; | 60: afc60040 sw a2,64(s8) ; | spill first 4 args into prev frame's reserved spill space in param area (although not actually needing to spill, here but just do a temp copy, but space is reserved for them anyways) 64: afc70044 sw a3,68(s8) ; | 68: 27bdff18 addiu sp,sp,-232 ; alloca(220) - with padding to guarantee alignment 6c: 27a20020 addiu v0,sp,32 ; | 70: afc20028 sw v0,40(s8) ; | 74: 8fc30028 lw v1,40(s8) ; | start of alloca()'d memory -> v1, by ... 78: 24620007 addiu v0,v1,7 ; | ... using v0 as helper to align to 8b 7c: 000210c2 srl v0,v0,0x3 ; | @@@ unsure about use of helper space at 40(s8) in prev frame..? 80: 000210c0 sll v0,v0,0x3 ; | 84: afc20028 sw v0,40(s8) ; | 88: 8fc30028 lw v1,40(s8) ; | 8c: 2402004c li v0,76 ; 'L' -> v0, and... 90: a0620000 sb v0,0(v1) ; ... store in local area (of alloca()'d space) 94: 8fc2004c lw v0,76(s8) ; arg 4 (fetched from prev frame's param area), and ... 98: afa20010 sw v0,16(sp) ; ... "pushed" onto stack 9c: 8fc20050 lw v0,80(s8) ; arg 5 (fetched from prev frame's param area), and ... a0: afa20014 sw v0,20(sp) ; ... "pushed" onto stack a4: 8fc20054 lw v0,84(s8) ; arg 6 (fetched from prev frame's param area), and ... a8: afa20018 sw v0,24(sp) ; ... "pushed" onto stack ac: 8fc4003c lw a0,60(s8) ; arg 0 (fetched from spill area of prev frame) b0: 8fc50040 lw a1,64(s8) ; arg 1 (fetched from spill area of prev frame) b4: 8fc60044 lw a2,68(s8) ; arg 2 (fetched from spill area of prev frame) b8: 8fc70048 lw a3,72(s8) ; arg 3 (fetched from prev frame's param area) bc: 8f990000 lw t9,0(gp) ; func to call -> t9 c0: 0320f809 jalr t9 ; call and ret addr -> ra c4: 00000000 nop ; branch delay slot c8: 8fdc0020 lw gp,32(s8) ; | cc: 03c0e821 move sp,s8 ; | d0: 8fbf0034 lw ra,52(sp) ; | d4: 8fbe0030 lw s8,48(sp) ; | epilog d8: 03e00008 jr ra ; | dc: 27bd0038 addiu sp,sp,56 ; | 000000e0 <main>: e0: 3c1c0000 lui gp,0x0 ; | e4: 279c0000 addiu gp,gp,0 ; | e8: 0399e021 addu gp,gp,t9 ; | ec: 27bdffd0 addiu sp,sp,-48 ; | prolog f0: afbf002c sw ra,44(sp) ; | f4: afbe0028 sw s8,40(sp) ; | f8: 03a0f021 move s8,sp ; | frame pointer (note: with offset to frame start, but static compared to sp) fc: afbc0020 sw gp,32(sp) ; | 100: 24020004 li v0,4 ; arg 4, and ... 104: afa20010 sw v0,16(sp) ; ... "pushed" onto stack 108: 24020005 li v0,5 ; arg 5, and ... 10c: afa20014 sw v0,20(sp) ; ... "pushed" onto stack 110: 24020006 li v0,6 ; arg 6, and ... 114: afa20018 sw v0,24(sp) ; ... "pushed" onto stack 118: 24020007 li v0,7 ; arg 7, and ... 11c: afa2001c sw v0,28(sp) ; ... "pushed" onto stack 120: 00002021 move a0,zero ; arg 0 124: 24050001 li a1,1 ; arg 1 128: 24060002 li a2,2 ; arg 2 12c: 24070003 li a3,3 ; arg 3 130: 8f990000 lw t9,0(gp) ; func to call -> t9 134: 0320f809 jalr t9 ; call and ret addr -> ra 138: 00000000 nop ; branch delay slot 13c: 8fdc0020 lw gp,32(s8) ; | 140: 00001021 move v0,zero ; : return value: not part of epilog, but unordered (branch delay slot style) 144: 03c0e821 move sp,s8 ; | 148: 8fbf002c lw ra,44(sp) ; | epilog 14c: 8fbe0028 lw s8,40(sp) ; | 150: 03e00008 jr ra ; | 154: 27bd0030 addiu sp,sp,48 ; | ; output from netbsd-5.0.2-pmax_mipsel_o32 w/ gcc 4.1.3 -----> ; nearly the same, equivalent to above except non-optimal use of branch delay slots and $gp preserving in leaf call 00000000 <leaf_call>: 0: 27bdfff8 addiu sp,sp,-8 4: afbe0000 sw s8,0(sp) 8: 03a0f021 move s8,sp c: afc40008 sw a0,8(s8) 10: afc5000c sw a1,12(s8) 14: afc60010 sw a2,16(s8) 18: afc70014 sw a3,20(s8) 1c: 03c0e821 move sp,s8 20: 8fbe0000 lw s8,0(sp) 24: 27bd0008 addiu sp,sp,8 28: 03e00008 jr ra 2c: 00000000 nop 00000030 <nonleaf_call>: 30: 3c1c0000 lui gp,0x0 34: 279c0000 addiu gp,gp,0 38: 0399e021 addu gp,gp,t9 3c: 27bdffc8 addiu sp,sp,-56 40: afbf0034 sw ra,52(sp) 44: afbe0030 sw s8,48(sp) 48: 03a0f021 move s8,sp 4c: afbc0020 sw gp,32(sp) 50: afc40038 sw a0,56(s8) 54: afc5003c sw a1,60(s8) 58: afc60040 sw a2,64(s8) 5c: afc70044 sw a3,68(s8) 60: 27bdff18 addiu sp,sp,-232 64: 27a20020 addiu v0,sp,32 68: afc20028 sw v0,40(s8) 6c: 8fc30028 lw v1,40(s8) 70: 00000000 nop 74: 24620007 addiu v0,v1,7 78: 000210c2 srl v0,v0,0x3 7c: 000210c0 sll v0,v0,0x3 80: afc20028 sw v0,40(s8) 84: 8fc30028 lw v1,40(s8) 88: 2402004c li v0,76 8c: a0620000 sb v0,0(v1) 90: 8fc2004c lw v0,76(s8) 94: 00000000 nop 98: afa20010 sw v0,16(sp) 9c: 8fc20050 lw v0,80(s8) a0: 00000000 nop a4: afa20014 sw v0,20(sp) a8: 8fc20054 lw v0,84(s8) ac: 00000000 nop b0: afa20018 sw v0,24(sp) b4: 8fc4003c lw a0,60(s8) b8: 8fc50040 lw a1,64(s8) bc: 8fc60044 lw a2,68(s8) c0: 8fc70048 lw a3,72(s8) c4: 8f990000 lw t9,0(gp) c8: 00000000 nop cc: 0320f809 jalr t9 d0: 00000000 nop d4: 8fdc0020 lw gp,32(s8) d8: 03c0e821 move sp,s8 dc: 8fbf0034 lw ra,52(sp) e0: 8fbe0030 lw s8,48(sp) e4: 27bd0038 addiu sp,sp,56 e8: 03e00008 jr ra ec: 00000000 nop 000000f0 <main>: f0: 3c1c0000 lui gp,0x0 f4: 279c0000 addiu gp,gp,0 f8: 0399e021 addu gp,gp,t9 fc: 27bdffd0 addiu sp,sp,-48 100: afbf002c sw ra,44(sp) 104: afbe0028 sw s8,40(sp) 108: 03a0f021 move s8,sp 10c: afbc0020 sw gp,32(sp) 110: 24020004 li v0,4 114: afa20010 sw v0,16(sp) 118: 24020005 li v0,5 11c: afa20014 sw v0,20(sp) 120: 24020006 li v0,6 124: afa20018 sw v0,24(sp) 128: 24020007 li v0,7 12c: afa2001c sw v0,28(sp) 130: 00002021 move a0,zero 134: 24050001 li a1,1 138: 24060002 li a2,2 13c: 24070003 li a3,3 140: 8f990000 lw t9,0(gp) 144: 00000000 nop 148: 0320f809 jalr t9 14c: 00000000 nop 150: 8fdc0020 lw gp,32(s8) 154: 00001021 move v0,zero 158: 03c0e821 move sp,s8 15c: 8fbf002c lw ra,44(sp) 160: 8fbe0028 lw s8,40(sp) 164: 27bd0030 addiu sp,sp,48 168: 03e00008 jr ra 16c: 00000000 nop ; ---------- 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 freebsd-12.0_r333647-malta_mipsebhf w/ gcc 4.2.1 -----> 00000000 <leaf_call>: 0: 3c1c0000 lui gp,0x0 4: 279c0000 addiu gp,gp,0 8: 0399e021 addu gp,gp,t9 c: 27bdfff8 addiu sp,sp,-8 10: afbe0000 sw s8,0(sp) 14: 03a0f021 move s8,sp 18: afc40008 sw a0,8(s8) 1c: afc5000c sw a1,12(s8) 20: afc60010 sw a2,16(s8) 24: afc70014 sw a3,20(s8) 28: 03c0e821 move sp,s8 2c: 8fbe0000 lw s8,0(sp) 30: 03e00008 jr ra 34: 27bd0008 addiu sp,sp,8 00000038 <nonleaf_call>: 38: 3c1c0000 lui gp,0x0 3c: 279c0000 addiu gp,gp,0 40: 0399e021 addu gp,gp,t9 44: 27bdff60 addiu sp,sp,-160 48: afbf009c sw ra,156(sp) 4c: afbe0098 sw s8,152(sp) 50: 03a0f021 move s8,sp 54: afbc0028 sw gp,40(sp) 58: afc400a0 sw a0,160(s8) 5c: afc500a4 sw a1,164(s8) 60: afc600a8 sw a2,168(s8) 64: afc700ac sw a3,172(s8) 68: 27c20030 addiu v0,s8,48 6c: 24030064 li v1,100 70: 00402021 move a0,v0 74: 00002821 move a1,zero 78: 00603021 move a2,v1 7c: 8f990000 lw t9,0(gp) 80: 0320f809 jalr t9 84: 00000000 nop 88: 8fdc0028 lw gp,40(s8) 8c: 2402004c li v0,76 90: a3c20030 sb v0,48(s8) 94: 8fc200b8 lw v0,184(s8) 98: 8fc300bc lw v1,188(s8) 9c: 8fc400c0 lw a0,192(s8) a0: 8fc500c4 lw a1,196(s8) a4: afa20010 sw v0,16(sp) a8: afa30014 sw v1,20(sp) ac: afa40018 sw a0,24(sp) b0: afa5001c sw a1,28(sp) b4: 8fc200c8 lw v0,200(s8) b8: afa20020 sw v0,32(sp) bc: 8fc200cc lw v0,204(s8) c0: afa20024 sw v0,36(sp) c4: 8fc400a4 lw a0,164(s8) c8: 8fc500a8 lw a1,168(s8) cc: 8fc600ac lw a2,172(s8) d0: 8fc700b0 lw a3,176(s8) d4: 8f990000 lw t9,0(gp) d8: 0320f809 jalr t9 dc: 00000000 nop e0: 8fdc0028 lw gp,40(s8) e4: 03c0e821 move sp,s8 e8: 8fbf009c lw ra,156(sp) ec: 8fbe0098 lw s8,152(sp) f0: 03e00008 jr ra f4: 27bd00a0 addiu sp,sp,160 000000f8 <main>: f8: 3c1c0000 lui gp,0x0 ; | fc: 279c0000 addiu gp,gp,0 ; | 100: 0399e021 addu gp,gp,t9 ; | 104: 27bdffb0 addiu sp,sp,-80 ; | prolog 108: afbf004c sw ra,76(sp) ; | 10c: afbe0048 sw s8,72(sp) ; | 110: 03a0f021 move s8,sp ; | frame pointer (note: with offset to frame start, but static compared to sp) 114: afbc0030 sw gp,48(sp) ; / 118: 8f820000 lw v0,0(gp) ; \ \ 11c: 24420000 addiu v0,v0,0 ; | | field j -> v0 120: 8c420000 lw v0,0(v0) ; | / 124: 8f830000 lw v1,0(gp) ; | \ 128: 24630000 addiu v1,v1,0 ; | | field j -> v1 12c: 8c630004 lw v1,4(v1) ; | prep local struct A data ... / 130: 8f840000 lw a0,0(gp) ; | \ 134: 24840000 addiu a0,a0,0 ; | | 138: 8c840008 lw a0,8(a0) ; | | field l -> a0 & a1 13c: 8f850000 lw a1,0(gp) ; | | 140: 24a50000 addiu a1,a1,0 ; | | 144: 8ca5000c lw a1,12(a1) ; / / 148: afc20038 sw v0,56(s8) ; \ 14c: afc3003c sw v1,60(s8) ; | ... and write to local area 150: afc40040 sw a0,64(s8) ; | 154: afc50044 sw a1,68(s8) ; / 158: 24020004 li v0,4 ; push arg 4 ... 15c: afa20010 sw v0,16(sp) ; ... onto stack 160: 8fc20038 lw v0,56(s8) ; \ 164: 8fc3003c lw v1,60(s8) ; | 168: 8fc40040 lw a0,64(s8) ; | prep arg 5 (struct A) ... 16c: 8fc50044 lw a1,68(s8) ; / 170: afa20018 sw v0,24(sp) ; \ 174: afa3001c sw v1,28(sp) ; | ... and push onto stack 178: afa40020 sw a0,32(sp) ; | 17c: afa50024 sw a1,36(sp) ; / 180: 24020008 li v0,8 ; push arg 6 ... 184: afa20028 sw v0,40(sp) ; ... onto stack 188: 24020009 li v0,9 ; push arg 7 ... 18c: afa2002c sw v0,44(sp) ; ... onto stack 190: 00002021 move a0,zero ; arg 0 194: 24050001 li a1,1 ; arg 1 198: 24060002 li a2,2 ; arg 2 19c: 24070003 li a3,3 ; arg 3 1a0: 8f990000 lw t9,0(gp) ; func to call -> t9 1a4: 0320f809 jalr t9 ; call and ret addr -> ra 1a8: 00000000 nop ; branch delay slot 1ac: 8fdc0030 lw gp,48(s8) ; | 1b0: 00001021 move v0,zero ; : return value: not part of epilog, but unordered (branch delay slot style) 1b4: 03c0e821 move sp,s8 ; | 1b8: 8fbf004c lw ra,76(sp) ; | epilog 1bc: 8fbe0048 lw s8,72(sp) ; | 1c0: 03e00008 jr ra ; | 1c4: 27bd0050 addiu sp,sp,80 ; | ... ; output from freebsd-12.0_r333647-malta_mipsebhf w/ gcc 4.2.1 *and* -mhard-float -----> 00000000 <leaf_call>: 0: 3c1c0000 lui gp,0x0 4: 279c0000 addiu gp,gp,0 8: 0399e021 addu gp,gp,t9 c: 27bdfff8 addiu sp,sp,-8 10: afbe0000 sw s8,0(sp) 14: 03a0f021 move s8,sp 18: afc40008 sw a0,8(s8) 1c: afc5000c sw a1,12(s8) 20: afc60010 sw a2,16(s8) 24: afc70014 sw a3,20(s8) 28: 03c0e821 move sp,s8 2c: 8fbe0000 lw s8,0(sp) 30: 03e00008 jr ra 34: 27bd0008 addiu sp,sp,8 00000038 <nonleaf_call>: 38: 3c1c0000 lui gp,0x0 3c: 279c0000 addiu gp,gp,0 40: 0399e021 addu gp,gp,t9 44: 27bdff60 addiu sp,sp,-160 48: afbf009c sw ra,156(sp) 4c: afbe0098 sw s8,152(sp) 50: 03a0f021 move s8,sp 54: afbc0028 sw gp,40(sp) 58: afc400a0 sw a0,160(s8) 5c: afc500a4 sw a1,164(s8) 60: afc600a8 sw a2,168(s8) 64: afc700ac sw a3,172(s8) 68: 27c20030 addiu v0,s8,48 6c: 24030064 li v1,100 70: 00402021 move a0,v0 74: 00002821 move a1,zero 78: 00603021 move a2,v1 7c: 8f990000 lw t9,0(gp) 80: 0320f809 jalr t9 84: 00000000 nop 88: 8fdc0028 lw gp,40(s8) 8c: 2402004c li v0,76 90: a3c20030 sb v0,48(s8) 94: 8fc200b8 lw v0,184(s8) 98: 8fc300bc lw v1,188(s8) 9c: 8fc400c0 lw a0,192(s8) a0: 8fc500c4 lw a1,196(s8) a4: afa20010 sw v0,16(sp) a8: afa30014 sw v1,20(sp) ac: afa40018 sw a0,24(sp) b0: afa5001c sw a1,28(sp) b4: 8fc200c8 lw v0,200(s8) b8: afa20020 sw v0,32(sp) bc: 8fc200cc lw v0,204(s8) c0: afa20024 sw v0,36(sp) c4: 8fc400a4 lw a0,164(s8) c8: 8fc500a8 lw a1,168(s8) cc: 8fc600ac lw a2,172(s8) d0: 8fc700b0 lw a3,176(s8) d4: 8f990000 lw t9,0(gp) d8: 0320f809 jalr t9 dc: 00000000 nop e0: 8fdc0028 lw gp,40(s8) e4: 03c0e821 move sp,s8 e8: 8fbf009c lw ra,156(sp) ec: 8fbe0098 lw s8,152(sp) f0: 03e00008 jr ra f4: 27bd00a0 addiu sp,sp,160 000000f8 <main>: f8: 3c1c0000 lui gp,0x0 ; | fc: 279c0000 addiu gp,gp,0 ; | 100: 0399e021 addu gp,gp,t9 ; | 104: 27bdffb0 addiu sp,sp,-80 ; | prolog 108: afbf004c sw ra,76(sp) ; | 10c: afbe0048 sw s8,72(sp) ; | 110: 03a0f021 move s8,sp ; | frame pointer (note: with offset to frame start, but static compared to sp) 114: afbc0030 sw gp,48(sp) ; / 118: 8f820000 lw v0,0(gp) ; \ \ 11c: 24420000 addiu v0,v0,0 ; | | field j -> v0 120: 8c420000 lw v0,0(v0) ; | / 124: 8f830000 lw v1,0(gp) ; | \ 128: 24630000 addiu v1,v1,0 ; | | field j -> v1 12c: 8c630004 lw v1,4(v1) ; | prep local struct A data ... / 130: 8f840000 lw a0,0(gp) ; | \ 134: 24840000 addiu a0,a0,0 ; | | 138: 8c840008 lw a0,8(a0) ; | | field l -> a0 & a1 13c: 8f850000 lw a1,0(gp) ; | | 140: 24a50000 addiu a1,a1,0 ; | | 144: 8ca5000c lw a1,12(a1) ; / / 148: afc20038 sw v0,56(s8) ; \ 14c: afc3003c sw v1,60(s8) ; | ... and write to local area 150: afc40040 sw a0,64(s8) ; | 154: afc50044 sw a1,68(s8) ; / 158: 24020004 li v0,4 ; push arg 4 ... 15c: afa20010 sw v0,16(sp) ; ... onto stack 160: 8fc20038 lw v0,56(s8) ; \ 164: 8fc3003c lw v1,60(s8) ; | 168: 8fc40040 lw a0,64(s8) ; | prep arg 5 (struct A) ... 16c: 8fc50044 lw a1,68(s8) ; / 170: afa20018 sw v0,24(sp) ; \ 174: afa3001c sw v1,28(sp) ; | ... and push onto stack 178: afa40020 sw a0,32(sp) ; | 17c: afa50024 sw a1,36(sp) ; / 180: 24020008 li v0,8 ; push arg 6 ... 184: afa20028 sw v0,40(sp) ; ... onto stack 188: 24020009 li v0,9 ; push arg 7 ... 18c: afa2002c sw v0,44(sp) ; ... onto stack 190: 00002021 move a0,zero ; arg 0 194: 24050001 li a1,1 ; arg 1 198: 24060002 li a2,2 ; arg 2 19c: 24070003 li a3,3 ; arg 3 1a0: 8f990000 lw t9,0(gp) ; func to call -> t9 1a4: 0320f809 jalr t9 ; call and ret addr -> ra 1a8: 00000000 nop ; branch delay slot 1ac: 8fdc0030 lw gp,48(s8) ; | 1b0: 00001021 move v0,zero ; : return value: not part of epilog, but unordered (branch delay slot style) 1b4: 03c0e821 move sp,s8 ; | 1b8: 8fbf004c lw ra,76(sp) ; | epilog 1bc: 8fbe0048 lw s8,72(sp) ; | 1c0: 03e00008 jr ra ; | 1c4: 27bd0050 addiu sp,sp,80 ; | ... ; ---------- 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 freebsd-12.0_r333647-malta_mipsebhf w/ gcc 4.2.1 -----> 00000000 <leaf_call>: 0: 3c1c0000 lui gp,0x0 4: 279c0000 addiu gp,gp,0 8: 0399e021 addu gp,gp,t9 c: 27bdfff8 addiu sp,sp,-8 10: afbe0000 sw s8,0(sp) 14: 03a0f021 move s8,sp 18: afc40008 sw a0,8(s8) 1c: afc5000c sw a1,12(s8) 20: afc60010 sw a2,16(s8) 24: afc70014 sw a3,20(s8) 28: 03c0e821 move sp,s8 2c: 8fbe0000 lw s8,0(sp) 30: 03e00008 jr ra 34: 27bd0008 addiu sp,sp,8 00000038 <nonleaf_call>: 38: 3c1c0000 lui gp,0x0 3c: 279c0000 addiu gp,gp,0 40: 0399e021 addu gp,gp,t9 44: 27bdff38 addiu sp,sp,-200 48: afbf00c4 sw ra,196(sp) 4c: afbe00c0 sw s8,192(sp) 50: 03a0f021 move s8,sp 54: afbc0050 sw gp,80(sp) 58: afc400c8 sw a0,200(s8) 5c: afc500cc sw a1,204(s8) 60: afc600d0 sw a2,208(s8) 64: afc700d4 sw a3,212(s8) 68: 27c20058 addiu v0,s8,88 6c: 24030064 li v1,100 70: 00402021 move a0,v0 74: 00002821 move a1,zero 78: 00603021 move a2,v1 7c: 8f990000 lw t9,0(gp) 80: 0320f809 jalr t9 84: 00000000 nop 88: 8fdc0050 lw gp,80(s8) 8c: 2402004c li v0,76 90: a3c20058 sb v0,88(s8) 94: 8fc200e0 lw v0,224(s8) 98: 8fc300e4 lw v1,228(s8) 9c: 8fc400e8 lw a0,232(s8) a0: 8fc500ec lw a1,236(s8) a4: afa20010 sw v0,16(sp) a8: afa30014 sw v1,20(sp) ac: afa40018 sw a0,24(sp) b0: afa5001c sw a1,28(sp) b4: 8fc200f0 lw v0,240(s8) b8: afa20020 sw v0,32(sp) bc: 8fc200f4 lw v0,244(s8) c0: afa20024 sw v0,36(sp) c4: 8fc200f8 lw v0,248(s8) c8: 8fc300fc lw v1,252(s8) cc: 8fc40100 lw a0,256(s8) d0: afa20028 sw v0,40(sp) d4: afa3002c sw v1,44(sp) d8: afa40030 sw a0,48(sp) dc: 8fc20108 lw v0,264(s8) e0: 8fc3010c lw v1,268(s8) e4: 8fc40110 lw a0,272(s8) e8: 8fc50114 lw a1,276(s8) ec: afa20038 sw v0,56(sp) f0: afa3003c sw v1,60(sp) f4: afa40040 sw a0,64(sp) f8: afa50044 sw a1,68(sp) fc: 8fc20118 lw v0,280(s8) 100: afa20048 sw v0,72(sp) 104: 8fc2011c lw v0,284(s8) 108: afa2004c sw v0,76(sp) 10c: 8fc400cc lw a0,204(s8) 110: 8fc500d0 lw a1,208(s8) 114: 8fc600d4 lw a2,212(s8) 118: 8fc700d8 lw a3,216(s8) 11c: 8f990000 lw t9,0(gp) 120: 0320f809 jalr t9 124: 00000000 nop 128: 8fdc0050 lw gp,80(s8) 12c: 03c0e821 move sp,s8 130: 8fbf00c4 lw ra,196(sp) 134: 8fbe00c0 lw s8,192(sp) 138: 03e00008 jr ra 13c: 27bd00c8 addiu sp,sp,200 00000140 <main>: 140: 3c1c0000 lui gp,0x0 ; | 144: 279c0000 addiu gp,gp,0 ; | 148: 0399e021 addu gp,gp,t9 ; | 14c: 27bdff58 addiu sp,sp,-168 ; | prolog 150: afbf00a4 sw ra,164(sp) ; | 154: afbe00a0 sw s8,160(sp) ; | 158: 03a0f021 move s8,sp ; | frame pointer (note: with offset to frame start, but static compared to sp) 15c: afbc0058 sw gp,88(sp) ; / 160: 8f820000 lw v0,0(gp) ; \ | 164: 24420030 addiu v0,v0,48 ; | | field j -> v0 168: 8c420000 lw v0,0(v0) ; | / 16c: 8f830000 lw v1,0(gp) ; | prep (first) local struct A data ... \ 170: 24630030 addiu v1,v1,48 ; | | field j -> v1 174: 8c630004 lw v1,4(v1) ; | / 178: 8f840000 lw a0,0(gp) ; | \ 17c: 24840030 addiu a0,a0,48 ; | | field f -> a0 180: 8c840008 lw a0,8(a0) ; / | 184: afc20090 sw v0,144(s8) ; \ 188: afc30094 sw v1,148(s8) ; | ... and write to local area 18c: afc40098 sw a0,152(s8) ; / 190: 8f820000 lw v0,0(gp) ; \ | 194: 24420020 addiu v0,v0,32 ; | | 198: 8c420000 lw v0,0(v0) ; | | 19c: 8f830000 lw v1,0(gp) ; | | field d -> v0 & v1 1a0: 24630020 addiu v1,v1,32 ; | | 1a4: 8c630004 lw v1,4(v1) ; | prep (first) local struct B data ... / 1a8: 8f840000 lw a0,0(gp) ; | \ 1ac: 24840020 addiu a0,a0,32 ; | | 1b0: 8c840008 lw a0,8(a0) ; | | 1b4: 8f850000 lw a1,0(gp) ; | | field l -> a0 & a1 1b8: 24a50020 addiu a1,a1,32 ; | | 1bc: 8ca5000c lw a1,12(a1) ; / | 1c0: afc20080 sw v0,128(s8) ; \ 1c4: afc30084 sw v1,132(s8) ; | 1c8: afc40088 sw a0,136(s8) ; | ... and write to local area 1cc: afc5008c sw a1,140(s8) ; / 1d0: 8f820000 lw v0,0(gp) ; \ | 1d4: 24420010 addiu v0,v0,16 ; | | field j -> v0 1d8: 8c420000 lw v0,0(v0) ; | / 1dc: 8f830000 lw v1,0(gp) ; | prep (second) local struct A data ... \ 1e0: 24630010 addiu v1,v1,16 ; | | field j -> v1 1e4: 8c630004 lw v1,4(v1) ; | / 1e8: 8f840000 lw a0,0(gp) ; | \ 1ec: 24840010 addiu a0,a0,16 ; | | field f -> a0 1f0: 8c840008 lw a0,8(a0) ; / | 1f4: afc20070 sw v0,112(s8) ; \ 1f8: afc30074 sw v1,116(s8) ; | ... and write to local area 1fc: afc40078 sw a0,120(s8) ; / 200: 8f820000 lw v0,0(gp) ; \ | 204: 24420000 addiu v0,v0,0 ; | | 208: 8c420000 lw v0,0(v0) ; | | 20c: 8f830000 lw v1,0(gp) ; | | field d -> v0 & v1 210: 24630000 addiu v1,v1,0 ; | | 214: 8c630004 lw v1,4(v1) ; | prep (second) local struct B data ... / 218: 8f840000 lw a0,0(gp) ; | \ 21c: 24840000 addiu a0,a0,0 ; | | 220: 8c840008 lw a0,8(a0) ; | | 224: 8f850000 lw a1,0(gp) ; | | field l -> a0 & a1 228: 24a50000 addiu a1,a1,0 ; | | 22c: 8ca5000c lw a1,12(a1) ; / | 230: afc20060 sw v0,96(s8) ; \ 234: afc30064 sw v1,100(s8) ; | 238: afc40068 sw a0,104(s8) ; | ... and write to local area 23c: afc5006c sw a1,108(s8) ; / 240: 8fc20080 lw v0,128(s8) ; \ 244: 8fc30084 lw v1,132(s8) ; | 248: 8fc40088 lw a0,136(s8) ; | 24c: 8fc5008c lw a1,140(s8) ; | 250: afa20018 sw v0,24(sp) ; | | d 254: afa3001c sw v1,28(sp) ; | arg 3 (first struct B) / 258: afa40020 sw a0,32(sp) ; | \ 25c: afa50024 sw a1,36(sp) ; / | l 260: 24020007 li v0,7 ; \ 264: afa20028 sw v0,40(sp) ; / arg 4 268: 24020008 li v0,8 ; \ 26c: afa2002c sw v0,44(sp) ; / arg 5 270: 8fc20070 lw v0,112(s8) ; \ 274: 8fc30074 lw v1,116(s8) ; | 278: 8fc40078 lw a0,120(s8) ; | arg 6 (second struct A, note that 60(sp) isn't used, so sizeof(struct A) is probably a padded 16) 27c: afa20030 sw v0,48(sp) ; | i 280: afa30034 sw v1,52(sp) ; | j 284: afa40038 sw a0,56(sp) ; / f 288: 8fc20060 lw v0,96(s8) ; \ 28c: 8fc30064 lw v1,100(s8) ; | 290: 8fc40068 lw a0,104(s8) ; | 294: 8fc5006c lw a1,108(s8) ; | 298: afa20040 sw v0,64(sp) ; | | d 29c: afa30044 sw v1,68(sp) ; | arg 7 (second struct B) / 2a0: afa40048 sw a0,72(sp) ; | \ 2a4: afa5004c sw a1,76(sp) ; | | l 2a8: 2402000e li v0,14 ; arg 8 pushed ... 2ac: afa20050 sw v0,80(sp) ; ... onto stack 2b0: 2402000f li v0,15 ; arg 9 pushed ... 2b4: afa20054 sw v0,84(sp) ; ... onto stack 2b8: 8fc20098 lw v0,152(s8) ; | | f (via stack, first slot after save area) 2bc: afa20010 sw v0,16(sp) ; | | note that 20(sp) isn't used, so sizeof(struct A) is probably a padded 16 2c0: 8fc60090 lw a2,144(s8) ; | arg 2 (first struct A) i (via reg) 2c4: 8fc70094 lw a3,148(s8) ; | j (via reg) 2c8: 00002021 move a0,zero ; arg 0 2cc: 24050001 li a1,1 ; arg 1 2d0: 8f990000 lw t9,0(gp) ; func to call -> t9 2d4: 0320f809 jalr t9 ; call and ret addr -> ra 2d8: 00000000 nop ; branch delay slot 2dc: 8fdc0058 lw gp,88(s8) ; | 2e0: 00001021 move v0,zero ; : return value: not part of epilog, but unordered (branch delay slot style) 2e4: 03c0e821 move sp,s8 ; | 2e8: 8fbf00a4 lw ra,164(sp) ; | epilog 2ec: 8fbe00a0 lw s8,160(sp) ; | 2f0: 03e00008 jr ra ; | 2f4: 27bd00a8 addiu sp,sp,168 ; | ... ; output from freebsd-12.0_r333647-malta_mipsebhf w/ gcc 4.2.1 *and* -mhard-float -----> 00000000 <leaf_call>: 0: 3c1c0000 lui gp,0x0 4: 279c0000 addiu gp,gp,0 8: 0399e021 addu gp,gp,t9 c: 27bdfff8 addiu sp,sp,-8 10: afbe0000 sw s8,0(sp) 14: 03a0f021 move s8,sp 18: afc40008 sw a0,8(s8) 1c: afc5000c sw a1,12(s8) 20: afc60010 sw a2,16(s8) 24: afc70014 sw a3,20(s8) 28: 03c0e821 move sp,s8 2c: 8fbe0000 lw s8,0(sp) 30: 03e00008 jr ra 34: 27bd0008 addiu sp,sp,8 00000038 <nonleaf_call>: 38: 3c1c0000 lui gp,0x0 3c: 279c0000 addiu gp,gp,0 40: 0399e021 addu gp,gp,t9 44: 27bdff38 addiu sp,sp,-200 48: afbf00c4 sw ra,196(sp) 4c: afbe00c0 sw s8,192(sp) 50: 03a0f021 move s8,sp 54: afbc0050 sw gp,80(sp) 58: afc400c8 sw a0,200(s8) 5c: afc500cc sw a1,204(s8) 60: afc600d0 sw a2,208(s8) 64: afc700d4 sw a3,212(s8) 68: 27c20058 addiu v0,s8,88 6c: 24030064 li v1,100 70: 00402021 move a0,v0 74: 00002821 move a1,zero 78: 00603021 move a2,v1 7c: 8f990000 lw t9,0(gp) 80: 0320f809 jalr t9 84: 00000000 nop 88: 8fdc0050 lw gp,80(s8) 8c: 2402004c li v0,76 90: a3c20058 sb v0,88(s8) 94: 8fc200e0 lw v0,224(s8) 98: 8fc300e4 lw v1,228(s8) 9c: 8fc400e8 lw a0,232(s8) a0: 8fc500ec lw a1,236(s8) a4: afa20010 sw v0,16(sp) a8: afa30014 sw v1,20(sp) ac: afa40018 sw a0,24(sp) b0: afa5001c sw a1,28(sp) b4: 8fc200f0 lw v0,240(s8) b8: afa20020 sw v0,32(sp) bc: 8fc200f4 lw v0,244(s8) c0: afa20024 sw v0,36(sp) c4: 8fc200f8 lw v0,248(s8) c8: 8fc300fc lw v1,252(s8) cc: 8fc40100 lw a0,256(s8) d0: afa20028 sw v0,40(sp) d4: afa3002c sw v1,44(sp) d8: afa40030 sw a0,48(sp) dc: 8fc20108 lw v0,264(s8) e0: 8fc3010c lw v1,268(s8) e4: 8fc40110 lw a0,272(s8) e8: 8fc50114 lw a1,276(s8) ec: afa20038 sw v0,56(sp) f0: afa3003c sw v1,60(sp) f4: afa40040 sw a0,64(sp) f8: afa50044 sw a1,68(sp) fc: 8fc20118 lw v0,280(s8) 100: afa20048 sw v0,72(sp) 104: 8fc2011c lw v0,284(s8) 108: afa2004c sw v0,76(sp) 10c: 8fc400cc lw a0,204(s8) 110: 8fc500d0 lw a1,208(s8) 114: 8fc600d4 lw a2,212(s8) 118: 8fc700d8 lw a3,216(s8) 11c: 8f990000 lw t9,0(gp) 120: 0320f809 jalr t9 124: 00000000 nop 128: 8fdc0050 lw gp,80(s8) 12c: 03c0e821 move sp,s8 130: 8fbf00c4 lw ra,196(sp) 134: 8fbe00c0 lw s8,192(sp) 138: 03e00008 jr ra 13c: 27bd00c8 addiu sp,sp,200 00000140 <main>: 140: 3c1c0000 lui gp,0x0 ; | 144: 279c0000 addiu gp,gp,0 ; | 148: 0399e021 addu gp,gp,t9 ; | 14c: 27bdff58 addiu sp,sp,-168 ; | prolog 150: afbf00a4 sw ra,164(sp) ; | 154: afbe00a0 sw s8,160(sp) ; | 158: 03a0f021 move s8,sp ; | frame pointer (note: with offset to frame start, but static compared to sp) 15c: afbc0058 sw gp,88(sp) ; / 160: 8f820000 lw v0,0(gp) ; \ | 164: 24420030 addiu v0,v0,48 ; | | field j -> v0 168: 8c420000 lw v0,0(v0) ; | / 16c: 8f830000 lw v1,0(gp) ; | prep (first) local struct A data ... \ 170: 24630030 addiu v1,v1,48 ; | | field j -> v1 174: 8c630004 lw v1,4(v1) ; | / 178: 8f840000 lw a0,0(gp) ; | \ 17c: 24840030 addiu a0,a0,48 ; | | field f -> a0 180: 8c840008 lw a0,8(a0) ; / | 184: afc20090 sw v0,144(s8) ; \ 188: afc30094 sw v1,148(s8) ; | ... and write to local area 18c: afc40098 sw a0,152(s8) ; / 190: 8f820000 lw v0,0(gp) ; \ | 194: 24420020 addiu v0,v0,32 ; | | 198: 8c420000 lw v0,0(v0) ; | | 19c: 8f830000 lw v1,0(gp) ; | | field d -> v0 & v1 1a0: 24630020 addiu v1,v1,32 ; | | 1a4: 8c630004 lw v1,4(v1) ; | prep (first) local struct B data ... / 1a8: 8f840000 lw a0,0(gp) ; | \ 1ac: 24840020 addiu a0,a0,32 ; | | 1b0: 8c840008 lw a0,8(a0) ; | | 1b4: 8f850000 lw a1,0(gp) ; | | field l -> a0 & a1 1b8: 24a50020 addiu a1,a1,32 ; | | 1bc: 8ca5000c lw a1,12(a1) ; / | 1c0: afc20080 sw v0,128(s8) ; \ 1c4: afc30084 sw v1,132(s8) ; | 1c8: afc40088 sw a0,136(s8) ; | ... and write to local area 1cc: afc5008c sw a1,140(s8) ; / 1d0: 8f820000 lw v0,0(gp) ; \ | 1d4: 24420010 addiu v0,v0,16 ; | | field j -> v0 1d8: 8c420000 lw v0,0(v0) ; | / 1dc: 8f830000 lw v1,0(gp) ; | prep (second) local struct A data ... \ 1e0: 24630010 addiu v1,v1,16 ; | | field j -> v1 1e4: 8c630004 lw v1,4(v1) ; | / 1e8: 8f840000 lw a0,0(gp) ; | \ 1ec: 24840010 addiu a0,a0,16 ; | | field f -> a0 1f0: 8c840008 lw a0,8(a0) ; / | 1f4: afc20070 sw v0,112(s8) ; \ 1f8: afc30074 sw v1,116(s8) ; | ... and write to local area 1fc: afc40078 sw a0,120(s8) ; / 200: 8f820000 lw v0,0(gp) ; \ | 204: 24420000 addiu v0,v0,0 ; | | 208: 8c420000 lw v0,0(v0) ; | | 20c: 8f830000 lw v1,0(gp) ; | | field d -> v0 & v1 210: 24630000 addiu v1,v1,0 ; | | 214: 8c630004 lw v1,4(v1) ; | prep (second) local struct B data ... / 218: 8f840000 lw a0,0(gp) ; | \ 21c: 24840000 addiu a0,a0,0 ; | | 220: 8c840008 lw a0,8(a0) ; | | 224: 8f850000 lw a1,0(gp) ; | | field l -> a0 & a1 228: 24a50000 addiu a1,a1,0 ; | | 22c: 8ca5000c lw a1,12(a1) ; / | 230: afc20060 sw v0,96(s8) ; \ 234: afc30064 sw v1,100(s8) ; | 238: afc40068 sw a0,104(s8) ; | ... and write to local area 23c: afc5006c sw a1,108(s8) ; / 240: 8fc20080 lw v0,128(s8) ; \ 244: 8fc30084 lw v1,132(s8) ; | 248: 8fc40088 lw a0,136(s8) ; | 24c: 8fc5008c lw a1,140(s8) ; | 250: afa20018 sw v0,24(sp) ; | | d 254: afa3001c sw v1,28(sp) ; | arg 3 (first struct B) / 258: afa40020 sw a0,32(sp) ; | \ 25c: afa50024 sw a1,36(sp) ; / | l 260: 24020007 li v0,7 ; \ 264: afa20028 sw v0,40(sp) ; / arg 4 268: 24020008 li v0,8 ; \ 26c: afa2002c sw v0,44(sp) ; / arg 5 270: 8fc20070 lw v0,112(s8) ; \ 274: 8fc30074 lw v1,116(s8) ; | 278: 8fc40078 lw a0,120(s8) ; | arg 6 (second struct A, note that 60(sp) isn't used, so sizeof(struct A) is probably a padded 16) 27c: afa20030 sw v0,48(sp) ; | i 280: afa30034 sw v1,52(sp) ; | j 284: afa40038 sw a0,56(sp) ; / f 288: 8fc20060 lw v0,96(s8) ; \ 28c: 8fc30064 lw v1,100(s8) ; | 290: 8fc40068 lw a0,104(s8) ; | 294: 8fc5006c lw a1,108(s8) ; | 298: afa20040 sw v0,64(sp) ; | | d 29c: afa30044 sw v1,68(sp) ; | arg 7 (second struct B) / 2a0: afa40048 sw a0,72(sp) ; | \ 2a4: afa5004c sw a1,76(sp) ; | | l 2a8: 2402000e li v0,14 ; arg 8 pushed ... 2ac: afa20050 sw v0,80(sp) ; ... onto stack 2b0: 2402000f li v0,15 ; arg 9 pushed ... 2b4: afa20054 sw v0,84(sp) ; ... onto stack 2b8: 8fc20098 lw v0,152(s8) ; | | f (via stack, first slot after save area) 2bc: afa20010 sw v0,16(sp) ; | | note that 20(sp) isn't used, so sizeof(struct A) is probably a padded 16 2c0: 8fc60090 lw a2,144(s8) ; | arg 2 (first struct A) i (via reg) 2c4: 8fc70094 lw a3,148(s8) ; | j (via reg) 2c8: 00002021 move a0,zero ; arg 0 2cc: 24050001 li a1,1 ; arg 1 2d0: 8f990000 lw t9,0(gp) ; func to call -> t9 2d4: 0320f809 jalr t9 ; call and ret addr -> ra 2d8: 00000000 nop ; branch delay slot 2dc: 8fdc0058 lw gp,88(s8) ; | 2e0: 00001021 move v0,zero ; : return value: not part of epilog, but unordered (branch delay slot style) 2e4: 03c0e821 move sp,s8 ; | 2e8: 8fbf00a4 lw ra,164(sp) ; | epilog 2ec: 8fbe00a0 lw s8,160(sp) ; | 2f0: 03e00008 jr ra ; | 2f4: 27bd00a8 addiu sp,sp,168 ; | ... ; ---------- 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 freebsd-12.0_r333647-malta_mipsebhf w/ gcc 4.2.1 -----> 00000000 <f0>: 0: 3c1c0000 lui gp,0x0 ; | 4: 279c0000 addiu gp,gp,0 ; | 8: 0399e021 addu gp,gp,t9 ; | prolog c: 27bdffe8 addiu sp,sp,-24 ; | 10: afbe0010 sw s8,16(sp) ; | 14: 03a0f021 move s8,sp ; | 18: 00801021 move v0,a0 ; hidden first arg (ptr to struct ret) -> v0 1c: 2403ff84 li v1,-124 ; | put together local struct 20: a3c30008 sb v1,8(s8) ; / 24: 93c30008 lbu v1,8(s8) ; read struct data from local area ... 28: a0430000 sb v1,0(v0) ; ... and write to return value area 2c: 03c0e821 move sp,s8 ; \ 30: 8fbe0010 lw s8,16(sp) ; | 34: 03e00008 jr ra ; | epilog 38: 27bd0018 addiu sp,sp,24 ; | 0000003c <f1>: 3c: 3c1c0000 lui gp,0x0 ; | 40: 279c0000 addiu gp,gp,0 ; | 44: 0399e021 addu gp,gp,t9 ; | 48: 27bdffb0 addiu sp,sp,-80 ; | 4c: afbf0048 sw ra,72(sp) ; | prolog 50: afbe0044 sw s8,68(sp) ; | 54: afb00040 sw s0,64(sp) ; | 58: 03a0f021 move s8,sp ; | 5c: afbc0010 sw gp,16(sp) ; | 60: 00808021 move s0,a0 ; hidden first arg (ptr to struct ret) -> s0 64: 27c20018 addiu v0,s8,24 ; 68: 8f830000 lw v1,0(gp) ; 6c: 24630000 addiu v1,v1,0 ; 70: 24060028 li a2,40 ; 74: 00402021 move a0,v0 ; 78: 00602821 move a1,v1 ; 7c: 8f990000 lw t9,0(gp) ; 80: 0320f809 jalr t9 ; 84: 00000000 nop ; @@@ unsure why those two jumps, but seems to put return value data together 88: 8fdc0010 lw gp,16(s8) ; 8c: 02001021 move v0,s0 ; 90: 27c30018 addiu v1,s8,24 ; 94: 24060028 li a2,40 ; 98: 00402021 move a0,v0 ; 9c: 00602821 move a1,v1 ; a0: 8f990000 lw t9,0(gp) ; a4: 0320f809 jalr t9 ; a8: 00000000 nop ; ac: 8fdc0010 lw gp,16(s8) ; | b0: 02001021 move v0,s0 ; : return value (hidden ptr): not part of epilog, but unordered (branch delay slot style) b4: 03c0e821 move sp,s8 ; | b8: 8fbf0048 lw ra,72(sp) ; | bc: 8fbe0044 lw s8,68(sp) ; | epilog c0: 8fb00040 lw s0,64(sp) ; | c4: 03e00008 jr ra ; | c8: 27bd0050 addiu sp,sp,80 ; | 000000cc <main>: cc: 3c1c0000 lui gp,0x0 ; | d0: 279c0000 addiu gp,gp,0 ; | d4: 0399e021 addu gp,gp,t9 ; | d8: 27bdffb0 addiu sp,sp,-80 ; | dc: afbf004c sw ra,76(sp) ; | prolog e0: afbe0048 sw s8,72(sp) ; | e4: 03a0f021 move s8,sp ; | e8: afbc0010 sw gp,16(sp) ; / ec: 27c20018 addiu v0,s8,24 ; \ f0: 00402021 move a0,v0 ; | hidden first arg (ptr to space for ret val) f4: 8f990000 lw t9,0(gp) ; func to call (f0) -> t9 f8: 0320f809 jalr t9 ; call and ret addr -> ra fc: 00000000 nop ; branch delay slot 100: 8fdc0010 lw gp,16(s8) ; restore gp @@@ unsure why? 104: 27c20020 addiu v0,s8,32 ; | 108: 00402021 move a0,v0 ; | hidden first arg (ptr to space for ret val) 10c: 8f990000 lw t9,0(gp) ; func to call (f1) -> t9 110: 0320f809 jalr t9 ; call and ret addr -> ra 114: 00000000 nop ; branch delay slot 118: 8fdc0010 lw gp,16(s8) ; restore gp @@@ unsure why? 11c: 8fc3002c lw v1,44(s8) ; | | 120: 8fc20028 lw v0,40(s8) ; | | b.j -> v0 & v1 124: 00602021 move a0,v1 ; | a0 = (int)b.j 128: 8fc30034 lw v1,52(s8) ; | | 12c: 8fc20030 lw v0,48(s8) ; | | b.j -> v0 & v1 130: 00601021 move v0,v1 ; | return value v0 = (int)b.k 134: 00821821 addu v1,a0,v0 ; | (int)b.j + (int)b.k -> v1 138: 8fc20040 lw v0,64(s8) ; | b.m -> v0 13c: 00621821 addu v1,v1,v0 ; | ((int)b.j + (int)b.k) + b.m -> v1 140: 83c20018 lb v0,24(s8) ; | s.x -> v0 144: 00621021 addu v0,v1,v0 ; / (((int)b.j + (int)b.k) + b.m) + s.x -> v0 148: 03c0e821 move sp,s8 ; \ 14c: 8fbf004c lw ra,76(sp) ; | 150: 8fbe0048 lw s8,72(sp) ; | epilog 154: 03e00008 jr ra ; | 158: 27bd0050 addiu sp,sp,80 ; | 15c: 00000000 nop ; | ; output from freebsd-12.0_r333647-malta_mipsebhf w/ gcc 4.2.1 *and* -mhard-float -----> 00000000 <f0>: 0: 3c1c0000 lui gp,0x0 4: 279c0000 addiu gp,gp,0 8: 0399e021 addu gp,gp,t9 c: 27bdffe8 addiu sp,sp,-24 10: afbe0010 sw s8,16(sp) 14: 03a0f021 move s8,sp 18: 00801021 move v0,a0 1c: 2403ff84 li v1,-124 20: a3c30008 sb v1,8(s8) 24: 93c30008 lbu v1,8(s8) 28: a0430000 sb v1,0(v0) 2c: 03c0e821 move sp,s8 30: 8fbe0010 lw s8,16(sp) 34: 03e00008 jr ra 38: 27bd0018 addiu sp,sp,24 0000003c <f1>: 3c: 3c1c0000 lui gp,0x0 40: 279c0000 addiu gp,gp,0 44: 0399e021 addu gp,gp,t9 48: 27bdffb0 addiu sp,sp,-80 4c: afbf0048 sw ra,72(sp) 50: afbe0044 sw s8,68(sp) 54: afb00040 sw s0,64(sp) 58: 03a0f021 move s8,sp 5c: afbc0010 sw gp,16(sp) 60: 00808021 move s0,a0 64: 27c20018 addiu v0,s8,24 68: 8f830000 lw v1,0(gp) 6c: 24630000 addiu v1,v1,0 70: 24060028 li a2,40 74: 00402021 move a0,v0 78: 00602821 move a1,v1 7c: 8f990000 lw t9,0(gp) 80: 0320f809 jalr t9 84: 00000000 nop 88: 8fdc0010 lw gp,16(s8) 8c: 02001021 move v0,s0 90: 27c30018 addiu v1,s8,24 94: 24060028 li a2,40 98: 00402021 move a0,v0 9c: 00602821 move a1,v1 a0: 8f990000 lw t9,0(gp) a4: 0320f809 jalr t9 a8: 00000000 nop ac: 8fdc0010 lw gp,16(s8) b0: 02001021 move v0,s0 b4: 03c0e821 move sp,s8 b8: 8fbf0048 lw ra,72(sp) bc: 8fbe0044 lw s8,68(sp) c0: 8fb00040 lw s0,64(sp) c4: 03e00008 jr ra c8: 27bd0050 addiu sp,sp,80 000000cc <main>: cc: 3c1c0000 lui gp,0x0 d0: 279c0000 addiu gp,gp,0 d4: 0399e021 addu gp,gp,t9 d8: 27bdffb0 addiu sp,sp,-80 dc: afbf004c sw ra,76(sp) e0: afbe0048 sw s8,72(sp) e4: 03a0f021 move s8,sp e8: afbc0010 sw gp,16(sp) ec: 27c20018 addiu v0,s8,24 f0: 00402021 move a0,v0 f4: 8f990000 lw t9,0(gp) f8: 0320f809 jalr t9 fc: 00000000 nop 100: 8fdc0010 lw gp,16(s8) 104: 27c20020 addiu v0,s8,32 108: 00402021 move a0,v0 10c: 8f990000 lw t9,0(gp) 110: 0320f809 jalr t9 114: 00000000 nop 118: 8fdc0010 lw gp,16(s8) 11c: 8fc3002c lw v1,44(s8) 120: 8fc20028 lw v0,40(s8) 124: 00602021 move a0,v1 128: 8fc30034 lw v1,52(s8) 12c: 8fc20030 lw v0,48(s8) 130: 00601021 move v0,v1 134: 00821821 addu v1,a0,v0 138: 8fc20040 lw v0,64(s8) 13c: 00621821 addu v1,v1,v0 140: 83c20018 lb v0,24(s8) 144: 00621021 addu v0,v1,v0 148: 03c0e821 move sp,s8 14c: 8fbf004c lw ra,76(sp) 150: 8fbe0048 lw s8,72(sp) 154: 03e00008 jr ra 158: 27bd0050 addiu sp,sp,80 15c: 00000000 nop ; ---------- returning long long ----------> ; ; long long f() ; { ; return 7171LL; ; } ; ; int main() ; { ; return (int)f(); ; } ; output from freebsd-12.0_r333647-malta_mipsebhf w/ gcc 4.2.1 -----> 00000000 <f>: 0: 3c1c0000 lui gp,0x0 ; 4: 279c0000 addiu gp,gp,0 ; 8: 0399e021 addu gp,gp,t9 ; c: 27bdfff8 addiu sp,sp,-8 ; 10: afbe0000 sw s8,0(sp) ; 14: 03a0f021 move s8,sp ; 18: 24031c03 li v1,7171 ; | return value 1c: 00001021 move v0,zero ; | 20: 03c0e821 move sp,s8 ; 24: 8fbe0000 lw s8,0(sp) ; 28: 03e00008 jr ra ; 2c: 27bd0008 addiu sp,sp,8 ; 00000030 <main>: 30: 3c1c0000 lui gp,0x0 34: 279c0000 addiu gp,gp,0 38: 0399e021 addu gp,gp,t9 3c: 27bdffe0 addiu sp,sp,-32 40: afbf001c sw ra,28(sp) 44: afbe0018 sw s8,24(sp) 48: 03a0f021 move s8,sp 4c: afbc0010 sw gp,16(sp) 50: 8f990000 lw t9,0(gp) 54: 0320f809 jalr t9 58: 00000000 nop 5c: 8fdc0010 lw gp,16(s8) 60: 00601021 move v0,v1 64: 03c0e821 move sp,s8 68: 8fbf001c lw ra,28(sp) 6c: 8fbe0018 lw s8,24(sp) 70: 03e00008 jr ra 74: 27bd0020 addiu sp,sp,32 ... ; output from freebsd-12.0_r333647-malta_mipsebhf w/ gcc 4.2.1 *and* -mhard-float -----> 00000000 <f>: 0: 3c1c0000 lui gp,0x0 ; 4: 279c0000 addiu gp,gp,0 ; 8: 0399e021 addu gp,gp,t9 ; c: 27bdfff8 addiu sp,sp,-8 ; 10: afbe0000 sw s8,0(sp) ; 14: 03a0f021 move s8,sp ; 18: 24031c03 li v1,7171 ; | return value 1c: 00001021 move v0,zero ; | 20: 03c0e821 move sp,s8 ; 24: 8fbe0000 lw s8,0(sp) ; 28: 03e00008 jr ra ; 2c: 27bd0008 addiu sp,sp,8 ; 00000030 <main>: 30: 3c1c0000 lui gp,0x0 34: 279c0000 addiu gp,gp,0 38: 0399e021 addu gp,gp,t9 3c: 27bdffe0 addiu sp,sp,-32 40: afbf001c sw ra,28(sp) 44: afbe0018 sw s8,24(sp) 48: 03a0f021 move s8,sp 4c: afbc0010 sw gp,16(sp) 50: 8f990000 lw t9,0(gp) 54: 0320f809 jalr t9 58: 00000000 nop 5c: 8fdc0010 lw gp,16(s8) 60: 00601021 move v0,v1 64: 03c0e821 move sp,s8 68: 8fbf001c lw ra,28(sp) 6c: 8fbe0018 lw s8,24(sp) 70: 03e00008 jr ra 74: 27bd0020 addiu sp,sp,32 ... ; ---------- 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 freebsd-12.0_r333647-malta_mipsebhf w/ gcc 4.2.1 -----> 00000000 <leaf_call>: 0: 3c1c0000 lui gp,0x0 4: 279c0000 addiu gp,gp,0 8: 0399e021 addu gp,gp,t9 c: 27bdfff8 addiu sp,sp,-8 10: afbe0000 sw s8,0(sp) 14: 03a0f021 move s8,sp 18: afc40008 sw a0,8(s8) 1c: afc5000c sw a1,12(s8) 20: afc60010 sw a2,16(s8) 24: afc70014 sw a3,20(s8) 28: 03c0e821 move sp,s8 2c: 8fbe0000 lw s8,0(sp) 30: 03e00008 jr ra 34: 27bd0008 addiu sp,sp,8 00000038 <main>: 38: 3c1c0000 lui gp,0x0 ; | 3c: 279c0000 addiu gp,gp,0 ; | 40: 0399e021 addu gp,gp,t9 ; | 44: 27bdff60 addiu sp,sp,-160 ; | prolog 48: afbf009c sw ra,156(sp) ; | 4c: afbe0098 sw s8,152(sp) ; | 50: 03a0f021 move s8,sp ; | frame pointer (note: with offset to frame start, but static compared to sp) 54: afbc0048 sw gp,72(sp) ; / 58: 8f820000 lw v0,0(gp) ; \ 5c: 24420044 addiu v0,v0,68 ; | prep local struct A data ... 60: 8c420000 lw v0,0(v0) ; / 64: afc20094 sw v0,148(s8) ; ... and write to local area 68: 8f820000 lw v0,0(gp) ; \ 6c: 2442003c addiu v0,v0,60 ; | 70: 8c420000 lw v0,0(v0) ; | 74: 8f830000 lw v1,0(gp) ; | prep local struct B data ... 78: 2463003c addiu v1,v1,60 ; | 7c: 8c630004 lw v1,4(v1) ; / 80: afc2008c sw v0,140(s8) ; \ ... and write to local area a 84: afc30090 sw v1,144(s8) ; / b 88: 8f820000 lw v0,0(gp) ; \ 8c: 24420030 addiu v0,v0,48 ; | 90: 8c420000 lw v0,0(v0) ; | 94: 8f830000 lw v1,0(gp) ; | 98: 24630030 addiu v1,v1,48 ; | prep local struct C data ... 9c: 8c630004 lw v1,4(v1) ; | a0: 8f840000 lw a0,0(gp) ; | a4: 24840030 addiu a0,a0,48 ; | a8: 8c840008 lw a0,8(a0) ; / ac: afc20080 sw v0,128(s8) ; \ a b0: afc30084 sw v1,132(s8) ; | ... and write to local area b b4: afc40088 sw a0,136(s8) ; / c b8: 8f830000 lw v1,0(gp) ; \ bc: 24630028 addiu v1,v1,40 ; | c0: 8c630004 lw v1,4(v1) ; | c4: 8f820000 lw v0,0(gp) ; | prep local struct D data ... c8: 24420028 addiu v0,v0,40 ; | cc: 8c420000 lw v0,0(v0) ; / d0: afc3007c sw v1,124(s8) ; \ ... and write to local area d4: afc20078 sw v0,120(s8) ; / d8: 8f820000 lw v0,0(gp) ; \ dc: 24420018 addiu v0,v0,24 ; | e0: 8c420000 lw v0,0(v0) ; | e4: 8f830000 lw v1,0(gp) ; | e8: 24630018 addiu v1,v1,24 ; | ec: 8c630004 lw v1,4(v1) ; | prep local struct E data ... f0: 8f840000 lw a0,0(gp) ; | f4: 24840018 addiu a0,a0,24 ; | f8: 8c840008 lw a0,8(a0) ; | fc: 8f850000 lw a1,0(gp) ; | 100: 24a50018 addiu a1,a1,24 ; | 104: 8ca5000c lw a1,12(a1) ; / 108: afc20068 sw v0,104(s8) ; \ | a 10c: afc3006c sw v1,108(s8) ; | ... and write to local area / 110: afc40070 sw a0,112(s8) ; | \ 114: afc50074 sw a1,116(s8) ; / | b 118: 8f820000 lw v0,0(gp) ; \ 11c: 24420000 addiu v0,v0,0 ; | 120: 8c420000 lw v0,0(v0) ; | 124: 8f830000 lw v1,0(gp) ; | 128: 24630000 addiu v1,v1,0 ; | 12c: 8c630004 lw v1,4(v1) ; | 130: 8f840000 lw a0,0(gp) ; | 134: 24840000 addiu a0,a0,0 ; | 138: 8c840008 lw a0,8(a0) ; | 13c: 8f850000 lw a1,0(gp) ; | prep local struct F data ... 140: 24a50000 addiu a1,a1,0 ; | 144: 8ca5000c lw a1,12(a1) ; | 148: 8f860000 lw a2,0(gp) ; | 14c: 24c60000 addiu a2,a2,0 ; | 150: 8cc60010 lw a2,16(a2) ; | 154: 8f870000 lw a3,0(gp) ; | 158: 24e70000 addiu a3,a3,0 ; | 15c: 8ce70014 lw a3,20(a3) ; / 160: afc20050 sw v0,80(s8) ; \ | a 164: afc30054 sw v1,84(s8) ; | / 168: afc40058 sw a0,88(s8) ; | \ b 16c: afc5005c sw a1,92(s8) ; | ... and write to local area / 170: afc60060 sw a2,96(s8) ; | \ 174: afc70064 sw a3,100(s8) ; / | c 178: 8fc3007c lw v1,124(s8) ; \ 17c: 8fc20078 lw v0,120(s8) ; | 180: afa3001c sw v1,28(sp) ; | arg 3 (struct D) 184: afa20018 sw v0,24(sp) ; / 188: 8fc20068 lw v0,104(s8) ; \ 18c: 8fc3006c lw v1,108(s8) ; | 190: 8fc40070 lw a0,112(s8) ; | 194: 8fc50074 lw a1,116(s8) ; | 198: afa20020 sw v0,32(sp) ; | arg 4 (struct E) 19c: afa30024 sw v1,36(sp) ; | 1a0: afa40028 sw a0,40(sp) ; | 1a4: afa5002c sw a1,44(sp) ; / 1a8: 8fc20050 lw v0,80(s8) ; \ 1ac: 8fc30054 lw v1,84(s8) ; | 1b0: 8fc40058 lw a0,88(s8) ; | 1b4: 8fc5005c lw a1,92(s8) ; | 1b8: 8fc60060 lw a2,96(s8) ; | 1bc: 8fc70064 lw a3,100(s8) ; | 1c0: afa20030 sw v0,48(sp) ; | arg 5 (struct F) 1c4: afa30034 sw v1,52(sp) ; | 1c8: afa40038 sw a0,56(sp) ; | 1cc: afa5003c sw a1,60(sp) ; | 1d0: afa60040 sw a2,64(sp) ; | 1d4: afa70044 sw a3,68(sp) ; / 1d8: 8fc20084 lw v0,132(s8) ; \ 1dc: 8fc30088 lw v1,136(s8) ; | 1e0: afa20010 sw v0,16(sp) ; | arg 2 (struct C) b (via stack) 1e4: afa30014 sw v1,20(sp) ; | c (via stack) 1e8: 8fc70080 lw a3,128(s8) ; | a (via reg) 1ec: 8fc40094 lw a0,148(s8) ; arg 0 (struct A, via reg) 1f0: 8fc5008c lw a1,140(s8) ; | arg 1 (struct B, via regs) a 1f4: 8fc60090 lw a2,144(s8) ; | b 1f8: 8f990000 lw t9,0(gp) ; func to call -> t9 1fc: 0320f809 jalr t9 ; call and ret addr -> ra 200: 00000000 nop ; branch delay slot 204: 8fdc0048 lw gp,72(s8) ; | 208: 00001021 move v0,zero ; : return value: not part of epilog, but unordered (branch delay slot style) 20c: 03c0e821 move sp,s8 ; | 210: 8fbf009c lw ra,156(sp) ; | epilog 214: 8fbe0098 lw s8,152(sp) ; | 218: 03e00008 jr ra ; | 21c: 27bd00a0 addiu sp,sp,160 ; | ; output from freebsd-12.0_r333647-malta_mipsebhf w/ gcc 4.2.1 *and* -mhard-float -----> 00000000 <leaf_call>: 0: 3c1c0000 lui gp,0x0 4: 279c0000 addiu gp,gp,0 8: 0399e021 addu gp,gp,t9 c: 27bdfff8 addiu sp,sp,-8 10: afbe0000 sw s8,0(sp) 14: 03a0f021 move s8,sp 18: afc40008 sw a0,8(s8) 1c: afc5000c sw a1,12(s8) 20: afc60010 sw a2,16(s8) 24: afc70014 sw a3,20(s8) 28: 03c0e821 move sp,s8 2c: 8fbe0000 lw s8,0(sp) 30: 03e00008 jr ra 34: 27bd0008 addiu sp,sp,8 00000038 <main>: 38: 3c1c0000 lui gp,0x0 ; | 3c: 279c0000 addiu gp,gp,0 ; | 40: 0399e021 addu gp,gp,t9 ; | 44: 27bdff60 addiu sp,sp,-160 ; | prolog 48: afbf009c sw ra,156(sp) ; | 4c: afbe0098 sw s8,152(sp) ; | 50: 03a0f021 move s8,sp ; | frame pointer (note: with offset to frame start, but static compared to sp) 54: afbc0048 sw gp,72(sp) ; / 58: 8f810000 lw at,0(gp) ; \ 5c: 24210044 addiu at,at,68 ; | prep local struct A (single float field) data ... 60: c4200000 lwc1 $f0,0(at) ; / 64: e7c00094 swc1 $f0,148(s8) ; ... and write to local area 68: 8f820000 lw v0,0(gp) ; \ 6c: 2442003c addiu v0,v0,60 ; | 70: 8c420000 lw v0,0(v0) ; | 74: 8f830000 lw v1,0(gp) ; | prep local struct B data ... 78: 2463003c addiu v1,v1,60 ; | 7c: 8c630004 lw v1,4(v1) ; / 80: afc2008c sw v0,140(s8) ; \ ... and write to local area a 84: afc30090 sw v1,144(s8) ; / b 88: 8f820000 lw v0,0(gp) ; \ 8c: 24420030 addiu v0,v0,48 ; | 90: 8c420000 lw v0,0(v0) ; | 94: 8f830000 lw v1,0(gp) ; | 98: 24630030 addiu v1,v1,48 ; | prep local struct C data ... 9c: 8c630004 lw v1,4(v1) ; | a0: 8f840000 lw a0,0(gp) ; | a4: 24840030 addiu a0,a0,48 ; | a8: 8c840008 lw a0,8(a0) ; / ac: afc20080 sw v0,128(s8) ; \ a b0: afc30084 sw v1,132(s8) ; | ... and write to local area b b4: afc40088 sw a0,136(s8) ; / c b8: 8f810000 lw at,0(gp) ; \ bc: 24210028 addiu at,at,40 ; | prep local struct D (single double field) data ... c0: d4200000 ldc1 $f0,0(at) ; / c4: f7c00078 sdc1 $f0,120(s8) ; ... and write to local area c8: 8f820000 lw v0,0(gp) ; \ cc: 24420018 addiu v0,v0,24 ; | d0: 8c420000 lw v0,0(v0) ; | d4: 8f830000 lw v1,0(gp) ; | d8: 24630018 addiu v1,v1,24 ; | dc: 8c630004 lw v1,4(v1) ; | prep local struct E data ... e0: 8f840000 lw a0,0(gp) ; | e4: 24840018 addiu a0,a0,24 ; | e8: 8c840008 lw a0,8(a0) ; | ec: 8f850000 lw a1,0(gp) ; | f0: 24a50018 addiu a1,a1,24 ; | f4: 8ca5000c lw a1,12(a1) ; / f8: afc20068 sw v0,104(s8) ; \ | a fc: afc3006c sw v1,108(s8) ; | ... and write to local area / 100: afc40070 sw a0,112(s8) ; | \ 104: afc50074 sw a1,116(s8) ; / | b 108: 8f820000 lw v0,0(gp) ; \ 10c: 24420000 addiu v0,v0,0 ; | 110: 8c420000 lw v0,0(v0) ; | 114: 8f830000 lw v1,0(gp) ; | 118: 24630000 addiu v1,v1,0 ; | 11c: 8c630004 lw v1,4(v1) ; | 120: 8f840000 lw a0,0(gp) ; | 124: 24840000 addiu a0,a0,0 ; | 128: 8c840008 lw a0,8(a0) ; | 12c: 8f850000 lw a1,0(gp) ; | prep local struct F data ... 130: 24a50000 addiu a1,a1,0 ; | 134: 8ca5000c lw a1,12(a1) ; | 138: 8f860000 lw a2,0(gp) ; | 13c: 24c60000 addiu a2,a2,0 ; | 140: 8cc60010 lw a2,16(a2) ; | 144: 8f870000 lw a3,0(gp) ; | 148: 24e70000 addiu a3,a3,0 ; | 14c: 8ce70014 lw a3,20(a3) ; / 150: afc20050 sw v0,80(s8) ; \ | a 154: afc30054 sw v1,84(s8) ; | / 158: afc40058 sw a0,88(s8) ; | \ b 15c: afc5005c sw a1,92(s8) ; | ... and write to local area / 160: afc60060 sw a2,96(s8) ; | \ 164: afc70064 sw a3,100(s8) ; / | c 168: d7c00078 ldc1 $f0,120(s8) ; \ 16c: f7a00018 sdc1 $f0,24(sp) ; / arg 3 (struct D) 170: 8fc20068 lw v0,104(s8) ; \ 174: 8fc3006c lw v1,108(s8) ; | 178: 8fc40070 lw a0,112(s8) ; | 17c: 8fc50074 lw a1,116(s8) ; | 180: afa20020 sw v0,32(sp) ; | arg 4 (struct E) 184: afa30024 sw v1,36(sp) ; | 188: afa40028 sw a0,40(sp) ; | 18c: afa5002c sw a1,44(sp) ; / 190: 8fc20050 lw v0,80(s8) ; \ 194: 8fc30054 lw v1,84(s8) ; | 198: 8fc40058 lw a0,88(s8) ; | 19c: 8fc5005c lw a1,92(s8) ; | 1a0: 8fc60060 lw a2,96(s8) ; | 1a4: 8fc70064 lw a3,100(s8) ; | 1a8: afa20030 sw v0,48(sp) ; | arg 5 (struct F) 1ac: afa30034 sw v1,52(sp) ; | 1b0: afa40038 sw a0,56(sp) ; | 1b4: afa5003c sw a1,60(sp) ; | 1b8: afa60040 sw a2,64(sp) ; | 1bc: afa70044 sw a3,68(sp) ; / 1c0: 8fc20084 lw v0,132(s8) ; \ 1c4: 8fc30088 lw v1,136(s8) ; | 1c8: afa20010 sw v0,16(sp) ; | arg 2 (struct C) b (via stack) 1cc: afa30014 sw v1,20(sp) ; | c (via stack) 1d0: 8fc70080 lw a3,128(s8) ; | a (via reg) 1d4: 8fc40094 lw a0,148(s8) ; arg 0 (struct A, via reg) 1d8: 8fc5008c lw a1,140(s8) ; | arg 1 (struct B, via regs) a 1dc: 8fc60090 lw a2,144(s8) ; | b 1e0: 8f990000 lw t9,0(gp) ; func to call -> t9 1e4: 0320f809 jalr t9 ; call and ret addr -> ra 1e8: 00000000 nop ; branch delay slot 1ec: 8fdc0048 lw gp,72(s8) ; | 1f0: 00001021 move v0,zero ; : return value: not part of epilog, but unordered (branch delay slot style) 1f4: 03c0e821 move sp,s8 ; | 1f8: 8fbf009c lw ra,156(sp) ; | epilog 1fc: 8fbe0098 lw s8,152(sp) ; | 200: 03e00008 jr ra ; | 204: 27bd00a0 addiu sp,sp,160 ; | ... ; ---------- 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 freebsd-12.0_r333647-malta_mipsebhf w/ gcc 4.2.1 -----> 00000000 <leaf_call>: 0: 3c1c0000 lui gp,0x0 4: 279c0000 addiu gp,gp,0 8: 0399e021 addu gp,gp,t9 c: 27bdfff8 addiu sp,sp,-8 10: afbe0000 sw s8,0(sp) 14: 03a0f021 move s8,sp 18: afc40008 sw a0,8(s8) 1c: afc5000c sw a1,12(s8) 20: afc60010 sw a2,16(s8) 24: afc70014 sw a3,20(s8) 28: 03c0e821 move sp,s8 2c: 8fbe0000 lw s8,0(sp) 30: 03e00008 jr ra 34: 27bd0008 addiu sp,sp,8 00000038 <main>: 38: 3c1c0000 lui gp,0x0 3c: 279c0000 addiu gp,gp,0 40: 0399e021 addu gp,gp,t9 44: 27bdffa0 addiu sp,sp,-96 48: afbf005c sw ra,92(sp) 4c: afbe0058 sw s8,88(sp) 50: 03a0f021 move s8,sp 54: afbc0028 sw gp,40(sp) 58: 8f820000 lw v0,0(gp) 5c: 24420010 addiu v0,v0,16 60: 90420000 lbu v0,0(v0) 64: a3c2004b sb v0,75(s8) 68: 8f820000 lw v0,0(gp) 6c: 24420010 addiu v0,v0,16 70: 90420001 lbu v0,1(v0) 74: a3c2004c sb v0,76(s8) 78: 24020002 li v0,2 7c: a3c2004a sb v0,74(s8) 80: 24020003 li v0,3 84: a7c20048 sh v0,72(s8) 88: 24020004 li v0,4 8c: afc20044 sw v0,68(s8) 90: 8f820000 lw v0,0(gp) 94: 24420014 addiu v0,v0,20 98: 8c420000 lw v0,0(v0) 9c: afc20040 sw v0,64(s8) a0: 8f830000 lw v1,0(gp) a4: 24630008 addiu v1,v1,8 a8: 8c630004 lw v1,4(v1) ac: 8f820000 lw v0,0(gp) b0: 24420008 addiu v0,v0,8 b4: 8c420000 lw v0,0(v0) b8: afc3003c sw v1,60(s8) bc: afc20038 sw v0,56(s8) c0: 8f820000 lw v0,0(gp) c4: 24420000 addiu v0,v0,0 c8: 94420000 lhu v0,0(v0) cc: a7c20030 sh v0,48(s8) d0: 8f820000 lw v0,0(gp) d4: 24420000 addiu v0,v0,0 d8: 90420002 lbu v0,2(v0) dc: a3c20032 sb v0,50(s8) e0: 8fc20040 lw v0,64(s8) e4: afa20010 sw v0,16(sp) e8: 8fc3003c lw v1,60(s8) ec: 8fc20038 lw v0,56(s8) f0: afa3001c sw v1,28(sp) f4: afa20018 sw v0,24(sp) f8: 97c20030 lhu v0,48(s8) fc: a7a20020 sh v0,32(sp) 100: 93c20032 lbu v0,50(s8) 104: a3a20022 sb v0,34(sp) 108: 93c2004b lbu v0,75(s8) 10c: 00021a00 sll v1,v0,0x8 110: 93c2004c lbu v0,76(s8) 114: 00431025 or v0,v0,v1 118: afc00050 sw zero,80(s8) 11c: 00021c00 sll v1,v0,0x10 120: 8fc40050 lw a0,80(s8) 124: 3082ffff andi v0,a0,0xffff 128: 00431025 or v0,v0,v1 12c: afc20050 sw v0,80(s8) 130: 8fc40050 lw a0,80(s8) 134: 93c5004a lbu a1,74(s8) 138: 00052e00 sll a1,a1,0x18 13c: 97c60048 lhu a2,72(s8) 140: 00063400 sll a2,a2,0x10 144: 8fc70044 lw a3,68(s8) 148: 8f990000 lw t9,0(gp) 14c: 0320f809 jalr t9 150: 00000000 nop 154: 8fdc0028 lw gp,40(s8) 158: 00001021 move v0,zero 15c: 03c0e821 move sp,s8 160: 8fbf005c lw ra,92(sp) 164: 8fbe0058 lw s8,88(sp) 168: 03e00008 jr ra 16c: 27bd0060 addiu sp,sp,96 ; output from freebsd-12.0_r333647-malta_mipsebhf w/ gcc 4.2.1 *and* -mhard-float -----> 00000000 <leaf_call>: 0: 3c1c0000 lui gp,0x0 4: 279c0000 addiu gp,gp,0 8: 0399e021 addu gp,gp,t9 c: 27bdfff8 addiu sp,sp,-8 10: afbe0000 sw s8,0(sp) 14: 03a0f021 move s8,sp 18: afc40008 sw a0,8(s8) 1c: afc5000c sw a1,12(s8) 20: afc60010 sw a2,16(s8) 24: afc70014 sw a3,20(s8) 28: 03c0e821 move sp,s8 2c: 8fbe0000 lw s8,0(sp) 30: 03e00008 jr ra 34: 27bd0008 addiu sp,sp,8 00000038 <main>: 38: 3c1c0000 lui gp,0x0 3c: 279c0000 addiu gp,gp,0 40: 0399e021 addu gp,gp,t9 44: 27bdffa0 addiu sp,sp,-96 48: afbf005c sw ra,92(sp) 4c: afbe0058 sw s8,88(sp) 50: 03a0f021 move s8,sp 54: afbc0028 sw gp,40(sp) 58: 8f820000 lw v0,0(gp) 5c: 24420010 addiu v0,v0,16 60: 90420000 lbu v0,0(v0) 64: a3c2004b sb v0,75(s8) 68: 8f820000 lw v0,0(gp) 6c: 24420010 addiu v0,v0,16 70: 90420001 lbu v0,1(v0) 74: a3c2004c sb v0,76(s8) 78: 24020002 li v0,2 7c: a3c2004a sb v0,74(s8) 80: 24020003 li v0,3 84: a7c20048 sh v0,72(s8) 88: 24020004 li v0,4 8c: afc20044 sw v0,68(s8) 90: 8f810000 lw at,0(gp) 94: 24210014 addiu at,at,20 98: c4200000 lwc1 $f0,0(at) 9c: e7c00040 swc1 $f0,64(s8) a0: 8f810000 lw at,0(gp) a4: 24210008 addiu at,at,8 a8: d4200000 ldc1 $f0,0(at) ac: f7c00038 sdc1 $f0,56(s8) b0: 8f820000 lw v0,0(gp) b4: 24420000 addiu v0,v0,0 b8: 94420000 lhu v0,0(v0) bc: a7c20030 sh v0,48(s8) c0: 8f820000 lw v0,0(gp) c4: 24420000 addiu v0,v0,0 c8: 90420002 lbu v0,2(v0) cc: a3c20032 sb v0,50(s8) d0: c7c00040 lwc1 $f0,64(s8) d4: e7a00010 swc1 $f0,16(sp) d8: d7c00038 ldc1 $f0,56(s8) dc: f7a00018 sdc1 $f0,24(sp) e0: 97c20030 lhu v0,48(s8) e4: a7a20020 sh v0,32(sp) e8: 93c20032 lbu v0,50(s8) ec: a3a20022 sb v0,34(sp) f0: 93c2004b lbu v0,75(s8) f4: 00021a00 sll v1,v0,0x8 f8: 93c2004c lbu v0,76(s8) fc: 00431025 or v0,v0,v1 100: afc00050 sw zero,80(s8) 104: 00021c00 sll v1,v0,0x10 108: 8fc40050 lw a0,80(s8) 10c: 3082ffff andi v0,a0,0xffff 110: 00431025 or v0,v0,v1 114: afc20050 sw v0,80(s8) 118: 8fc40050 lw a0,80(s8) 11c: 93c5004a lbu a1,74(s8) 120: 00052e00 sll a1,a1,0x18 124: 97c60048 lhu a2,72(s8) 128: 00063400 sll a2,a2,0x10 12c: 8fc70044 lw a3,68(s8) 130: 8f990000 lw t9,0(gp) 134: 0320f809 jalr t9 138: 00000000 nop 13c: 8fdc0028 lw gp,40(s8) 140: 00001021 move v0,zero 144: 03c0e821 move sp,s8 148: 8fbf005c lw ra,92(sp) 14c: 8fbe0058 lw s8,88(sp) 150: 03e00008 jr ra 154: 27bd0060 addiu sp,sp,96 ... ; ---------- 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 freebsd-12.0_r333647-malta_mipsebhf w/ gcc 4.2.1 004008c0 <f1>: 4008c0: 3c1c0002 lui gp,0x2 4008c4: 279c8330 addiu gp,gp,-31952 4008c8: 0399e021 addu gp,gp,t9 4008cc: 27bdfff8 addiu sp,sp,-8 4008d0: afbe0000 sw s8,0(sp) 4008d4: 03a0f021 move s8,sp 4008d8: afc40008 sw a0,8(s8) 4008dc: 03c0e821 move sp,s8 4008e0: 8fbe0000 lw s8,0(sp) 4008e4: 03e00008 jr ra 4008e8: 27bd0008 addiu sp,sp,8 004008ec <f2>: 4008ec: 3c1c0002 lui gp,0x2 4008f0: 279c8304 addiu gp,gp,-31996 4008f4: 0399e021 addu gp,gp,t9 4008f8: 27bdfff8 addiu sp,sp,-8 4008fc: afbe0000 sw s8,0(sp) 400900: 03a0f021 move s8,sp 400904: afc40008 sw a0,8(s8) 400908: 03c0e821 move sp,s8 40090c: 8fbe0000 lw s8,0(sp) 400910: 03e00008 jr ra 400914: 27bd0008 addiu sp,sp,8 00400918 <f>: 400918: 3c1c0002 lui gp,0x2 ; 40091c: 279c82d8 addiu gp,gp,-32040 ; 400920: 0399e021 addu gp,gp,t9 ; 400924: 27bdffd0 addiu sp,sp,-48 ; 400928: afbf002c sw ra,44(sp) ; 40092c: afbe0028 sw s8,40(sp) ; 400930: 03a0f021 move s8,sp ; 400934: afbc0010 sw gp,16(sp) ; 400938: 27c20024 addiu v0,s8,36 ; 40093c: 00402021 move a0,v0 ; 400940: 8f998064 lw t9,-32668(gp) ; | 400944: 0320f809 jalr t9 ; | NonTrivial::NonTrivial() / ctor 400948: 00000000 nop ; 40094c: 8fdc0010 lw gp,16(s8) ; 400950: 24020001 li v0,1 ; 400954: afc20018 sw v0,24(s8) ; 400958: 8fc20018 lw v0,24(s8) ; 40095c: 2442007b addiu v0,v0,123 ; 400960: afc20018 sw v0,24(s8) ; 400964: 8fc40020 lw a0,32(s8) ; 400968: 8f998060 lw t9,-32672(gp) ; | 40096c: 0320f809 jalr t9 ; | call f1(struct Trivial) 400970: 00000000 nop ; 400974: 8fdc0010 lw gp,16(s8) ; 400978: 8fc20018 lw v0,24(s8) ; 40097c: 2442ff85 addiu v0,v0,-123 ; 400980: afc20018 sw v0,24(s8) ; 400984: 27c2001c addiu v0,s8,28 ; 400988: 27c30024 addiu v1,s8,36 ; 40098c: 00402021 move a0,v0 ; | ptr to dest of copy of n 400990: 00602821 move a1,v1 ; | ptr to n 400994: 8f998050 lw t9,-32688(gp) ; | copy n | 400998: 0320f809 jalr t9 ; | | NonTrivial::NonTrivial(const NonTrivial&) / copy ctor 40099c: 00000000 nop ; 4009a0: 8fdc0010 lw gp,16(s8) ; 4009a4: 27c2001c addiu v0,s8,28 ; get ptr to copy of n -> v0 4009a8: 00402021 move a0,v0 ; f2 arg 0 (ptr to copy of struct NonTrivial), via ptr as non-trivial 4009ac: 8f998058 lw t9,-32680(gp) ; | 4009b0: 0320f809 jalr t9 ; | call f2(struct NonTrivial) 4009b4: 00000000 nop ; 4009b8: 8fdc0010 lw gp,16(s8) ; 4009bc: 8fc20018 lw v0,24(s8) ; 4009c0: 2442fff4 addiu v0,v0,-12 ; 4009c4: afc20018 sw v0,24(s8) ; 4009c8: 03c0e821 move sp,s8 ; 4009cc: 8fbf002c lw ra,44(sp) ; 4009d0: 8fbe0028 lw s8,40(sp) ; 4009d4: 03e00008 jr ra ; 4009d8: 27bd0030 addiu sp,sp,48 ; ; ... 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 freebsd-12.0_r333647-malta_mipsebhf w/ gcc 4.2.1 004008b0 <f1>: 4008b0: 3c1c0002 lui gp,0x2 4008b4: 279c8310 addiu gp,gp,-31984 4008b8: 0399e021 addu gp,gp,t9 4008bc: 27bdfff8 addiu sp,sp,-8 4008c0: afbe0000 sw s8,0(sp) 4008c4: 03a0f021 move s8,sp 4008c8: 00801021 move v0,a0 ; ptr to retval space -> v0 4008cc: ac400000 sw zero,0(v0) ; return val 4008d0: 03c0e821 move sp,s8 4008d4: 8fbe0000 lw s8,0(sp) 4008d8: 03e00008 jr ra 4008dc: 27bd0008 addiu sp,sp,8 004008e0 <_Z2f2v>: 4008e0: 3c1c0002 lui gp,0x2 ; | 4008e4: 279c82e0 addiu gp,gp,-32032 ; | 4008e8: 0399e021 addu gp,gp,t9 ; | 4008ec: 27bdffd8 addiu sp,sp,-40 ; | prolog 4008f0: afbf0020 sw ra,32(sp) ; | 4008f4: afbe001c sw s8,28(sp) ; | 4008f8: afb00018 sw s0,24(sp) ; | 4008fc: 03a0f021 move s8,sp ; | frame pointer (note: with offset to frame start, but static compared to sp) 400900: afbc0010 sw gp,16(sp) ; 400904: 00808021 move s0,a0 ; 400908: 02001021 move v0,s0 ; 40090c: 00402021 move a0,v0 ; 400910: 8f998060 lw t9,-32672(gp) ; 400914: 0320f809 jalr t9 ; 400918: 00000000 nop ; 40091c: 8fdc0010 lw gp,16(s8) ; 400920: 02001021 move v0,s0 ; ptr to retval space -> v0 400924: 03c0e821 move sp,s8 ; | 400928: 8fbf0020 lw ra,32(sp) ; | 40092c: 8fbe001c lw s8,28(sp) ; | 400930: 8fb00018 lw s0,24(sp) ; | epilog 400934: 03e00008 jr ra ; | 400938: 27bd0028 addiu sp,sp,40 ; | 0040093c <f>: 40093c: 3c1c0002 lui gp,0x2 ; 400940: 279c8284 addiu gp,gp,-32124 ; 400944: 0399e021 addu gp,gp,t9 ; 400948: 27bdffd0 addiu sp,sp,-48 ; 40094c: afbf002c sw ra,44(sp) ; 400950: afbe0028 sw s8,40(sp) ; 400954: 03a0f021 move s8,sp ; 400958: afbc0010 sw gp,16(sp) ; 40095c: 24020001 li v0,1 ; 400960: afc20018 sw v0,24(s8) ; 400964: 8fc20018 lw v0,24(s8) ; 400968: 2442007b addiu v0,v0,123 ; 40096c: afc20018 sw v0,24(s8) ; 400970: 27c2001c addiu v0,s8,28 ; 400974: 00402021 move a0,v0 ; hidden first arg (ptr to space for ret val) 400978: 8f99805c lw t9,-32676(gp) ; | 40097c: 0320f809 jalr t9 ; | call f1() 400980: 00000000 nop ; 400984: 8fdc0010 lw gp,16(s8) ; 400988: 8fc20018 lw v0,24(s8) ; 40098c: 2442ff85 addiu v0,v0,-123 ; 400990: afc20018 sw v0,24(s8) ; 400994: 27c20020 addiu v0,s8,32 ; 400998: 00402021 move a0,v0 ; hidden first arg (ptr to space for ret val) 40099c: 8f998064 lw t9,-32668(gp) ; | 4009a0: 0320f809 jalr t9 ; | call f2() 4009a4: 00000000 nop ; 4009a8: 8fdc0010 lw gp,16(s8) ; 4009ac: 8fc20018 lw v0,24(s8) ; 4009b0: 2442fff4 addiu v0,v0,-12 ; 4009b4: afc20018 sw v0,24(s8) ; 4009b8: 03c0e821 move sp,s8 ; 4009bc: 8fbf002c lw ra,44(sp) ; 4009c0: 8fbe0028 lw s8,40(sp) ; 4009c4: 03e00008 jr ra ; 4009c8: 27bd0030 addiu sp,sp,48 ; ; vim: ft=asm