changeset 473:ead041d93e36

- ppc doc and disas examples related to aggregates
author Tassilo Philipp
date Wed, 16 Feb 2022 16:44:11 +0100
parents e5820b7a3fbc
children c9e19249ecd3
files doc/disas_examples/ppc.darwin.disas doc/disas_examples/ppc.sysv.disas doc/disas_examples/ppc64.elfabi.disas doc/disas_examples/x86.plan9call.disas doc/manual/callconvs/callconv_ppc32.tex doc/manual/callconvs/callconv_ppc64.tex
diffstat 6 files changed, 1540 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/doc/disas_examples/ppc.darwin.disas	Thu Feb 10 17:32:05 2022 +0100
+++ b/doc/disas_examples/ppc.darwin.disas	Wed Feb 16 16:44:11 2022 +0100
@@ -405,5 +405,552 @@
      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
+
+
+
 ; vim: ft=asm
 
--- a/doc/disas_examples/ppc.sysv.disas	Thu Feb 10 17:32:05 2022 +0100
+++ b/doc/disas_examples/ppc.sysv.disas	Wed Feb 16 16:44:11 2022 +0100
@@ -610,5 +610,509 @@
  4e4:   7d 61 5b 78     mr      r1,r11          ; |
  4e8:   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 debian-4.1.1-21-ppc w/ gcc 4.1.2
+
+00000000 <leaf_call>:
+   0:   94 21 ff d0     stwu    r1,-48(r1)
+   4:   93 e1 00 2c     stw     r31,44(r1)
+   8:   7c 3f 0b 78     mr      r31,r1
+   c:   90 7f 00 08     stw     r3,8(r31)
+  10:   90 9f 00 0c     stw     r4,12(r31)
+  14:   90 bf 00 10     stw     r5,16(r31)
+  18:   90 df 00 14     stw     r6,20(r31)
+  1c:   91 1f 00 18     stw     r8,24(r31)
+  20:   91 3f 00 1c     stw     r9,28(r31)
+  24:   81 61 00 00     lwz     r11,0(r1)
+  28:   83 eb ff fc     lwz     r31,-4(r11)
+  2c:   7d 61 5b 78     mr      r1,r11
+  30:   4e 80 00 20     blr
+
+00000034 <nonleaf_call>:
+  34:   94 21 ff 40     stwu    r1,-192(r1)
+  38:   7c 08 02 a6     mflr    r0
+  3c:   93 a1 00 b4     stw     r29,180(r1)
+  40:   93 e1 00 bc     stw     r31,188(r1)
+  44:   90 01 00 c4     stw     r0,196(r1)
+  48:   7c 3f 0b 78     mr      r31,r1
+  4c:   90 7f 00 78     stw     r3,120(r31)
+  50:   90 9f 00 7c     stw     r4,124(r31)
+  54:   90 bf 00 80     stw     r5,128(r31)
+  58:   90 df 00 84     stw     r6,132(r31)
+  5c:   90 ff 00 88     stw     r7,136(r31)
+  60:   7d 1d 43 78     mr      r29,r8
+  64:   91 3f 00 8c     stw     r9,140(r31)
+  68:   91 5f 00 90     stw     r10,144(r31)
+  6c:   38 1f 00 08     addi    r0,r31,8
+  70:   39 20 00 64     li      r9,100
+  74:   7c 03 03 78     mr      r3,r0
+  78:   38 80 00 00     li      r4,0
+  7c:   7d 25 4b 78     mr      r5,r9
+  80:   48 00 00 01     bl      80 <nonleaf_call+0x4c>
+  84:   38 00 00 4c     li      r0,76
+  88:   98 1f 00 08     stb     r0,8(r31)
+  8c:   80 1d 00 00     lwz     r0,0(r29)
+  90:   81 3d 00 04     lwz     r9,4(r29)
+  94:   81 7d 00 08     lwz     r11,8(r29)
+  98:   81 5d 00 0c     lwz     r10,12(r29)
+  9c:   90 1f 00 a0     stw     r0,160(r31)
+  a0:   91 3f 00 a4     stw     r9,164(r31)
+  a4:   91 7f 00 a8     stw     r11,168(r31)
+  a8:   91 5f 00 ac     stw     r10,172(r31)
+  ac:   38 1f 00 a0     addi    r0,r31,160
+  b0:   80 7f 00 7c     lwz     r3,124(r31)
+  b4:   80 9f 00 80     lwz     r4,128(r31)
+  b8:   80 bf 00 84     lwz     r5,132(r31)
+  bc:   80 df 00 88     lwz     r6,136(r31)
+  c0:   7c 07 03 78     mr      r7,r0
+  c4:   81 1f 00 8c     lwz     r8,140(r31)
+  c8:   81 3f 00 90     lwz     r9,144(r31)
+  cc:   48 00 00 01     bl      cc <nonleaf_call+0x98>
+  d0:   81 61 00 00     lwz     r11,0(r1)
+  d4:   80 0b 00 04     lwz     r0,4(r11)
+  d8:   7c 08 03 a6     mtlr    r0
+  dc:   83 ab ff f4     lwz     r29,-12(r11)
+  e0:   83 eb ff fc     lwz     r31,-4(r11)
+  e4:   7d 61 5b 78     mr      r1,r11
+  e8:   4e 80 00 20     blr
+
+000000ec <main>:
+  ec:   94 21 ff c0     stwu    r1,-64(r1)      ;
+  f0:   7c 08 02 a6     mflr    r0              ;
+  f4:   93 e1 00 3c     stw     r31,60(r1)      ;
+  f8:   90 01 00 44     stw     r0,68(r1)       ;
+  fc:   7c 3f 0b 78     mr      r31,r1          ;
+ 100:   3d 20 00 00     lis     r9,0            ;
+ 104:   39 29 00 00     addi    r9,r9,0         ;
+ 108:   80 09 00 00     lwz     r0,0(r9)        ;
+ 10c:   81 69 00 04     lwz     r11,4(r9)       ;
+ 110:   81 49 00 08     lwz     r10,8(r9)       ;
+ 114:   81 29 00 0c     lwz     r9,12(r9)       ;
+ 118:   90 1f 00 08     stw     r0,8(r31)       ;
+ 11c:   91 7f 00 0c     stw     r11,12(r31)     ;
+ 120:   91 5f 00 10     stw     r10,16(r31)     ;
+ 124:   91 3f 00 14     stw     r9,20(r31)      ;
+ 128:   80 1f 00 08     lwz     r0,8(r31)       ;
+ 12c:   81 3f 00 0c     lwz     r9,12(r31)      ;
+ 130:   81 7f 00 10     lwz     r11,16(r31)     ;
+ 134:   81 5f 00 14     lwz     r10,20(r31)     ;
+ 138:   90 1f 00 20     stw     r0,32(r31)      ;
+ 13c:   91 3f 00 24     stw     r9,36(r31)      ;
+ 140:   91 7f 00 28     stw     r11,40(r31)     ;
+ 144:   91 5f 00 2c     stw     r10,44(r31)     ;
+ 148:   38 1f 00 20     addi    r0,r31,32       ;
+ 14c:   38 60 00 00     li      r3,0            ; arg 0
+ 150:   38 80 00 01     li      r4,1            ; arg 1
+ 154:   38 a0 00 02     li      r5,2            ; arg 2
+ 158:   38 c0 00 03     li      r6,3            ; arg 3
+ 15c:   38 e0 00 04     li      r7,4            ; arg 4
+ 160:   7c 08 03 78     mr      r8,r0           ; arg 5 (struct, passed as pointer to local copy)
+ 164:   39 20 00 08     li      r9,8            ; arg 6
+ 168:   39 40 00 09     li      r10,9           ; arg 7
+ 16c:   48 00 00 01     bl      16c <main+0x80> ;
+ 170:   38 00 00 00     li      r0,0            ;
+ 174:   7c 03 03 78     mr      r3,r0           ;
+ 178:   81 61 00 00     lwz     r11,0(r1)       ;
+ 17c:   80 0b 00 04     lwz     r0,4(r11)       ;
+ 180:   7c 08 03 a6     mtlr    r0              ;
+ 184:   83 eb ff fc     lwz     r31,-4(r11)     ;
+ 188:   7d 61 5b 78     mr      r1,r11          ;
+ 18c:   4e 80 00 20     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 debian-4.1.1-21-ppc w/ gcc 4.1.2
+
+00000000 <leaf_call>:
+   0:   94 21 ff e0     stwu    r1,-32(r1)
+   4:   93 e1 00 1c     stw     r31,28(r1)
+   8:   7c 3f 0b 78     mr      r31,r1
+   c:   90 7f 00 08     stw     r3,8(r31)
+  10:   90 df 00 0c     stw     r6,12(r31)
+  14:   90 ff 00 10     stw     r7,16(r31)
+  18:   91 5f 00 14     stw     r10,20(r31)
+  1c:   81 61 00 00     lwz     r11,0(r1)
+  20:   83 eb ff fc     lwz     r31,-4(r11)
+  24:   7d 61 5b 78     mr      r1,r11
+  28:   4e 80 00 20     blr
+
+0000002c <nonleaf_call>:
+  2c:   94 21 ff 00     stwu    r1,-256(r1)
+  30:   7c 08 02 a6     mflr    r0
+  34:   93 41 00 e8     stw     r26,232(r1)
+  38:   93 61 00 ec     stw     r27,236(r1)
+  3c:   93 81 00 f0     stw     r28,240(r1)
+  40:   93 a1 00 f4     stw     r29,244(r1)
+  44:   93 e1 00 fc     stw     r31,252(r1)
+  48:   90 01 01 04     stw     r0,260(r1)
+  4c:   7c 3f 0b 78     mr      r31,r1
+  50:   90 7f 00 80     stw     r3,128(r31)
+  54:   90 9f 00 84     stw     r4,132(r31)
+  58:   7c bd 2b 78     mr      r29,r5
+  5c:   7c dc 33 78     mr      r28,r6
+  60:   90 ff 00 88     stw     r7,136(r31)
+  64:   91 1f 00 8c     stw     r8,140(r31)
+  68:   7d 3b 4b 78     mr      r27,r9
+  6c:   7d 5a 53 78     mr      r26,r10
+  70:   38 1f 00 10     addi    r0,r31,16
+  74:   39 20 00 64     li      r9,100
+  78:   7c 03 03 78     mr      r3,r0
+  7c:   38 80 00 00     li      r4,0
+  80:   7d 25 4b 78     mr      r5,r9
+  84:   48 00 00 01     bl      84 <nonleaf_call+0x58>
+  88:   38 00 00 4c     li      r0,76
+  8c:   98 1f 00 10     stb     r0,16(r31)
+  90:   80 1d 00 00     lwz     r0,0(r29)
+  94:   81 3d 00 04     lwz     r9,4(r29)
+  98:   81 7d 00 08     lwz     r11,8(r29)
+  9c:   90 1f 00 98     stw     r0,152(r31)
+  a0:   91 3f 00 9c     stw     r9,156(r31)
+  a4:   91 7f 00 a0     stw     r11,160(r31)
+  a8:   80 1c 00 00     lwz     r0,0(r28)
+  ac:   81 3c 00 04     lwz     r9,4(r28)
+  b0:   81 7c 00 08     lwz     r11,8(r28)
+  b4:   81 5c 00 0c     lwz     r10,12(r28)
+  b8:   90 1f 00 a8     stw     r0,168(r31)
+  bc:   91 3f 00 ac     stw     r9,172(r31)
+  c0:   91 7f 00 b0     stw     r11,176(r31)
+  c4:   91 5f 00 b4     stw     r10,180(r31)
+  c8:   80 1b 00 00     lwz     r0,0(r27)
+  cc:   81 3b 00 04     lwz     r9,4(r27)
+  d0:   81 7b 00 08     lwz     r11,8(r27)
+  d4:   90 1f 00 b8     stw     r0,184(r31)
+  d8:   91 3f 00 bc     stw     r9,188(r31)
+  dc:   91 7f 00 c0     stw     r11,192(r31)
+  e0:   80 1a 00 00     lwz     r0,0(r26)
+  e4:   81 3a 00 04     lwz     r9,4(r26)
+  e8:   81 7a 00 08     lwz     r11,8(r26)
+  ec:   81 5a 00 0c     lwz     r10,12(r26)
+  f0:   90 1f 00 c8     stw     r0,200(r31)
+  f4:   91 3f 00 cc     stw     r9,204(r31)
+  f8:   91 7f 00 d0     stw     r11,208(r31)
+  fc:   91 5f 00 d4     stw     r10,212(r31)
+ 100:   39 3f 00 98     addi    r9,r31,152
+ 104:   39 7f 00 a8     addi    r11,r31,168
+ 108:   39 5f 00 b8     addi    r10,r31,184
+ 10c:   3b bf 00 c8     addi    r29,r31,200
+ 110:   80 1f 01 0c     lwz     r0,268(r31)
+ 114:   90 01 00 08     stw     r0,8(r1)
+ 118:   80 7f 00 84     lwz     r3,132(r31)
+ 11c:   7d 24 4b 78     mr      r4,r9
+ 120:   7d 65 5b 78     mr      r5,r11
+ 124:   80 df 00 88     lwz     r6,136(r31)
+ 128:   80 ff 00 8c     lwz     r7,140(r31)
+ 12c:   7d 48 53 78     mr      r8,r10
+ 130:   7f a9 eb 78     mr      r9,r29
+ 134:   81 5f 01 08     lwz     r10,264(r31)
+ 138:   48 00 00 01     bl      138 <nonleaf_call+0x10c>
+ 13c:   81 61 00 00     lwz     r11,0(r1)
+ 140:   80 0b 00 04     lwz     r0,4(r11)
+ 144:   7c 08 03 a6     mtlr    r0
+ 148:   83 4b ff e8     lwz     r26,-24(r11)
+ 14c:   83 6b ff ec     lwz     r27,-20(r11)
+ 150:   83 8b ff f0     lwz     r28,-16(r11)
+ 154:   83 ab ff f4     lwz     r29,-12(r11)
+ 158:   83 eb ff fc     lwz     r31,-4(r11)
+ 15c:   7d 61 5b 78     mr      r1,r11
+ 160:   4e 80 00 20     blr
+
+00000164 <main>:
+ 164:   94 21 ff 50     stwu    r1,-176(r1)
+ 168:   7c 08 02 a6     mflr    r0
+ 16c:   93 a1 00 a4     stw     r29,164(r1)
+ 170:   93 e1 00 ac     stw     r31,172(r1)
+ 174:   90 01 00 b4     stw     r0,180(r1)
+ 178:   7c 3f 0b 78     mr      r31,r1
+ 17c:   3d 20 00 00     lis     r9,0
+ 180:   39 29 00 30     addi    r9,r9,48
+ 184:   80 09 00 00     lwz     r0,0(r9)
+ 188:   81 69 00 04     lwz     r11,4(r9)
+ 18c:   81 29 00 08     lwz     r9,8(r9)
+ 190:   90 1f 00 40     stw     r0,64(r31)
+ 194:   91 7f 00 44     stw     r11,68(r31)
+ 198:   91 3f 00 48     stw     r9,72(r31)
+ 19c:   3d 20 00 00     lis     r9,0
+ 1a0:   39 29 00 20     addi    r9,r9,32
+ 1a4:   80 09 00 00     lwz     r0,0(r9)
+ 1a8:   81 69 00 04     lwz     r11,4(r9)
+ 1ac:   81 49 00 08     lwz     r10,8(r9)
+ 1b0:   81 29 00 0c     lwz     r9,12(r9)
+ 1b4:   90 1f 00 30     stw     r0,48(r31)
+ 1b8:   91 7f 00 34     stw     r11,52(r31)
+ 1bc:   91 5f 00 38     stw     r10,56(r31)
+ 1c0:   91 3f 00 3c     stw     r9,60(r31)
+ 1c4:   3d 20 00 00     lis     r9,0
+ 1c8:   39 29 00 10     addi    r9,r9,16
+ 1cc:   80 09 00 00     lwz     r0,0(r9)
+ 1d0:   81 69 00 04     lwz     r11,4(r9)
+ 1d4:   81 29 00 08     lwz     r9,8(r9)
+ 1d8:   90 1f 00 20     stw     r0,32(r31)
+ 1dc:   91 7f 00 24     stw     r11,36(r31)
+ 1e0:   91 3f 00 28     stw     r9,40(r31)
+ 1e4:   3d 20 00 00     lis     r9,0
+ 1e8:   39 29 00 00     addi    r9,r9,0
+ 1ec:   80 09 00 00     lwz     r0,0(r9)
+ 1f0:   81 69 00 04     lwz     r11,4(r9)
+ 1f4:   81 49 00 08     lwz     r10,8(r9)
+ 1f8:   81 29 00 0c     lwz     r9,12(r9)
+ 1fc:   90 1f 00 10     stw     r0,16(r31)
+ 200:   91 7f 00 14     stw     r11,20(r31)
+ 204:   91 5f 00 18     stw     r10,24(r31)
+ 208:   91 3f 00 1c     stw     r9,28(r31)
+ 20c:   80 1f 00 40     lwz     r0,64(r31)
+ 210:   81 3f 00 44     lwz     r9,68(r31)
+ 214:   81 7f 00 48     lwz     r11,72(r31)
+ 218:   90 1f 00 58     stw     r0,88(r31)
+ 21c:   91 3f 00 5c     stw     r9,92(r31)
+ 220:   91 7f 00 60     stw     r11,96(r31)
+ 224:   80 1f 00 30     lwz     r0,48(r31)
+ 228:   81 3f 00 34     lwz     r9,52(r31)
+ 22c:   81 7f 00 38     lwz     r11,56(r31)
+ 230:   81 5f 00 3c     lwz     r10,60(r31)
+ 234:   90 1f 00 68     stw     r0,104(r31)
+ 238:   91 3f 00 6c     stw     r9,108(r31)
+ 23c:   91 7f 00 70     stw     r11,112(r31)
+ 240:   91 5f 00 74     stw     r10,116(r31)
+ 244:   80 1f 00 20     lwz     r0,32(r31)
+ 248:   81 3f 00 24     lwz     r9,36(r31)
+ 24c:   81 7f 00 28     lwz     r11,40(r31)
+ 250:   90 1f 00 78     stw     r0,120(r31)
+ 254:   91 3f 00 7c     stw     r9,124(r31)
+ 258:   91 7f 00 80     stw     r11,128(r31)
+ 25c:   80 1f 00 10     lwz     r0,16(r31)
+ 260:   81 3f 00 14     lwz     r9,20(r31)
+ 264:   81 7f 00 18     lwz     r11,24(r31)
+ 268:   81 5f 00 1c     lwz     r10,28(r31)
+ 26c:   90 1f 00 88     stw     r0,136(r31)
+ 270:   91 3f 00 8c     stw     r9,140(r31)
+ 274:   91 7f 00 90     stw     r11,144(r31)
+ 278:   91 5f 00 94     stw     r10,148(r31)
+ 27c:   39 3f 00 58     addi    r9,r31,88
+ 280:   39 7f 00 68     addi    r11,r31,104
+ 284:   39 5f 00 78     addi    r10,r31,120
+ 288:   3b bf 00 88     addi    r29,r31,136
+ 28c:   38 00 00 0e     li      r0,14
+ 290:   90 01 00 08     stw     r0,8(r1)
+ 294:   38 00 00 0f     li      r0,15
+ 298:   90 01 00 0c     stw     r0,12(r1)
+ 29c:   38 60 00 00     li      r3,0
+ 2a0:   38 80 00 01     li      r4,1
+ 2a4:   7d 25 4b 78     mr      r5,r9
+ 2a8:   7d 66 5b 78     mr      r6,r11
+ 2ac:   38 e0 00 07     li      r7,7
+ 2b0:   39 00 00 08     li      r8,8
+ 2b4:   7d 49 53 78     mr      r9,r10
+ 2b8:   7f aa eb 78     mr      r10,r29
+ 2bc:   48 00 00 01     bl      2bc <main+0x158>
+ 2c0:   38 00 00 00     li      r0,0
+ 2c4:   7c 03 03 78     mr      r3,r0
+ 2c8:   81 61 00 00     lwz     r11,0(r1)
+ 2cc:   80 0b 00 04     lwz     r0,4(r11)
+ 2d0:   7c 08 03 a6     mtlr    r0
+ 2d4:   83 ab ff f4     lwz     r29,-12(r11)
+ 2d8:   83 eb ff fc     lwz     r31,-4(r11)
+ 2dc:   7d 61 5b 78     mr      r1,r11
+ 2e0:   4e 80 00 20     blr
+
+
+
+; ---------- returning qwords ---------->
+;
+; long long f()
+; {
+;     return 7171LL;
+; }
+;
+; int main()
+; {
+;     return (int)f();
+; }
+
+
+
+; output from debian-4.1.1-21-ppc w/ gcc 4.1.2
+
+00000000 <f>:
+   0:   94 21 ff f0     stwu    r1,-16(r1)
+   4:   93 e1 00 0c     stw     r31,12(r1)
+   8:   7c 3f 0b 78     mr      r31,r1
+   c:   39 20 00 00     li      r9,0
+  10:   39 40 1c 03     li      r10,7171
+  14:   7d 23 4b 78     mr      r3,r9
+  18:   7d 44 53 78     mr      r4,r10
+  1c:   81 61 00 00     lwz     r11,0(r1)
+  20:   83 eb ff fc     lwz     r31,-4(r11)
+  24:   7d 61 5b 78     mr      r1,r11
+  28:   4e 80 00 20     blr
+
+0000002c <main>:
+  2c:   94 21 ff f0     stwu    r1,-16(r1)
+  30:   7c 08 02 a6     mflr    r0
+  34:   93 e1 00 0c     stw     r31,12(r1)
+  38:   90 01 00 14     stw     r0,20(r1)
+  3c:   7c 3f 0b 78     mr      r31,r1
+  40:   48 00 00 01     bl      40 <main+0x14>
+  44:   7c 8a 23 78     mr      r10,r4
+  48:   7c 69 1b 78     mr      r9,r3
+  4c:   7d 40 53 78     mr      r0,r10
+  50:   7c 03 03 78     mr      r3,r0
+  54:   81 61 00 00     lwz     r11,0(r1)
+  58:   80 0b 00 04     lwz     r0,4(r11)
+  5c:   7c 08 03 a6     mtlr    r0
+  60:   83 eb ff fc     lwz     r31,-4(r11)
+  64:   7d 61 5b 78     mr      r1,r11
+  68:   4e 80 00 20     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 debian-4.1.1-21-ppc w/ gcc 4.1.2
+
+00000000 <f0>:
+   0:   94 21 ff e0     stwu    r1,-32(r1)
+   4:   93 e1 00 1c     stw     r31,28(r1)
+   8:   7c 3f 0b 78     mr      r31,r1
+   c:   7c 69 1b 78     mr      r9,r3
+  10:   38 00 ff 84     li      r0,-124
+  14:   98 1f 00 08     stb     r0,8(r31)
+  18:   88 1f 00 08     lbz     r0,8(r31)
+  1c:   98 09 00 00     stb     r0,0(r9)
+  20:   7d 23 4b 78     mr      r3,r9
+  24:   81 61 00 00     lwz     r11,0(r1)
+  28:   83 eb ff fc     lwz     r31,-4(r11)
+  2c:   7d 61 5b 78     mr      r1,r11
+  30:   4e 80 00 20     blr
+
+00000034 <f1>:
+  34:   94 21 ff e0     stwu    r1,-32(r1)
+  38:   93 e1 00 1c     stw     r31,28(r1)
+  3c:   7c 3f 0b 78     mr      r31,r1
+  40:   7c 6b 1b 78     mr      r11,r3
+  44:   3d 20 00 00     lis     r9,0
+  48:   39 29 00 00     addi    r9,r9,0
+  4c:   80 09 00 00     lwz     r0,0(r9)
+  50:   81 49 00 04     lwz     r10,4(r9)
+  54:   81 09 00 08     lwz     r8,8(r9)
+  58:   81 29 00 0c     lwz     r9,12(r9)
+  5c:   90 1f 00 08     stw     r0,8(r31)
+  60:   91 5f 00 0c     stw     r10,12(r31)
+  64:   91 1f 00 10     stw     r8,16(r31)
+  68:   91 3f 00 14     stw     r9,20(r31)
+  6c:   80 1f 00 08     lwz     r0,8(r31)
+  70:   81 3f 00 0c     lwz     r9,12(r31)
+  74:   81 5f 00 10     lwz     r10,16(r31)
+  78:   81 1f 00 14     lwz     r8,20(r31)
+  7c:   90 0b 00 00     stw     r0,0(r11)
+  80:   91 2b 00 04     stw     r9,4(r11)
+  84:   91 4b 00 08     stw     r10,8(r11)
+  88:   91 0b 00 0c     stw     r8,12(r11)
+  8c:   7d 63 5b 78     mr      r3,r11
+  90:   81 61 00 00     lwz     r11,0(r1)
+  94:   83 eb ff fc     lwz     r31,-4(r11)
+  98:   7d 61 5b 78     mr      r1,r11
+  9c:   4e 80 00 20     blr
+
+000000a0 <main>:
+  a0:   94 21 ff c0     stwu    r1,-64(r1)
+  a4:   7c 08 02 a6     mflr    r0
+  a8:   93 e1 00 3c     stw     r31,60(r1)
+  ac:   90 01 00 44     stw     r0,68(r1)
+  b0:   7c 3f 0b 78     mr      r31,r1
+  b4:   38 1f 00 28     addi    r0,r31,40
+  b8:   7c 03 03 78     mr      r3,r0
+  bc:   4c c6 31 82     crclr   4*cr1+eq
+  c0:   48 00 00 01     bl      c0 <main+0x20>
+  c4:   88 1f 00 28     lbz     r0,40(r31)
+  c8:   98 1f 00 08     stb     r0,8(r31)
+  cc:   38 1f 00 10     addi    r0,r31,16
+  d0:   7c 03 03 78     mr      r3,r0
+  d4:   4c c6 31 82     crclr   4*cr1+eq
+  d8:   48 00 00 01     bl      d8 <main+0x38>
+  dc:   81 3f 00 18     lwz     r9,24(r31)
+  e0:   88 1f 00 08     lbz     r0,8(r31)
+  e4:   54 00 06 3e     clrlwi  r0,r0,24
+  e8:   7c 09 02 14     add     r0,r9,r0
+  ec:   7c 03 03 78     mr      r3,r0
+  f0:   81 61 00 00     lwz     r11,0(r1)
+  f4:   80 0b 00 04     lwz     r0,4(r11)
+  f8:   7c 08 03 a6     mtlr    r0
+  fc:   83 eb ff fc     lwz     r31,-4(r11)
+ 100:   7d 61 5b 78     mr      r1,r11
+ 104:   4e 80 00 20     blr
+
+
+
 ; vim: ft=asm68k
 
--- a/doc/disas_examples/ppc64.elfabi.disas	Thu Feb 10 17:32:05 2022 +0100
+++ b/doc/disas_examples/ppc64.elfabi.disas	Wed Feb 16 16:44:11 2022 +0100
@@ -269,5 +269,470 @@
  180:	00 00 00 01 	.long 0x1                ; data
  184:	80 01 00 01 	lwz     r0,1(r1)         ; unsure@@@. data?
 
+
+
+; ---------- 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-11.0-ppc64 w/ gcc 4.2.1
+
+0000000000000000 <.leaf_call>:
+   0:	fb e1 ff f8 	std     r31,-8(r1)
+   4:	f8 21 ff c1 	stdu    r1,-64(r1)
+   8:	7c 3f 0b 78 	mr      r31,r1
+   c:	7c 60 1b 78 	mr      r0,r3
+  10:	39 7f 00 90 	addi    r11,r31,144
+  14:	f8 eb 00 00 	std     r7,0(r11)
+  18:	f9 0b 00 08 	std     r8,8(r11)
+  1c:	7d 4b 53 78 	mr      r11,r10
+  20:	90 1f 00 70 	stw     r0,112(r31)
+  24:	90 9f 00 78 	stw     r4,120(r31)
+  28:	90 bf 00 80 	stw     r5,128(r31)
+  2c:	90 df 00 88 	stw     r6,136(r31)
+  30:	91 3f 00 a0 	stw     r9,160(r31)
+  34:	91 7f 00 a8 	stw     r11,168(r31)
+  38:	e8 21 00 00 	ld      r1,0(r1)
+  3c:	eb e1 ff f8 	ld      r31,-8(r1)
+  40:	4e 80 00 20 	blr
+	...
+  4c:	80 01 00 01 	lwz     r0,1(r1)
+
+0000000000000050 <.nonleaf_call>:
+  50:	7c 08 02 a6 	mflr    r0
+  54:	fb a1 ff e8 	std     r29,-24(r1)
+  58:	fb e1 ff f8 	std     r31,-8(r1)
+  5c:	f8 01 00 10 	std     r0,16(r1)
+  60:	f8 21 ff 01 	stdu    r1,-256(r1)
+  64:	7c 3f 0b 78 	mr      r31,r1
+  68:	7c 60 1b 78 	mr      r0,r3
+  6c:	39 7f 01 58 	addi    r11,r31,344
+  70:	f9 0b 00 00 	std     r8,0(r11)
+  74:	f9 2b 00 08 	std     r9,8(r11)
+  78:	7d 49 53 78 	mr      r9,r10
+  7c:	90 1f 01 30 	stw     r0,304(r31)
+  80:	90 9f 01 38 	stw     r4,312(r31)
+  84:	90 bf 01 40 	stw     r5,320(r31)
+  88:	90 df 01 48 	stw     r6,328(r31)
+  8c:	90 ff 01 50 	stw     r7,336(r31)
+  90:	91 3f 01 68 	stw     r9,360(r31)
+  94:	38 1f 00 70 	addi    r0,r31,112
+  98:	39 20 00 64 	li      r9,100
+  9c:	7c 03 03 78 	mr      r3,r0
+  a0:	38 80 00 00 	li      r4,0
+  a4:	7d 25 4b 78 	mr      r5,r9
+  a8:	48 00 00 01 	bl      a8 <.nonleaf_call+0x58>
+  ac:	4f ff fb 82 	crmove  4*cr7+so,4*cr7+so
+  b0:	38 00 00 4c 	li      r0,76
+  b4:	98 1f 00 70 	stb     r0,112(r31)
+  b8:	80 1f 01 38 	lwz     r0,312(r31)
+  bc:	7c 08 07 b4 	extsw   r8,r0
+  c0:	80 1f 01 40 	lwz     r0,320(r31)
+  c4:	7c 09 07 b4 	extsw   r9,r0
+  c8:	80 1f 01 48 	lwz     r0,328(r31)
+  cc:	7c 0b 07 b4 	extsw   r11,r0
+  d0:	80 1f 01 50 	lwz     r0,336(r31)
+  d4:	7c 0a 07 b4 	extsw   r10,r0
+  d8:	80 1f 01 68 	lwz     r0,360(r31)
+  dc:	7c 1d 07 b4 	extsw   r29,r0
+  e0:	80 1f 01 74 	lwz     r0,372(r31)
+  e4:	7c 00 07 b4 	extsw   r0,r0
+  e8:	7d 03 43 78 	mr      r3,r8
+  ec:	7d 24 4b 78 	mr      r4,r9
+  f0:	7d 65 5b 78 	mr      r5,r11
+  f4:	7d 46 53 78 	mr      r6,r10
+  f8:	39 3f 01 58 	addi    r9,r31,344
+  fc:	e8 e9 00 00 	ld      r7,0(r9)
+ 100:	e9 09 00 08 	ld      r8,8(r9)
+ 104:	7f a9 eb 78 	mr      r9,r29
+ 108:	7c 0a 03 78 	mr      r10,r0
+ 10c:	48 00 00 01 	bl      10c <.nonleaf_call+0xbc>
+ 110:	e8 21 00 00 	ld      r1,0(r1)
+ 114:	e8 01 00 10 	ld      r0,16(r1)
+ 118:	7c 08 03 a6 	mtlr    r0
+ 11c:	eb a1 ff e8 	ld      r29,-24(r1)
+ 120:	eb e1 ff f8 	ld      r31,-8(r1)
+ 124:	4e 80 00 20 	blr
+ 128:	00 00 00 00 	.long 0x0
+ 12c:	00 00 00 01 	.long 0x1
+ 130:	80 03 00 01 	lwz     r0,1(r3)
+
+0000000000000134 <.main>:
+ 134:	7c 08 02 a6 	mflr    r0               ; |             lr -> gpr0
+ 138:	fb e1 ff f8 	std     r31,-8(r1)       ; |             preseve gpr31 (as used in func as helper addr)
+ 13c:	f8 01 00 10 	std     r0,16(r1)        ; | prolog      store lr
+ 140:	f8 21 ff 61 	stdu    r1,-160(r1)      ; |             open frame
+ 144:	7c 3f 0b 78 	mr      r31,r1           ; use gpr31 as sort of frame pointer, below
+ 148:	e9 22 00 00 	ld      r9,0(r2)         ; |
+ 14c:	e9 49 00 08 	ld      r10,8(r9)        ; | fetch local struct data's 2 doublewords (r2 = TOC ptr) -> r9/r10, and ...
+ 150:	e9 29 00 00 	ld      r9,0(r9)         ; |
+ 154:	f9 3f 00 80 	std     r9,128(r31)      ; | ... write to local area on stack
+ 158:	f9 5f 00 88 	std     r10,136(r31)     ; /
+ 15c:	38 00 00 09 	li      r0,9             ; \ arg 7, ...
+ 160:	f8 01 00 70 	std     r0,112(r1)       ; | ... "pushed" onto stack
+ 164:	38 60 00 00 	li      r3,0             ; arg 0
+ 168:	38 80 00 01 	li      r4,1             ; arg 1
+ 16c:	38 a0 00 02 	li      r5,2             ; arg 2
+ 170:	38 c0 00 03 	li      r6,3             ; arg 3
+ 174:	38 e0 00 04 	li      r7,4             ; arg 4
+ 178:	e9 1f 00 80 	ld      r8,128(r31)      ; |
+ 17c:	e9 3f 00 88 	ld      r9,136(r31)      ; | arg 5 (struct, fetch from local area, pass as 2 doublewords)
+ 180:	39 40 00 08 	li      r10,8            ; arg 6
+ 184:	48 00 00 01 	bl      184 <.main+0x50> ; call and put return address -> lr
+ 188:	38 00 00 00 	li      r0,0             ; return value ...
+ 18c:	7c 03 03 78 	mr      r3,r0            ; ... in gpr3
+ 190:	e8 21 00 00 	ld      r1,0(r1)         ; |
+ 194:	e8 01 00 10 	ld      r0,16(r1)        ; |
+ 198:	7c 08 03 a6 	mtlr    r0               ; | epilog
+ 19c:	eb e1 ff f8 	ld      r31,-8(r1)       ; |
+ 1a0:	4e 80 00 20 	blr                      ; |
+ 1a4:	00 00 00 00 	.long 0x0                ; data
+ 1a8:	00 00 00 01 	.long 0x1                ; data
+ 1ac:	80 01 00 01 	lwz     r0,1(r1)         ; unsure@@@. data?
+
+
+
+; ---------- 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-11.0-ppc64 w/ gcc 4.2.1
+
+0000000000000000 <.leaf_call>:
+   0:	fb e1 ff f8 	std     r31,-8(r1)
+   4:	f8 21 ff c1 	stdu    r1,-64(r1)
+   8:	7c 3f 0b 78 	mr      r31,r1
+   c:	f8 9f 00 78 	std     r4,120(r31)
+  10:	f8 bf 00 80 	std     r5,128(r31)
+  14:	39 7f 00 88 	addi    r11,r31,136
+  18:	f8 cb 00 00 	std     r6,0(r11)
+  1c:	f8 eb 00 08 	std     r7,8(r11)
+  20:	7d 00 43 78 	mr      r0,r8
+  24:	f9 5f 00 a8 	std     r10,168(r31)
+  28:	90 7f 00 70 	stw     r3,112(r31)
+  2c:	90 1f 00 98 	stw     r0,152(r31)
+  30:	91 3f 00 a0 	stw     r9,160(r31)
+  34:	e8 21 00 00 	ld      r1,0(r1)
+  38:	eb e1 ff f8 	ld      r31,-8(r1)
+  3c:	4e 80 00 20 	blr
+	...
+  48:	80 01 00 01 	lwz     r0,1(r1)
+
+000000000000004c <.nonleaf_call>:
+  4c:	7c 08 02 a6 	mflr    r0
+  50:	fb 81 ff e0 	std     r28,-32(r1)
+  54:	fb a1 ff e8 	std     r29,-24(r1)
+  58:	fb e1 ff f8 	std     r31,-8(r1)
+  5c:	f8 01 00 10 	std     r0,16(r1)
+  60:	f8 21 fe d1 	stdu    r1,-304(r1)
+  64:	7c 3f 0b 78 	mr      r31,r1
+  68:	f8 bf 01 70 	std     r5,368(r31)
+  6c:	f8 df 01 78 	std     r6,376(r31)
+  70:	39 7f 01 80 	addi    r11,r31,384
+  74:	f8 eb 00 00 	std     r7,0(r11)
+  78:	f9 0b 00 08 	std     r8,8(r11)
+  7c:	7d 20 4b 78 	mr      r0,r9
+  80:	7d 49 53 78 	mr      r9,r10
+  84:	90 7f 01 60 	stw     r3,352(r31)
+  88:	90 9f 01 68 	stw     r4,360(r31)
+  8c:	90 1f 01 90 	stw     r0,400(r31)
+  90:	91 3f 01 98 	stw     r9,408(r31)
+  94:	38 1f 00 a0 	addi    r0,r31,160
+  98:	39 20 00 64 	li      r9,100
+  9c:	7c 03 03 78 	mr      r3,r0
+  a0:	38 80 00 00 	li      r4,0
+  a4:	7d 25 4b 78 	mr      r5,r9
+  a8:	48 00 00 01 	bl      a8 <.nonleaf_call+0x5c>
+  ac:	4f ff fb 82 	crmove  4*cr7+so,4*cr7+so
+  b0:	38 00 00 4c 	li      r0,76
+  b4:	98 1f 00 a0 	stb     r0,160(r31)
+  b8:	80 1f 01 68 	lwz     r0,360(r31)
+  bc:	7c 08 07 b4 	extsw   r8,r0
+  c0:	80 1f 01 90 	lwz     r0,400(r31)
+  c4:	7c 1d 07 b4 	extsw   r29,r0
+  c8:	80 1f 01 98 	lwz     r0,408(r31)
+  cc:	7c 1c 07 b4 	extsw   r28,r0
+  d0:	39 3f 01 b0 	addi    r9,r31,432
+  d4:	e9 49 00 08 	ld      r10,8(r9)
+  d8:	e9 29 00 00 	ld      r9,0(r9)
+  dc:	39 61 00 78 	addi    r11,r1,120
+  e0:	f9 2b 00 00 	std     r9,0(r11)
+  e4:	f9 4b 00 08 	std     r10,8(r11)
+  e8:	80 1f 01 c4 	lwz     r0,452(r31)
+  ec:	7c 00 07 b4 	extsw   r0,r0
+  f0:	f8 01 00 88 	std     r0,136(r1)
+  f4:	80 1f 01 cc 	lwz     r0,460(r31)
+  f8:	7c 00 07 b4 	extsw   r0,r0
+  fc:	f8 01 00 90 	std     r0,144(r1)
+ 100:	80 1f 01 a8 	lwz     r0,424(r31)
+ 104:	90 01 00 70 	stw     r0,112(r1)
+ 108:	e9 5f 01 a0 	ld      r10,416(r31)
+ 10c:	7d 03 43 78 	mr      r3,r8
+ 110:	e8 9f 01 70 	ld      r4,368(r31)
+ 114:	e8 bf 01 78 	ld      r5,376(r31)
+ 118:	39 3f 01 80 	addi    r9,r31,384
+ 11c:	e8 c9 00 00 	ld      r6,0(r9)
+ 120:	e8 e9 00 08 	ld      r7,8(r9)
+ 124:	7f a8 eb 78 	mr      r8,r29
+ 128:	7f 89 e3 78 	mr      r9,r28
+ 12c:	48 00 00 01 	bl      12c <.nonleaf_call+0xe0>
+ 130:	e8 21 00 00 	ld      r1,0(r1)
+ 134:	e8 01 00 10 	ld      r0,16(r1)
+ 138:	7c 08 03 a6 	mtlr    r0
+ 13c:	eb 81 ff e0 	ld      r28,-32(r1)
+ 140:	eb a1 ff e8 	ld      r29,-24(r1)
+ 144:	eb e1 ff f8 	ld      r31,-8(r1)
+ 148:	4e 80 00 20 	blr
+ 14c:	00 00 00 00 	.long 0x0
+ 150:	00 00 00 01 	.long 0x1
+ 154:	80 04 00 01 	lwz     r0,1(r4)
+
+0000000000000158 <.main>:
+ 158:	7c 08 02 a6 	mflr    r0               ; |             lr -> gpr0
+ 15c:	fb e1 ff f8 	std     r31,-8(r1)       ; |             preseve gpr31 (as used in func as helper addr)
+ 160:	f8 01 00 10 	std     r0,16(r1)        ; | prolog      store lr
+ 164:	f8 21 ff 11 	stdu    r1,-240(r1)      ; |             open frame
+ 168:	7c 3f 0b 78 	mr      r31,r1           ; use gpr31 as sort of frame pointer, below
+ 16c:	e9 22 00 00 	ld      r9,0(r2)         ; |
+ 170:	e8 09 00 00 	ld      r0,0(r9)         ; | fetch local first struct A data's 2 doublewords (r2 = TOC ptr) -> r9/r10, and ...
+ 174:	81 29 00 08 	lwz     r9,8(r9)         ; |
+ 178:	f8 1f 00 d0 	std     r0,208(r31)      ; | ... write to local area on stack
+ 17c:	91 3f 00 d8 	stw     r9,216(r31)      ; /
+ 180:	e9 22 00 08 	ld      r9,8(r2)         ; \
+ 184:	e9 49 00 08 	ld      r10,8(r9)        ; | fetch local first struct B data's 2 doublewords (r2 = TOC ptr) -> r9/r10, and ...
+ 188:	e9 29 00 00 	ld      r9,0(r9)         ; |
+ 18c:	39 7f 00 c0 	addi    r11,r31,192      ; | ... write to local area on stack
+ 190:	f9 2b 00 00 	std     r9,0(r11)        ; |
+ 194:	f9 4b 00 08 	std     r10,8(r11)       ; /
+ 198:	e9 22 00 10 	ld      r9,16(r2)        ; \
+ 19c:	e8 09 00 00 	ld      r0,0(r9)         ; | fetch local second struct A data's 2 doublewords (r2 = TOC ptr) -> r9/r10, and ...
+ 1a0:	81 29 00 08 	lwz     r9,8(r9)         ; |
+ 1a4:	f8 1f 00 b0 	std     r0,176(r31)      ; | ... write to local area on stack
+ 1a8:	91 3f 00 b8 	stw     r9,184(r31)      ; /
+ 1ac:	e9 22 00 18 	ld      r9,24(r2)        ; \
+ 1b0:	e9 49 00 08 	ld      r10,8(r9)        ; | fetch local second struct B data's 2 doublewords (r2 = TOC ptr) -> r9/r10, and ...
+ 1b4:	e9 29 00 00 	ld      r9,0(r9)         ; |
+ 1b8:	f9 3f 00 a0 	std     r9,160(r31)      ; | ... write to local area on stack
+ 1bc:	f9 5f 00 a8 	std     r10,168(r31)     ; /
+ 1c0:	e8 1f 00 b0 	ld      r0,176(r31)      ; \
+ 1c4:	81 3f 00 b8 	lwz     r9,184(r31)      ; | arg 6 (second struct A, fetch from local area, pushed onto stack, pass as 2 doublewords)
+ 1c8:	f8 01 00 70 	std     r0,112(r1)       ; |
+ 1cc:	91 21 00 78 	stw     r9,120(r1)       ; /
+ 1d0:	e9 3f 00 a0 	ld      r9,160(r31)      ; \
+ 1d4:	e9 5f 00 a8 	ld      r10,168(r31)     ; |
+ 1d8:	39 61 00 80 	addi    r11,r1,128       ; | arg 7 (second struct A, fetch from local area, pushed onto stack, pass as 2 doublewords)
+ 1dc:	f9 2b 00 00 	std     r9,0(r11)        ; |
+ 1e0:	f9 4b 00 08 	std     r10,8(r11)       ; /
+ 1e4:	38 00 00 0e 	li      r0,14            ; arg 8, ...
+ 1e8:	f8 01 00 90 	std     r0,144(r1)       ; ... "pushed" onto stack
+ 1ec:	38 00 00 0f 	li      r0,15            ; arg 9, ...
+ 1f0:	f8 01 00 98 	std     r0,152(r1)       ; ... "pushed" onto stack
+ 1f4:	38 60 00 00 	li      r3,0             ; arg 0
+ 1f8:	38 80 00 01 	li      r4,1             ; arg 1
+ 1fc:	e8 bf 00 d0 	ld      r5,208(r31)      ; | arg 2 (first struct A, fetch from local area, pass as 2 doublewords)
+ 200:	e8 df 00 d8 	ld      r6,216(r31)      ; /
+ 204:	39 3f 00 c0 	addi    r9,r31,192       ; \
+ 208:	e8 e9 00 00 	ld      r7,0(r9)         ; | arg 3 (first struct B, fetch from local area, pass as 2 doublewords)
+ 20c:	e9 09 00 08 	ld      r8,8(r9)         ; |
+ 210:	39 20 00 07 	li      r9,7             ; arg 4
+ 214:	39 40 00 08 	li      r10,8            ; arg 5
+ 218:	48 00 00 01 	bl      218 <.main+0xc0> ; call and put return address -> lr
+ 21c:	38 00 00 00 	li      r0,0             ; return value ...
+ 220:	7c 03 03 78 	mr      r3,r0            ; ... in gpr3
+ 224:	e8 21 00 00 	ld      r1,0(r1)         ; |
+ 228:	e8 01 00 10 	ld      r0,16(r1)        ; |
+ 22c:	7c 08 03 a6 	mtlr    r0               ; | epilog
+ 230:	eb e1 ff f8 	ld      r31,-8(r1)       ; |
+ 234:	4e 80 00 20 	blr                      ; |
+ 238:	00 00 00 00 	.long 0x0                ; data
+ 23c:	00 00 00 01 	.long 0x1                ; data
+ 240:	80 01 00 01 	lwz     r0,1(r1)         ; unsure@@@. data?
+
+
+
+; ---------- returning qwords ---------->
+;
+; long long f()
+; {
+;     return 7171LL;
+; }
+;
+; int main()
+; {
+;     return (int)f();
+; }
+
+
+
+; output from freebsd-11.0-ppc64 w/ gcc 4.2.1
+
+0000000000000000 <.f>:
+   0:	fb e1 ff f8 	std     r31,-8(r1)
+   4:	f8 21 ff c1 	stdu    r1,-64(r1)
+   8:	7c 3f 0b 78 	mr      r31,r1
+   c:	38 00 1c 03 	li      r0,7171
+  10:	7c 03 03 78 	mr      r3,r0
+  14:	e8 21 00 00 	ld      r1,0(r1)
+  18:	eb e1 ff f8 	ld      r31,-8(r1)
+  1c:	4e 80 00 20 	blr
+	...
+  28:	80 01 00 01 	lwz     r0,1(r1)
+
+000000000000002c <.main>:
+  2c:	7c 08 02 a6 	mflr    r0
+  30:	fb e1 ff f8 	std     r31,-8(r1)
+  34:	f8 01 00 10 	std     r0,16(r1)
+  38:	f8 21 ff 81 	stdu    r1,-128(r1)
+  3c:	7c 3f 0b 78 	mr      r31,r1
+  40:	48 00 00 01 	bl      40 <.main+0x14>
+  44:	7c 60 1b 78 	mr      r0,r3
+  48:	7c 00 07 b4 	extsw   r0,r0
+  4c:	7c 03 03 78 	mr      r3,r0
+  50:	e8 21 00 00 	ld      r1,0(r1)
+  54:	e8 01 00 10 	ld      r0,16(r1)
+  58:	7c 08 03 a6 	mtlr    r0
+  5c:	eb e1 ff f8 	ld      r31,-8(r1)
+  60:	4e 80 00 20 	blr
+  64:	00 00 00 00 	.long 0x0
+  68:	00 00 00 01 	.long 0x1
+  6c:	80 01 00 01 	lwz     r0,1(r1)
+
+
+
+; ---------- 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 freebsd-11.0-ppc64 w/ gcc 4.2.1
+
+0000000000000000 <.f0>:
+   0:	fb e1 ff f8 	std     r31,-8(r1)
+   4:	f8 21 ff b1 	stdu    r1,-80(r1)
+   8:	7c 3f 0b 78 	mr      r31,r1
+   c:	7c 69 1b 78 	mr      r9,r3
+  10:	38 00 ff 84 	li      r0,-124
+  14:	98 1f 00 30 	stb     r0,48(r31)
+  18:	88 1f 00 30 	lbz     r0,48(r31)
+  1c:	98 09 00 00 	stb     r0,0(r9)
+  20:	7d 23 4b 78 	mr      r3,r9
+  24:	e8 21 00 00 	ld      r1,0(r1)
+  28:	eb e1 ff f8 	ld      r31,-8(r1)
+  2c:	4e 80 00 20 	blr
+	...
+  38:	80 01 00 01 	lwz     r0,1(r1)
+
+000000000000003c <.f1>:
+  3c:	fb e1 ff f8 	std     r31,-8(r1)
+  40:	f8 21 ff b1 	stdu    r1,-80(r1)
+  44:	7c 3f 0b 78 	mr      r31,r1
+  48:	7c 6b 1b 78 	mr      r11,r3
+  4c:	e9 22 00 00 	ld      r9,0(r2)
+  50:	e9 49 00 08 	ld      r10,8(r9)
+  54:	e9 29 00 00 	ld      r9,0(r9)
+  58:	f9 3f 00 30 	std     r9,48(r31)
+  5c:	f9 5f 00 38 	std     r10,56(r31)
+  60:	e9 3f 00 30 	ld      r9,48(r31)
+  64:	e9 5f 00 38 	ld      r10,56(r31)
+  68:	f9 2b 00 00 	std     r9,0(r11)
+  6c:	f9 4b 00 08 	std     r10,8(r11)
+  70:	7d 63 5b 78 	mr      r3,r11
+  74:	e8 21 00 00 	ld      r1,0(r1)
+  78:	eb e1 ff f8 	ld      r31,-8(r1)
+  7c:	4e 80 00 20 	blr
+	...
+  88:	80 01 00 01 	lwz     r0,1(r1)
+
+000000000000008c <.main>:
+  8c:	7c 08 02 a6 	mflr    r0
+  90:	fb e1 ff f8 	std     r31,-8(r1)
+  94:	f8 01 00 10 	std     r0,16(r1)
+  98:	f8 21 ff 61 	stdu    r1,-160(r1)
+  9c:	7c 3f 0b 78 	mr      r31,r1
+  a0:	38 1f 00 70 	addi    r0,r31,112
+  a4:	7c 03 03 78 	mr      r3,r0
+  a8:	48 00 00 01 	bl      a8 <.main+0x1c>
+  ac:	38 1f 00 78 	addi    r0,r31,120
+  b0:	7c 03 03 78 	mr      r3,r0
+  b4:	48 00 00 01 	bl      b4 <.main+0x28>
+  b8:	e8 1f 00 80 	ld      r0,128(r31)
+  bc:	78 09 00 20 	clrldi  r9,r0,32
+  c0:	88 1f 00 70 	lbz     r0,112(r31)
+  c4:	78 00 06 20 	clrldi  r0,r0,56
+  c8:	7c 09 02 14 	add     r0,r9,r0
+  cc:	78 00 00 20 	clrldi  r0,r0,32
+  d0:	7c 00 07 b4 	extsw   r0,r0
+  d4:	7c 03 03 78 	mr      r3,r0
+  d8:	e8 21 00 00 	ld      r1,0(r1)
+  dc:	e8 01 00 10 	ld      r0,16(r1)
+  e0:	7c 08 03 a6 	mtlr    r0
+  e4:	eb e1 ff f8 	ld      r31,-8(r1)
+  e8:	4e 80 00 20 	blr
+  ec:	00 00 00 00 	.long 0x0
+  f0:	00 00 00 01 	.long 0x1
+  f4:	80 01 00 01 	lwz     r0,1(r1)
+
+
+
 ; vim: ft=asm
 
--- a/doc/disas_examples/x86.plan9call.disas	Thu Feb 10 17:32:05 2022 +0100
+++ b/doc/disas_examples/x86.plan9call.disas	Wed Feb 16 16:44:11 2022 +0100
@@ -73,7 +73,7 @@
 ; 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';
+;     char l[100] = { 'L' };
 ;     leaf_call(b, c, d, e, f, g, h);
 ; }
 ;
@@ -165,7 +165,7 @@
 ; 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';
+;     char l[100] = { 'L' };
 ;     leaf_call(b, c, d, e, f, g, h, i, j);
 ; }
 ;
@@ -301,6 +301,8 @@
 ;     return (int)f();
 ; }
 
+
+
 ; output from plan9-4th_edition-x86 w/ 8c x.c && 8l -a x.8
 
 001020                  (2)     TEXT f1+0(SB),$0
@@ -345,6 +347,8 @@
 ;     return b.j + s.x;
 ; }
 
+
+
 ; output from plan9-4th_edition-x86 w/ 8c x.c && 8l -a x.8
 
 001020                  (5)     TEXT f0+0 (SB),$16
--- a/doc/manual/callconvs/callconv_ppc32.tex	Thu Feb 10 17:32:05 2022 +0100
+++ b/doc/manual/callconvs/callconv_ppc32.tex	Wed Feb 16 16:44:11 2022 +0100
@@ -95,6 +95,8 @@
 binary interfaces. In AIX and mac OS 9, padding bytes always follow the data structure
 \item composite parameters 3 bytes or larger in size occupy high-order bytes
 \item integer parameters \textless\ 32 bit are right-justified (meaning occupy higher-address bytes) in their 4-byte slot on the stack, requiring extra-care for big-endian targets
+\item aggregates (struct, union) with only one (non-aggregate / non-array) field are passed as if the field itself would be passed
+\item all other aggregates are passed as a sequence of words (like integer parameters)
 \end{itemize}
 
 
@@ -104,8 +106,8 @@
 \item return values of integer \textless=\ 32bit or pointer type use gpr3
 \item 64 bit integers use gpr3 and gpr4 (hiword in gpr3, loword in gpr4)
 \item floating point values are returned via fpr1
-\item structures \textless=\ 64 bits use gpr3 and gpr4
-\item for types \textgreater\ 64 bits, a secret first parameter with an address to the return value is passed
+\item aggregates (struct, union) \textless=\ 64 bits use gpr3 and gpr4
+\item for all other aggregates and types \textgreater\ 64 bits, a secret first parameter with an address to a caller allocated space is passed to the function (in gpr3), which is written to by the callee
 \end{itemize}
 
 
@@ -196,23 +198,26 @@
 \paragraph{Parameter passing}
 
 \begin{itemize}
-\item Stack pointer (r1) is always 16-byte aligned. The EABI differs here - it is 8-byte alignment.
-\item 8 general-purpose registers (r3-r10) for integer and pointer types.
-\item 8 floating-pointer registers (f1-f8) for float (promoted to double) and double types.
-\item Additional arguments are passed on the stack directly after the back-chain and saved return address (8 bytes structure) on the callers stack frame.
+\item Stack pointer (r1) is always 16-byte aligned. The EABI differs here - it is 8-byte alignment
+\item 8 general-purpose registers (r3-r10) for integer and pointer types
+\item 8 floating-pointer registers (f1-f8) for float (promoted to double) and double types
+\item Additional arguments are passed on the stack directly after the back-chain and saved return address (8 bytes structure) on the callers stack frame
 \item 64-bit integer data types are passed in general-purpose registers as a whole in two
  32-bit general purpose registers (an odd and an even e.g. r3 and r4), skipping an even integer register
  or passed on the stack; they are never splitted into a register and stack part
 \item Ellipsis calls set CR bit 6 
 \item integer parameters \textless\ 32 bit are right-justified (meaning occupy high-order bytes) in their 4-byte area, requiring extra-care for big-endian targets
 \item no spill area is used on stack, iterating over varargs requires a specific va\_list implementation
+\item aggregates (struct, union) and types \textgreater\ 64 bits are passed indirectly, as a pointer to the data (or a copy of it, if necessary to avoid modification)
 \end{itemize}
 
 \paragraph{Return values}
 
 \begin{itemize}
-\item 32-bit integers use register r3, 64-bit use registers r3 and r4 (hiword in r3, loword in r4).
-\item floating-point values are returned using register f1.
+\item 32-bit integers use register r3, 64-bit use registers r3 and r4 (hiword in r3, loword in r4)
+\item floating-point values are returned using register f1
+\item aggregates (struct, union) \textless=\ 64 bits use gpr3 and gpr4
+\item for all other aggregates and types \textgreater\ 64 bits, a secret first parameter with an address to a caller allocated space is passed to the function (in gpr3), which is written to by the callee
 \end{itemize}
 
 
--- a/doc/manual/callconvs/callconv_ppc64.tex	Thu Feb 10 17:32:05 2022 +0100
+++ b/doc/manual/callconvs/callconv_ppc64.tex	Wed Feb 16 16:44:11 2022 +0100
@@ -1,6 +1,6 @@
 %//////////////////////////////////////////////////////////////////////////////
 %
-% Copyright (c) 2007-2019 Daniel Adler <dadler@uni-goettingen.de>, 
+% Copyright (c) 2007-2022 Daniel Adler <dadler@uni-goettingen.de>, 
 %                         Tassilo Philipp <tphilipp@potion-studios.com>
 %
 % Permission to use, copy, modify, and distribute this software for any
@@ -26,6 +26,7 @@
 
 \begin{itemize}
 \item Word size is 32 bits for historical reasons
+\item Doublework size is 64 bits.
 \item Big endian (MSB) and litte endian (LSB) operating modes.
 \item Apple Mac OS X/Darwin PPC is specified in "Mac OS X ABI Function Call Guide"\cite{ppcMacOSX}. It uses Big Endian (MSB).
 \item Linux PPC 64-bit ABI is specified in "64-bit PowerPC ELF Application Binary Interface Supplement"\cite{ppcelf64abi} which is based on "System V ABI".
@@ -103,6 +104,7 @@
 \item all nonvector parameters are aligned on 8-byte boundaries
 \item vector parameters are aligned on 16-byte boundaries
 \item integer parameters \textless\ 64 bit are right-justified (meaning occupy higher-address bytes) in their 8-byte slot on the stack, requiring extra-care for big-endian targets
+\item aggregates (struct, union) are passed as a sequence of doublewords (following above rules for doublewords)
 \end{itemize}
 
 
@@ -112,8 +114,8 @@
 \item return values of integer \textless=\ 32bit or pointer type use gpr3 and are zero or sign extended depending on their type
 \item 64 bit integers use gpr3
 \item floating point values are returned via fpr1
-\item character arrays \textless=\ 8 bytes use gpr3, and are right justified
-\item for all structs/unions (regardless of size) or character arrays \textgreater\ 8 bytes, a secret first parameter with an address to a caller allocated space is passed as first argument to the function (meaning in gpr3), which is written to by the callee
+\item for aggregates (struct, union) of any size, a secret first parameter with an address
+to a caller allocated space is passed to the function (in gpr3), which is written to by the callee
 \end{itemize}