view doc/disas_examples/ppc.darwin.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 ead041d93e36
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 darwin-8.0.1-ppc w/ gcc 3.3

_leaf_call:
       0:       bf c1 ff f8     stmw 30, -8(1)
       4:       94 21 ff d0     stwu 1, -48(1)
       8:       7c 3e 0b 78     mr 30, 1
       c:       90 7e 00 48     stw 3, 72(30)
      10:       90 9e 00 4c     stw 4, 76(30)
      14:       90 be 00 50     stw 5, 80(30)
      18:       90 de 00 54     stw 6, 84(30)
      1c:       90 fe 00 58     stw 7, 88(30)
      20:       91 1e 00 5c     stw 8, 92(30)
      24:       91 3e 00 60     stw 9, 96(30)
      28:       80 21 00 00     lwz 1, 0(1)
      2c:       bb c1 ff f8     lmw 30, -8(1)
      30:       4e 80 00 20     blr

_nonleaf_call:
      34:       7c 08 02 a6     mflr 0          ; |         lr -> gpr0
      38:       bf c1 ff f8     stmw 30, -8(1)  ; |         store gpr{30,31}
      3c:       90 01 00 08     stw 0, 8(1)     ; | prolog  store lr
      40:       94 21 ff b0     stwu 1, -80(1)  ; |         open frame and store sp at top of stack
      44:       7c 3e 0b 78     mr 30, 1        ; /         sp -> gpr30, latter used for some fixed addressing below
      48:       90 7e 00 68     stw 3, 104(30)  ; \
      4c:       90 9e 00 6c     stw 4, 108(30)  ; |
      50:       90 be 00 70     stw 5, 112(30)  ; |
      54:       90 de 00 74     stw 6, 116(30)  ; |
      58:       90 fe 00 78     stw 7, 120(30)  ; | all in args -> spill area in prev frame
      5c:       91 1e 00 7c     stw 8, 124(30)  ; |
      60:       91 3e 00 80     stw 9, 128(30)  ; |
      64:       91 5e 00 84     stw 10, 132(30) ; |
      68:       80 01 00 00     lwz 0, 0(1)     ; fetch back-chain ptr (parent frame's sp) from stack of top by prolog -> gpr0, and ...
      6c:       94 01 ff 10     stwu 0, -240(1) ; ... update it further up the stack for alloca(220) - with padding to guarantee alignment
      70:       38 41 00 40     addi 2, 1, 64   ; |
      74:       38 02 00 0f     addi 0, 2, 15   ; | start of alloca()'d memory -> gpr2, by ...
      78:       54 00 e1 3e     srwi 0, 0, 4    ; | ... using gpr0 as helper to align to 16b, leaving at least 64b at top of stack
      7c:       54 02 20 36     slwi 2, 0, 4    ; |
      80:       38 00 00 4c     li 0, 76        ; 'L' -> gpr0, and ...
      84:       98 02 00 00     stb 0, 0(2)     ; ... store in local area (of alloca()'d space)
      88:       80 7e 00 6c     lwz 3, 108(30)  ; |
      8c:       80 9e 00 70     lwz 4, 112(30)  ; |
      90:       80 be 00 74     lwz 5, 116(30)  ; |
      94:       80 de 00 78     lwz 6, 120(30)  ; | arg 0,1,2,3,4,5,6 (fetched from spill area from prev frame)
      98:       80 fe 00 7c     lwz 7, 124(30)  ; |
      9c:       81 1e 00 80     lwz 8, 128(30)  ; |
      a0:       81 3e 00 84     lwz 9, 132(30)  ; |
      a4:       4b ff ff 5d     bl .+67108700   ; call and put return address -> lr
      a8:       80 21 00 00     lwz 1, 0(1)     ; |
      ac:       80 01 00 08     lwz 0, 8(1)     ; |
      b0:       7c 08 03 a6     mtlr 0          ; | epilog
      b4:       bb c1 ff f8     lmw 30, -8(1)   ; |
      b8:       4e 80 00 20     blr             ; |

_main:
      bc:       7c 08 02 a6     mflr 0          ; |
      c0:       bf c1 ff f8     stmw 30, -8(1)  ; |
      c4:       90 01 00 08     stw 0, 8(1)     ; | prolog
      c8:       94 21 ff b0     stwu 1, -80(1)  ; |
      cc:       7c 3e 0b 78     mr 30, 1        ; |
      d0:       38 60 00 00     li 3, 0         ; arg 0
      d4:       38 80 00 01     li 4, 1         ; arg 1
      d8:       38 a0 00 02     li 5, 2         ; arg 2
      dc:       38 c0 00 03     li 6, 3         ; arg 3
      e0:       38 e0 00 04     li 7, 4         ; arg 4
      e4:       39 00 00 05     li 8, 5         ; arg 5
      e8:       39 20 00 06     li 9, 6         ; arg 6
      ec:       39 40 00 07     li 10, 7        ; arg 7
      f0:       4b ff ff 45     bl .+67108676   ; call and put return address -> lr
      f4:       38 00 00 00     li 0, 0         ; return value (pointlessly) via gpr0 ...
      f8:       7c 03 03 78     mr 3, 0         ; ... to gpr3
      fc:       80 21 00 00     lwz 1, 0(1)     ; |
     100:       80 01 00 08     lwz 0, 8(1)     ; |
     104:       7c 08 03 a6     mtlr 0          ; | epilog
     108:       bb c1 ff f8     lmw 30, -8(1)   ; |
     10c:       4e 80 00 20     blr             ; |



; ------------- more than 8 int args ----------->

; #include <stdlib.h>
; 
; void leaf_call(int b, int c, int d, int e, int f, int g, int h, int i, int j)
; {
; }
; 
; void nonleaf_call(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j)
; {
; 	/* use some local data */
; 	*(char*)alloca(220) = 'L';
; 	leaf_call(b, c, d, e, f, g, h, i, j);
; }
; 
; int main()
; {
; 	nonleaf_call(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
; 	return 0;
; }



; output from darwin-8.0.1-ppc w/ gcc 3.3

_leaf_call:
       0:       bf c1 ff f8     stmw 30, -8(1)
       4:       94 21 ff d0     stwu 1, -48(1)
       8:       7c 3e 0b 78     mr 30, 1
       c:       90 7e 00 48     stw 3, 72(30)
      10:       90 9e 00 4c     stw 4, 76(30)
      14:       90 be 00 50     stw 5, 80(30)
      18:       90 de 00 54     stw 6, 84(30)
      1c:       90 fe 00 58     stw 7, 88(30)
      20:       91 1e 00 5c     stw 8, 92(30)
      24:       91 3e 00 60     stw 9, 96(30)
      28:       91 5e 00 64     stw 10, 100(30)
      2c:       80 21 00 00     lwz 1, 0(1)
      30:       bb c1 ff f8     lmw 30, -8(1)
      34:       4e 80 00 20     blr

_nonleaf_call:
      38:       7c 08 02 a6     mflr 0          ; |
      3c:       bf c1 ff f8     stmw 30, -8(1)  ; |
      40:       90 01 00 08     stw 0, 8(1)     ; | prolog
      44:       94 21 ff a0     stwu 1, -96(1)  ; |
      48:       7c 3e 0b 78     mr 30, 1        ; /
      4c:       90 7e 00 78     stw 3, 120(30)  ; \
      50:       90 9e 00 7c     stw 4, 124(30)  ; |
      54:       90 be 00 80     stw 5, 128(30)  ; |
      58:       90 de 00 84     stw 6, 132(30)  ; |
      5c:       90 fe 00 88     stw 7, 136(30)  ; | in args 0,1,2,3,4,5,6,7 -> spill area in prev frame
      60:       91 1e 00 8c     stw 8, 140(30)  ; |
      64:       91 3e 00 90     stw 9, 144(30)  ; |
      68:       91 5e 00 94     stw 10, 148(30) ; |
      6c:       80 01 00 00     lwz 0, 0(1)     ; fetch back-chain ptr (parent frame's sp) from stack of top by prolog -> gpr0, and ...
      70:       94 01 ff 10     stwu 0, -240(1) ; ... update it further up the stack for alloca(220) - with padding to guarantee alignment
      74:       38 41 00 50     addi 2, 1, 80   ; |
      78:       38 02 00 0f     addi 0, 2, 15   ; | start of alloca()'d memory -> gpr2, by ...
      7c:       54 00 e1 3e     srwi 0, 0, 4    ; | ... using gpr0 as helper to align to 16b, leaving at least 64b at top of stack
      80:       54 02 20 36     slwi 2, 0, 4    ; |
      84:       38 00 00 4c     li 0, 76        ; 'L' -> gpr0, and ...
      88:       98 02 00 00     stb 0, 0(2)     ; ... store in local area (of alloca()'d space)
      8c:       80 1e 00 9c     lwz 0, 156(30)  ; arg 7 (fetched from stack param area from prev frame), and ...
      90:       90 01 00 38     stw 0, 56(1)    ; ... "pushed" onto stack
      94:       80 7e 00 7c     lwz 3, 124(30)  ; |
      98:       80 9e 00 80     lwz 4, 128(30)  ; |
      9c:       80 be 00 84     lwz 5, 132(30)  ; |
      a0:       80 de 00 88     lwz 6, 136(30)  ; | arg 0,1,2,3,4,5,6 (fetched from spill area from prev frame)
      a4:       80 fe 00 8c     lwz 7, 140(30)  ; |
      a8:       81 1e 00 90     lwz 8, 144(30)  ; |
      ac:       81 3e 00 94     lwz 9, 148(30)  ; |
      b0:       81 5e 00 98     lwz 10, 152(30) ; arg 7 (fetched from stack param area from prev frame)
      b4:       4b ff ff 4d     bl .+67108684   ; call and put return address -> lr
      b8:       80 21 00 00     lwz 1, 0(1)     ; |
      bc:       80 01 00 08     lwz 0, 8(1)     ; |
      c0:       7c 08 03 a6     mtlr 0          ; | epilog
      c4:       bb c1 ff f8     lmw 30, -8(1)   ; |
      c8:       4e 80 00 20     blr             ; |

_main:
      cc:       7c 08 02 a6     mflr 0          ; |
      d0:       bf c1 ff f8     stmw 30, -8(1)  ; |
      d4:       90 01 00 08     stw 0, 8(1)     ; | prolog
      d8:       94 21 ff a0     stwu 1, -96(1)  ; |
      dc:       7c 3e 0b 78     mr 30, 1        ; |
      e0:       38 00 00 08     li 0, 8         ; arg 8, ...
      e4:       90 01 00 38     stw 0, 56(1)    ; ... "pushed" onto stack
      e8:       38 00 00 09     li 0, 9         ; arg 9, ...
      ec:       90 01 00 3c     stw 0, 60(1)    ; ... "pushed" onto stack
      f0:       38 60 00 00     li 3, 0         ; arg 0
      f4:       38 80 00 01     li 4, 1         ; arg 1
      f8:       38 a0 00 02     li 5, 2         ; arg 2
      fc:       38 c0 00 03     li 6, 3         ; arg 3
     100:       38 e0 00 04     li 7, 4         ; arg 4
     104:       39 00 00 05     li 8, 5         ; arg 5
     108:       39 20 00 06     li 9, 6         ; arg 6
     10c:       39 40 00 07     li 10, 7        ; arg 7
     110:       4b ff ff 29     bl .+67108648   ; call and put return address -> lr
     114:       38 00 00 00     li 0, 0         ; return value (pointlessly) via gpr0 ...
     118:       7c 03 03 78     mr 3, 0         ; ... to gpr3
     11c:       80 21 00 00     lwz 1, 0(1)     ; |
     120:       80 01 00 08     lwz 0, 8(1)     ; |
     124:       7c 08 03 a6     mtlr 0          ; | epilog
     128:       bb c1 ff f8     lmw 30, -8(1)   ; |
     12c:       4e 80 00 20     blr             ; |



; ------------- var args with ints and floats to see spilling (which remains only int regs), b/c doubles are passed via them and floats are promoted to doubles in (...) ----------->

; #include <stdlib.h>
; #include <stdarg.h>
; 
; void leaf_call(int b, int c, int d, int e, float f, float g, int h, int i, float j)
; {
; }
; 
; void nonleaf_call(int a, ...)
; {
;     int b, c, d, e, h, i;
;     float f, g, j;
;     va_list ap;
;     va_start(ap, a);
;     b = va_arg(ap, int);
;     c = va_arg(ap, int);
;     d = va_arg(ap, int);
;     e = va_arg(ap, int);
;     f = (float)va_arg(ap, double);
;     g = (float)va_arg(ap, double);
;     h = va_arg(ap, int);
;     i = va_arg(ap, int);
;     j = (float)va_arg(ap, double);
;     /* use some local data */
;     *(char*)alloca(220) = 'L';
;     leaf_call(b, c, d, e, f, g, h, i, j);
; }
; 
; int main()
; {
;     nonleaf_call(0, 1, 2, 3, 4, 5.f, 6.f, 7, 8, 9.f);
;     return 0;
; }



; output from darwin-8.0.1-ppc w/ gcc 3.3

_leaf_call:
       0:       bf c1 ff f8     stmw 30, -8(1)
       4:       94 21 ff d0     stwu 1, -48(1)
       8:       7c 3e 0b 78     mr 30, 1
       c:       90 7e 00 48     stw 3, 72(30)
      10:       90 9e 00 4c     stw 4, 76(30)
      14:       90 be 00 50     stw 5, 80(30)
      18:       90 de 00 54     stw 6, 84(30)
      1c:       d0 3e 00 58     stfs 1, 88(30)
      20:       d0 5e 00 5c     stfs 2, 92(30)
      24:       91 3e 00 60     stw 9, 96(30)
      28:       91 5e 00 64     stw 10, 100(30)
      2c:       d0 7e 00 68     stfs 3, 104(30)
      30:       80 21 00 00     lwz 1, 0(1)
      34:       bb c1 ff f8     lmw 30, -8(1)
      38:       4e 80 00 20     blr

_nonleaf_call:
      3c:       7c 08 02 a6     mflr 0          ; |
      40:       bf c1 ff f8     stmw 30, -8(1)  ; |
      44:       90 01 00 08     stw 0, 8(1)     ; | prolog
      48:       94 21 ff 70     stwu 1, -144(1) ; |
      4c:       7c 3e 0b 78     mr 30, 1        ; /
      50:       90 9e 00 ac     stw 4, 172(30)  ; \
      54:       90 be 00 b0     stw 5, 176(30)  ; |
      58:       90 de 00 b4     stw 6, 180(30)  ; |
      5c:       90 fe 00 b8     stw 7, 184(30)  ; |
      60:       91 1e 00 bc     stw 8, 188(30)  ; | in args ,1,2,3,4,5,6,7 -> spill area in prev frame
      64:       91 3e 00 c0     stw 9, 192(30)  ; |
      68:       91 5e 00 c4     stw 10, 196(30) ; |
      6c:       90 7e 00 a8     stw 3, 168(30)  ; |                  <- this is in arg 0, the only named arg
      70:       38 1e 00 ac     addi 0, 30, 172 ; get pointer to first unnamed arg in gpr0 for vararg iteration, ...
      74:       90 1e 00 74     stw 0, 116(30)  ; ... and store read ptr in local area
      78:       81 3e 00 74     lwz 9, 116(30)  ; \              read ptr -> gpr0
      7c:       80 5e 00 74     lwz 2, 116(30)  ; |              use gpr2 as helper ...
      80:       38 02 00 04     addi 0, 2, 4    ; |              ... to increment read ptr ...
      84:       90 1e 00 74     stw 0, 116(30)  ; | in arg 1     ... and restore
      88:       80 09 00 00     lwz 0, 0(9)     ; |              load in arg 1, and ...
      8c:       90 1e 00 50     stw 0, 80(30)   ; /              ... store in temp space in local area
      90:       81 3e 00 74     lwz 9, 116(30)  ; \
      94:       80 5e 00 74     lwz 2, 116(30)  ; |
      98:       38 02 00 04     addi 0, 2, 4    ; |
      9c:       90 1e 00 74     stw 0, 116(30)  ; | in arg 2
      a0:       80 09 00 00     lwz 0, 0(9)     ; |
      a4:       90 1e 00 54     stw 0, 84(30)   ; /
      a8:       81 3e 00 74     lwz 9, 116(30)  ; \
      ac:       80 5e 00 74     lwz 2, 116(30)  ; |
      b0:       38 02 00 04     addi 0, 2, 4    ; |
      b4:       90 1e 00 74     stw 0, 116(30)  ; | in arg 3
      b8:       80 09 00 00     lwz 0, 0(9)     ; |
      bc:       90 1e 00 58     stw 0, 88(30)   ; /
      c0:       81 3e 00 74     lwz 9, 116(30)  ; \
      c4:       80 5e 00 74     lwz 2, 116(30)  ; |
      c8:       38 02 00 04     addi 0, 2, 4    ; |
      cc:       90 1e 00 74     stw 0, 116(30)  ; | in arg 4
      d0:       80 09 00 00     lwz 0, 0(9)     ; |
      d4:       90 1e 00 5c     stw 0, 92(30)   ; /
      d8:       81 3e 00 74     lwz 9, 116(30)  ; \
      dc:       80 5e 00 74     lwz 2, 116(30)  ; |
      e0:       38 02 00 08     addi 0, 2, 8    ; |
      e4:       90 1e 00 74     stw 0, 116(30)  ; | in arg 5 (float, promoted to double)
      e8:       c8 09 00 00     lfd 0, 0(9)     ; |
      ec:       fc 00 00 18     frsp 0, 0       ; |
      f0:       d0 1e 00 68     stfs 0, 104(30) ; /
      f4:       81 3e 00 74     lwz 9, 116(30)  ; \
      f8:       80 5e 00 74     lwz 2, 116(30)  ; |
      fc:       38 02 00 08     addi 0, 2, 8    ; |
     100:       90 1e 00 74     stw 0, 116(30)  ; | in arg 6 (float, promoted to double)
     104:       c8 09 00 00     lfd 0, 0(9)     ; |
     108:       fc 00 00 18     frsp 0, 0       ; |
     10c:       d0 1e 00 6c     stfs 0, 108(30) ; /
     110:       81 3e 00 74     lwz 9, 116(30)  ; \
     114:       80 5e 00 74     lwz 2, 116(30)  ; |
     118:       38 02 00 04     addi 0, 2, 4    ; |
     11c:       90 1e 00 74     stw 0, 116(30)  ; | in arg 7
     120:       80 09 00 00     lwz 0, 0(9)     ; |
     124:       90 1e 00 60     stw 0, 96(30)   ; /
     128:       81 3e 00 74     lwz 9, 116(30)  ; \
     12c:       80 5e 00 74     lwz 2, 116(30)  ; |
     130:       38 02 00 04     addi 0, 2, 4    ; |
     134:       90 1e 00 74     stw 0, 116(30)  ; | in arg 8
     138:       80 09 00 00     lwz 0, 0(9)     ; |
     13c:       90 1e 00 64     stw 0, 100(30)  ; /
     140:       81 3e 00 74     lwz 9, 116(30)  ; \
     144:       80 5e 00 74     lwz 2, 116(30)  ; |
     148:       38 02 00 08     addi 0, 2, 8    ; |
     14c:       90 1e 00 74     stw 0, 116(30)  ; | in arg 9 (float, promoted to double)
     150:       c8 09 00 00     lfd 0, 0(9)     ; |
     154:       fc 00 00 18     frsp 0, 0       ; |
     158:       d0 1e 00 70     stfs 0, 112(30) ; /
     15c:       80 01 00 00     lwz 0, 0(1)     ; fetch back-chain ptr (parent frame's sp) from stack of top by prolog -> gpr0, and ...
     160:       94 01 ff 10     stwu 0, -240(1) ; ... update it further up the stack for alloca
     164:       38 41 00 50     addi 2, 1, 80   ; |
     168:       38 02 00 0f     addi 0, 2, 15   ; | start of alloca()'d memory -> gpr2, by ...
     16c:       54 00 e1 3e     srwi 0, 0, 4    ; | ... using gpr0 as helper to align to 16b, l
     170:       54 02 20 36     slwi 2, 0, 4    ; |
     174:       38 00 00 4c     li 0, 76        ; 'L' -> gpr0, and ...
     178:       98 02 00 00     stb 0, 0(2)     ; ... store in local area (of alloca()'d space)
     17c:       80 7e 00 50     lwz 3, 80(30)   ; arg 0
     180:       80 9e 00 54     lwz 4, 84(30)   ; arg 1
     184:       80 be 00 58     lwz 5, 88(30)   ; arg 2
     188:       80 de 00 5c     lwz 6, 92(30)   ; arg 3
     18c:       c0 3e 00 68     lfs 1, 104(30)  ; arg 4 (float)
     190:       c0 5e 00 6c     lfs 2, 108(30)  ; arg 5 (float)
     194:       81 3e 00 60     lwz 9, 96(30)   ; arg 6
     198:       81 5e 00 64     lwz 10, 100(30) ; arg 7
     19c:       c0 7e 00 70     lfs 3, 112(30)  ; arg 8 (float)
     1a0:       4b ff fe 61     bl .+67108448   ; call and put return address -> lr
     1a4:       80 21 00 00     lwz 1, 0(1)     ; |
     1a8:       80 01 00 08     lwz 0, 8(1)     ; |
     1ac:       7c 08 03 a6     mtlr 0          ; | epilog
     1b0:       bb c1 ff f8     lmw 30, -8(1)   ; |
     1b4:       4e 80 00 20     blr             ; |

_main:
     1b8:       7c 08 02 a6     mflr 0          ; |
     1bc:       bf c1 ff f8     stmw 30, -8(1)  ; |
     1c0:       90 01 00 08     stw 0, 8(1)     ; | prolog
     1c4:       94 21 ff 90     stwu 1, -112(1) ; |
     1c8:       7c 3e 0b 78     mr 30, 1        ; |
     1cc:       42 9f 00 05     bcl 20, 31, .+4 ; ppc way to get PC in ...
     1d0:       7f e8 02 a6     mflr 31         ; ... gpr31
     1d4:       38 00 00 07     li 0, 7         ; arg 7, ...
     1d8:       90 01 00 3c     stw 0, 60(1)    ; ... "pushed" onto stack
     1dc:       38 00 00 08     li 0, 8         ; arg 8, ...
     1e0:       90 01 00 40     stw 0, 64(1)    ; ... "pushed" onto stack
     1e4:       3c 40 40 22     lis 2, 16418    ; | arg 9, top-half (double b/c of vararg), and ...
     1e8:       38 60 00 00     li 3, 0         ; | ... bottom-half ...
     1ec:       90 41 00 44     stw 2, 68(1)    ; | ... "pushed" into stack
     1f0:       90 61 00 48     stw 3, 72(1)    ; |         "
     1f4:       38 00 00 00     li 0, 0         ; arg 6, bottom-half, ...
     1f8:       90 01 00 38     stw 0, 56(1)    ; ... "pushed" onto stack (first word in param area, top-half passed via gpr10, see below)
     1fc:       38 60 00 00     li 3, 0         ; arg 0
     200:       38 80 00 01     li 4, 1         ; arg 1
     204:       38 a0 00 02     li 5, 2         ; arg 2
     208:       38 c0 00 03     li 6, 3         ; arg 3
     20c:       38 e0 00 04     li 7, 4         ; arg 4
     210:       3d 20 40 14     lis 9, 16404    ; | prep arg 5 (double b/c of vararg) for move to arg reg later: top-half -> gpr9
     214:       39 40 00 00     li 10, 0        ; |                                                           bottom-half -> gpr10
     218:       3c 5f 00 00     addis 2, 31, 0  ; PC -> gpr2, to ...
     21c:       c8 02 00 98     lfd 0, 152(2)   ; ... load some static data (arg 5, the float) stored right after this function -> gpr0
     220:       7d 28 4b 78     mr 8, 9         ; arg 5, top-half
     224:       7d 49 53 78     mr 9, 10        ; arg 5, bottom-half
     228:       fc 20 00 90     fmr 1, 0        ; arg 5 in 1st fp reg
     22c:       3d 60 40 18     lis 11, 16408   ; | prep arg 6 (double b/c of vararg) for move to arg reg later: top-half -> gpr11
     230:       39 80 00 00     li 12, 0        ; |                                                           bottom-half -> gpr12 (this one is pointless, unused, bottom-half already placed on stack)
     234:       3c 5f 00 00     addis 2, 31, 0  ; PC -> gpr2, to ...
     238:       c8 02 00 a0     lfd 0, 160(2)   ; ... load some static data (arg 6, the 2nd float) stored right after this function -> gpr0
     23c:       7d 6a 5b 78     mr 10, 11       ; arg 6, top-half
     240:       fc 40 00 90     fmr 2, 0        ; arg 5 in 2nd fp reg
     244:       c8 01 00 44     lfd 0, 68(1)    ; arg 9, ...
     248:       fc 60 00 90     fmr 3, 0        ; ... -> 3rd fp reg
     24c:       4b ff fd f1     bl .+67108336   ; call and put return address -> lr
     250:       7c 03 03 78     mr 3, 0         ; return value @@@unsure why gpr0 is guaranteed to be 0 here
     254:       80 21 00 00     lwz 1, 0(1)     ; |
     258:       80 01 00 08     lwz 0, 8(1)     ; |
     25c:       7c 08 03 a6     mtlr 0          ; | epilog
     260:       bb c1 ff f8     lmw 30, -8(1)   ; |
     264:       4e 80 00 20     blr             ; |



; ---------- 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 darwin-8.0.1-ppc w/ gcc 3.3

_leaf_call:
00000000	stmw	r30,0xfff8(r1)
00000004	stwu	r1,0xffd0(r1)
00000008	or	r30,r1,r1
0000000c	stw	r3,0x48(r30)
00000010	stw	r4,0x4c(r30)
00000014	stw	r5,0x50(r30)
00000018	stw	r6,0x54(r30)
0000001c	stw	r7,0x58(r30)
00000020	stw	r8,0x5c(r30)
00000024	stw	r9,0x60(r30)
00000028	stw	r10,0x64(r30)
0000002c	lwz	r1,0x0(r1)
00000030	lmw	r30,0xfff8(r1)
00000034	blr
_nonleaf_call:
00000038	mfspr	r0,lr
0000003c	stmw	r30,0xfff8(r1)
00000040	stw	r0,0x8(r1)
00000044	stwu	r1,0xff30(r1)
00000048	or	r30,r1,r1
0000004c	bcl	20,31,0x50
00000050	mfspr	r31,lr
00000054	stw	r3,0xe8(r30)
00000058	stw	r4,0xec(r30)
0000005c	stw	r5,0xf0(r30)
00000060	stw	r6,0xf4(r30)
00000064	stw	r7,0xf8(r30)
00000068	stw	r8,0xfc(r30)
0000006c	stw	r9,0x100(r30)
00000070	stw	r10,0x104(r30)
00000074	addis	r2,r31,0x0
00000078	addi	r2,r2,0x148
0000007c	addi	r0,r30,0x50
00000080	li	r9,0x64
00000084	or	r3,r0,r0
00000088	or	r4,r2,r2
0000008c	or	r5,r9,r9
00000090	bl	0x178
00000094	lwz	r0,0x10c(r30)
00000098	stw	r0,0x38(r1)
0000009c	lwz	r0,0x110(r30)
000000a0	stw	r0,0x3c(r1)
000000a4	lwz	r3,0xec(r30)
000000a8	lwz	r4,0xf0(r30)
000000ac	lwz	r5,0xf4(r30)
000000b0	lwz	r6,0xf8(r30)
000000b4	lwz	r7,0xfc(r30)
000000b8	lwz	r8,0x100(r30)
000000bc	lwz	r9,0x104(r30)
000000c0	lwz	r10,0x108(r30)
000000c4	bl	0x0
000000c8	lwz	r1,0x0(r1)
000000cc	lwz	r0,0x8(r1)
000000d0	mtspr	lr,r0
000000d4	lmw	r30,0xfff8(r1)
000000d8	blr
_main:
000000dc	mfspr	r0,lr          ;
000000e0	stmw	r30,0xfff8(r1) ;
000000e4	stw	r0,0x8(r1)         ;
000000e8	stwu	r1,0xff90(r1)  ;
000000ec	or	r30,r1,r1          ;
000000f0	bcl	20,31,0xf4         ;
000000f4	mfspr	r31,lr         ;
000000f8	addis	r2,r31,0x0     ;
000000fc	addi	r2,r2,0x108    ;
00000100	lwz	r0,0x0(r2)         ;
00000104	lwz	r9,0x4(r2)         ;
00000108	lwz	r11,0x8(r2)        ;
0000010c	lwz	r2,0xc(r2)         ;
00000110	stw	r0,0x50(r30)       ;
00000114	stw	r9,0x54(r30)       ;
00000118	stw	r11,0x58(r30)      ;
0000011c	stw	r2,0x5c(r30)       ;
00000120	li	r0,0x8             ; arg 6, ...
00000124	stw	r0,0x3c(r1)        ; ... "pushed" onto stack
00000128	li	r0,0x9             ; arg 7, ...
0000012c	stw	r0,0x40(r1)        ; ... "pushed" onto stack
00000130	lwz	r0,0x5c(r30)       ; |                                       | last word of struct "pushed" onto stack
00000134	stw	r0,0x38(r1)        ; |                                       /
00000138	lwz	r8,0x50(r30)       ; | arg 5 (struct, passed as 4 words)     \
0000013c	lwz	r9,0x54(r30)       ; |                                       | first 3 words of struct passed in remaining regs
00000140	lwz	r10,0x58(r30)      ; |                                       |
00000144	li	r3,0x0             ; arg 0
00000148	li	r4,0x1             ; arg 1
0000014c	li	r5,0x2             ; arg 2
00000150	li	r6,0x3             ; arg 3
00000154	li	r7,0x4             ; arg 4
00000158	bl	0x38               ; call and put return address -> lr
0000015c	li	r0,0x0             ; return value (pointlessly) via gpr0 ...
00000160	or	r3,r0,r0           ; ... to gpr3
00000164	lwz	r1,0x0(r1)         ; |
00000168	lwz	r0,0x8(r1)         ; |
0000016c	mtspr	lr,r0          ; | epilog
00000170	lmw	r30,0xfff8(r1)     ; |
00000174	blr                    ; |



; ---------- single-field structs by value (of different sizes) ---------->
;
; struct C { char c;   }; // <= 2 bytes, but normal alignment as passed like a char
; struct S { short s;  }; // <= 2 bytes, but normal alignment as passed like a short
; struct I { int i;    };
; struct F { float f;  };
; struct D { double d; };
;
; struct C2 { char c[2]; }; // <= 2 bytes, special alignment
; struct C3 { char c[3]; }; //  > 2 bytes, normal alignment
;
; 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 darwin-8.0.1-ppc w/ gcc 3.3

_leaf_call:
00000000	stmw	r30,0xfff8(r1)
00000004	stwu	r1,0xffc0(r1)
00000008	or	r30,r1,r1
0000000c	sth	r3,0x58(r30)
00000010	stb	r4,0x5c(r30)
00000014	sth	r5,0x60(r30)
00000018	stw	r6,0x64(r30)
0000001c	stfs	f1,0x68(r30)
00000020	stfd	f2,0x20(r30)
00000024	lwz	r1,0x0(r1)
00000028	lmw	r30,0xfff8(r1)
0000002c	blr
_main:
00000030	mfspr	r0,lr          ; |
00000034	stmw	r30,0xfff8(r1) ; |
00000038	stw	r0,0x8(r1)         ; | prolog
0000003c	stwu	r1,0xff80(r1)  ; |
00000040	or	r30,r1,r1          ; |
00000044	bcl	20,31,0x48         ; ppc way to get PC in ...
00000048	mfspr	r31,lr         ; ... gpr31
0000004c	li	r0,0x0             ; |                          \
00000050	stb	r0,0x40(r30)       ; |                          |
00000054	li	r0,0x1             ; |                          | C2
00000058	stb	r0,0x41(r30)       ; |                          /
0000005c	li	r0,0x2             ; | local area struct init   \ C
00000060	stb	r0,0x42(r30)       ; |                          /
00000064	li	r0,0x3             ; |                          \ S
00000068	sth	r0,0x44(r30)       ; |                          /
0000006c	li	r0,0x4             ; |                          \ I
00000070	stw	r0,0x48(r30)       ; |                          /
00000074	lis	r0,0x40a0          ; |                          \ F
00000078	stw	r0,0x4c(r30)       ; |                          /
0000007c	addis	r2,r31,0x0     ; |                          \
00000080	addi	r2,r2,0xa8     ; |                          | D
00000084	lfd	f0,0x0(r2)         ; |                          |
00000088	stfd	f0,0x50(r30)   ; |                          /
0000008c	addis	r2,r31,0x0     ; |                          \
00000090	addi	r2,r2,0xb0     ; |                          |
00000094	lhz	r0,0x0(r2)         ; |                          | C3
00000098	lbz	r2,0x2(r2)         ; |                          |
0000009c	sth	r0,0x60(r30)       ; |                          |
000000a0	stb	r2,0x62(r30)       ; /                          /
000000a4	lhz	r0,0x60(r30)       ; \
000000a8	lbz	r2,0x62(r30)       ; |
000000ac	sth	r0,0x34(r1)        ; | prep arg 6 (struct C3), zero-extended, right justified -> local area on stack
000000b0	stb	r2,0x36(r1)        ; /
000000b4	lhz	r3,0x40(r30)       ; arg 0 (struct C2)
000000b8	lbz	r4,0x42(r30)       ; arg 1 (struct C)
000000bc	lhz	r5,0x44(r30)       ; arg 2 (struct S)
000000c0	lwz	r6,0x48(r30)       ; arg 3 (struct I)
000000c4	lfs	f1,0x4c(r30)       ; arg 4 (struct F, int arg reg r7 then skipped)
000000c8	lfd	f2,0x50(r30)       ; arg 5 (struct D, int arg regs r8 and r9 then skipped)
000000cc	lwz	r10,0x34(r1)       ; arg 6 (struct C3, fetched from local area)
000000d0	bl	0x0                ; call and put return address -> lr
000000d4	li	r0,0x0             ; return value (pointlessly) via gpr0 ...
000000d8	or	r3,r0,r0           ; ... to gpr3
000000dc	lwz	r1,0x0(r1)         ; |
000000e0	lwz	r0,0x8(r1)         ; |
000000e4	mtspr	lr,r0          ; | epilog
000000e8	lmw	r30,0xfff8(r1)     ; |
000000ec	blr                    ; |



; ---------- 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 darwin-8.0.1-ppc w/ gcc 3.3

_leaf_call:
00000000	stmw	r30,0xfff8(r1)
00000004	stwu	r1,0xffd0(r1)
00000008	or	r30,r1,r1
0000000c	stw	r3,0x48(r30)
00000010	stw	r4,0x4c(r30)
00000014	stw	r5,0x50(r30)
00000018	stw	r6,0x54(r30)
0000001c	stw	r7,0x58(r30)
00000020	stw	r8,0x5c(r30)
00000024	stw	r9,0x60(r30)
00000028	stw	r10,0x64(r30)
0000002c	lwz	r1,0x0(r1)
00000030	lmw	r30,0xfff8(r1)
00000034	blr
_nonleaf_call:
00000038	mfspr	r0,lr
0000003c	stmw	r30,0xfff8(r1)
00000040	stw	r0,0x8(r1)
00000044	stwu	r1,0xff10(r1)
00000048	or	r30,r1,r1
0000004c	bcl	20,31,0x50
00000050	mfspr	r31,lr
00000054	stw	r3,0x108(r30)
00000058	stw	r4,0x10c(r30)
0000005c	stw	r5,0x110(r30)
00000060	stw	r6,0x114(r30)
00000064	stw	r7,0x118(r30)
00000068	stw	r8,0x11c(r30)
0000006c	stw	r9,0x120(r30)
00000070	stw	r10,0x124(r30)
00000074	addis	r2,r31,0x0
00000078	addi	r2,r2,0x240
0000007c	addi	r0,r30,0x70
00000080	li	r9,0x64
00000084	or	r3,r0,r0
00000088	or	r4,r2,r2
0000008c	or	r5,r9,r9
00000090	bl	0x270
00000094	lwz	r0,0x12c(r30)
00000098	stw	r0,0x38(r1)
0000009c	lwz	r0,0x130(r30)
000000a0	stw	r0,0x3c(r1)
000000a4	lwz	r0,0x134(r30)
000000a8	lwz	r2,0x138(r30)
000000ac	lwz	r9,0x13c(r30)
000000b0	stw	r0,0x40(r1)
000000b4	stw	r2,0x44(r1)
000000b8	stw	r9,0x48(r1)
000000bc	lwz	r0,0x140(r30)
000000c0	lwz	r2,0x144(r30)
000000c4	lwz	r9,0x148(r30)
000000c8	lwz	r11,0x14c(r30)
000000cc	stw	r0,0x4c(r1)
000000d0	stw	r2,0x50(r1)
000000d4	stw	r9,0x54(r1)
000000d8	stw	r11,0x58(r1)
000000dc	lwz	r0,0x150(r30)
000000e0	stw	r0,0x5c(r1)
000000e4	lwz	r0,0x154(r30)
000000e8	stw	r0,0x60(r1)
000000ec	lwz	r3,0x10c(r30)
000000f0	lwz	r4,0x110(r30)
000000f4	lwz	r5,0x114(r30)
000000f8	lwz	r6,0x118(r30)
000000fc	lwz	r7,0x11c(r30)
00000100	lwz	r8,0x120(r30)
00000104	lwz	r9,0x124(r30)
00000108	lwz	r10,0x128(r30)
0000010c	bl	0x0
00000110	lwz	r1,0x0(r1)
00000114	lwz	r0,0x8(r1)
00000118	mtspr	lr,r0
0000011c	lmw	r30,0xfff8(r1)
00000120	blr
_main:
00000124	mfspr	r0,lr
00000128	stmw	r30,0xfff8(r1)
0000012c	stw	r0,0x8(r1)
00000130	stwu	r1,0xff40(r1)
00000134	or	r30,r1,r1
00000138	bcl	20,31,0x13c
0000013c	mfspr	r31,lr
00000140	addis	r2,r31,0x0
00000144	addi	r2,r2,0x1b8
00000148	lwz	r0,0x0(r2)
0000014c	lwz	r9,0x4(r2)
00000150	lwz	r2,0x8(r2)
00000154	stw	r0,0x70(r30)
00000158	stw	r9,0x74(r30)
0000015c	stw	r2,0x78(r30)
00000160	addis	r2,r31,0x0
00000164	addi	r2,r2,0x1c4
00000168	lwz	r0,0x0(r2)
0000016c	lwz	r9,0x4(r2)
00000170	lwz	r11,0x8(r2)
00000174	lwz	r2,0xc(r2)
00000178	stw	r0,0x80(r30)
0000017c	stw	r9,0x84(r30)
00000180	stw	r11,0x88(r30)
00000184	stw	r2,0x8c(r30)
00000188	addis	r2,r31,0x0
0000018c	addi	r2,r2,0x1d4
00000190	lwz	r0,0x0(r2)
00000194	lwz	r9,0x4(r2)
00000198	lwz	r2,0x8(r2)
0000019c	stw	r0,0x90(r30)
000001a0	stw	r9,0x94(r30)
000001a4	stw	r2,0x98(r30)
000001a8	addis	r2,r31,0x0
000001ac	addi	r2,r2,0x1e4
000001b0	lwz	r0,0x0(r2)
000001b4	lwz	r9,0x4(r2)
000001b8	lwz	r11,0x8(r2)
000001bc	lwz	r2,0xc(r2)
000001c0	stw	r0,0xa0(r30)
000001c4	stw	r9,0xa4(r30)
000001c8	stw	r11,0xa8(r30)
000001cc	stw	r2,0xac(r30)
000001d0	li	r0,0x7
000001d4	stw	r0,0x3c(r1)
000001d8	li	r0,0x8
000001dc	stw	r0,0x40(r1)
000001e0	lwz	r0,0x90(r30)
000001e4	lwz	r2,0x94(r30)
000001e8	lwz	r9,0x98(r30)
000001ec	stw	r0,0x44(r1)
000001f0	stw	r2,0x48(r1)
000001f4	stw	r9,0x4c(r1)
000001f8	lwz	r0,0xa0(r30)
000001fc	lwz	r2,0xa4(r30)
00000200	lwz	r9,0xa8(r30)
00000204	lwz	r11,0xac(r30)
00000208	stw	r0,0x50(r1)
0000020c	stw	r2,0x54(r1)
00000210	stw	r9,0x58(r1)
00000214	stw	r11,0x5c(r1)
00000218	li	r0,0xe
0000021c	stw	r0,0x60(r1)
00000220	li	r0,0xf
00000224	stw	r0,0x64(r1)
00000228	lwz	r0,0x8c(r30)
0000022c	stw	r0,0x38(r1)
00000230	lwz	r8,0x80(r30)
00000234	lwz	r9,0x84(r30)
00000238	lwz	r10,0x88(r30)
0000023c	li	r3,0x0
00000240	li	r4,0x1
00000244	lwz	r5,0x70(r30)
00000248	lwz	r6,0x74(r30)
0000024c	lwz	r7,0x78(r30)
00000250	bl	0x38
00000254	li	r0,0x0
00000258	or	r3,r0,r0
0000025c	lwz	r1,0x0(r1)
00000260	lwz	r0,0x8(r1)
00000264	mtspr	lr,r0
00000268	lmw	r30,0xfff8(r1)
0000026c	blr



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



; output from darwin-8.0.1-ppc w/ gcc 3.3

_f:
00000000	stmw	r30,0xfff8(r1)
00000004	stwu	r1,0xffd0(r1)
00000008	or	r30,r1,r1
0000000c	li	r2,0x0
00000010	li	r3,0x1c03
00000014	or	r4,r3,r3
00000018	or	r3,r2,r2
0000001c	lwz	r1,0x0(r1)
00000020	lmw	r30,0xfff8(r1)
00000024	blr
_main:
00000028	mfspr	r0,lr
0000002c	stmw	r30,0xfff8(r1)
00000030	stw	r0,0x8(r1)
00000034	stwu	r1,0xffb0(r1)
00000038	or	r30,r1,r1
0000003c	bl	0x0
00000040	or	r2,r3,r3
00000044	or	r3,r4,r4
00000048	or	r0,r3,r3
0000004c	or	r3,r0,r0
00000050	lwz	r1,0x0(r1)
00000054	lwz	r0,0x8(r1)
00000058	mtspr	lr,r0
0000005c	lmw	r30,0xfff8(r1)
00000060	blr



; ---------- returning structs by value ---------->
;
; struct Small { char x; };
; struct Big { long long i; long j; };
;
; 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 darwin-8.0.1-ppc w/ gcc 3.3

_f0:
00000000	stmw	r30,0xfff8(r1)
00000004	stwu	r1,0xffc0(r1)
00000008	or	r30,r1,r1
0000000c	or	r2,r3,r3
00000010	li	r0,0xff84
00000014	stb	r0,0x20(r30)
00000018	lbz	r0,0x20(r30)
0000001c	stb	r0,0x0(r2)
00000020	or	r3,r2,r2
00000024	lwz	r1,0x0(r1)
00000028	lmw	r30,0xfff8(r1)
0000002c	blr
_f1:
00000030	stmw	r30,0xfff8(r1)
00000034	stwu	r1,0xffc0(r1)
00000038	or	r30,r1,r1
0000003c	mfspr	r0,lr
00000040	bcl	20,31,0x44
00000044	mfspr	r8,lr
00000048	mtspr	lr,r0
0000004c	or	r9,r3,r3
00000050	addis	r2,r8,0x0
00000054	addi	r2,r2,0xb4
00000058	lwz	r0,0x0(r2)
0000005c	lwz	r11,0x4(r2)
00000060	lwz	r10,0x8(r2)
00000064	lwz	r2,0xc(r2)
00000068	stw	r0,0x20(r30)
0000006c	stw	r11,0x24(r30)
00000070	stw	r10,0x28(r30)
00000074	stw	r2,0x2c(r30)
00000078	lwz	r0,0x20(r30)
0000007c	lwz	r2,0x24(r30)
00000080	lwz	r11,0x28(r30)
00000084	lwz	r10,0x2c(r30)
00000088	stw	r0,0x0(r9)
0000008c	stw	r2,0x4(r9)
00000090	stw	r11,0x8(r9)
00000094	stw	r10,0xc(r9)
00000098	or	r3,r9,r9
0000009c	lwz	r1,0x0(r1)
000000a0	lmw	r30,0xfff8(r1)
000000a4	blr
_main:
000000a8	mfspr	r0,lr
000000ac	stmw	r30,0xfff8(r1)
000000b0	stw	r0,0x8(r1)
000000b4	stwu	r1,0xff90(r1)
000000b8	or	r30,r1,r1
000000bc	addi	r3,r30,0x40
000000c0	bl	0x0
000000c4	addi	r0,r30,0x50
000000c8	or	r3,r0,r0
000000cc	bl	0x30
000000d0	lbz	r0,0x40(r30)
000000d4	extsb	r2,r0
000000d8	lwz	r0,0x58(r30)
000000dc	add	r0,r2,r0
000000e0	or	r3,r0,r0
000000e4	lwz	r1,0x0(r1)
000000e8	lwz	r0,0x8(r1)
000000ec	mtspr	lr,r0
000000f0	lmw	r30,0xfff8(r1)
000000f4	blr



; ---------- 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 darwin-8.0.1-ppc w/ gcc 3.3

_f1:
00000000    stmw    r30,0xfff8(r1)
00000004    stwu    r1,0xffd0(r1)
00000008    or  r30,r1,r1
0000000c    stw r3,0x48(r30)
00000010    lwz r1,_f1(r1)
00000014    lmw r30,0xfff8(r1)
00000018    blr
_f2:
0000001c    stmw    r30,0xfff8(r1)
00000020    stwu    r1,0xffd0(r1)
00000024    or  r30,r1,r1
00000028    lwz r1,_f1(r1)
0000002c    lmw r30,0xfff8(r1)
00000030    blr
_f:
00000034    mfspr   r0,lr                       ;
00000038    stmw    r30,0xfff8(r1)              ;
0000003c    stw r0,0x8(r1)                      ;
00000040    stwu    r1,0xff70(r1)               ;
00000044    or  r30,r1,r1                       ;
00000048    addi    r0,r30,0x50                 ;
0000004c    or  r3,r0,r0                        ;
00000050    bl  0x140 ; __ZN10NonTrivialC1Ev    ; NonTrivial::NonTrivial() / ctor
00000054    li  r0,0x1                          ;
00000058    stw r0,0x60(r30)                    ;
0000005c    lwz r2,0x60(r30)                    ;
00000060    addi    r0,r2,0x7b                  ;
00000064    stw r0,0x60(r30)                    ;
00000068    lwz r0,0x40(r30)                    ;
0000006c    or  r3,r0,r0                        ;
00000070    bl  _f1                             ; call f1(struct Trivial)
00000074    lwz r2,0x60(r30)                    ;
00000078    addi    r0,r2,0xff85                ;
0000007c    stw r0,0x60(r30)                    ;
00000080    addi    r0,r30,0x70                 ;
00000084    addi    r2,r30,0x50                 ;
00000088    or  r3,r0,r0                        ; |               ptr to dest of copy of n
0000008c    or  r4,r2,r2                        ; | copy n        ptr to n
00000090    bl  0x120 ; __ZN10NonTrivialC1ERKS_ ; /               NonTrivial::NonTrivial(const NonTrivial&) / copy ctor
00000094    addi    r0,r30,0x70                 ; \
00000098    or  r3,r0,r0                        ; | f2 arg 0 (ptr to copy of struct NonTrivial), via ptr as non-trivial
0000009c    bl  _f2                             ; call f2(struct NonTrivial)
000000a0    lwz r2,0x60(r30)                    ;
000000a4    addi    r0,r2,0xfff4                ;
000000a8    stw r0,0x60(r30)                    ;
000000ac    lwz r1,_f1(r1)                      ;
000000b0    lwz r0,0x8(r1)                      ;
000000b4    mtspr   lr,r0                       ;
000000b8    lmw r30,0xfff8(r1)                  ;
000000bc    blr                                 ;

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



; vim: ft=asm