# HG changeset patch # User Tassilo Philipp # Date 1645026251 -3600 # Node ID ead041d93e36faff69a2a67f746b93312e85f90b # Parent e5820b7a3fbc180889f63bd75540e8cf2b7fd68f - ppc doc and disas examples related to aggregates diff -r e5820b7a3fbc -r ead041d93e36 doc/disas_examples/ppc.darwin.disas --- 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 diff -r e5820b7a3fbc -r ead041d93e36 doc/disas_examples/ppc.sysv.disas --- 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 : + 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 : + 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 + 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 + 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
: + 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 ; + 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 : + 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 : + 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 + 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 + 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
: + 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 + 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 : + 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
: + 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 + 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 : + 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 : + 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
: + 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 + 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 + 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 diff -r e5820b7a3fbc -r ead041d93e36 doc/disas_examples/ppc64.elfabi.disas --- 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 diff -r e5820b7a3fbc -r ead041d93e36 doc/disas_examples/x86.plan9call.disas --- 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 diff -r e5820b7a3fbc -r ead041d93e36 doc/manual/callconvs/callconv_ppc32.tex --- 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} diff -r e5820b7a3fbc -r ead041d93e36 doc/manual/callconvs/callconv_ppc64.tex --- 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 , +% Copyright (c) 2007-2022 Daniel Adler , % Tassilo Philipp % % 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}