view doc/disas_examples/arm.atpcs_arm.disas @ 497:cb19b2fe2422

- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
author Tassilo Philipp
date Wed, 23 Mar 2022 15:24:31 +0100
parents 0fc22b5feac7
children fc614cb865c6
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 netbsd-4.0.1-cats w/ gcc 4.1.2

00000000 <leaf_call>:
   0:   e1a0c00d        mov     ip, sp
   4:   e92dd800        stmdb   sp!, {fp, ip, lr, pc}
   8:   e24cb004        sub     fp, ip, #4      ; 0x4
   c:   e24dd010        sub     sp, sp, #16     ; 0x10
  10:   e50b0010        str     r0, [fp, #-16]
  14:   e50b1014        str     r1, [fp, #-20]
  18:   e50b2018        str     r2, [fp, #-24]
  1c:   e50b301c        str     r3, [fp, #-28]
  20:   e24bd00c        sub     sp, fp, #12     ; 0xc
  24:   e89da800        ldmia   sp, {fp, sp, pc}

00000028 <nonleaf_call>:
  28:   e1a0c00d        mov     ip, sp                 ; |
;spill here, if needed: stmdb   sp!, {r0, r1, r2, r3}  ; |         just for ref, if present this would change below offsets
  2c:   e92dd800        stmdb   sp!, {fp, ip, lr, pc}  ; |
  30:   e24cb004        sub     fp, ip, #4             ; | prolog
  34:   e24dd020        sub     sp, sp, #32            ; |
  38:   e50b0010        str     r0, [fp, #-16]         ; in arg 0 -> temp space in local area
  3c:   e50b1014        str     r1, [fp, #-20]         ; in arg 1 -> temp space in local area
  40:   e50b2018        str     r2, [fp, #-24]         ; in arg 2 -> temp space in local area
  44:   e50b301c        str     r3, [fp, #-28]         ; in arg 3 -> temp space in local area
  48:   e24dd0e0        sub     sp, sp, #224           ; alloca(220) - with padding to guarantee alignment
  4c:   e28d200c        add     r2, sp, #12            ; |
  50:   e50b2020        str     r2, [fp, #-32]         ; |        @@@ pointless push of r2 to local area to put it back ...
  54:   e51b2020        ldr     r2, [fp, #-32]         ; |        @@@ ... into r2
  58:   e2823003        add     r3, r2, #3             ; | start of (aligned) alloca()'d memory -> r3, leaving room at top of stack for param area
  5c:   e1a03123        mov     r3, r3, lsr #2         ; |
  60:   e1a03103        mov     r3, r3, lsl #2         ; /
  64:   e50b3020        str     r3, [fp, #-32]         ; \
  68:   e51b2020        ldr     r2, [fp, #-32]         ; | r2 -> r3, to free r2 (kinda pointless as followup code could use r2 and r3 the other way round)
  6c:   e3a0304c        mov     r3, #76                ; 'L' -> r3, and ...
  70:   e5c23000        strb    r3, [r2]               ; ... store in local area (of alloca()'d space)
  74:   e59b3008        ldr     r3, [fp, #8]           ; arg 4 (fetched from prev frame's param area), and ...
  78:   e58d3000        str     r3, [sp]               ; ... "pushed" onto stack
  7c:   e59b300c        ldr     r3, [fp, #12]          ; arg 5 (fetched from prev frame's param area), and ...
  80:   e58d3004        str     r3, [sp, #4]           ; ... "pushed" onto stack
  84:   e59b3010        ldr     r3, [fp, #16]          ; arg 6 (fetched from prev frame's param area), and ...
  88:   e58d3008        str     r3, [sp, #8]           ; ... "pushed" onto stack
  8c:   e51b0014        ldr     r0, [fp, #-20]         ; arg 0
  90:   e51b1018        ldr     r1, [fp, #-24]         ; arg 1
  94:   e51b201c        ldr     r2, [fp, #-28]         ; arg 2
  98:   e59b3004        ldr     r3, [fp, #4]           ; arg 3 (fetched from prev frame's param area)
  9c:   ebfffffe        bl      9c <nonleaf_call+0x74> ; return address -> r14/lr, and call
  a0:   e24bd00c        sub     sp, fp, #12            ; |
  a4:   e89da800        ldmia   sp, {fp, sp, pc}       ; | epilog

000000a8 <main>:
  a8:   e1a0c00d        mov     ip, sp                 ; |
  ac:   e92dd800        stmdb   sp!, {fp, ip, lr, pc}  ; |
  b0:   e24cb004        sub     fp, ip, #4             ; | prolog
  b4:   e24dd010        sub     sp, sp, #16            ; |
  b8:   e3a03004        mov     r3, #4                 ; arg 4, and ...
  bc:   e58d3000        str     r3, [sp]               ; ... "pushed" onto stack
  c0:   e3a03005        mov     r3, #5                 ; arg 5, and ...
  c4:   e58d3004        str     r3, [sp, #4]           ; ... "pushed" onto stack
  c8:   e3a03006        mov     r3, #6                 ; arg 6, and ...
  cc:   e58d3008        str     r3, [sp, #8]           ; ... "pushed" onto stack
  d0:   e3a03007        mov     r3, #7                 ; arg 7, and ...
  d4:   e58d300c        str     r3, [sp, #12]          ; ... "pushed" onto stack
  d8:   e3a00000        mov     r0, #0                 ; arg 0
  dc:   e3a01001        mov     r1, #1                 ; arg 1
  e0:   e3a02002        mov     r2, #2                 ; arg 2
  e4:   e3a03003        mov     r3, #3                 ; arg 3
  e8:   ebfffffe        bl      e8 <main+0x40>         ; return address -> r14/lr, and call
  ec:   e3a03000        mov     r3, #0                 ; return value via r3, ... (a bit unoptimal)
  f0:   e1a00003        mov     r0, r3                 ; ... to r0
  f4:   e24bd00c        sub     sp, fp, #12            ; |
  f8:   e89da800        ldmia   sp, {fp, sp, pc}       ; | epilog



; output from freebsd-11.0_r260099-raspberrypi w/ clang 3.3

00000000 <leaf_call>:
   0:   e24dd030        sub     sp, sp, #48     ; 0x30
   4:   e58d002c        str     r0, [sp, #44]
   8:   e58d1028        str     r1, [sp, #40]
   c:   e58d2024        str     r2, [sp, #36]
  10:   e58d3020        str     r3, [sp, #32]
  14:   e59dc030        ldr     ip, [sp, #48]
  18:   e58dc01c        str     ip, [sp, #28]
  1c:   e59dc034        ldr     ip, [sp, #52]
  20:   e58dc018        str     ip, [sp, #24]
  24:   e59dc038        ldr     ip, [sp, #56]
  28:   e58dc014        str     ip, [sp, #20]
  2c:   e58d1010        str     r1, [sp, #16]
  30:   e58d300c        str     r3, [sp, #12]
  34:   e58d2008        str     r2, [sp, #8]
  38:   e58d0004        str     r0, [sp, #4]
  3c:   e28dd030        add     sp, sp, #48     ; 0x30
  40:   e12fff1e        bx      lr

00000044 <nonleaf_call>:
  44:   e92d4bf0        push    {r4, r5, r6, r7, r8, r9, fp, lr}
  48:   e28db018        add     fp, sp, #24     ; 0x18
  4c:   e24ddf4a        sub     sp, sp, #296    ; 0x128
  50:   e50b001c        str     r0, [fp, #-28]
  54:   e50b1020        str     r1, [fp, #-32]
  58:   e50b2024        str     r2, [fp, #-36]
  5c:   e50b3028        str     r3, [fp, #-40]
  60:   e59bc008        ldr     ip, [fp, #8]
  64:   e50bc02c        str     ip, [fp, #-44]
  68:   e59bc00c        ldr     ip, [fp, #12]
  6c:   e50bc030        str     ip, [fp, #-48]
  70:   e59bc010        ldr     ip, [fp, #16]
  74:   e50bc034        str     ip, [fp, #-52]
  78:   e59bc014        ldr     ip, [fp, #20]
  7c:   e50bc038        str     ip, [fp, #-56]
  80:   e3a0c04c        mov     ip, #76 ; 0x4c
  84:   e5cdc02c        strb    ip, [sp, #44]
  88:   e51bc020        ldr     ip, [fp, #-32]
  8c:   e51be024        ldr     lr, [fp, #-36]
  90:   e51b4028        ldr     r4, [fp, #-40]
  94:   e51b502c        ldr     r5, [fp, #-44]
  98:   e51b6030        ldr     r6, [fp, #-48]
  9c:   e51b7034        ldr     r7, [fp, #-52]
  a0:   e51b8038        ldr     r8, [fp, #-56]
  a4:   e1a0900d        mov     r9, sp
  a8:   e5898008        str     r8, [r9, #8]
  ac:   e5897004        str     r7, [r9, #4]
  b0:   e5896000        str     r6, [r9]
  b4:   e58d0028        str     r0, [sp, #40]
  b8:   e1a0000c        mov     r0, ip
  bc:   e58d1024        str     r1, [sp, #36]
  c0:   e1a0100e        mov     r1, lr
  c4:   e58d2020        str     r2, [sp, #32]
  c8:   e1a02004        mov     r2, r4
  cc:   e58d301c        str     r3, [sp, #28]
  d0:   e1a03005        mov     r3, r5
  d4:   ebfffffe        bl      0 <leaf_call>
  d8:   e59d001c        ldr     r0, [sp, #28]
  dc:   e59d1020        ldr     r1, [sp, #32]
  e0:   e59d2024        ldr     r2, [sp, #36]
  e4:   e59d3028        ldr     r3, [sp, #40]
  e8:   e58d0018        str     r0, [sp, #24]
  ec:   e58d1014        str     r1, [sp, #20]
  f0:   e58d2010        str     r2, [sp, #16]
  f4:   e58d300c        str     r3, [sp, #12]
  f8:   e24bd018        sub     sp, fp, #24     ; 0x18
  fc:   e8bd8bf0        pop     {r4, r5, r6, r7, r8, r9, fp, pc}

00000100 <main>:
 100:   e92d4800        push    {fp, lr}
 104:   e1a0b00d        mov     fp, sp
 108:   e24dd018        sub     sp, sp, #24     ; 0x18
 10c:   e3a00000        mov     r0, #0  ; 0x0
 110:   e50b0004        str     r0, [fp, #-4]
 114:   e3a01007        mov     r1, #7  ; 0x7
 118:   e1a0200d        mov     r2, sp
 11c:   e582100c        str     r1, [r2, #12]
 120:   e3a01006        mov     r1, #6  ; 0x6
 124:   e5821008        str     r1, [r2, #8]
 128:   e3a01005        mov     r1, #5  ; 0x5
 12c:   e5821004        str     r1, [r2, #4]
 130:   e3a01004        mov     r1, #4  ; 0x4
 134:   e5821000        str     r1, [r2]
 138:   e3a01001        mov     r1, #1  ; 0x1
 13c:   e3a02002        mov     r2, #2  ; 0x2
 140:   e3a03003        mov     r3, #3  ; 0x3
 144:   e50b0008        str     r0, [fp, #-8]
 148:   ebfffffe        bl      44 <nonleaf_call>
 14c:   e51b0008        ldr     r0, [fp, #-8]
 150:   e1a0d00b        mov     sp, fp
 154:   e8bd8800        pop     {fp, pc}



; ---------- 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 debian-6.0.8-armel w/ gcc 4.4.5

00000000 <leaf_call>:
   0:   e52db004        push    {fp}            ; (str fp, [sp, #-4]!)
   4:   e28db000        add     fp, sp, #0
   8:   e24dd014        sub     sp, sp, #20
   c:   e50b0008        str     r0, [fp, #-8]
  10:   e50b100c        str     r1, [fp, #-12]
  14:   e50b2010        str     r2, [fp, #-16]
  18:   e50b3014        str     r3, [fp, #-20]
  1c:   e28bd000        add     sp, fp, #0
  20:   e8bd0800        pop     {fp}
  24:   e12fff1e        bx      lr

00000028 <nonleaf_call>:
  28:   e92d4800        push    {fp, lr}
  2c:   e28db004        add     fp, sp, #4
  30:   e24dd090        sub     sp, sp, #144    ; 0x90
  34:   e50b0070        str     r0, [fp, #-112] ; 0x70
  38:   e50b1074        str     r1, [fp, #-116] ; 0x74
  3c:   e50b2078        str     r2, [fp, #-120] ; 0x78
  40:   e50b307c        str     r3, [fp, #-124] ; 0x7c
  44:   e24b2068        sub     r2, fp, #104    ; 0x68
  48:   e3a03064        mov     r3, #100        ; 0x64
  4c:   e1a00002        mov     r0, r2
  50:   e3a01000        mov     r1, #0
  54:   e1a02003        mov     r2, r3
  58:   ebfffffe        bl      0 <memset>
  5c:   e3a0304c        mov     r3, #76 ; 0x4c
  60:   e54b3068        strb    r3, [fp, #-104] ; 0x68
  64:   e1a0c00d        mov     ip, sp
  68:   e28b300c        add     r3, fp, #12
  6c:   e893000f        ldm     r3, {r0, r1, r2, r3}
  70:   e88c000f        stm     ip, {r0, r1, r2, r3}
  74:   e59b301c        ldr     r3, [fp, #28]
  78:   e58d3010        str     r3, [sp, #16]
  7c:   e59b3020        ldr     r3, [fp, #32]
  80:   e58d3014        str     r3, [sp, #20]
  84:   e51b0074        ldr     r0, [fp, #-116] ; 0x74
  88:   e51b1078        ldr     r1, [fp, #-120] ; 0x78
  8c:   e51b207c        ldr     r2, [fp, #-124] ; 0x7c
  90:   e59b3004        ldr     r3, [fp, #4]
  94:   ebfffffe        bl      0 <leaf_call>
  98:   e24bd004        sub     sp, fp, #4
  9c:   e8bd4800        pop     {fp, lr}
  a0:   e12fff1e        bx      lr

000000a4 <main>:
  a4:   e92d4800        push    {fp, lr}             ;
  a8:   e28db004        add     fp, sp, #4           ;
  ac:   e24dd030        sub     sp, sp, #48          ;
  b0:   e59f3058        ldr     r3, [pc, #88]        ;
  b4:   e24bc014        sub     ip, fp, #20          ;
  b8:   e893000f        ldm     r3, {r0, r1, r2, r3} ;
  bc:   e88c000f        stm     ip, {r0, r1, r2, r3} ;
  c0:   e3a03004        mov     r3, #4               ; arg 4, ...
  c4:   e58d3000        str     r3, [sp]             ; ... pushed onto stack
  c8:   e28dc008        add     ip, sp, #8           ; prep arg 5, write ptr ...
  cc:   e24b3014        sub     r3, fp, #20          ; ... read ptr (local area)
  d0:   e893000f        ldm     r3, {r0, r1, r2, r3} ; arg 5 (struct A), ...
  d4:   e88c000f        stm     ip, {r0, r1, r2, r3} ; ... pushed onto stack (as 4 words)
  d8:   e3a03008        mov     r3, #8               ; arg 6, ...
  dc:   e58d3018        str     r3, [sp, #24]        ; ... pushed onto stack
  e0:   e3a03009        mov     r3, #9               ; arg 6, ...
  e4:   e58d301c        str     r3, [sp, #28]        ; ... pushed onto stack
  e8:   e3a00000        mov     r0, #0               ; arg 0
  ec:   e3a01001        mov     r1, #1               ; arg 1
  f0:   e3a02002        mov     r2, #2               ; arg 2
  f4:   e3a03003        mov     r3, #3               ; arg 3
  f8:   ebfffffe        bl      28 <nonleaf_call>    ;
  fc:   e3a03000        mov     r3, #0               ;
 100:   e1a00003        mov     r0, r3               ;
 104:   e24bd004        sub     sp, fp, #4           ;
 108:   e8bd4800        pop     {fp, lr}             ;
 10c:   e12fff1e        bx      lr                   ;
 110:   00000000        .word   0x00000000



; ---------- 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 debian-6.0.8-armel w/ gcc 4.4.5

00000000 <leaf_call>:
   0:   e52db004        push    {fp}            ; (str fp, [sp, #-4]!)
   4:   e28db000        add     fp, sp, #0
   8:   e24dd014        sub     sp, sp, #20
   c:   e50b0008        str     r0, [fp, #-8]
  10:   e24b0014        sub     r0, fp, #20
  14:   e880000e        stm     r0, {r1, r2, r3}
  18:   e28bd000        add     sp, fp, #0
  1c:   e8bd0800        pop     {fp}
  20:   e12fff1e        bx      lr

00000024 <nonleaf_call>:
  24:   e24dd008        sub     sp, sp, #8
  28:   e92d4800        push    {fp, lr}
  2c:   e28db004        add     fp, sp, #4
  30:   e24dd0b0        sub     sp, sp, #176    ; 0xb0
  34:   e50b0070        str     r0, [fp, #-112] ; 0x70
  38:   e50b1074        str     r1, [fp, #-116] ; 0x74
  3c:   e28b1004        add     r1, fp, #4
  40:   e881000c        stm     r1, {r2, r3}
  44:   e24b2068        sub     r2, fp, #104    ; 0x68
  48:   e3a03064        mov     r3, #100        ; 0x64
  4c:   e1a00002        mov     r0, r2
  50:   e3a01000        mov     r1, #0
  54:   e1a02003        mov     r2, r3
  58:   ebfffffe        bl      0 <memset>
  5c:   e3a0304c        mov     r3, #76 ; 0x4c
  60:   e54b3068        strb    r3, [fp, #-104] ; 0x68
  64:   e1a0c00d        mov     ip, sp
  68:   e28b3014        add     r3, fp, #20
  6c:   e893000f        ldm     r3, {r0, r1, r2, r3}
  70:   e88c000f        stm     ip, {r0, r1, r2, r3}
  74:   e59b3024        ldr     r3, [fp, #36]   ; 0x24
  78:   e58d3010        str     r3, [sp, #16]
  7c:   e59b3028        ldr     r3, [fp, #40]   ; 0x28
  80:   e58d3014        str     r3, [sp, #20]
  84:   e28dc018        add     ip, sp, #24
  88:   e28b302c        add     r3, fp, #44     ; 0x2c
  8c:   e8930007        ldm     r3, {r0, r1, r2}
  90:   e88c0007        stm     ip, {r0, r1, r2}
  94:   e28dc028        add     ip, sp, #40     ; 0x28
  98:   e28b303c        add     r3, fp, #60     ; 0x3c
  9c:   e893000f        ldm     r3, {r0, r1, r2, r3}
  a0:   e88c000f        stm     ip, {r0, r1, r2, r3}
  a4:   e59b304c        ldr     r3, [fp, #76]   ; 0x4c
  a8:   e58d3038        str     r3, [sp, #56]   ; 0x38
  ac:   e59b3050        ldr     r3, [fp, #80]   ; 0x50
  b0:   e58d303c        str     r3, [sp, #60]   ; 0x3c
  b4:   e51b0074        ldr     r0, [fp, #-116] ; 0x74
  b8:   e28b3004        add     r3, fp, #4
  bc:   e893000e        ldm     r3, {r1, r2, r3}
  c0:   ebfffffe        bl      0 <leaf_call>
  c4:   e24bd004        sub     sp, fp, #4
  c8:   e8bd4800        pop     {fp, lr}
  cc:   e28dd008        add     sp, sp, #8
  d0:   e12fff1e        bx      lr

000000d4 <main>:
  d4:   e92d4800        push    {fp, lr}
  d8:   e28db004        add     fp, sp, #4
  dc:   e24dd088        sub     sp, sp, #136    ; 0x88
  e0:   e59f20b8        ldr     r2, [pc, #184]  ; 1a0 <main+0xcc>
  e4:   e24b3040        sub     r3, fp, #64     ; 0x40
  e8:   e8920007        ldm     r2, {r0, r1, r2}
  ec:   e8830007        stm     r3, {r0, r1, r2}
  f0:   e59f30ac        ldr     r3, [pc, #172]  ; 1a4 <main+0xd0>
  f4:   e24bc034        sub     ip, fp, #52     ; 0x34
  f8:   e893000f        ldm     r3, {r0, r1, r2, r3}
  fc:   e88c000f        stm     ip, {r0, r1, r2, r3}
 100:   e59f20a0        ldr     r2, [pc, #160]  ; 1a8 <main+0xd4>
 104:   e24b3020        sub     r3, fp, #32
 108:   e8920007        ldm     r2, {r0, r1, r2}
 10c:   e8830007        stm     r3, {r0, r1, r2}
 110:   e59f3094        ldr     r3, [pc, #148]  ; 1ac <main+0xd8>
 114:   e24bc014        sub     ip, fp, #20
 118:   e893000f        ldm     r3, {r0, r1, r2, r3}
 11c:   e88c000f        stm     ip, {r0, r1, r2, r3}
 120:   e28dc008        add     ip, sp, #8
 124:   e24b3034        sub     r3, fp, #52     ; 0x34
 128:   e893000f        ldm     r3, {r0, r1, r2, r3}
 12c:   e88c000f        stm     ip, {r0, r1, r2, r3}
 130:   e3a03007        mov     r3, #7
 134:   e58d3018        str     r3, [sp, #24]
 138:   e3a03008        mov     r3, #8
 13c:   e58d301c        str     r3, [sp, #28]
 140:   e28dc020        add     ip, sp, #32
 144:   e24b3020        sub     r3, fp, #32
 148:   e8930007        ldm     r3, {r0, r1, r2}
 14c:   e88c0007        stm     ip, {r0, r1, r2}
 150:   e28dc030        add     ip, sp, #48     ; 0x30
 154:   e24b3014        sub     r3, fp, #20
 158:   e893000f        ldm     r3, {r0, r1, r2, r3}
 15c:   e88c000f        stm     ip, {r0, r1, r2, r3}
 160:   e3a0300e        mov     r3, #14
 164:   e58d3040        str     r3, [sp, #64]   ; 0x40
 168:   e3a0300f        mov     r3, #15
 16c:   e58d3044        str     r3, [sp, #68]   ; 0x44
 170:   e51b3038        ldr     r3, [fp, #-56]  ; 0x38
 174:   e58d3000        str     r3, [sp]
 178:   e24b3040        sub     r3, fp, #64     ; 0x40
 17c:   e893000c        ldm     r3, {r2, r3}
 180:   e3a00000        mov     r0, #0
 184:   e3a01001        mov     r1, #1
 188:   ebfffffe        bl      24 <nonleaf_call>
 18c:   e3a03000        mov     r3, #0
 190:   e1a00003        mov     r0, r3
 194:   e24bd004        sub     sp, fp, #4
 198:   e8bd4800        pop     {fp, lr}
 19c:   e12fff1e        bx      lr
 1a0:   00000000        .word   0x00000000
 1a4:   00000010        .word   0x00000010
 1a8:   00000020        .word   0x00000020
 1ac:   00000030        .word   0x00000030



; ---------- returning long long ---------->
;
; long long f()
; {
;     return 7171LL;
; }
;
; int main()
; {
;     return (int)f();
; }



; output from debian-6.0.8-armel w/ gcc 4.4.5

00000000 <f>:
   0:   e92d0810        push    {r4, fp}   ;
   4:   e28db004        add     fp, sp, #4 ;
   8:   e3a03b07        mov     r3, #7168  ;
   c:   e2833003        add     r3, r3, #3 ;
  10:   e3a04000        mov     r4, #0     ;
  14:   e1a00003        mov     r0, r3     ; | retval in two regs
  18:   e1a01004        mov     r1, r4     ; |
  1c:   e24bd004        sub     sp, fp, #4 ;
  20:   e8bd0810        pop     {r4, fp}   ;
  24:   e12fff1e        bx      lr         ;

00000028 <main>:
  28:   e92d4830        push    {r4, r5, fp, lr}
  2c:   e28db00c        add     fp, sp, #12
  30:   ebfffffe        bl      0 <f>
  34:   e1a03000        mov     r3, r0
  38:   e1a04001        mov     r4, r1
  3c:   e1a00003        mov     r0, r3
  40:   e24bd00c        sub     sp, fp, #12
  44:   e8bd4830        pop     {r4, r5, fp, lr}
  48:   e12fff1e        bx      lr



; ---------- 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 debian-6.0.8-armel w/ gcc 4.4.5

00000000 <leaf_call>:
   0:   e24dd008        sub     sp, sp, #8
   4:   e52db004        push    {fp}            ; (str fp, [sp, #-4]!)
   8:   e28db000        add     fp, sp, #0
   c:   e24dd014        sub     sp, sp, #20
  10:   e50b0008        str     r0, [fp, #-8]
  14:   e24b0010        sub     r0, fp, #16
  18:   e8800006        stm     r0, {r1, r2}
  1c:   e58b3008        str     r3, [fp, #8]
  20:   e28bd000        add     sp, fp, #0
  24:   e8bd0800        pop     {fp}
  28:   e28dd008        add     sp, sp, #8
  2c:   e12fff1e        bx      lr

00000030 <main>:
  30:   e92d4810        push    {r4, fp, lr}          ;
  34:   e28db008        add     fp, sp, #8            ;
  38:   e24dd084        sub     sp, sp, #132          ;
  3c:   e59f30d0        ldr     r3, [pc, #208]        ;
  40:   e50b3054        str     r3, [fp, #-84]        ;
  44:   e59f20cc        ldr     r2, [pc, #204]        ;
  48:   e24b3050        sub     r3, fp, #80           ;
  4c:   e8920003        ldm     r2, {r0, r1}          ;
  50:   e8830003        stm     r3, {r0, r1}          ;
  54:   e59f20c0        ldr     r2, [pc, #192]        ;
  58:   e24b3048        sub     r3, fp, #72           ;
  5c:   e8920007        ldm     r2, {r0, r1, r2}      ;
  60:   e8830007        stm     r3, {r0, r1, r2}      ;
  64:   e3a03000        mov     r3, #0                ;
  68:   e3a045ff        mov     r4, #1069547520       ;
  6c:   e2844603        add     r4, r4, #3145728      ;
  70:   e50b303c        str     r3, [fp, #-60]        ;
  74:   e50b4038        str     r4, [fp, #-56]        ;
  78:   e59f30a0        ldr     r3, [pc, #160]        ;
  7c:   e24bc034        sub     ip, fp, #52           ;
  80:   e893000f        ldm     r3, {r0, r1, r2, r3}  ;
  84:   e88c000f        stm     ip, {r0, r1, r2, r3}  ;
  88:   e59f3094        ldr     r3, [pc, #148]        ;
  8c:   e24bc024        sub     ip, fp, #36           ;
  90:   e1a0e003        mov     lr, r3                ;
  94:   e8be000f        ldm     lr!, {r0, r1, r2, r3} ;
  98:   e8ac000f        stmia   ip!, {r0, r1, r2, r3} ;
  9c:   e89e0003        ldm     lr, {r0, r1}          ;
  a0:   e88c0003        stm     ip, {r0, r1}          ;
  a4:   e24b403c        sub     r4, fp, #60           ;
  a8:   e8940018        ldm     r4, {r3, r4}          ;
  ac:   e58d3008        str     r3, [sp, #8]          ;
  b0:   e58d400c        str     r4, [sp, #12]         ;
  b4:   e28dc010        add     ip, sp, #16           ;
  b8:   e24b3034        sub     r3, fp, #52           ;
  bc:   e893000f        ldm     r3, {r0, r1, r2, r3}  ;
  c0:   e88c000f        stm     ip, {r0, r1, r2, r3}  ;
  c4:   e28de020        add     lr, sp, #32           ;
  c8:   e24bc024        sub     ip, fp, #36           ;
  cc:   e8bc000f        ldm     ip!, {r0, r1, r2, r3} ;
  d0:   e8ae000f        stmia   lr!, {r0, r1, r2, r3} ;
  d4:   e89c0003        ldm     ip, {r0, r1}          ;
  d8:   e88e0003        stm     lr, {r0, r1}          ;
  dc:   e1a0300d        mov     r3, sp                ; |              write ptr
  e0:   e24b2044        sub     r2, fp, #68           ; |              read ptr
  e4:   e8920003        ldm     r2, {r0, r1}          ; | arg 3 (struct C), split via  |
  e8:   e8830003        stm     r3, {r0, r1}          ; |                              | stack    b & c
  ec:   e51b3048        ldr     r3, [fp, #-72]        ; |                              reg        a
  f0:   e51b0054        ldr     r0, [fp, #-84]        ; arg 0 (struct A), via reg as word         a
  f4:   e24b2050        sub     r2, fp, #80           ; |
  f8:   e8920006        ldm     r2, {r1, r2}          ; | arg 1 (struct B), via reg as 2 words    a & b
  fc:   ebfffffe        bl      0 <leaf_call>         ;
 100:   e3a03000        mov     r3, #0                ;
 104:   e1a00003        mov     r0, r3                ;
 108:   e24bd008        sub     sp, fp, #8            ;
 10c:   e8bd4810        pop     {r4, fp, lr}          ;
 110:   e12fff1e        bx      lr                    ;
 114:   3f800000        .word   0x3f800000
 118:   00000000        .word   0x00000000
 11c:   00000008        .word   0x00000008
 120:   00000018        .word   0x00000018
 124:   00000028        .word   0x00000028



; ---------- returning structs by value ---------->
;
; struct Small { char x; };
; struct Big { long long i; long j; }; /* bigger than a word */
;
; struct Small f0()
; {
;     struct Small s = { 132 };
;     return s;
; }
;
; struct Big f1()
; {
;     struct Big b = { 7171LL, 232 };
;     return b;
; }
;
; int main()
; {
;     struct Small s = f0();
;     struct Big b = f1();
;     return b.j + s.x;
; }



; output from debian-6.0.8-armel w/ gcc 4.4.5

00000000 <f0>:
   0:   e52db004        push    {fp}                 ;
   4:   e28db000        add     fp, sp, #0           ;
   8:   e24dd00c        sub     sp, sp, #12          ;
   c:   e3e0307b        mvn     r3, #123             ;
  10:   e54b3008        strb    r3, [fp, #-8]        ;
  14:   e55b3008        ldrb    r3, [fp, #-8]        ;
  18:   e1a00003        mov     r0, r3               ; return value (via reg as <= 4b)
  1c:   e28bd000        add     sp, fp, #0           ;
  20:   e8bd0800        pop     {fp}                 ;
  24:   e12fff1e        bx      lr                   ;

00000028 <f1>:
  28:   e92d0810        push    {r4, fp}             ;
  2c:   e28db004        add     fp, sp, #4           ;
  30:   e24dd010        sub     sp, sp, #16          ;
  34:   e1a0c000        mov     ip, r0               ; ptr to retval space, tmp copy
  38:   e59f3028        ldr     r3, [pc, #40]        ;
  3c:   e24b4014        sub     r4, fp, #20          ;
  40:   e893000f        ldm     r3, {r0, r1, r2, r3} ;
  44:   e884000f        stm     r4, {r0, r1, r2, r3} ;
  48:   e1a0400c        mov     r4, ip               ; write ptr
  4c:   e24b3014        sub     r3, fp, #20          ; read ptr
  50:   e893000f        ldm     r3, {r0, r1, r2, r3} ; |
  54:   e884000f        stm     r4, {r0, r1, r2, r3} ; | copy struct from local area to retval space
  58:   e1a0000c        mov     r0, ip               ; return value: ptr to retval space
  5c:   e24bd004        sub     sp, fp, #4           ;
  60:   e8bd0810        pop     {r4, fp}             ;
  64:   e12fff1e        bx      lr                   ;
  68:   00000000        .word   0x00000000

0000006c <main>:
  6c:   e92d4800        push    {fp, lr}
  70:   e28db004        add     fp, sp, #4
  74:   e24dd018        sub     sp, sp, #24
  78:   ebfffffe        bl      0 <f0>
  7c:   e1a03000        mov     r3, r0
  80:   e54b3008        strb    r3, [fp, #-8]
  84:   e24b301c        sub     r3, fp, #28
  88:   e1a00003        mov     r0, r3
  8c:   ebfffffe        bl      28 <f1>
  90:   e51b2014        ldr     r2, [fp, #-20]
  94:   e55b3008        ldrb    r3, [fp, #-8]
  98:   e0823003        add     r3, r2, r3
  9c:   e1a00003        mov     r0, r3
  a0:   e24bd004        sub     sp, fp, #4
  a4:   e8bd4800        pop     {fp, lr}
  a8:   e12fff1e        bx      lr



; ---------- 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 debian-6.0.8-armel w/ gcc 4.4.5

00000000 <leaf_call>:
   0:   e52db004        push    {fp}            ; (str fp, [sp, #-4]!)
   4:   e28db000        add     fp, sp, #0
   8:   e24dd014        sub     sp, sp, #20
   c:   e14b00b8        strh    r0, [fp, #-8]
  10:   e54b100c        strb    r1, [fp, #-12]
  14:   e14b21b0        strh    r2, [fp, #-16]
  18:   e50b3014        str     r3, [fp, #-20]
  1c:   e28bd000        add     sp, fp, #0
  20:   e8bd0800        pop     {fp}
  24:   e12fff1e        bx      lr

00000028 <main>:
  28:   e92d4810        push    {r4, fp, lr}     ;
  2c:   e28db008        add     fp, sp, #8       ;
  30:   e24dd044        sub     sp, sp, #68      ;
  34:   e3a03000        mov     r3, #0           ;
  38:   e54b3030        strb    r3, [fp, #-48]   ;
  3c:   e3a03001        mov     r3, #1           ;
  40:   e54b302f        strb    r3, [fp, #-47]   ;
  44:   e3a03002        mov     r3, #2           ;
  48:   e54b302c        strb    r3, [fp, #-44]   ;
  4c:   e3a03003        mov     r3, #3           ;
  50:   e14b32b8        strh    r3, [fp, #-40]   ;
  54:   e3a03004        mov     r3, #4           ;
  58:   e50b3024        str     r3, [fp, #-36]   ;
  5c:   e59f308c        ldr     r3, [pc, #140]   ;
  60:   e50b3020        str     r3, [fp, #-32]   ;
  64:   e3a03000        mov     r3, #0           ;
  68:   e3a04101        mov     r4, #1073741824  ;
  6c:   e2844706        add     r4, r4, #1572864 ;
  70:   e50b301c        str     r3, [fp, #-28]   ;
  74:   e50b4018        str     r4, [fp, #-24]   ;
  78:   e59f2074        ldr     r2, [pc, #116]   ;
  7c:   e24b3010        sub     r3, fp, #16      ;
  80:   e5922000        ldr     r2, [r2]         ;
  84:   e1c320b0        strh    r2, [r3]         ;
  88:   e2833002        add     r3, r3, #2       ;
  8c:   e1a02822        lsr     r2, r2, #16      ;
  90:   e5c32000        strb    r2, [r3]         ;
  94:   e51b3020        ldr     r3, [fp, #-32]   ; |
  98:   e58d3000        str     r3, [sp]         ; | arg 4 (struct F), via stack as word
  9c:   e24b401c        sub     r4, fp, #28      ;
  a0:   e8940018        ldm     r4, {r3, r4}     ;
  a4:   e58d3008        str     r3, [sp, #8]     ; |
  a8:   e58d400c        str     r4, [sp, #12]    ; | arg 5 (struct D), via stack as 2 words (aligned to 8, b/c double?)
  ac:   e28d3010        add     r3, sp, #16      ;
  b0:   e24b2010        sub     r2, fp, #16      ;
  b4:   e5922000        ldr     r2, [r2]         ; |
  b8:   e1c320b0        strh    r2, [r3]         ; |
  bc:   e2833002        add     r3, r3, #2       ; | arg 6 (struct C3), via stack as 3 bytes in word slot
  c0:   e1a02822        lsr     r2, r2, #16      ; |
  c4:   e5c32000        strb    r2, [r3]         ; |
  c8:   e51b0030        ldr     r0, [fp, #-48]   ; arg 0 (struct C2), via reg as word
  cc:   e55b102c        ldrb    r1, [fp, #-44]   ; arg 1 (struct C), via reg as word
  d0:   e15b22b8        ldrh    r2, [fp, #-40]   ; arg 2 (struct S), via reg as word
  d4:   e51b3024        ldr     r3, [fp, #-36]   ; arg 3 (struct I), via reg as word
  d8:   ebfffffe        bl      0 <leaf_call>    ;
  dc:   e3a03000        mov     r3, #0           ;
  e0:   e1a00003        mov     r0, r3           ;
  e4:   e24bd008        sub     sp, fp, #8       ;
  e8:   e8bd4810        pop     {r4, fp, lr}     ;
  ec:   e12fff1e        bx      lr               ;
  f0:   40a00000        .word   0x40a00000
  f4:   00000000        .word   0x00000000



; ---------- 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 debian-6.0.8-armel w/ gcc 4.4.5

00000000 <f1>:
   0:   e52db004        push    {fp}
   4:   e28db000        add     fp, sp, #0
   8:   e24dd00c        sub     sp, sp, #12
   c:   e50b0008        str     r0, [fp, #-8]
  10:   e28bd000        add     sp, fp, #0
  14:   e8bd0800        pop     {fp}
  18:   e12fff1e        bx      lr

0000001c <f2>:
  1c:   e52db004        push    {fp}
  20:   e28db000        add     fp, sp, #0
  24:   e24dd00c        sub     sp, sp, #12
  28:   e50b0008        str     r0, [fp, #-8]
  2c:   e28bd000        add     sp, fp, #0
  30:   e8bd0800        pop     {fp}
  34:   e12fff1e        bx      lr

00000038 <f>:
  38:   e92d4800        push    {fp, lr}                   ; |
  3c:   e28db004        add     fp, sp, #4                 ; | prolog
  40:   e24dd010        sub     sp, sp, #16                ; /
  44:   e24b3014        sub     r3, fp, #20                ; \
  48:   e1a00003        mov     r0, r3                     ; | this ptr (ptr to n's (NonTrivial) space)
  4c:   ebfffffe        bl      0 <_ZN10NonTrivialC1Ev>    ; | NonTrivial::NonTrivial() / ctor
  50:   e3a03001        mov     r3, #1                     ; a = 1
  54:   e50b3008        str     r3, [fp, #-8]              ; |
  58:   e51b3008        ldr     r3, [fp, #-8]              ; | a += 123
  5c:   e283307b        add     r3, r3, #123               ; |
  60:   e50b3008        str     r3, [fp, #-8]              ; |
  64:   e51b0010        ldr     r0, [fp, #-16]             ; f1 arg 0 (struct Trivial), via reg as small struct
  68:   ebfffffe        bl      0 <f1>                     ; call f1(struct Trivial)
  6c:   e51b3008        ldr     r3, [fp, #-8]              ; |
  70:   e243307b        sub     r3, r3, #123               ; | a -= 123
  74:   e50b3008        str     r3, [fp, #-8]              ; /
  78:   e24b200c        sub     r2, fp, #12                ; \
  7c:   e24b3014        sub     r3, fp, #20                ; |
  80:   e1a00002        mov     r0, r2                     ; |               ptr to dest of copy of n
  84:   e1a01003        mov     r1, r3                     ; | copy n        ptr to n
  88:   ebfffffe        bl      0 <_ZN10NonTrivialC1ERKS_> ; /               NonTrivial::NonTrivial(const NonTrivial&) / copy ctor
  8c:   e24b300c        sub     r3, fp, #12                ; \
  90:   e1a00003        mov     r0, r3                     ; | f2 arg 0 (ptr to copy of struct NonTrivial), via ptr as non-trivial
  94:   ebfffffe        bl      1c <f2>                    ; call f2(struct NonTrivial)
  98:   e51b3008        ldr     r3, [fp, #-8]              ; |
  9c:   e243300c        sub     r3, r3, #12                ; | a -= 12
  a0:   e50b3008        str     r3, [fp, #-8]              ; /
  a4:   e24bd004        sub     sp, fp, #4                 ; \
  a8:   e8bd4800        pop     {fp, lr}                   ; | epilog
  ac:   e12fff1e        bx      lr                         ; |

  ; ... snip, removed code of ctor and copy ctor ...



; vim: ft=asm68k