changeset 497:cb19b2fe2422

- more disas examples to check behaviour of passing C++ non-trivial aggregates by value; they all behave the same, calling the copy ctor first, passing a pointer then
author Tassilo Philipp
date Wed, 23 Mar 2022 15:24:31 +0100
parents da5232da6270
children fd9ba3a6d348
files doc/disas_examples/arm.armhf.disas doc/disas_examples/arm.atpcs_arm.disas doc/disas_examples/arm64.aapcs.disas doc/disas_examples/mips.o32.disas doc/disas_examples/mips64.n64.disas doc/disas_examples/ppc.darwin.disas doc/disas_examples/ppc.sysv.disas doc/disas_examples/ppc64.elfabi.disas doc/disas_examples/sparc.sparc.disas doc/disas_examples/sparc64.sparc64.disas doc/disas_examples/x86.cdecl.disas doc/disas_examples/x86.fastcall_gnu.disas doc/disas_examples/x86.stdcall.disas
diffstat 13 files changed, 1204 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/doc/disas_examples/arm.armhf.disas	Mon Mar 21 18:11:38 2022 +0100
+++ b/doc/disas_examples/arm.armhf.disas	Wed Mar 23 15:24:31 2022 +0100
@@ -613,5 +613,88 @@
 
 
 
+; ---------- C++ trivial and non-trivial aggrs passed to C funcs ---------->
+;
+; struct Trivial { int a; };
+; struct NonTrivial { int a; NonTrivial() : a(0) {} NonTrivial(const NonTrivial& rhs) : a(rhs.a) { } };
+;
+; extern "C" {
+; 
+;     void f1(struct Trivial s)    { }
+;     void f2(struct NonTrivial s) { }
+;
+;     void f()
+;     {
+;         struct Trivial t;
+;         struct NonTrivial n;
+;         int a=1;
+;         a += 123;
+;         f1(t);
+;         a -= 123;
+;         f2(n);
+;         a -= 12;
+;     }
+; }
+
+
+
+; output from raspbian-11-armelhf w/ gcc 10.2.1
+
+00000000 <f1>:
+   0:   e52db004        push    {fp}
+   4:   e28db000        add     fp, sp, #0
+   8:   e24dd00c        sub     sp, sp, #12
+   c:   e50b0008        str     r0, [fp, #-8]
+  10:   e1a00000        nop
+  14:   e28bd000        add     sp, fp, #0
+  18:   e49db004        pop     {fp}
+  1c:   e12fff1e        bx      lr
+
+00000020 <f2>:
+  20:   e52db004        push    {fp}
+  24:   e28db000        add     fp, sp, #0
+  28:   e24dd00c        sub     sp, sp, #12
+  2c:   e50b0008        str     r0, [fp, #-8]
+  30:   e1a00000        nop
+  34:   e28bd000        add     sp, fp, #0
+  38:   e49db004        pop     {fp}
+  3c:   e12fff1e        bx      lr
+
+00000040 <f>:
+  40:   e92d4800        push    {fp, lr}                   ; |
+  44:   e28db004        add     fp, sp, #4                 ; | prolog
+  48:   e24dd010        sub     sp, sp, #16                ; /
+  4c:   e24b3014        sub     r3, fp, #20                ; \
+  50:   e1a00003        mov     r0, r3                     ; | this ptr (ptr to n's (NonTrivial) space)
+  54:   ebfffffe        bl      0 <_ZN10NonTrivialC1Ev>    ; | NonTrivial::NonTrivial() / ctor
+  58:   e3a03001        mov     r3, #1                     ; a = 1
+  5c:   e50b3008        str     r3, [fp, #-8]              ; |
+  60:   e51b3008        ldr     r3, [fp, #-8]              ; | a += 123
+  64:   e283307b        add     r3, r3, #123               ; |
+  68:   e50b3008        str     r3, [fp, #-8]              ; |
+  6c:   e51b0010        ldr     r0, [fp, #-16]             ; f1 arg 0 (struct Trivial), via reg as small struct
+  70:   ebfffffe        bl      0 <f1>                     ; call f1(struct Trivial)
+  74:   e51b3008        ldr     r3, [fp, #-8]              ; |
+  78:   e243307b        sub     r3, r3, #123               ; | a -= 123
+  7c:   e50b3008        str     r3, [fp, #-8]              ; /
+  80:   e24b2014        sub     r2, fp, #20                ; \
+  84:   e24b300c        sub     r3, fp, #12                ; |
+  88:   e1a01002        mov     r1, r2                     ; |               ptr to n
+  8c:   e1a00003        mov     r0, r3                     ; | copy n        ptr to dest of copy of n
+  90:   ebfffffe        bl      0 <_ZN10NonTrivialC1ERKS_> ; /               NonTrivial::NonTrivial(const NonTrivial&) / copy ctor
+  94:   e24b300c        sub     r3, fp, #12                ; \
+  98:   e1a00003        mov     r0, r3                     ; | f2 arg 0 (ptr to copy of struct NonTrivial), via ptr as non-trivial
+  9c:   ebfffffe        bl      20 <f2>                    ; call f2(struct NonTrivial)
+  a0:   e51b3008        ldr     r3, [fp, #-8]              ; |
+  a4:   e243300c        sub     r3, r3, #12                ; | a -= 12
+  a8:   e50b3008        str     r3, [fp, #-8]              ; /
+  ac:   e1a00000        nop                                ; \
+  b0:   e24bd004        sub     sp, fp, #4                 ; | epilog
+  b4:   e8bd8800        pop     {fp, pc}                   ; |
+
+  ; ... snip, removed code of ctor and copy ctor ...
+
+
+
 ; vim: ft=asm68k
 
--- a/doc/disas_examples/arm.atpcs_arm.disas	Mon Mar 21 18:11:38 2022 +0100
+++ b/doc/disas_examples/arm.atpcs_arm.disas	Wed Mar 23 15:24:31 2022 +0100
@@ -749,5 +749,86 @@
 
 
 
+; ---------- C++ trivial and non-trivial aggrs passed to C funcs ---------->
+;
+; struct Trivial { int a; };
+; struct NonTrivial { int a; NonTrivial() : a(0) {} NonTrivial(const NonTrivial& rhs) : a(rhs.a) { } };
+;
+; extern "C" {
+; 
+;     void f1(struct Trivial s)    { }
+;     void f2(struct NonTrivial s) { }
+;
+;     void f()
+;     {
+;         struct Trivial t;
+;         struct NonTrivial n;
+;         int a=1;
+;         a += 123;
+;         f1(t);
+;         a -= 123;
+;         f2(n);
+;         a -= 12;
+;     }
+; }
+
+
+
+; output from debian-6.0.8-armel w/ gcc 4.4.5
+
+00000000 <f1>:
+   0:   e52db004        push    {fp}
+   4:   e28db000        add     fp, sp, #0
+   8:   e24dd00c        sub     sp, sp, #12
+   c:   e50b0008        str     r0, [fp, #-8]
+  10:   e28bd000        add     sp, fp, #0
+  14:   e8bd0800        pop     {fp}
+  18:   e12fff1e        bx      lr
+
+0000001c <f2>:
+  1c:   e52db004        push    {fp}
+  20:   e28db000        add     fp, sp, #0
+  24:   e24dd00c        sub     sp, sp, #12
+  28:   e50b0008        str     r0, [fp, #-8]
+  2c:   e28bd000        add     sp, fp, #0
+  30:   e8bd0800        pop     {fp}
+  34:   e12fff1e        bx      lr
+
+00000038 <f>:
+  38:   e92d4800        push    {fp, lr}                   ; |
+  3c:   e28db004        add     fp, sp, #4                 ; | prolog
+  40:   e24dd010        sub     sp, sp, #16                ; /
+  44:   e24b3014        sub     r3, fp, #20                ; \
+  48:   e1a00003        mov     r0, r3                     ; | this ptr (ptr to n's (NonTrivial) space)
+  4c:   ebfffffe        bl      0 <_ZN10NonTrivialC1Ev>    ; | NonTrivial::NonTrivial() / ctor
+  50:   e3a03001        mov     r3, #1                     ; a = 1
+  54:   e50b3008        str     r3, [fp, #-8]              ; |
+  58:   e51b3008        ldr     r3, [fp, #-8]              ; | a += 123
+  5c:   e283307b        add     r3, r3, #123               ; |
+  60:   e50b3008        str     r3, [fp, #-8]              ; |
+  64:   e51b0010        ldr     r0, [fp, #-16]             ; f1 arg 0 (struct Trivial), via reg as small struct
+  68:   ebfffffe        bl      0 <f1>                     ; call f1(struct Trivial)
+  6c:   e51b3008        ldr     r3, [fp, #-8]              ; |
+  70:   e243307b        sub     r3, r3, #123               ; | a -= 123
+  74:   e50b3008        str     r3, [fp, #-8]              ; /
+  78:   e24b200c        sub     r2, fp, #12                ; \
+  7c:   e24b3014        sub     r3, fp, #20                ; |
+  80:   e1a00002        mov     r0, r2                     ; |               ptr to dest of copy of n
+  84:   e1a01003        mov     r1, r3                     ; | copy n        ptr to n
+  88:   ebfffffe        bl      0 <_ZN10NonTrivialC1ERKS_> ; /               NonTrivial::NonTrivial(const NonTrivial&) / copy ctor
+  8c:   e24b300c        sub     r3, fp, #12                ; \
+  90:   e1a00003        mov     r0, r3                     ; | f2 arg 0 (ptr to copy of struct NonTrivial), via ptr as non-trivial
+  94:   ebfffffe        bl      1c <f2>                    ; call f2(struct NonTrivial)
+  98:   e51b3008        ldr     r3, [fp, #-8]              ; |
+  9c:   e243300c        sub     r3, r3, #12                ; | a -= 12
+  a0:   e50b3008        str     r3, [fp, #-8]              ; /
+  a4:   e24bd004        sub     sp, fp, #4                 ; \
+  a8:   e8bd4800        pop     {fp, lr}                   ; | epilog
+  ac:   e12fff1e        bx      lr                         ; |
+
+  ; ... snip, removed code of ctor and copy ctor ...
+
+
+
 ; vim: ft=asm68k
 
--- a/doc/disas_examples/arm64.aapcs.disas	Mon Mar 21 18:11:38 2022 +0100
+++ b/doc/disas_examples/arm64.aapcs.disas	Wed Mar 23 15:24:31 2022 +0100
@@ -2168,5 +2168,94 @@
 
 
 
+; ---------- C++ trivial and non-trivial aggrs passed to C funcs ---------->
+;
+; struct Trivial { int a; };
+; struct NonTrivial { int a; NonTrivial() : a(0) {} NonTrivial(const NonTrivial& rhs) : a(rhs.a) { } };
+;
+; extern "C" {
+; 
+;     void f1(struct Trivial s)    { }
+;     void f2(struct NonTrivial s) { }
+;
+;     void f()
+;     {
+;         struct Trivial t;
+;         struct NonTrivial n;
+;         int a=1;
+;         a += 123;
+;         f1(t);
+;         a -= 123;
+;         f2(n);
+;         a -= 12;
+;     }
+; }
+
+
+
+; output from freebsd-13.0_r348764-arm64 w/ clang 8.0.0
+
+0000000000210250 f1:
+  210250:       ff 43 00 d1     sub     sp, sp, #16
+  210254:       e8 33 00 91     add     x8, sp, #12
+  210258:       e9 03 00 2a     mov     w9, w0
+  21025c:       09 01 00 b9     str     w9, [x8]
+  210260:       ff 43 00 91     add     sp, sp, #16
+  210264:       c0 03 5f d6     ret
+
+0000000000210268 f2:
+  210268:       c0 03 5f d6     ret
+
+000000000021026c f:
+  21026c:       ff 43 01 d1     sub     sp, sp, #80                  ;
+  210270:       fd 7b 04 a9     stp     x29, x30, [sp, #64]          ;
+  210274:       fd 03 01 91     add     x29, sp, #64                 ;
+  210278:       e8 03 00 32     orr     w8, wzr, #0x1                ;
+  21027c:       e2 03 7e b2     orr     x2, xzr, #0x4                ;
+  210280:       a1 13 00 d1     sub     x1, x29, #4                  ;
+  210284:       a9 23 00 d1     sub     x9, x29, #8                  ;
+  210288:       aa 43 00 d1     sub     x10, x29, #16                ;
+  21028c:       ab 53 00 d1     sub     x11, x29, #20                ;
+  210290:       e0 03 09 aa     mov     x0, x9                       ;
+  210294:       a8 83 1e b8     stur    w8, [x29, #-24]              ;
+  210298:       e2 13 00 f9     str     x2, [sp, #32]                ;
+  21029c:       e1 0f 00 f9     str     x1, [sp, #24]                ;
+  2102a0:       e9 0b 00 f9     str     x9, [sp, #16]                ;
+  2102a4:       ea 07 00 f9     str     x10, [sp, #8]                ;
+  2102a8:       eb 03 00 f9     str     x11, [sp]                    ;
+  2102ac:       1f 00 00 94     bl      #124 <_ZN10NonTrivialC2Ev>   ;
+  2102b0:       a8 83 5e b8     ldur    w8, [x29, #-24]              ;
+  2102b4:       a8 43 1f b8     stur    w8, [x29, #-12]              ;
+  2102b8:       ac 43 5f b8     ldur    w12, [x29, #-12]             ;
+  2102bc:       8c ed 01 11     add     w12, w12, #123               ;
+  2102c0:       ac 43 1f b8     stur    w12, [x29, #-12]             ;
+  2102c4:       e0 07 40 f9     ldr     x0, [sp, #8]                 ;
+  2102c8:       e1 0f 40 f9     ldr     x1, [sp, #24]                ;
+  2102cc:       e2 13 40 f9     ldr     x2, [sp, #32]                ;
+  2102d0:       50 00 00 94     bl      #320 <memcpy@plt>            ;
+  2102d4:       e9 07 40 f9     ldr     x9, [sp, #8]                 ;
+  2102d8:       28 01 40 b9     ldr     w8, [x9]                     ;
+  2102dc:       ea 03 08 2a     mov     w10, w8                      ;
+  2102e0:       40 7d 40 d3     ubfx    x0, x10, #0, #32             ;
+  2102e4:       db ff ff 97     bl      #-148 <f1>                   ;
+  2102e8:       a8 43 5f b8     ldur    w8, [x29, #-12]              ;
+  2102ec:       08 ed 01 71     subs    w8, w8, #123                 ;
+  2102f0:       a8 43 1f b8     stur    w8, [x29, #-12]              ;
+  2102f4:       e0 03 40 f9     ldr     x0, [sp]                     ; |               ptr to dest of copy of n
+  2102f8:       e1 0b 40 f9     ldr     x1, [sp, #16]                ; | copy n        ptr to n
+  2102fc:       11 00 00 94     bl      #68 <_ZN10NonTrivialC2ERKS_> ; |               NonTrivial::NonTrivial(const NonTrivial&) / copy ctor
+  210300:       e0 03 40 f9     ldr     x0, [sp]                     ; f2 arg 0 (ptr to copy of struct NonTrivial), via ptr as non-trivial
+  210304:       d9 ff ff 97     bl      #-156 <f2>                   ; call f2(struct NonTrivial)
+  210308:       a8 43 5f b8     ldur    w8, [x29, #-12]              ;
+  21030c:       08 31 00 71     subs    w8, w8, #12                  ;
+  210310:       a8 43 1f b8     stur    w8, [x29, #-12]              ;
+  210314:       fd 7b 44 a9     ldp     x29, x30, [sp, #64]          ;
+  210318:       ff 43 01 91     add     sp, sp, #80                  ;
+  21031c:       c0 03 5f d6     ret                                  ;
+
+  ; ... snip, removed code of ctor and copy ctor ...
+
+
+
 ; vim: ft=asm68k
 
--- a/doc/disas_examples/mips.o32.disas	Mon Mar 21 18:11:38 2022 +0100
+++ b/doc/disas_examples/mips.o32.disas	Wed Mar 23 15:24:31 2022 +0100
@@ -1754,5 +1754,113 @@
 
 
 
+; ---------- C++ trivial and non-trivial aggrs passed to C funcs ---------->
+;
+; struct Trivial { int a; };
+; struct NonTrivial { int a; NonTrivial() : a(0) {} NonTrivial(const NonTrivial& rhs) : a(rhs.a) { } };
+;
+; extern "C" {
+; 
+;     void f1(struct Trivial s)    { }
+;     void f2(struct NonTrivial s) { }
+;
+;     void f()
+;     {
+;         struct Trivial t;
+;         struct NonTrivial n;
+;         int a=1;
+;         a += 123;
+;         f1(t);
+;         a -= 123;
+;         f2(n);
+;         a -= 12;
+;     }
+; }
+
+
+
+; output from freebsd-12.0_r333647-malta_mipsebhf w/ gcc 4.2.1 *and* -mhard-float ----->
+
+004008c0 <f1>:
+  4008c0:       3c1c0002        lui     gp,0x2
+  4008c4:       279c8330        addiu   gp,gp,-31952
+  4008c8:       0399e021        addu    gp,gp,t9
+  4008cc:       27bdfff8        addiu   sp,sp,-8
+  4008d0:       afbe0000        sw      s8,0(sp)
+  4008d4:       03a0f021        move    s8,sp
+  4008d8:       afc40008        sw      a0,8(s8)
+  4008dc:       03c0e821        move    sp,s8
+  4008e0:       8fbe0000        lw      s8,0(sp)
+  4008e4:       03e00008        jr      ra
+  4008e8:       27bd0008        addiu   sp,sp,8
+
+004008ec <f2>:
+  4008ec:       3c1c0002        lui     gp,0x2
+  4008f0:       279c8304        addiu   gp,gp,-31996
+  4008f4:       0399e021        addu    gp,gp,t9
+  4008f8:       27bdfff8        addiu   sp,sp,-8
+  4008fc:       afbe0000        sw      s8,0(sp)
+  400900:       03a0f021        move    s8,sp
+  400904:       afc40008        sw      a0,8(s8)
+  400908:       03c0e821        move    sp,s8
+  40090c:       8fbe0000        lw      s8,0(sp)
+  400910:       03e00008        jr      ra
+  400914:       27bd0008        addiu   sp,sp,8
+
+00400918 <f>:
+  400918:       3c1c0002        lui     gp,0x2        ;
+  40091c:       279c82d8        addiu   gp,gp,-32040  ;
+  400920:       0399e021        addu    gp,gp,t9      ;
+  400924:       27bdffd0        addiu   sp,sp,-48     ;
+  400928:       afbf002c        sw      ra,44(sp)     ;
+  40092c:       afbe0028        sw      s8,40(sp)     ;
+  400930:       03a0f021        move    s8,sp         ;
+  400934:       afbc0010        sw      gp,16(sp)     ;
+  400938:       27c20024        addiu   v0,s8,36      ;
+  40093c:       00402021        move    a0,v0         ;
+  400940:       8f998064        lw      t9,-32668(gp) ; |
+  400944:       0320f809        jalr    t9            ; | NonTrivial::NonTrivial() / ctor
+  400948:       00000000        nop                   ;
+  40094c:       8fdc0010        lw      gp,16(s8)     ;
+  400950:       24020001        li      v0,1          ;
+  400954:       afc20018        sw      v0,24(s8)     ;
+  400958:       8fc20018        lw      v0,24(s8)     ;
+  40095c:       2442007b        addiu   v0,v0,123     ;
+  400960:       afc20018        sw      v0,24(s8)     ;
+  400964:       8fc40020        lw      a0,32(s8)     ;
+  400968:       8f998060        lw      t9,-32672(gp) ; |
+  40096c:       0320f809        jalr    t9            ; | call f1(struct Trivial)
+  400970:       00000000        nop                   ;
+  400974:       8fdc0010        lw      gp,16(s8)     ;
+  400978:       8fc20018        lw      v0,24(s8)     ;
+  40097c:       2442ff85        addiu   v0,v0,-123    ;
+  400980:       afc20018        sw      v0,24(s8)     ;
+  400984:       27c2001c        addiu   v0,s8,28      ;
+  400988:       27c30024        addiu   v1,s8,36      ;
+  40098c:       00402021        move    a0,v0         ; |               ptr to dest of copy of n
+  400990:       00602821        move    a1,v1         ; |               ptr to n
+  400994:       8f998050        lw      t9,-32688(gp) ; | copy n        |
+  400998:       0320f809        jalr    t9            ; |               | NonTrivial::NonTrivial(const NonTrivial&) / copy ctor
+  40099c:       00000000        nop                   ;
+  4009a0:       8fdc0010        lw      gp,16(s8)     ;
+  4009a4:       27c2001c        addiu   v0,s8,28      ; get ptr to copy of n -> v0
+  4009a8:       00402021        move    a0,v0         ; f2 arg 0 (ptr to copy of struct NonTrivial), via ptr as non-trivial
+  4009ac:       8f998058        lw      t9,-32680(gp) ; |
+  4009b0:       0320f809        jalr    t9            ; | call f2(struct NonTrivial)
+  4009b4:       00000000        nop                   ;
+  4009b8:       8fdc0010        lw      gp,16(s8)     ;
+  4009bc:       8fc20018        lw      v0,24(s8)     ;
+  4009c0:       2442fff4        addiu   v0,v0,-12     ;
+  4009c4:       afc20018        sw      v0,24(s8)     ;
+  4009c8:       03c0e821        move    sp,s8         ;
+  4009cc:       8fbf002c        lw      ra,44(sp)     ;
+  4009d0:       8fbe0028        lw      s8,40(sp)     ;
+  4009d4:       03e00008        jr      ra            ;
+  4009d8:       27bd0030        addiu   sp,sp,48      ;
+
+  ; ... snip, removed code of ctor and copy ctor ...
+
+
+
 ; vim: ft=asm
 
--- a/doc/disas_examples/mips64.n64.disas	Mon Mar 21 18:11:38 2022 +0100
+++ b/doc/disas_examples/mips64.n64.disas	Wed Mar 23 15:24:31 2022 +0100
@@ -3233,5 +3233,118 @@
 
 
 
+; ---------- C++ trivial and non-trivial aggrs passed to C funcs ---------->
+;
+; struct Trivial { int a; };
+; struct NonTrivial { int a; NonTrivial() : a(0) {} NonTrivial(const NonTrivial& rhs) : a(rhs.a) { } };
+;
+; extern "C" {
+; 
+;     void f1(struct Trivial s)    { }
+;     void f2(struct NonTrivial s) { }
+;
+;     void f()
+;     {
+;         struct Trivial t;
+;         struct NonTrivial n;
+;         int a=1;
+;         a += 123;
+;         f1(t);
+;         a -= 123;
+;         f2(n);
+;         a -= 12;
+;     }
+; }
+
+
+
+; output from freebsd-12.0_r333647-malta_mips64ebhf w/ gcc 4.2.1 *and* -mhard-float
+
+0000000120000b70 <f1>:
+   120000b70:   67bdffe0        daddiu  sp,sp,-32
+   120000b74:   ffbe0018        sd      s8,24(sp)
+   120000b78:   ffbc0010        sd      gp,16(sp)
+   120000b7c:   03a0f02d        move    s8,sp
+   120000b80:   3c1c0002        lui     gp,0x2
+   120000b84:   0399e02d        daddu   gp,gp,t9
+   120000b88:   679c84e0        daddiu  gp,gp,-31520
+   120000b8c:   ffc40000        sd      a0,0(s8)
+   120000b90:   03c0e82d        move    sp,s8
+   120000b94:   dfbe0018        ld      s8,24(sp)
+   120000b98:   dfbc0010        ld      gp,16(sp)
+   120000b9c:   03e00008        jr      ra
+   120000ba0:   67bd0020        daddiu  sp,sp,32
+   120000ba4:   00000000        nop
+
+0000000120000ba8 <f2>:
+   120000ba8:   67bdffe0        daddiu  sp,sp,-32
+   120000bac:   ffbe0018        sd      s8,24(sp)
+   120000bb0:   ffbc0010        sd      gp,16(sp)
+   120000bb4:   03a0f02d        move    s8,sp
+   120000bb8:   3c1c0002        lui     gp,0x2
+   120000bbc:   0399e02d        daddu   gp,gp,t9
+   120000bc0:   679c84a8        daddiu  gp,gp,-31576
+   120000bc4:   ffc40000        sd      a0,0(s8)
+   120000bc8:   03c0e82d        move    sp,s8
+   120000bcc:   dfbe0018        ld      s8,24(sp)
+   120000bd0:   dfbc0010        ld      gp,16(sp)
+   120000bd4:   03e00008        jr      ra
+   120000bd8:   67bd0020        daddiu  sp,sp,32
+   120000bdc:   00000000        nop
+
+0000000120000be0 <f>:
+   120000be0:   67bdffd0        daddiu  sp,sp,-48     ;
+   120000be4:   ffbf0020        sd      ra,32(sp)     ;
+   120000be8:   ffbe0018        sd      s8,24(sp)     ;
+   120000bec:   ffbc0010        sd      gp,16(sp)     ;
+   120000bf0:   03a0f02d        move    s8,sp         ;
+   120000bf4:   3c1c0002        lui     gp,0x2        ;
+   120000bf8:   0399e02d        daddu   gp,gp,t9      ;
+   120000bfc:   679c8470        daddiu  gp,gp,-31632  ;
+   120000c00:   67c2000c        daddiu  v0,s8,12      ;
+   120000c04:   0040202d        move    a0,v0         ;
+   120000c08:   df9980e8        ld      t9,-32536(gp) ;
+   120000c0c:   0320f809        jalr    t9            ;
+   120000c10:   00000000        nop                   ;
+   120000c14:   24020001        li      v0,1          ;
+   120000c18:   afc20000        sw      v0,0(s8)      ;
+   120000c1c:   8fc20000        lw      v0,0(s8)      ;
+   120000c20:   2442007b        addiu   v0,v0,123     ;
+   120000c24:   afc20000        sw      v0,0(s8)      ;
+   120000c28:   8fc40008        lw      a0,8(s8)      ;
+   120000c2c:   0004203c        dsll32  a0,a0,0x0     ;
+   120000c30:   df9980e0        ld      t9,-32544(gp) ;
+   120000c34:   0320f809        jalr    t9            ;
+   120000c38:   00000000        nop                   ;
+   120000c3c:   8fc20000        lw      v0,0(s8)      ;
+   120000c40:   2442ff85        addiu   v0,v0,-123    ;
+   120000c44:   afc20000        sw      v0,0(s8)      ;
+   120000c48:   67c20004        daddiu  v0,s8,4       ;
+   120000c4c:   67c3000c        daddiu  v1,s8,12      ;
+   120000c50:   0040202d        move    a0,v0         ; |               ptr to dest of copy of n
+   120000c54:   0060282d        move    a1,v1         ; |               ptr to n
+   120000c58:   df9980c0        ld      t9,-32576(gp) ; | copy n        |
+   120000c5c:   0320f809        jalr    t9            ; |               | NonTrivial::NonTrivial(const NonTrivial&) / copy ctor
+   120000c60:   00000000        nop                   ;
+   120000c64:   67c20004        daddiu  v0,s8,4       ; get ptr to copy of n -> v0
+   120000c68:   0040202d        move    a0,v0         ; f2 arg 0 (ptr to copy of struct NonTrivial), via ptr as non-trivial
+   120000c6c:   df9980d0        ld      t9,-32560(gp) ; |
+   120000c70:   0320f809        jalr    t9            ; | call f2(struct NonTrivial)
+   120000c74:   00000000        nop                   ;
+   120000c78:   8fc20000        lw      v0,0(s8)      ;
+   120000c7c:   2442fff4        addiu   v0,v0,-12     ;
+   120000c80:   afc20000        sw      v0,0(s8)      ;
+   120000c84:   03c0e82d        move    sp,s8         ;
+   120000c88:   dfbf0020        ld      ra,32(sp)     ;
+   120000c8c:   dfbe0018        ld      s8,24(sp)     ;
+   120000c90:   dfbc0010        ld      gp,16(sp)     ;
+   120000c94:   03e00008        jr      ra            ;
+   120000c98:   67bd0030        daddiu  sp,sp,48      ;
+   120000c9c:   00000000        nop                   ;
+
+  ; ... snip, removed code of ctor and copy ctor ...
+
+
+
 ; vim: ft=asm
 
--- a/doc/disas_examples/ppc.darwin.disas	Mon Mar 21 18:11:38 2022 +0100
+++ b/doc/disas_examples/ppc.darwin.disas	Wed Mar 23 15:24:31 2022 +0100
@@ -952,5 +952,88 @@
 
 
 
+; ---------- C++ trivial and non-trivial aggrs passed to C funcs ---------->
+;
+; struct Trivial { int a; };
+; struct NonTrivial { int a; NonTrivial() : a(0) {} NonTrivial(const NonTrivial& rhs) : a(rhs.a) { } };
+;
+; extern "C" {
+; 
+;     void f1(struct Trivial s)    { }
+;     void f2(struct NonTrivial s) { }
+;
+;     void f()
+;     {
+;         struct Trivial t;
+;         struct NonTrivial n;
+;         int a=1;
+;         a += 123;
+;         f1(t);
+;         a -= 123;
+;         f2(n);
+;         a -= 12;
+;     }
+; }
+
+
+
+; output from darwin-8.0.1-ppc w/ gcc 3.3
+
+_f1:
+00000000    stmw    r30,0xfff8(r1)
+00000004    stwu    r1,0xffd0(r1)
+00000008    or  r30,r1,r1
+0000000c    stw r3,0x48(r30)
+00000010    lwz r1,_f1(r1)
+00000014    lmw r30,0xfff8(r1)
+00000018    blr
+_f2:
+0000001c    stmw    r30,0xfff8(r1)
+00000020    stwu    r1,0xffd0(r1)
+00000024    or  r30,r1,r1
+00000028    lwz r1,_f1(r1)
+0000002c    lmw r30,0xfff8(r1)
+00000030    blr
+_f:
+00000034    mfspr   r0,lr                       ;
+00000038    stmw    r30,0xfff8(r1)              ;
+0000003c    stw r0,0x8(r1)                      ;
+00000040    stwu    r1,0xff70(r1)               ;
+00000044    or  r30,r1,r1                       ;
+00000048    addi    r0,r30,0x50                 ;
+0000004c    or  r3,r0,r0                        ;
+00000050    bl  0x140 ; __ZN10NonTrivialC1Ev    ; NonTrivial::NonTrivial() / ctor
+00000054    li  r0,0x1                          ;
+00000058    stw r0,0x60(r30)                    ;
+0000005c    lwz r2,0x60(r30)                    ;
+00000060    addi    r0,r2,0x7b                  ;
+00000064    stw r0,0x60(r30)                    ;
+00000068    lwz r0,0x40(r30)                    ;
+0000006c    or  r3,r0,r0                        ;
+00000070    bl  _f1                             ; call f1(struct Trivial)
+00000074    lwz r2,0x60(r30)                    ;
+00000078    addi    r0,r2,0xff85                ;
+0000007c    stw r0,0x60(r30)                    ;
+00000080    addi    r0,r30,0x70                 ;
+00000084    addi    r2,r30,0x50                 ;
+00000088    or  r3,r0,r0                        ; |               ptr to dest of copy of n
+0000008c    or  r4,r2,r2                        ; | copy n        ptr to n
+00000090    bl  0x120 ; __ZN10NonTrivialC1ERKS_ ; /               NonTrivial::NonTrivial(const NonTrivial&) / copy ctor
+00000094    addi    r0,r30,0x70                 ; \
+00000098    or  r3,r0,r0                        ; | f2 arg 0 (ptr to copy of struct NonTrivial), via ptr as non-trivial
+0000009c    bl  _f2                             ; call f2(struct NonTrivial)
+000000a0    lwz r2,0x60(r30)                    ;
+000000a4    addi    r0,r2,0xfff4                ;
+000000a8    stw r0,0x60(r30)                    ;
+000000ac    lwz r1,_f1(r1)                      ;
+000000b0    lwz r0,0x8(r1)                      ;
+000000b4    mtspr   lr,r0                       ;
+000000b8    lmw r30,0xfff8(r1)                  ;
+000000bc    blr                                 ;
+
+  ; ... snip, removed code of ctor and copy ctor ...
+
+
+
 ; vim: ft=asm
 
--- a/doc/disas_examples/ppc.sysv.disas	Mon Mar 21 18:11:38 2022 +0100
+++ b/doc/disas_examples/ppc.sysv.disas	Wed Mar 23 15:24:31 2022 +0100
@@ -1114,5 +1114,95 @@
 
 
 
+; ---------- C++ trivial and non-trivial aggrs passed to C funcs ---------->
+;
+; struct Trivial { int a; };
+; struct NonTrivial { int a; NonTrivial() : a(0) {} NonTrivial(const NonTrivial& rhs) : a(rhs.a) { } };
+;
+; extern "C" {
+; 
+;     void f1(struct Trivial s)    { }
+;     void f2(struct NonTrivial s) { }
+;
+;     void f()
+;     {
+;         struct Trivial t;
+;         struct NonTrivial n;
+;         int a=1;
+;         a += 123;
+;         f1(t);
+;         a -= 123;
+;         f2(n);
+;         a -= 12;
+;     }
+; }
+
+
+
+; output from debian-4.1.1-21-ppc w/ gcc 4.1.2
+
+100003e0 <f1>:
+100003e0:       94 21 ff f0     stwu    r1,-16(r1)
+100003e4:       93 e1 00 0c     stw     r31,12(r1)
+100003e8:       7c 3f 0b 78     mr      r31,r1
+100003ec:       81 61 00 00     lwz     r11,0(r1)
+100003f0:       83 eb ff fc     lwz     r31,-4(r11)
+100003f4:       7d 61 5b 78     mr      r1,r11
+100003f8:       4e 80 00 20     blr
+
+100003fc <f2>:
+100003fc:       94 21 ff e0     stwu    r1,-32(r1)
+10000400:       93 e1 00 1c     stw     r31,28(r1)
+10000404:       7c 3f 0b 78     mr      r31,r1
+10000408:       90 7f 00 08     stw     r3,8(r31)
+1000040c:       81 61 00 00     lwz     r11,0(r1)
+10000410:       83 eb ff fc     lwz     r31,-4(r11)
+10000414:       7d 61 5b 78     mr      r1,r11
+10000418:       4e 80 00 20     blr
+
+1000041c <f>:
+1000041c:       94 21 ff d0     stwu    r1,-48(r1)                        ;
+10000420:       7c 08 02 a6     mflr    r0                                ;
+10000424:       93 e1 00 2c     stw     r31,44(r1)                        ;
+10000428:       90 01 00 34     stw     r0,52(r1)                         ;
+1000042c:       7c 3f 0b 78     mr      r31,r1                            ;
+10000430:       38 1f 00 14     addi    r0,r31,20                         ;
+10000434:       7c 03 03 78     mr      r3,r0                             ;
+10000438:       48 00 00 a1     bl      100004d8 <_ZN10NonTrivialC1Ev>    ; NonTrivial::NonTrivial() / ctor
+1000043c:       38 00 00 01     li      r0,1                              ;
+10000440:       90 1f 00 08     stw     r0,8(r31)                         ;
+10000444:       81 3f 00 08     lwz     r9,8(r31)                         ;
+10000448:       38 09 00 7b     addi    r0,r9,123                         ;
+1000044c:       90 1f 00 08     stw     r0,8(r31)                         ;
+10000450:       80 1f 00 10     lwz     r0,16(r31)                        ;
+10000454:       90 1f 00 18     stw     r0,24(r31)                        ;
+10000458:       38 1f 00 18     addi    r0,r31,24                         ;
+1000045c:       7c 03 03 78     mr      r3,r0                             ;
+10000460:       4b ff ff 81     bl      100003e0 <f1>                     ; call f1(struct Trivial)
+10000464:       81 3f 00 08     lwz     r9,8(r31)                         ;
+10000468:       38 09 ff 85     addi    r0,r9,-123                        ;
+1000046c:       90 1f 00 08     stw     r0,8(r31)                         ;
+10000470:       38 1f 00 0c     addi    r0,r31,12                         ;
+10000474:       39 3f 00 14     addi    r9,r31,20                         ;
+10000478:       7c 03 03 78     mr      r3,r0                             ; |               ptr to dest of copy of n
+1000047c:       7d 24 4b 78     mr      r4,r9                             ; | copy n        ptr to n
+10000480:       48 00 00 85     bl      10000504 <_ZN10NonTrivialC1ERKS_> ; /               NonTrivial::NonTrivial(const NonTrivial&) / copy ctor
+10000484:       38 1f 00 0c     addi    r0,r31,12                         ; \
+10000488:       7c 03 03 78     mr      r3,r0                             ; | f2 arg 0 (ptr to copy of struct NonTrivial), via ptr as non-trivial
+1000048c:       4b ff ff 71     bl      100003fc <f2>                     ; call f2(struct NonTrivial)
+10000490:       81 3f 00 08     lwz     r9,8(r31)                         ;
+10000494:       38 09 ff f4     addi    r0,r9,-12                         ;
+10000498:       90 1f 00 08     stw     r0,8(r31)                         ;
+1000049c:       81 61 00 00     lwz     r11,0(r1)                         ;
+100004a0:       80 0b 00 04     lwz     r0,4(r11)                         ;
+100004a4:       7c 08 03 a6     mtlr    r0                                ;
+100004a8:       83 eb ff fc     lwz     r31,-4(r11)                       ;
+100004ac:       7d 61 5b 78     mr      r1,r11                            ;
+100004b0:       4e 80 00 20     blr                                       ;
+
+  ; ... snip, removed code of ctor and copy ctor ...
+
+
+
 ; vim: ft=asm68k
 
--- a/doc/disas_examples/ppc64.elfabi.disas	Mon Mar 21 18:11:38 2022 +0100
+++ b/doc/disas_examples/ppc64.elfabi.disas	Wed Mar 23 15:24:31 2022 +0100
@@ -734,5 +734,101 @@
 
 
 
+; ---------- C++ trivial and non-trivial aggrs passed to C funcs ---------->
+;
+; struct Trivial { int a; };
+; struct NonTrivial { int a; NonTrivial() : a(0) {} NonTrivial(const NonTrivial& rhs) : a(rhs.a) { } };
+;
+; extern "C" {
+; 
+;     void f1(struct Trivial s)    { }
+;     void f2(struct NonTrivial s) { }
+;
+;     void f()
+;     {
+;         struct Trivial t;
+;         struct NonTrivial n;
+;         int a=1;
+;         a += 123;
+;         f1(t);
+;         a -= 123;
+;         f2(n);
+;         a -= 12;
+;     }
+; }
+
+
+
+; output from freebsd-11.0-ppc64 w/ gcc 4.2.1
+
+0000000010000828 <.f1>:
+    10000828:   fb e1 ff f8     std     r31,-8(r1)
+    1000082c:   f8 21 ff c1     stdu    r1,-64(r1)
+    10000830:   7c 3f 0b 78     mr      r31,r1
+    10000834:   90 7f 00 70     stw     r3,112(r31)
+    10000838:   e8 21 00 00     ld      r1,0(r1)
+    1000083c:   eb e1 ff f8     ld      r31,-8(r1)
+    10000840:   4e 80 00 20     blr
+    10000844:   00 00 00 00     .long 0x0
+    10000848:   00 09 00 00     .long 0x90000
+    1000084c:   80 01 00 01     lwz     r0,1(r1)
+
+0000000010000850 <.f2>:
+    10000850:   fb e1 ff f8     std     r31,-8(r1)
+    10000854:   f8 21 ff c1     stdu    r1,-64(r1)
+    10000858:   7c 3f 0b 78     mr      r31,r1
+    1000085c:   f8 7f 00 70     std     r3,112(r31)
+    10000860:   e8 21 00 00     ld      r1,0(r1)
+    10000864:   eb e1 ff f8     ld      r31,-8(r1)
+    10000868:   4e 80 00 20     blr
+    1000086c:   00 00 00 00     .long 0x0
+    10000870:   00 09 00 00     .long 0x90000
+    10000874:   80 01 00 01     lwz     r0,1(r1)
+
+0000000010000878 <.f>:
+    10000878:   7c 08 02 a6     mflr    r0                                 ;
+    1000087c:   fb e1 ff f8     std     r31,-8(r1)                         ;
+    10000880:   f8 01 00 10     std     r0,16(r1)                          ;
+    10000884:   f8 21 ff 71     stdu    r1,-144(r1)                        ;
+    10000888:   7c 3f 0b 78     mr      r31,r1                             ;
+    1000088c:   38 1f 00 7c     addi    r0,r31,124                         ;
+    10000890:   7c 03 03 78     mr      r3,r0                              ;
+    10000894:   48 00 00 ad     bl      10000940 <._ZN10NonTrivialC1Ev>    ; NonTrivial::NonTrivial() / ctor
+    10000898:   4f ff fb 82     crmove  4*cr7+so,4*cr7+so                  ;
+    1000089c:   38 00 00 01     li      r0,1                               ;
+    100008a0:   90 1f 00 70     stw     r0,112(r31)                        ;
+    100008a4:   81 3f 00 70     lwz     r9,112(r31)                        ;
+    100008a8:   38 09 00 7b     addi    r0,r9,123                          ;
+    100008ac:   90 1f 00 70     stw     r0,112(r31)                        ;
+    100008b0:   80 7f 00 78     lwz     r3,120(r31)                        ;
+    100008b4:   4b ff ff 75     bl      10000828 <.f1>                     ; call f1(struct Trivial)
+    100008b8:   81 3f 00 70     lwz     r9,112(r31)                        ;
+    100008bc:   38 09 ff 85     addi    r0,r9,-123                         ;
+    100008c0:   90 1f 00 70     stw     r0,112(r31)                        ;
+    100008c4:   38 1f 00 74     addi    r0,r31,116                         ;
+    100008c8:   39 3f 00 7c     addi    r9,r31,124                         ;
+    100008cc:   7c 03 03 78     mr      r3,r0                              ; |               ptr to dest of copy of n
+    100008d0:   7d 24 4b 78     mr      r4,r9                              ; | copy n        ptr to n
+    100008d4:   48 00 00 a1     bl      10000974 <._ZN10NonTrivialC1ERKS_> ; |               NonTrivial::NonTrivial(const NonTrivial&) / copy ctor
+    100008d8:   4f ff fb 82     crmove  4*cr7+so,4*cr7+so                  ;
+    100008dc:   38 1f 00 74     addi    r0,r31,116                         ; |
+    100008e0:   7c 03 03 78     mr      r3,r0                              ; | f2 arg 0 (ptr to copy of struct NonTrivial), via ptr as non-trivial
+    100008e4:   4b ff ff 6d     bl      10000850 <.f2>                     ; call f2(struct NonTrivial)
+    100008e8:   81 3f 00 70     lwz     r9,112(r31)                        ;
+    100008ec:   38 09 ff f4     addi    r0,r9,-12                          ;
+    100008f0:   90 1f 00 70     stw     r0,112(r31)                        ;
+    100008f4:   e8 21 00 00     ld      r1,0(r1)                           ;
+    100008f8:   e8 01 00 10     ld      r0,16(r1)                          ;
+    100008fc:   7c 08 03 a6     mtlr    r0                                 ;
+    10000900:   eb e1 ff f8     ld      r31,-8(r1)                         ;
+    10000904:   4e 80 00 20     blr                                        ;
+    10000908:   00 00 00 00     .long 0x0                                  ;
+    1000090c:   00 09 00 01     .long 0x90001                              ;
+    10000910:   80 01 00 01     lwz     r0,1(r1)                           ;
+
+  ; ... snip, removed code of ctor and copy ctor ...
+
+
+
 ; vim: ft=asm
 
--- a/doc/disas_examples/sparc.sparc.disas	Mon Mar 21 18:11:38 2022 +0100
+++ b/doc/disas_examples/sparc.sparc.disas	Wed Mar 23 15:24:31 2022 +0100
@@ -1000,5 +1000,86 @@
 
 
 
+; ---------- C++ trivial and non-trivial aggrs passed to C funcs ---------->
+;
+; struct Trivial { int a; };
+; struct NonTrivial { int a; NonTrivial() : a(0) {} NonTrivial(const NonTrivial& rhs) : a(rhs.a) { } };
+;
+; extern "C" {
+; 
+;     void f1(struct Trivial s)    { }
+;     void f2(struct NonTrivial s) { }
+;
+;     void f()
+;     {
+;         struct Trivial t;
+;         struct NonTrivial n;
+;         int a=1;
+;         a += 123;
+;         f1(t);
+;         a -= 123;
+;         f2(n);
+;         a -= 12;
+;     }
+; }
+
+
+
+; output from debian-4.0_r3-sparc w/ gcc 4.1.2
+
+00010484 <f1>:
+   10484:       9d e3 bf 98     save  %sp, -104, %sp
+   10488:       81 e8 00 00     restore
+   1048c:       81 c3 e0 08     retl
+   10490:       01 00 00 00     nop
+
+00010494 <f2>:
+   10494:       9d e3 bf 98     save  %sp, -104, %sp
+   10498:       f0 27 a0 44     st  %i0, [ %fp + 0x44 ]
+   1049c:       81 e8 00 00     restore
+   104a0:       81 c3 e0 08     retl
+   104a4:       01 00 00 00     nop
+
+000104a8 <f>:
+   104a8:       9d e3 bf 80     save  %sp, -128, %sp                 ;
+   104ac:       82 07 bf e8     add  %fp, -24, %g1                   ;
+   104b0:       90 10 00 01     mov  %g1, %o0                        ;
+   104b4:       40 00 00 26     call  1054c <_ZN10NonTrivialC1Ev>    ; NonTrivial::NonTrivial() / ctor
+   104b8:       01 00 00 00     nop                                  ;
+   104bc:       82 10 20 01     mov  1, %g1     ! 1 <_init-0x102cb>  ;
+   104c0:       c2 27 bf f4     st  %g1, [ %fp + -12 ]               ;
+   104c4:       c2 07 bf f4     ld  [ %fp + -12 ], %g1               ;
+   104c8:       82 00 60 7b     add  %g1, 0x7b, %g1                  ;
+   104cc:       c2 27 bf f4     st  %g1, [ %fp + -12 ]               ;
+   104d0:       c2 07 bf ec     ld  [ %fp + -20 ], %g1               ;
+   104d4:       c2 27 bf e4     st  %g1, [ %fp + -28 ]               ;
+   104d8:       82 07 bf e4     add  %fp, -28, %g1                   ;
+   104dc:       90 10 00 01     mov  %g1, %o0                        ;
+   104e0:       7f ff ff e9     call  10484 <f1>                     ; call f1(struct Trivial)
+   104e4:       01 00 00 00     nop                                  ;
+   104e8:       c2 07 bf f4     ld  [ %fp + -12 ], %g1               ;
+   104ec:       82 00 7f 85     add  %g1, -123, %g1                  ;
+   104f0:       c2 27 bf f4     st  %g1, [ %fp + -12 ]               ;
+   104f4:       82 07 bf f0     add  %fp, -16, %g1                   ;
+   104f8:       84 07 bf e8     add  %fp, -24, %g2                   ;
+   104fc:       90 10 00 01     mov  %g1, %o0                        ; |               ptr to dest of copy of n
+   10500:       92 10 00 02     mov  %g2, %o1                        ; | copy n        ptr to n
+   10504:       40 00 00 19     call  10568 <_ZN10NonTrivialC1ERKS_> ; |               NonTrivial::NonTrivial(const NonTrivial&) / copy ctor
+   10508:       01 00 00 00     nop                                  ;
+   1050c:       82 07 bf f0     add  %fp, -16, %g1                   ; |
+   10510:       90 10 00 01     mov  %g1, %o0                        ; | f2 arg 0 (ptr to copy of struct NonTrivial), via ptr as non-trivial
+   10514:       7f ff ff e0     call  10494 <f2>                     ; call f2(struct NonTrivial)
+   10518:       01 00 00 00     nop                                  ;
+   1051c:       c2 07 bf f4     ld  [ %fp + -12 ], %g1               ;
+   10520:       82 00 7f f4     add  %g1, -12, %g1                   ;
+   10524:       c2 27 bf f4     st  %g1, [ %fp + -12 ]               ;
+   10528:       81 e8 00 00     restore                              ;
+   1052c:       81 c3 e0 08     retl                                 ;
+   10530:       01 00 00 00     nop                                  ;
+
+  ; ... snip, removed code of ctor and copy ctor ...
+
+
+
 ; vim: ft=asm
 
--- a/doc/disas_examples/sparc64.sparc64.disas	Mon Mar 21 18:11:38 2022 +0100
+++ b/doc/disas_examples/sparc64.sparc64.disas	Wed Mar 23 15:24:31 2022 +0100
@@ -1609,5 +1609,118 @@
 
 
 
+; ---------- C++ trivial and non-trivial aggrs passed to C funcs ---------->
+;
+; struct Trivial { int a; };
+; struct NonTrivial { int a; NonTrivial() : a(0) {} NonTrivial(const NonTrivial& rhs) : a(rhs.a) { } };
+;
+; extern "C" {
+; 
+;     void f1(struct Trivial s)    { }
+;     void f2(struct NonTrivial s) { }
+;
+;     void f()
+;     {
+;         struct Trivial t;
+;         struct NonTrivial n;
+;         int a=1;
+;         a += 123;
+;         f1(t);
+;         a -= 123;
+;         f2(n);
+;         a -= 12;
+;     }
+; }
+
+
+
+; output from openbsd-6.0-sparc64 w/ gcc 4.2.1
+
+0000000000000d20 <f1>:
+ d20:   9d e3 bf 30     save  %sp, -208, %sp
+ d24:   82 10 00 18     mov  %i0, %g1
+ d28:   83 38 70 20     srax  %g1, 0x20, %g1
+ d2c:   c4 07 a8 7f     ld  [ %fp + 0x87f ], %g2
+ d30:   84 08 a0 00     and  %g2, 0, %g2
+ d34:   82 10 80 01     or  %g2, %g1, %g1
+ d38:   c2 27 a8 7f     st  %g1, [ %fp + 0x87f ]
+ d3c:   81 cf e0 08     rett  %i7 + 8
+ d40:   01 00 00 00     nop
+
+0000000000000d44 <f2>:
+ d44:   9d e3 bf 30     save  %sp, -208, %sp
+ d48:   f0 77 a8 7f     stx  %i0, [ %fp + 0x87f ]
+ d4c:   81 cf e0 08     rett  %i7 + 8
+ d50:   01 00 00 00     nop
+ d54:   ae 03 c0 17     add  %o7, %l7, %l7
+ d58:   81 c3 e0 08     retl
+ d5c:   01 00 00 00     nop
+
+0000000000000d60 <f>:
+ d60:   9d e3 bf 20     save  %sp, -224, %sp                      ;
+ d64:   2f 00 0c 00     sethi  %hi(0x300000), %l7                 ;
+ d68:   ae 05 e2 ac     add  %l7, 0x2ac, %l7                      ;
+ d6c:   7f ff ff fa     call  d54 <f2+0x10>                       ;
+ d70:   01 00 00 00     nop                                       ;
+ d74:   03 00 00 00     sethi  %hi(0), %g1                        ;
+ d78:   82 10 60 48     or  %g1, 0x48, %g1                        ;
+ d7c:   c2 5d c0 01     ldx  [ %l7 + %g1 ], %g1                   ;
+ d80:   c4 58 40 00     ldx  [ %g1 ], %g2                         ;
+ d84:   c4 77 a7 e7     stx  %g2, [ %fp + 0x7e7 ]                 ;
+ d88:   84 10 20 00     clr  %g2                                  ;
+ d8c:   82 07 a7 df     add  %fp, 0x7df, %g1                      ;
+ d90:   90 10 00 01     mov  %g1, %o0                             ;
+ d94:   40 14 01 13     call  5011e0 <_ZN10NonTrivialC1Ev@plt>    ; NonTrivial::NonTrivial() / ctor
+ d98:   01 00 00 00     nop                                       ;
+ d9c:   82 10 20 01     mov  1, %g1                               ;
+ da0:   c2 27 a7 db     st  %g1, [ %fp + 0x7db ]                  ;
+ da4:   c2 07 a7 db     ld  [ %fp + 0x7db ], %g1                  ;
+ da8:   82 00 60 7b     add  %g1, 0x7b, %g1                       ;
+ dac:   c2 27 a7 db     st  %g1, [ %fp + 0x7db ]                  ;
+ db0:   c2 07 a7 e3     ld  [ %fp + 0x7e3 ], %g1                  ;
+ db4:   83 30 60 00     srl  %g1, 0, %g1                          ;
+ db8:   83 28 70 20     sllx  %g1, 0x20, %g1                      ;
+ dbc:   90 10 00 01     mov  %g1, %o0                             ;
+ dc0:   40 14 01 30     call  501280 <f1@plt>                     ; call f1(struct Trivial)
+ dc4:   01 00 00 00     nop                                       ;
+ dc8:   c2 07 a7 db     ld  [ %fp + 0x7db ], %g1                  ;
+ dcc:   82 00 7f 85     add  %g1, -123, %g1                       ;
+ dd0:   c2 27 a7 db     st  %g1, [ %fp + 0x7db ]                  ;
+ dd4:   82 07 a7 d7     add  %fp, 0x7d7, %g1                      ;
+ dd8:   84 07 a7 df     add  %fp, 0x7df, %g2                      ;
+ ddc:   90 10 00 01     mov  %g1, %o0                             ; |               ptr to dest of copy of n
+ de0:   92 10 00 02     mov  %g2, %o1                             ; | copy n        ptr to n
+ de4:   40 14 00 e7     call  501180 <_ZN10NonTrivialC1ERKS_@plt> ; |               NonTrivial::NonTrivial(const NonTrivial&) / copy ctor
+ de8:   01 00 00 00     nop                                       ;
+ dec:   82 07 a7 d7     add  %fp, 0x7d7, %g1                      ; |
+ df0:   90 10 00 01     mov  %g1, %o0                             ; | f2 arg 0 (ptr to copy of struct NonTrivial), via ptr as non-trivial
+ df4:   40 14 01 03     call  501200 <f2@plt>                     ; call f2(struct NonTrivial)
+ df8:   01 00 00 00     nop                                       ;
+ dfc:   c2 07 a7 db     ld  [ %fp + 0x7db ], %g1                  ;
+ e00:   82 00 7f f4     add  %g1, -12, %g1                        ;
+ e04:   c2 27 a7 db     st  %g1, [ %fp + 0x7db ]                  ;
+ e08:   03 00 00 00     sethi  %hi(0), %g1                        ;
+ e0c:   82 10 60 48     or  %g1, 0x48, %g1                        ;
+ e10:   c2 5d c0 01     ldx  [ %l7 + %g1 ], %g1                   ;
+ e14:   c6 5f a7 e7     ldx  [ %fp + 0x7e7 ], %g3                 ;
+ e18:   c4 58 40 00     ldx  [ %g1 ], %g2                         ;
+ e1c:   86 18 c0 02     xor  %g3, %g2, %g3                        ;
+ e20:   84 10 20 00     clr  %g2                                  ;
+ e24:   82 10 00 03     mov  %g3, %g1                             ;
+ e28:   02 c8 40 08     brz  %g1, e48 <f+0xe8>                    ;
+ e2c:   01 00 00 00     nop                                       ;
+ e30:   03 00 00 00     sethi  %hi(0), %g1                        ;
+ e34:   82 10 60 40     or  %g1, 0x40, %g1                        ;
+ e38:   c2 5d c0 01     ldx  [ %l7 + %g1 ], %g1                   ;
+ e3c:   90 10 00 01     mov  %g1, %o0                             ;
+ e40:   40 14 00 d8     call  5011a0 <__stack_smash_handler@plt>  ;
+ e44:   01 00 00 00     nop                                       ;
+ e48:   81 cf e0 08     rett  %i7 + 8                             ;
+ e4c:   01 00 00 00     nop                                       ;
+
+  ; ... snip, removed code of ctor and copy ctor ...
+
+
+
 ; vim: ft=asm
 
--- a/doc/disas_examples/x86.cdecl.disas	Mon Mar 21 18:11:38 2022 +0100
+++ b/doc/disas_examples/x86.cdecl.disas	Wed Mar 23 15:24:31 2022 +0100
@@ -633,5 +633,87 @@
 
 
 
+; ---------- C++ trivial and non-trivial aggrs passed to C funcs ---------->
+;
+; struct Trivial { int a; };
+; struct NonTrivial { int a; NonTrivial() : a(0) {} NonTrivial(const NonTrivial& rhs) : a(rhs.a) { } };
+;
+; extern "C" {
+; 
+;     void f1(struct Trivial s)    { }
+;     void f2(struct NonTrivial s) { }
+;
+;     void f()
+;     {
+;         struct Trivial t;
+;         struct NonTrivial n;
+;         int a=1;
+;         a += 123;
+;         f1(t);
+;         a -= 123;
+;         f2(n);
+;         a -= 12;
+;     }
+; }
+
+
+
+; output from openbsd-4.0-x86 w/ gcc 3.3.5 (propolice)
+
+1c0005a0 <f1>:
+1c0005a0:       55                      push   %ebp
+1c0005a1:       89 e5                   mov    %esp,%ebp
+1c0005a3:       c9                      leave
+1c0005a4:       c3                      ret
+1c0005a5:       90                      nop
+
+1c0005a6 <f2>:
+1c0005a6:       55                      push   %ebp
+1c0005a7:       89 e5                   mov    %esp,%ebp
+1c0005a9:       c9                      leave
+1c0005aa:       c3                      ret
+1c0005ab:       90                      nop
+
+1c0005ac <f>:
+1c0005ac:       55                      push   %ebp                              ;
+1c0005ad:       89 e5                   mov    %esp,%ebp                         ;
+1c0005af:       83 ec 48                sub    $0x48,%esp                        ;
+1c0005b2:       83 ec 0c                sub    $0xc,%esp                         ;
+1c0005b5:       8d 45 d8                lea    0xffffffd8(%ebp),%eax             ;
+1c0005b8:       50                      push   %eax                              ;
+1c0005b9:       e8 8e 00 00 00          call   1c00064c <_ZN10NonTrivialC1Ev>    ; NonTrivial::NonTrivial() / ctor
+1c0005be:       83 c4 10                add    $0x10,%esp                        ;
+1c0005c1:       c7 45 d4 01 00 00 00    movl   $0x1,0xffffffd4(%ebp)             ;
+1c0005c8:       8d 45 d4                lea    0xffffffd4(%ebp),%eax             ;
+1c0005cb:       83 00 7b                addl   $0x7b,(%eax)                      ;
+1c0005ce:       83 ec 0c                sub    $0xc,%esp                         ;
+1c0005d1:       8b 45 f4                mov    0xfffffff4(%ebp),%eax             ;
+1c0005d4:       50                      push   %eax                              ;
+1c0005d5:       e8 c6 ff ff ff          call   1c0005a0 <f1>                     ; call f1(struct Trivial)
+1c0005da:       83 c4 10                add    $0x10,%esp                        ;
+1c0005dd:       8d 45 d4                lea    0xffffffd4(%ebp),%eax             ;
+1c0005e0:       83 28 7b                subl   $0x7b,(%eax)                      ;
+1c0005e3:       83 ec 0c                sub    $0xc,%esp                         ;
+1c0005e6:       83 ec 0c                sub    $0xc,%esp                         ;
+1c0005e9:       8d 45 d8                lea    0xffffffd8(%ebp),%eax             ; |               |
+1c0005ec:       50                      push   %eax                              ; |               / ptr to n
+1c0005ed:       8d 45 b8                lea    0xffffffb8(%ebp),%eax             ; |               \
+1c0005f0:       50                      push   %eax                              ; | copy n        | ptr to dest of copy of n
+1c0005f1:       e8 64 00 00 00          call   1c00065a <_ZN10NonTrivialC1ERKS_> ; |               NonTrivial::NonTrivial(const NonTrivial&) / copy ctor
+1c0005f6:       83 c4 14                add    $0x14,%esp                        ;
+1c0005f9:       8d 45 b8                lea    0xffffffb8(%ebp),%eax             ; |
+1c0005fc:       50                      push   %eax                              ; | f2 arg 0 (ptr to copy of struct NonTrivial), via ptr as non-trivial
+1c0005fd:       e8 a4 ff ff ff          call   1c0005a6 <f2>                     ; call f2(struct NonTrivial)
+1c000602:       83 c4 10                add    $0x10,%esp                        ;
+1c000605:       8d 45 d4                lea    0xffffffd4(%ebp),%eax             ;
+1c000608:       83 28 0c                subl   $0xc,(%eax)                       ;
+1c00060b:       c9                      leave                                    ;
+1c00060c:       c3                      ret                                      ;
+1c00060d:       90                      nop                                      ;
+
+  ; ... snip, removed code of ctor and copy ctor ...
+
+
+
 ; vim: ft=asm
 
--- a/doc/disas_examples/x86.fastcall_gnu.disas	Mon Mar 21 18:11:38 2022 +0100
+++ b/doc/disas_examples/x86.fastcall_gnu.disas	Wed Mar 23 15:24:31 2022 +0100
@@ -279,5 +279,95 @@
 
 
 
+; ---------- C++ trivial and non-trivial aggrs passed to C funcs ---------->
+;
+; struct Trivial { int a; };
+; struct NonTrivial {
+;         int a;
+;         __attribute__((fastcall)) NonTrivial() : a(0) {}
+;         __attribute__((fastcall)) NonTrivial(const NonTrivial& rhs) : a(rhs.a) { }
+; };
+;
+; extern "C" {
+;
+;     void __attribute__((fastcall)) f1(struct Trivial s)    { }
+;     void __attribute__((fastcall)) f2(struct NonTrivial s) { }
+;
+;     void __attribute__((fastcall)) f()
+;     {
+;         struct Trivial t;
+;         struct NonTrivial n;
+;         int a=1;
+;         a += 123;
+;         f1(t);
+;         a -= 123;
+;         f2(n);
+;         a -= 12;
+;     }
+; }
+
+
+
+; output from alpine_linux-3.11.3-x86 w/ gcc 9.2.0
+
+00001215 <f1>:
+    1215:       55                      push   %ebp
+    1216:       89 e5                   mov    %esp,%ebp
+    1218:       e8 f0 ff ff ff          call   120d <__x86.get_pc_thunk.ax>
+    121d:       05 af 2d 00 00          add    $0x2daf,%eax
+    1222:       90                      nop
+    1223:       5d                      pop    %ebp
+    1224:       c2 04 00                ret    $0x4
+
+00001227 <f2>:
+    1227:       55                      push   %ebp
+    1228:       89 e5                   mov    %esp,%ebp
+    122a:       83 ec 04                sub    $0x4,%esp
+    122d:       e8 db ff ff ff          call   120d <__x86.get_pc_thunk.ax>
+    1232:       05 9a 2d 00 00          add    $0x2d9a,%eax
+    1237:       89 4d fc                mov    %ecx,-0x4(%ebp)
+    123a:       90                      nop
+    123b:       c9                      leave
+    123c:       c3                      ret
+
+0000123d <f>:
+    123d:       55                      push   %ebp                          ;
+    123e:       89 e5                   mov    %esp,%ebp                     ;
+    1240:       83 ec 28                sub    $0x28,%esp                    ;
+    1243:       e8 c5 ff ff ff          call   120d <__x86.get_pc_thunk.ax>  ;
+    1248:       05 84 2d 00 00          add    $0x2d84,%eax                  ;
+    124d:       65 a1 14 00 00 00       mov    %gs:0x14,%eax                 ;
+    1253:       89 45 f4                mov    %eax,-0xc(%ebp)               ;
+    1256:       31 c0                   xor    %eax,%eax                     ;
+    1258:       8d 45 e8                lea    -0x18(%ebp),%eax              ;
+    125b:       89 c1                   mov    %eax,%ecx                     ;
+    125d:       e8 60 00 00 00          call   12c2 <_ZN10NonTrivialC1Ev>    ; NonTrivial::NonTrivial() / ctor
+    1262:       c7 45 f0 01 00 00 00    movl   $0x1,-0x10(%ebp)              ;
+    1269:       83 45 f0 7b             addl   $0x7b,-0x10(%ebp)             ;
+    126d:       83 ec 0c                sub    $0xc,%esp                     ;
+    1270:       ff 75 e4                pushl  -0x1c(%ebp)                   ;
+    1273:       e8 9d ff ff ff          call   1215 <f1>                     ; call f1(struct Trivial)
+    1278:       83 c4 0c                add    $0xc,%esp                     ;
+    127b:       83 6d f0 7b             subl   $0x7b,-0x10(%ebp)             ;
+    127f:       8d 55 e8                lea    -0x18(%ebp),%edx              ; |               ptr to n
+    1282:       8d 45 ec                lea    -0x14(%ebp),%eax              ; |               |
+    1285:       89 c1                   mov    %eax,%ecx                     ; | copy n        | ptr to dest of copy of n
+    1287:       e8 56 00 00 00          call   12e2 <_ZN10NonTrivialC1ERKS_> ; /               NonTrivial::NonTrivial(const NonTrivial&) / copy ctor
+    128c:       8d 45 ec                lea    -0x14(%ebp),%eax              ; \
+    128f:       89 c1                   mov    %eax,%ecx                     ; | f2 arg 0 (ptr to copy of struct NonTrivial), via ptr as non-trivial
+    1291:       e8 91 ff ff ff          call   1227 <f2>                     ; call f2(struct NonTrivial)
+    1296:       83 6d f0 0c             subl   $0xc,-0x10(%ebp)              ;
+    129a:       90                      nop                                  ;
+    129b:       8b 45 f4                mov    -0xc(%ebp),%eax               ;
+    129e:       65 33 05 14 00 00 00    xor    %gs:0x14,%eax                 ;
+    12a5:       74 05                   je     12ac <f+0x6f>                 ;
+    12a7:       e8 59 00 00 00          call   1305 <__stack_chk_fail_local> ;
+    12ac:       c9                      leave                                ;
+    12ad:       c3                      ret                                  ;
+
+  ; ... snip, removed code of ctor and copy ctor ...
+
+
+
 ; vim: ft=asm
 
--- a/doc/disas_examples/x86.stdcall.disas	Mon Mar 21 18:11:38 2022 +0100
+++ b/doc/disas_examples/x86.stdcall.disas	Wed Mar 23 15:24:31 2022 +0100
@@ -166,5 +166,100 @@
 
 
 
+; ---------- C++ trivial and non-trivial aggrs passed to C funcs ---------->
+;
+; struct Trivial { int a; };
+; struct NonTrivial {
+;         int a;
+;         __attribute__((stdcall)) NonTrivial() : a(0) {}
+;         __attribute__((stdcall)) NonTrivial(const NonTrivial& rhs) : a(rhs.a) { }
+; };
+;
+; extern "C" {
+;
+;     void __attribute__((stdcall)) f1(struct Trivial s)    { }
+;     void __attribute__((stdcall)) f2(struct NonTrivial s) { }
+;
+;     void __attribute__((stdcall)) f()
+;     {
+;         struct Trivial t;
+;         struct NonTrivial n;
+;         int a=1;
+;         a += 123;
+;         f1(t);
+;         a -= 123;
+;         f2(n);
+;         a -= 12;
+;     }
+; }
+
+
+
+; output from alpine_linux-3.11.3-x86 w/ gcc 9.2.0
+
+00001215 <f1>:
+    1215:       55                      push   %ebp
+    1216:       89 e5                   mov    %esp,%ebp
+    1218:       e8 f0 ff ff ff          call   120d <__x86.get_pc_thunk.ax>
+    121d:       05 af 2d 00 00          add    $0x2daf,%eax
+    1222:       90                      nop
+    1223:       5d                      pop    %ebp
+    1224:       c2 04 00                ret    $0x4
+
+00001227 <f2>:
+    1227:       55                      push   %ebp
+    1228:       89 e5                   mov    %esp,%ebp
+    122a:       e8 de ff ff ff          call   120d <__x86.get_pc_thunk.ax>
+    122f:       05 9d 2d 00 00          add    $0x2d9d,%eax
+    1234:       90                      nop
+    1235:       5d                      pop    %ebp
+    1236:       c2 04 00                ret    $0x4
+
+00001239 <f>:
+    1239:       55                      push   %ebp                          ;
+    123a:       89 e5                   mov    %esp,%ebp                     ;
+    123c:       83 ec 28                sub    $0x28,%esp                    ;
+    123f:       e8 c9 ff ff ff          call   120d <__x86.get_pc_thunk.ax>  ;
+    1244:       05 88 2d 00 00          add    $0x2d88,%eax                  ;
+    1249:       65 a1 14 00 00 00       mov    %gs:0x14,%eax                 ;
+    124f:       89 45 f4                mov    %eax,-0xc(%ebp)               ;
+    1252:       31 c0                   xor    %eax,%eax                     ;
+    1254:       83 ec 0c                sub    $0xc,%esp                     ;
+    1257:       8d 45 e8                lea    -0x18(%ebp),%eax              ;
+    125a:       50                      push   %eax                          ;
+    125b:       e8 6e 00 00 00          call   12ce <_ZN10NonTrivialC1Ev>    ; NonTrivial::NonTrivial() / ctor
+    1260:       83 c4 0c                add    $0xc,%esp                     ;
+    1263:       c7 45 f0 01 00 00 00    movl   $0x1,-0x10(%ebp)              ;
+    126a:       83 45 f0 7b             addl   $0x7b,-0x10(%ebp)             ;
+    126e:       83 ec 0c                sub    $0xc,%esp                     ;
+    1271:       ff 75 e4                pushl  -0x1c(%ebp)                   ;
+    1274:       e8 9c ff ff ff          call   1215 <f1>                     ; call f1(struct Trivial)
+    1279:       83 c4 0c                add    $0xc,%esp                     ;
+    127c:       83 6d f0 7b             subl   $0x7b,-0x10(%ebp)             ;
+    1280:       83 ec 08                sub    $0x8,%esp                     ;
+    1283:       8d 45 e8                lea    -0x18(%ebp),%eax              ; |               | ptr to n
+    1286:       50                      push   %eax                          ; |               /
+    1287:       8d 45 ec                lea    -0x14(%ebp),%eax              ; |               \
+    128a:       50                      push   %eax                          ; | copy n        | ptr to dest of copy of n
+    128b:       e8 5a 00 00 00          call   12ea <_ZN10NonTrivialC1ERKS_> ; |               NonTrivial::NonTrivial(const NonTrivial&) / copy ctor
+    1290:       83 c4 08                add    $0x8,%esp                     ;
+    1293:       83 ec 0c                sub    $0xc,%esp                     ;
+    1296:       8d 45 ec                lea    -0x14(%ebp),%eax              ; |
+    1299:       50                      push   %eax                          ; | f2 arg 0 (ptr to copy of struct NonTrivial), via ptr as non-trivial
+    129a:       e8 88 ff ff ff          call   1227 <f2>                     ; call f2(struct NonTrivial)
+    129f:       83 c4 0c                add    $0xc,%esp                     ;
+    12a2:       83 6d f0 0c             subl   $0xc,-0x10(%ebp)              ;
+    12a6:       90                      nop                                  ;
+    12a7:       8b 45 f4                mov    -0xc(%ebp),%eax               ;
+    12aa:       65 33 05 14 00 00 00    xor    %gs:0x14,%eax                 ;
+    12b1:       74 05                   je     12b8 <f+0x7f>                 ;
+    12b3:       e8 4e 00 00 00          call   1306 <__stack_chk_fail_local> ;
+    12b8:       c9                      leave                                ;
+    12b9:       c3                      ret                                  ;
+
+  ; ... snip, removed code of ctor and copy ctor ...
+
+
+
 ; vim: ft=asm