changeset 474:c9e19249ecd3

- doc: sparc64 disas examples and doc additions regarding aggregates
author Tassilo Philipp
date Wed, 16 Feb 2022 19:26:21 +0100
parents ead041d93e36
children 5be9f5ccdd35
files doc/disas_examples/sparc64.sparc64.disas doc/manual/callconvs/callconv_sparc64.tex doc/manual/manual_literature.tex
diffstat 3 files changed, 862 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/doc/disas_examples/sparc64.sparc64.disas	Wed Feb 16 16:44:11 2022 +0100
+++ b/doc/disas_examples/sparc64.sparc64.disas	Wed Feb 16 19:26:21 2022 +0100
@@ -1,16 +1,16 @@
 ; #include <stdlib.h>
-; 
+;
 ; void leaf_call(int b, int c, int d, int e, int f, int g, int h)
 ; {
 ; }
-; 
+;
 ; void nonleaf_call(int a, int b, int c, int d, int e, int f, int g, int h)
 ; {
 ;     /* use some local data */
 ;     *(char*)alloca(220) = 'L';
 ;     leaf_call(b, c, d, e, f, g, h);
 ; }
-; 
+;
 ; int main()
 ; {
 ;     nonleaf_call(0, 1, 2, 3, 4, 5, 6, 7);
@@ -300,7 +300,7 @@
 
 
 
-; output from openbsd-7.1-sparc64 w/ gcc 4.2.1
+; output from openbsd-6.0-sparc64 w/ gcc 4.2.1
 
 0000000000000000 <leaf_call>:
    0:   9d e3 bf 30     save  %sp, -208, %sp
@@ -554,5 +554,796 @@
  164:   81 cf e0 08     rett  %i7 + 8                   ; | epilog
  168:   01 00 00 00     nop                             ; |            branch delay slot
 
+
+
+; ---------- 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 openbsd-6.0-sparc64 w/ gcc 4.2.1
+
+0000000000000000 <leaf_call>:
+   0:   9d e3 bf 30     save  %sp, -208, %sp
+   4:   82 10 00 18     mov  %i0, %g1
+   8:   84 10 00 19     mov  %i1, %g2
+   c:   86 10 00 1a     mov  %i2, %g3
+  10:   88 10 00 1b     mov  %i3, %g4
+  14:   8a 10 00 1c     mov  %i4, %g5
+  18:   c2 27 a8 7f     st  %g1, [ %fp + 0x87f ]
+  1c:   c4 27 a8 87     st  %g2, [ %fp + 0x887 ]
+  20:   c6 27 a8 8f     st  %g3, [ %fp + 0x88f ]
+  24:   c8 27 a8 97     st  %g4, [ %fp + 0x897 ]
+  28:   ca 77 a8 9f     stx  %g5, [ %fp + 0x89f ]
+  2c:   fa 77 a8 a7     stx  %i5, [ %fp + 0x8a7 ]
+  30:   81 cf e0 08     rett  %i7 + 8
+  34:   01 00 00 00     nop
+  38:   ae 03 c0 17     add  %o7, %l7, %l7
+  3c:   81 c3 e0 08     retl
+  40:   01 00 00 00     nop
+
+0000000000000044 <nonleaf_call>:
+  44:   9d e3 be c0     save  %sp, -320, %sp
+  48:   2f 00 00 00     sethi  %hi(0), %l7
+  4c:   ae 05 e0 00     add  %l7, 0, %l7        ! 0 <leaf_call>
+  50:   7f ff ff fa     call  38 <leaf_call+0x38>
+  54:   01 00 00 00     nop
+  58:   84 10 00 18     mov  %i0, %g2
+  5c:   86 10 00 19     mov  %i1, %g3
+  60:   88 10 00 1a     mov  %i2, %g4
+  64:   8a 10 00 1b     mov  %i3, %g5
+  68:   9a 10 00 1c     mov  %i4, %o5
+  6c:   82 10 00 1d     mov  %i5, %g1
+  70:   c2 77 a8 a7     stx  %g1, [ %fp + 0x8a7 ]
+  74:   c4 27 a8 7f     st  %g2, [ %fp + 0x87f ]
+  78:   c6 27 a8 87     st  %g3, [ %fp + 0x887 ]
+  7c:   c8 27 a8 8f     st  %g4, [ %fp + 0x88f ]
+  80:   ca 27 a8 97     st  %g5, [ %fp + 0x897 ]
+  84:   da 27 a8 9f     st  %o5, [ %fp + 0x89f ]
+  88:   03 00 00 00     sethi  %hi(0), %g1
+  8c:   82 10 60 00     mov  %g1, %g1   ! 0 <leaf_call>
+  90:   c2 5d c0 01     ldx  [ %l7 + %g1 ], %g1
+  94:   c4 58 40 00     ldx  [ %g1 ], %g2
+  98:   c4 77 a7 e7     stx  %g2, [ %fp + 0x7e7 ]
+  9c:   84 10 20 00     clr  %g2
+  a0:   c0 77 a7 7f     clrx  [ %fp + 0x77f ]
+  a4:   c0 77 a7 87     clrx  [ %fp + 0x787 ]
+  a8:   c0 77 a7 8f     clrx  [ %fp + 0x78f ]
+  ac:   c0 77 a7 97     clrx  [ %fp + 0x797 ]
+  b0:   c0 77 a7 9f     clrx  [ %fp + 0x79f ]
+  b4:   c0 77 a7 a7     clrx  [ %fp + 0x7a7 ]
+  b8:   c0 77 a7 af     clrx  [ %fp + 0x7af ]
+  bc:   c0 77 a7 b7     clrx  [ %fp + 0x7b7 ]
+  c0:   c0 77 a7 bf     clrx  [ %fp + 0x7bf ]
+  c4:   c0 77 a7 c7     clrx  [ %fp + 0x7c7 ]
+  c8:   c0 77 a7 cf     clrx  [ %fp + 0x7cf ]
+  cc:   c0 77 a7 d7     clrx  [ %fp + 0x7d7 ]
+  d0:   c0 27 a7 df     clr  [ %fp + 0x7df ]
+  d4:   82 10 20 4c     mov  0x4c, %g1
+  d8:   c2 2f a7 7f     stb  %g1, [ %fp + 0x77f ]
+  dc:   c2 07 a8 87     ld  [ %fp + 0x887 ], %g1
+  e0:   85 38 60 00     sra  %g1, 0, %g2
+  e4:   c2 07 a8 8f     ld  [ %fp + 0x88f ], %g1
+  e8:   87 38 60 00     sra  %g1, 0, %g3
+  ec:   c2 07 a8 97     ld  [ %fp + 0x897 ], %g1
+  f0:   89 38 60 00     sra  %g1, 0, %g4
+  f4:   c2 07 a8 9f     ld  [ %fp + 0x89f ], %g1
+  f8:   8b 38 60 00     sra  %g1, 0, %g5
+  fc:   da 5f a8 a7     ldx  [ %fp + 0x8a7 ], %o5
+ 100:   de 5f a8 af     ldx  [ %fp + 0x8af ], %o7
+ 104:   c2 07 a8 bb     ld  [ %fp + 0x8bb ], %g1
+ 108:   83 38 60 00     sra  %g1, 0, %g1
+ 10c:   c2 73 a8 af     stx  %g1, [ %sp + 0x8af ]
+ 110:   c2 07 a8 c3     ld  [ %fp + 0x8c3 ], %g1
+ 114:   83 38 60 00     sra  %g1, 0, %g1
+ 118:   c2 73 a8 b7     stx  %g1, [ %sp + 0x8b7 ]
+ 11c:   90 10 00 02     mov  %g2, %o0
+ 120:   92 10 00 03     mov  %g3, %o1
+ 124:   94 10 00 04     mov  %g4, %o2
+ 128:   96 10 00 05     mov  %g5, %o3
+ 12c:   98 10 00 0d     mov  %o5, %o4
+ 130:   9a 10 00 0f     mov  %o7, %o5
+ 134:   40 00 00 00     call  134 <nonleaf_call+0xf0>
+ 138:   01 00 00 00     nop
+ 13c:   03 00 00 00     sethi  %hi(0), %g1
+ 140:   82 10 60 00     mov  %g1, %g1   ! 0 <leaf_call>
+ 144:   c2 5d c0 01     ldx  [ %l7 + %g1 ], %g1
+ 148:   c6 5f a7 e7     ldx  [ %fp + 0x7e7 ], %g3
+ 14c:   c4 58 40 00     ldx  [ %g1 ], %g2
+ 150:   86 18 c0 02     xor  %g3, %g2, %g3
+ 154:   84 10 20 00     clr  %g2
+ 158:   82 10 00 03     mov  %g3, %g1
+ 15c:   02 c8 40 08     brz  %g1, 17c <nonleaf_call+0x138>
+ 160:   01 00 00 00     nop
+ 164:   03 00 00 00     sethi  %hi(0), %g1
+ 168:   82 10 60 00     mov  %g1, %g1   ! 0 <leaf_call>
+ 16c:   c2 5d c0 01     ldx  [ %l7 + %g1 ], %g1
+ 170:   90 10 00 01     mov  %g1, %o0
+ 174:   40 00 00 00     call  174 <nonleaf_call+0x130>
+ 178:   01 00 00 00     nop
+ 17c:   81 cf e0 08     rett  %i7 + 8
+ 180:   01 00 00 00     nop
+
+0000000000000184 <main>:
+ 184:   9d e3 bf 00     save  %sp, -256, %sp            ; prolog
+ 188:   82 10 20 05     mov  5, %g1                     ; |                            \ i
+ 18c:   c2 27 a7 d7     st  %g1, [ %fp + 0x7d7 ]        ; |                            /
+ 190:   82 10 20 06     mov  6, %g1                     ; | put together local struct  \ j
+ 194:   c2 27 a7 db     st  %g1, [ %fp + 0x7db ]        ; |                            /
+ 198:   82 10 20 07     mov  7, %g1                     ; |                            \ l
+ 19c:   c2 77 a7 df     stx  %g1, [ %fp + 0x7df ]       ; /                            /
+ 1a0:   84 03 a8 7f     add  %sp, 0x87f, %g2            ; \
+ 1a4:   c2 5f a7 d7     ldx  [ %fp + 0x7d7 ], %g1       ; |
+ 1a8:   c2 70 a0 28     stx  %g1, [ %g2 + 0x28 ]        ; | (part of) arg 5, fetched from local area, "pushed" onto stack (entirely, so first 8 bytes (i,j) are already placed in reg save area)
+ 1ac:   c2 5f a7 df     ldx  [ %fp + 0x7df ], %g1       ; |
+ 1b0:   c2 70 a0 30     stx  %g1, [ %g2 + 0x30 ]        ; /
+ 1b4:   c6 58 a0 28     ldx  [ %g2 + 0x28 ], %g3        ; get first 8 bytes of struct -> g3
+ 1b8:   82 10 20 08     mov  8, %g1                     ; arg 6, ...
+ 1bc:   c2 70 a0 38     stx  %g1, [ %g2 + 0x38 ]        ; ... "pushed" onto stack
+ 1c0:   82 10 20 09     mov  9, %g1                     ; arg 7
+ 1c4:   c2 70 a0 40     stx  %g1, [ %g2 + 0x40 ]        ; ... "pushed" onto stack
+ 1c8:   90 10 20 00     clr  %o0                        ; arg 0
+ 1cc:   92 10 20 01     mov  1, %o1                     ; arg 1
+ 1d0:   94 10 20 02     mov  2, %o2                     ; arg 2
+ 1d4:   96 10 20 03     mov  3, %o3                     ; arg 3
+ 1d8:   98 10 20 04     mov  4, %o4                     ; arg 4
+ 1dc:   9a 10 00 03     mov  %g3, %o5                   ; (part of) arg 5 (first 8 bytes of struct)
+ 1e0:   40 00 00 00     call  1e0 <main+0x5c>           ; call nonleaf_call (objdump not from final link but .o)
+ 1e4:   01 00 00 00     nop                             ; branch delay slot
+ 1e8:   82 10 20 00     clr  %g1        ! 0 <leaf_call> ; \
+ 1ec:   83 38 60 00     sra  %g1, 0, %g1                ; / return value
+ 1f0:   b0 10 00 01     mov  %g1, %i0                   ; \
+ 1f4:   81 cf e0 08     rett  %i7 + 8                   ; | epilog
+ 1f8:   01 00 00 00     nop                             ; |            branch delay slot
+
+
+
+; ---------- 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 openbsd-6.0-sparc64 w/ gcc 4.2.1
+
+0000000000000000 <leaf_call>:
+   0:   9d e3 bf 30     save  %sp, -208, %sp
+   4:   82 10 00 18     mov  %i0, %g1
+   8:   84 10 00 19     mov  %i1, %g2
+   c:   91 a0 00 24     fmovs  %f4, %f8
+  10:   95 a0 00 46     fmovd  %f6, %f10
+  14:   86 10 00 1c     mov  %i4, %g3
+  18:   88 10 00 1d     mov  %i5, %g4
+  1c:   93 a0 00 30     fmovs  %f16, %f9
+  20:   99 a0 00 52     fmovd  %f18, %f12
+  24:   c2 27 a8 7f     st  %g1, [ %fp + 0x87f ]
+  28:   c4 77 a8 87     stx  %g2, [ %fp + 0x887 ]
+  2c:   d1 27 a8 8f     st  %f8, [ %fp + 0x88f ]
+  30:   d5 3f a8 97     std  %f10, [ %fp + 0x897 ]
+  34:   c6 77 a8 9f     stx  %g3, [ %fp + 0x89f ]
+  38:   c8 27 a8 a7     st  %g4, [ %fp + 0x8a7 ]
+  3c:   d3 27 a8 bf     st  %f9, [ %fp + 0x8bf ]
+  40:   d9 3f a8 c7     std  %f12, [ %fp + 0x8c7 ]
+  44:   81 cf e0 08     rett  %i7 + 8
+  48:   01 00 00 00     nop
+
+  4c:   ae 03 c0 17     add  %o7, %l7, %l7
+  50:   81 c3 e0 08     retl
+  54:   01 00 00 00     nop
+
+0000000000000058 <nonleaf_call>:
+  58:   9d e3 be 90     save  %sp, -368, %sp
+  5c:   2f 00 00 00     sethi  %hi(0), %l7
+  60:   ae 05 e0 00     add  %l7, 0, %l7        ! 0 <leaf_call>
+  64:   7f ff ff fa     call  4c <leaf_call+0x4c>
+  68:   01 00 00 00     nop
+  6c:   82 10 00 18     mov  %i0, %g1
+  70:   84 10 00 19     mov  %i1, %g2
+  74:   86 10 00 1a     mov  %i2, %g3
+  78:   95 a0 00 26     fmovs  %f6, %f10
+  7c:   88 10 00 1d     mov  %i5, %g4
+  80:   97 a0 00 32     fmovs  %f18, %f11
+  84:   99 a0 00 54     fmovd  %f20, %f12
+  88:   c2 27 a8 7f     st  %g1, [ %fp + 0x87f ]
+  8c:   c4 27 a8 87     st  %g2, [ %fp + 0x887 ]
+  90:   c6 77 a8 8f     stx  %g3, [ %fp + 0x88f ]
+  94:   d5 27 a8 97     st  %f10, [ %fp + 0x897 ]
+  98:   d1 3f a8 9f     std  %f8, [ %fp + 0x89f ]
+  9c:   c8 77 a8 a7     stx  %g4, [ %fp + 0x8a7 ]
+  a0:   d7 27 a8 c7     st  %f11, [ %fp + 0x8c7 ]
+  a4:   d9 3f a8 cf     std  %f12, [ %fp + 0x8cf ]
+  a8:   03 00 00 00     sethi  %hi(0), %g1
+  ac:   82 10 60 00     mov  %g1, %g1   ! 0 <leaf_call>
+  b0:   c2 5d c0 01     ldx  [ %l7 + %g1 ], %g1
+  b4:   c4 58 40 00     ldx  [ %g1 ], %g2
+  b8:   c4 77 a7 e7     stx  %g2, [ %fp + 0x7e7 ]
+  bc:   84 10 20 00     clr  %g2
+  c0:   c0 77 a7 7f     clrx  [ %fp + 0x77f ]
+  c4:   c0 77 a7 87     clrx  [ %fp + 0x787 ]
+  c8:   c0 77 a7 8f     clrx  [ %fp + 0x78f ]
+  cc:   c0 77 a7 97     clrx  [ %fp + 0x797 ]
+  d0:   c0 77 a7 9f     clrx  [ %fp + 0x79f ]
+  d4:   c0 77 a7 a7     clrx  [ %fp + 0x7a7 ]
+  d8:   c0 77 a7 af     clrx  [ %fp + 0x7af ]
+  dc:   c0 77 a7 b7     clrx  [ %fp + 0x7b7 ]
+  e0:   c0 77 a7 bf     clrx  [ %fp + 0x7bf ]
+  e4:   c0 77 a7 c7     clrx  [ %fp + 0x7c7 ]
+  e8:   c0 77 a7 cf     clrx  [ %fp + 0x7cf ]
+  ec:   c0 77 a7 d7     clrx  [ %fp + 0x7d7 ]
+  f0:   c0 27 a7 df     clr  [ %fp + 0x7df ]
+  f4:   82 10 20 4c     mov  0x4c, %g1
+  f8:   c2 2f a7 7f     stb  %g1, [ %fp + 0x77f ]
+  fc:   84 03 a8 7f     add  %sp, 0x87f, %g2
+ 100:   c2 07 a8 87     ld  [ %fp + 0x887 ], %g1
+ 104:   87 38 60 00     sra  %g1, 0, %g3
+ 108:   c8 5f a8 8f     ldx  [ %fp + 0x88f ], %g4
+ 10c:   d1 07 a8 97     ld  [ %fp + 0x897 ], %f8
+ 110:   d5 1f a8 9f     ldd  [ %fp + 0x89f ], %f10
+ 114:   ca 5f a8 a7     ldx  [ %fp + 0x8a7 ], %g5
+ 118:   c2 07 a8 b3     ld  [ %fp + 0x8b3 ], %g1
+ 11c:   9b 38 60 00     sra  %g1, 0, %o5
+ 120:   c2 07 a8 bb     ld  [ %fp + 0x8bb ], %g1
+ 124:   83 38 60 00     sra  %g1, 0, %g1
+ 128:   c2 70 a0 30     stx  %g1, [ %g2 + 0x30 ]
+ 12c:   c2 5f a8 bf     ldx  [ %fp + 0x8bf ], %g1
+ 130:   c2 70 a0 38     stx  %g1, [ %g2 + 0x38 ]
+ 134:   c2 07 a8 c7     ld  [ %fp + 0x8c7 ], %g1
+ 138:   c2 20 a0 40     st  %g1, [ %g2 + 0x40 ]
+ 13c:   d3 00 a0 40     ld  [ %g2 + 0x40 ], %f9
+ 140:   c2 5f a8 cf     ldx  [ %fp + 0x8cf ], %g1
+ 144:   c2 70 a0 48     stx  %g1, [ %g2 + 0x48 ]
+ 148:   c2 5f a8 d7     ldx  [ %fp + 0x8d7 ], %g1
+ 14c:   c2 70 a0 50     stx  %g1, [ %g2 + 0x50 ]
+ 150:   d9 18 a0 48     ldd  [ %g2 + 0x48 ], %f12
+ 154:   c2 07 a8 e3     ld  [ %fp + 0x8e3 ], %g1
+ 158:   83 38 60 00     sra  %g1, 0, %g1
+ 15c:   c2 70 a0 58     stx  %g1, [ %g2 + 0x58 ]
+ 160:   c2 07 a8 eb     ld  [ %fp + 0x8eb ], %g1
+ 164:   83 38 60 00     sra  %g1, 0, %g1
+ 168:   c2 70 a0 60     stx  %g1, [ %g2 + 0x60 ]
+ 16c:   90 10 00 03     mov  %g3, %o0
+ 170:   92 10 00 04     mov  %g4, %o1
+ 174:   89 a0 00 28     fmovs  %f8, %f4
+ 178:   8d a0 00 4a     fmovd  %f10, %f6
+ 17c:   98 10 00 05     mov  %g5, %o4
+ 180:   a1 a0 00 29     fmovs  %f9, %f16
+ 184:   a5 a0 00 4c     fmovd  %f12, %f18
+ 188:   40 00 00 00     call  188 <nonleaf_call+0x130>
+ 18c:   01 00 00 00     nop
+ 190:   03 00 00 00     sethi  %hi(0), %g1
+ 194:   82 10 60 00     mov  %g1, %g1   ! 0 <leaf_call>
+ 198:   c2 5d c0 01     ldx  [ %l7 + %g1 ], %g1
+ 19c:   c6 5f a7 e7     ldx  [ %fp + 0x7e7 ], %g3
+ 1a0:   c4 58 40 00     ldx  [ %g1 ], %g2
+ 1a4:   86 18 c0 02     xor  %g3, %g2, %g3
+ 1a8:   84 10 20 00     clr  %g2
+ 1ac:   82 10 00 03     mov  %g3, %g1
+ 1b0:   02 c8 40 08     brz  %g1, 1d0 <nonleaf_call+0x178>
+ 1b4:   01 00 00 00     nop
+ 1b8:   03 00 00 00     sethi  %hi(0), %g1
+ 1bc:   82 10 60 00     mov  %g1, %g1   ! 0 <leaf_call>
+ 1c0:   c2 5d c0 01     ldx  [ %l7 + %g1 ], %g1
+ 1c4:   90 10 00 01     mov  %g1, %o0
+ 1c8:   40 00 00 00     call  1c8 <nonleaf_call+0x170>
+ 1cc:   01 00 00 00     nop
+ 1d0:   81 cf e0 08     rett  %i7 + 8
+ 1d4:   01 00 00 00     nop
+
+00000000000001d8 <main>:
+ 1d8:   9d e3 be c0     save  %sp, -320, %sp                    ; prolog
+ 1dc:   2f 00 00 00     sethi  %hi(0), %l7                      ; |
+ 1e0:   ae 05 e0 00     add  %l7, 0, %l7        ! 0 <leaf_call> ; | @@@ unsure, call to some code stub adding o7 to l7
+ 1e4:   7f ff ff 9a     call  4c <leaf_call+0x4c>               ; |
+ 1e8:   01 00 00 00     nop                                     ; /
+ 1ec:   82 10 20 02     mov  2, %g1     ! 2 <leaf_call+0x2>     ; \
+ 1f0:   c2 27 a7 db     st  %g1, [ %fp + 0x7db ]                ; |
+ 1f4:   82 10 20 03     mov  3, %g1                             ; |
+ 1f8:   c2 27 a7 df     st  %g1, [ %fp + 0x7df ]                ; |
+ 1fc:   03 00 00 00     sethi  %hi(0), %g1                      ; | put together first local struct A
+ 200:   82 10 60 00     mov  %g1, %g1   ! 0 <leaf_call>         ; |
+ 204:   c2 5d c0 01     ldx  [ %l7 + %g1 ], %g1                 ; |
+ 208:   d1 00 40 00     ld  [ %g1 ], %f8                        ; |
+ 20c:   d1 27 a7 e3     st  %f8, [ %fp + 0x7e3 ]                ; /
+ 210:   03 00 00 00     sethi  %hi(0), %g1                      ; \
+ 214:   82 10 60 00     mov  %g1, %g1   ! 0 <leaf_call>         ; |
+ 218:   c2 5d c0 01     ldx  [ %l7 + %g1 ], %g1                 ; |
+ 21c:   d1 18 40 00     ldd  [ %g1 ], %f8                       ; | put together first local struct B
+ 220:   d1 3f a7 bf     std  %f8, [ %fp + 0x7bf ]               ; |
+ 224:   82 10 20 06     mov  6, %g1                             ; |
+ 228:   c2 77 a7 c7     stx  %g1, [ %fp + 0x7c7 ]               ; /
+ 22c:   82 10 20 09     mov  9, %g1                             ; \
+ 230:   c2 27 a7 cf     st  %g1, [ %fp + 0x7cf ]                ; |
+ 234:   82 10 20 0a     mov  0xa, %g1                           ; |
+ 238:   c2 27 a7 d3     st  %g1, [ %fp + 0x7d3 ]                ; |
+ 23c:   03 00 00 00     sethi  %hi(0), %g1                      ; | put together second local struct A
+ 240:   82 10 60 00     mov  %g1, %g1   ! 0 <leaf_call>         ; |
+ 244:   c2 5d c0 01     ldx  [ %l7 + %g1 ], %g1                 ; |
+ 248:   d1 00 40 00     ld  [ %g1 ], %f8                        ; |
+ 24c:   d1 27 a7 d7     st  %f8, [ %fp + 0x7d7 ]                ; /
+ 250:   03 00 00 00     sethi  %hi(0), %g1                      ; \
+ 254:   82 10 60 00     mov  %g1, %g1   ! 0 <leaf_call>         ; |
+ 258:   c2 5d c0 01     ldx  [ %l7 + %g1 ], %g1                 ; |
+ 25c:   d1 18 40 00     ldd  [ %g1 ], %f8                       ; | put together second local struct B
+ 260:   d1 3f a7 af     std  %f8, [ %fp + 0x7af ]               ; |
+ 264:   82 10 20 0d     mov  0xd, %g1                           ; |
+ 268:   c2 77 a7 b7     stx  %g1, [ %fp + 0x7b7 ]               ; /
+ 26c:   84 03 a8 7f     add  %sp, 0x87f, %g2                    ; top of stack addr -> g2
+ 270:   c2 07 a7 db     ld  [ %fp + 0x7db ], %g1                ; |                |
+ 274:   83 30 60 00     srl  %g1, 0, %g1                        ; |                |
+ 278:   87 28 70 20     sllx  %g1, 0x20, %g3                    ; |                | get first struct A's first 8 bytes (i,j) into g3, with i occupying MSBs
+ 27c:   c2 07 a7 df     ld  [ %fp + 0x7df ], %g1                ; | prep arg 2     |
+ 280:   83 30 60 00     srl  %g1, 0, %g1                        ; |                |
+ 284:   86 10 40 03     or  %g1, %g3, %g3                       ; |                |
+ 288:   d1 07 a7 e3     ld  [ %fp + 0x7e3 ], %f8                ; /                first struct A's f -> f8
+ 28c:   d5 1f a7 bf     ldd  [ %fp + 0x7bf ], %f10              ; \                first struct B's d -> f10
+ 290:   c8 5f a7 c7     ldx  [ %fp + 0x7c7 ], %g4               ; / prep arg 3     first struct B's l -> g4
+ 294:   82 10 20 07     mov  7, %g1                             ; \
+ 298:   c2 70 a0 30     stx  %g1, [ %g2 + 0x30 ]                ; / arg 4, "pushed" onto stack
+ 29c:   82 10 20 08     mov  8, %g1                             ; \
+ 2a0:   c2 70 a0 38     stx  %g1, [ %g2 + 0x38 ]                ; / arg 5, "pushed" onto stack
+ 2a4:   c2 5f a7 cf     ldx  [ %fp + 0x7cf ], %g1               ; \
+ 2a8:   c2 70 a0 40     stx  %g1, [ %g2 + 0x40 ]                ; |
+ 2ac:   c2 07 a7 d7     ld  [ %fp + 0x7d7 ], %g1                ; | (part of) arg 6's int fields, "pushed" onto stack (second struct A, entirely)
+ 2b0:   c2 20 a0 48     st  %g1, [ %g2 + 0x48 ]                 ; /
+ 2b4:   d9 00 a0 48     ld  [ %g2 + 0x48 ], %f12                ; prep (part of) arg 6: second struct A's fp field f -> f12
+ 2b8:   c2 5f a7 af     ldx  [ %fp + 0x7af ], %g1               ; \
+ 2bc:   c2 70 a0 50     stx  %g1, [ %g2 + 0x50 ]                ; |
+ 2c0:   c2 5f a7 b7     ldx  [ %fp + 0x7b7 ], %g1               ; | (part of) arg 7, "pushed" onto stack (second struct B, entirely)
+ 2c4:   c2 70 a0 58     stx  %g1, [ %g2 + 0x58 ]                ; /
+ 2c8:   dd 18 a0 50     ldd  [ %g2 + 0x50 ], %f14               ; prep (part of) arg 7: second struct B's d -> d14
+ 2cc:   82 10 20 0e     mov  0xe, %g1                           ; \
+ 2d0:   c2 70 a0 60     stx  %g1, [ %g2 + 0x60 ]                ; / arg 8, "pushed" onto stack
+ 2d4:   82 10 20 0f     mov  0xf, %g1                           ; \
+ 2d8:   c2 70 a0 68     stx  %g1, [ %g2 + 0x68 ]                ; / arg 9, "pushed" onto stack
+ 2dc:   90 10 20 00     clr  %o0                                ; arg 0
+ 2e0:   92 10 20 01     mov  1, %o1                             ; arg 1
+ 2e4:   94 10 00 03     mov  %g3, %o2                           ; |                          (i,j -> int reg)
+ 2e8:   8d a0 00 28     fmovs  %f8, %f6                         ; / arg 2 (first struct A)   (f -> fp reg, (f{0,2,4} skipped))
+ 2ec:   91 a0 00 4a     fmovd  %f10, %f8                        ; \                          (d -> fp reg d8)
+ 2f0:   9a 10 00 04     mov  %g4, %o5                           ; / arg 3 (first struct B)   (l -> int reg, (o{3,4} skipped))
+ 2f4:   a5 a0 00 2c     fmovs  %f12, %f18                       ; (part of) arg 6 (second struct A)   (f -> fp reg, (f[10-16] skipped))
+ 2f8:   a9 a0 00 4e     fmovd  %f14, %f20                       ; (part of) arg 7 (second struct B)   (d -> fp reg d20))
+ 2fc:   40 00 00 00     call  2fc <main+0x124>                  ; call nonleaf_call (objdump not from final link but .o)
+ 300:   01 00 00 00     nop                                     ; branch delay slot
+ 304:   82 10 20 00     clr  %g1        ! 0 <leaf_call>         ; \
+ 308:   83 38 60 00     sra  %g1, 0, %g1                        ; / return value
+ 30c:   b0 10 00 01     mov  %g1, %i0                           ; \
+ 310:   81 cf e0 08     rett  %i7 + 8                           ; | epilog
+ 314:   01 00 00 00     nop                                     ; |            branch delay slot
+
+
+
+; ---------- passing structs with mixed 8-byte parts ---------->
+;
+; struct A { int i; float f; };
+; struct B { float f; char c; };
+; struct C { float f; short s, t; };
+; struct D { short s; float f; };
+;
+; void leaf_call(struct A a, struct B b, struct C c, struct D d)
+; {
+; }
+;
+; int main()
+; {
+;     leaf_call((struct A){0,1.f}, (struct B){2.f,3}, (struct C){4.f,5,6}, (struct D){7,8.f});
+;     return 0;
+; }
+
+
+
+; output from openbsd-6.0-sparc64 w/ gcc 4.2.1
+
+0000000000000000 <leaf_call>:
+   0:   9d e3 bf 30     save  %sp, -208, %sp
+   4:   82 10 00 18     mov  %i0, %g1
+   8:   91 a0 00 21     fmovs  %f1, %f8
+   c:   93 a0 00 22     fmovs  %f2, %f9
+  10:   84 10 00 19     mov  %i1, %g2
+  14:   95 a0 00 24     fmovs  %f4, %f10
+  18:   86 10 00 1a     mov  %i2, %g3
+  1c:   88 10 00 1b     mov  %i3, %g4
+  20:   97 a0 00 27     fmovs  %f7, %f11
+  24:   c2 77 a8 7f     stx  %g1, [ %fp + 0x87f ]
+  28:   d1 27 a8 83     st  %f8, [ %fp + 0x883 ]
+  2c:   d3 27 a8 87     st  %f9, [ %fp + 0x887 ]
+  30:   c4 27 a8 8b     st  %g2, [ %fp + 0x88b ]
+  34:   d5 27 a8 8f     st  %f10, [ %fp + 0x88f ]
+  38:   c6 27 a8 93     st  %g3, [ %fp + 0x893 ]
+  3c:   c8 77 a8 97     stx  %g4, [ %fp + 0x897 ]
+  40:   d7 27 a8 9b     st  %f11, [ %fp + 0x89b ]
+  44:   81 cf e0 08     rett  %i7 + 8
+  48:   01 00 00 00     nop
+  4c:   ae 03 c0 17     add  %o7, %l7, %l7
+  50:   81 c3 e0 08     retl
+  54:   01 00 00 00     nop
+
+0000000000000058 <main>:
+  58:   9d e3 bf 10     save  %sp, -240, %sp                    ; prolog
+  5c:   2f 00 00 00     sethi  %hi(0), %l7                      ; |
+  60:   ae 05 e0 00     add  %l7, 0, %l7        ! 0 <leaf_call> ; | @@@ unsure, call to some code stub adding o7 to l7
+  64:   7f ff ff fa     call  4c <leaf_call+0x4c>               ; |
+  68:   01 00 00 00     nop                                     ; /
+;     leaf_call((struct A){0,1.f}, (struct B){2.f,3}, (struct C){4.f,5,6}, (struct D){7,8.f});
+  6c:   c0 27 a7 df     clr  [ %fp + 0x7df ]                    ; \
+  70:   03 00 00 00     sethi  %hi(0), %g1                      ; |
+  74:   82 10 60 00     mov  %g1, %g1   ! 0 <leaf_call>         ; |
+  78:   c2 5d c0 01     ldx  [ %l7 + %g1 ], %g1                 ; | put together local struct A
+  7c:   d1 00 40 00     ld  [ %g1 ], %f8                        ; |
+  80:   d1 27 a7 e3     st  %f8, [ %fp + 0x7e3 ]                ; /
+  84:   03 00 00 00     sethi  %hi(0), %g1                      ; \
+  88:   82 10 60 00     mov  %g1, %g1   ! 0 <leaf_call>         ; |
+  8c:   c2 5d c0 01     ldx  [ %l7 + %g1 ], %g1                 ; |
+  90:   d1 00 40 00     ld  [ %g1 ], %f8                        ; | put together local struct B
+  94:   d1 27 a7 d7     st  %f8, [ %fp + 0x7d7 ]                ; |
+  98:   82 10 20 03     mov  3, %g1                             ; |
+  9c:   c2 2f a7 db     stb  %g1, [ %fp + 0x7db ]               ; /
+  a0:   03 00 00 00     sethi  %hi(0), %g1                      ; \
+  a4:   82 10 60 00     mov  %g1, %g1   ! 0 <leaf_call>         ; |
+  a8:   c2 5d c0 01     ldx  [ %l7 + %g1 ], %g1                 ; |
+  ac:   d1 00 40 00     ld  [ %g1 ], %f8                        ; |
+  b0:   d1 27 a7 cf     st  %f8, [ %fp + 0x7cf ]                ; | put together local struct C
+  b4:   82 10 20 05     mov  5, %g1                             ; |
+  b8:   c2 37 a7 d3     sth  %g1, [ %fp + 0x7d3 ]               ; |
+  bc:   82 10 20 06     mov  6, %g1                             ; |
+  c0:   c2 37 a7 d5     sth  %g1, [ %fp + 0x7d5 ]               ; /
+  c4:   82 10 20 07     mov  7, %g1                             ; \
+  c8:   c2 37 a7 c7     sth  %g1, [ %fp + 0x7c7 ]               ; |
+  cc:   03 00 00 00     sethi  %hi(0), %g1                      ; |
+  d0:   82 10 60 00     mov  %g1, %g1   ! 0 <leaf_call>         ; | put together local struct D
+  d4:   c2 5d c0 01     ldx  [ %l7 + %g1 ], %g1                 ; |
+  d8:   d1 00 40 00     ld  [ %g1 ], %f8                        ; |
+  dc:   d1 27 a7 cb     st  %f8, [ %fp + 0x7cb ]                ; /
+  e0:   c2 5f a7 df     ldx  [ %fp + 0x7df ], %g1               ; \               struct A's int           -> g1
+  e4:   d1 07 a7 e3     ld  [ %fp + 0x7e3 ], %f8                ; |               struct A's float         -> f8
+  e8:   d3 07 a7 d7     ld  [ %fp + 0x7d7 ], %f9                ; |               struct B's float         -> f9
+  ec:   c4 07 a7 db     ld  [ %fp + 0x7db ], %g2                ; | prep args     struct B's char          -> g2
+  f0:   d5 07 a7 cf     ld  [ %fp + 0x7cf ], %f10               ; |               struct C's float         -> f10
+  f4:   c6 07 a7 d3     ld  [ %fp + 0x7d3 ], %g3                ; |               struct C's shorts (both) -> g3
+  f8:   c8 5f a7 c7     ldx  [ %fp + 0x7c7 ], %g4               ; |               struct D's short         -> g4
+  fc:   d7 07 a7 cb     ld  [ %fp + 0x7cb ], %f11               ; /               struct D's float         -> f11
+ 100:   90 10 00 01     mov  %g1, %o0                           ; arg 0 (int part)
+ 104:   83 a0 00 28     fmovs  %f8, %f1                         ; arg 0 (fp part)
+ 108:   85 a0 00 29     fmovs  %f9, %f2                         ; arg 1 (fp part)
+ 10c:   92 10 00 02     mov  %g2, %o1                           ; arg 1 (int part)
+ 110:   89 a0 00 2a     fmovs  %f10, %f4                        ; arg 2 (fp part)
+ 114:   94 10 00 03     mov  %g3, %o2                           ; arg 2 (int part)
+ 118:   96 10 00 04     mov  %g4, %o3                           ; arg 3 (int part)
+ 11c:   8f a0 00 2b     fmovs  %f11, %f7                        ; arg 3 (fp part)
+ 120:   40 00 00 00     call  120 <main+0xc8>                   ; call nonleaf_call (objdump not from final link but .o)
+ 124:   01 00 00 00     nop                                     ; branch delay slot
+ 128:   82 10 20 00     clr  %g1        ! 0 <leaf_call>         ; \
+ 12c:   83 38 60 00     sra  %g1, 0, %g1                        ; / return value
+ 130:   b0 10 00 01     mov  %g1, %i0                           ; \
+ 134:   81 cf e0 08     rett  %i7 + 8                           ; | epilog
+ 138:   01 00 00 00     nop                                     ; |            branch delay slot
+
+
+
+; ---------- returning structs by value ---------->
+;
+; struct Small { char x; };
+; struct Big { long long i,j,k,l; long m; }; /* bigger than 32b */
+;
+; struct Small f0()
+; {
+;     struct Small s = { 132 };
+;     return s;
+; }
+;
+; struct Big f1()
+; {
+;     struct Big b = { 7171LL, 99LL, -99LL, -3102LL, 32 };
+;     return b;
+; }
+;
+; int main()
+; {
+;     struct Small s = f0();
+;     struct Big b = f1();
+;     return b.j + b.k + b.m + s.x;
+; }
+
+
+
+; output from openbsd-6.0-sparc64 w/ gcc 4.2.1
+
+0000000000000000 <f0>:
+   0:   9d e3 bf 30     save  %sp, -208, %sp
+   4:   82 10 3f 84     mov  -124, %g1
+   8:   c2 2f a7 e6     stb  %g1, [ %fp + 0x7e6 ]
+   c:   c2 0f a7 e6     ldub  [ %fp + 0x7e6 ], %g1
+  10:   82 08 60 ff     and  %g1, 0xff, %g1
+  14:   83 28 70 38     sllx  %g1, 0x38, %g1
+  18:   b0 10 00 01     mov  %g1, %i0
+  1c:   81 cf e0 08     rett  %i7 + 8
+  20:   01 00 00 00     nop
+
+0000000000000024 <f1>:
+  24:   9d e3 bf 10     save  %sp, -240, %sp
+  28:   84 10 00 18     mov  %i0, %g2
+  2c:   03 00 1c 03     sethi  %hi(0x700c00), %g1
+  30:   83 30 70 0a     srlx  %g1, 0xa, %g1
+  34:   c2 77 a7 bf     stx  %g1, [ %fp + 0x7bf ]
+  38:   82 10 20 63     mov  0x63, %g1
+  3c:   c2 77 a7 c7     stx  %g1, [ %fp + 0x7c7 ]
+  40:   82 10 3f 9d     mov  -99, %g1
+  44:   c2 77 a7 cf     stx  %g1, [ %fp + 0x7cf ]
+  48:   82 10 33 e2     mov  -3102, %g1
+  4c:   c2 77 a7 d7     stx  %g1, [ %fp + 0x7d7 ]
+  50:   82 10 20 20     mov  0x20, %g1
+  54:   c2 77 a7 df     stx  %g1, [ %fp + 0x7df ]
+  58:   c2 5f a7 bf     ldx  [ %fp + 0x7bf ], %g1
+  5c:   c2 70 80 00     stx  %g1, [ %g2 ]
+  60:   c2 5f a7 c7     ldx  [ %fp + 0x7c7 ], %g1
+  64:   c2 70 a0 08     stx  %g1, [ %g2 + 8 ]
+  68:   c2 5f a7 cf     ldx  [ %fp + 0x7cf ], %g1
+  6c:   c2 70 a0 10     stx  %g1, [ %g2 + 0x10 ]
+  70:   c2 5f a7 d7     ldx  [ %fp + 0x7d7 ], %g1
+  74:   c2 70 a0 18     stx  %g1, [ %g2 + 0x18 ]
+  78:   c2 5f a7 df     ldx  [ %fp + 0x7df ], %g1
+  7c:   c2 70 a0 20     stx  %g1, [ %g2 + 0x20 ]
+  80:   b0 10 00 02     mov  %g2, %i0
+  84:   81 cf e0 08     rett  %i7 + 8
+  88:   01 00 00 00     nop
+  8c:   ae 03 c0 17     add  %o7, %l7, %l7
+  90:   81 c3 e0 08     retl
+  94:   01 00 00 00     nop
+
+0000000000000098 <main>:
+  98:   9d e3 be f0     save  %sp, -272, %sp
+  9c:   2f 00 00 00     sethi  %hi(0), %l7
+  a0:   ae 05 e0 00     add  %l7, 0, %l7        ! 0 <f0>
+  a4:   7f ff ff fa     call  8c <f1+0x68>
+  a8:   01 00 00 00     nop
+  ac:   03 00 00 00     sethi  %hi(0), %g1
+  b0:   82 10 60 00     mov  %g1, %g1   ! 0 <f0>
+  b4:   c2 5d c0 01     ldx  [ %l7 + %g1 ], %g1
+  b8:   c4 58 40 00     ldx  [ %g1 ], %g2
+  bc:   c4 77 a7 e7     stx  %g2, [ %fp + 0x7e7 ]
+  c0:   84 10 20 00     clr  %g2
+  c4:   40 00 00 00     call  c4 <main+0x2c>
+  c8:   01 00 00 00     nop
+  cc:   84 10 00 08     mov  %o0, %g2
+  d0:   c0 2f a7 ae     clrb  [ %fp + 0x7ae ]
+  d4:   85 38 b0 38     srax  %g2, 0x38, %g2
+  d8:   c6 0f a7 ae     ldub  [ %fp + 0x7ae ], %g3
+  dc:   82 08 e0 00     and  %g3, 0, %g1
+  e0:   86 10 00 01     mov  %g1, %g3
+  e4:   82 10 00 02     mov  %g2, %g1
+  e8:   82 10 c0 01     or  %g3, %g1, %g1
+  ec:   c2 2f a7 ae     stb  %g1, [ %fp + 0x7ae ]
+  f0:   c2 0f a7 ae     ldub  [ %fp + 0x7ae ], %g1
+  f4:   c2 2f a7 e6     stb  %g1, [ %fp + 0x7e6 ]
+  f8:   82 07 a7 b7     add  %fp, 0x7b7, %g1
+  fc:   90 10 00 01     mov  %g1, %o0
+ 100:   40 00 00 00     call  100 <main+0x68>
+ 104:   01 00 00 00     nop
+ 108:   c2 5f a7 bf     ldx  [ %fp + 0x7bf ], %g1
+ 10c:   84 10 00 01     mov  %g1, %g2
+ 110:   c2 5f a7 c7     ldx  [ %fp + 0x7c7 ], %g1
+ 114:   84 00 80 01     add  %g2, %g1, %g2
+ 118:   c2 5f a7 d7     ldx  [ %fp + 0x7d7 ], %g1
+ 11c:   84 00 80 01     add  %g2, %g1, %g2
+ 120:   c2 0f a7 e6     ldub  [ %fp + 0x7e6 ], %g1
+ 124:   83 28 60 18     sll  %g1, 0x18, %g1
+ 128:   83 38 60 18     sra  %g1, 0x18, %g1
+ 12c:   82 00 80 01     add  %g2, %g1, %g1
+ 130:   83 38 60 00     sra  %g1, 0, %g1
+ 134:   b0 10 00 01     mov  %g1, %i0
+ 138:   03 00 00 00     sethi  %hi(0), %g1
+ 13c:   82 10 60 00     mov  %g1, %g1   ! 0 <f0>
+ 140:   c2 5d c0 01     ldx  [ %l7 + %g1 ], %g1
+ 144:   c4 5f a7 e7     ldx  [ %fp + 0x7e7 ], %g2
+ 148:   c6 58 40 00     ldx  [ %g1 ], %g3
+ 14c:   84 18 80 03     xor  %g2, %g3, %g2
+ 150:   86 10 20 00     clr  %g3
+ 154:   82 10 00 02     mov  %g2, %g1
+ 158:   02 c8 40 08     brz  %g1, 178 <main+0xe0>
+ 15c:   01 00 00 00     nop
+ 160:   03 00 00 00     sethi  %hi(0), %g1
+ 164:   82 10 60 00     mov  %g1, %g1   ! 0 <f0>
+ 168:   c2 5d c0 01     ldx  [ %l7 + %g1 ], %g1
+ 16c:   90 10 00 01     mov  %g1, %o0
+ 170:   40 00 00 00     call  170 <main+0xd8>
+ 174:   01 00 00 00     nop
+ 178:   81 cf e0 08     rett  %i7 + 8
+ 17c:   01 00 00 00     nop
+
+
+
+; ---------- single-field structs by values (and small array fields) ---------->
+;
+; struct C { char c; };
+; struct S { short s; };
+; struct I { int i; };
+; struct F { float f; };
+; struct D { double d; };
+; 
+; struct C2 { char c[2]; };
+; struct C3 { char c[3]; };
+; 
+; void leaf_call(struct C2 a, struct C b, struct S c, struct I d, struct F e, struct D f, struct C3 g)
+; {
+; }
+; 
+; int main()
+; {
+;     leaf_call((struct C2){{0,1}}, (struct C){2}, (struct S){3}, (struct I){4}, (struct F){5.f}, (struct D){6.}, (struct C3){{7,8,9}});
+;     return 0;
+; }
+
+
+; output from openbsd-6.0-sparc64 w/ gcc 4.2.1
+
+0000000000000000 <leaf_call>:
+   0:   9d e3 bf 30     save  %sp, -208, %sp
+   4:   82 10 00 18     mov  %i0, %g1
+   8:   86 10 00 19     mov  %i1, %g3
+   c:   8a 10 00 1a     mov  %i2, %g5
+  10:   ba 10 00 1b     mov  %i3, %i5
+  14:   d1 27 a8 9f     st  %f8, [ %fp + 0x89f ]
+  18:   d5 3f a8 a7     std  %f10, [ %fp + 0x8a7 ]
+  1c:   83 38 70 30     srax  %g1, 0x30, %g1
+  20:   89 28 70 30     sllx  %g1, 0x30, %g4
+  24:   c4 5f a8 7f     ldx  [ %fp + 0x87f ], %g2
+  28:   82 10 3f ff     mov  -1, %g1
+  2c:   83 30 70 10     srlx  %g1, 0x10, %g1
+  30:   82 08 80 01     and  %g2, %g1, %g1
+  34:   82 10 40 04     or  %g1, %g4, %g1
+  38:   c2 77 a8 7f     stx  %g1, [ %fp + 0x87f ]
+  3c:   87 38 f0 38     srax  %g3, 0x38, %g3
+  40:   c2 0f a8 87     ldub  [ %fp + 0x887 ], %g1
+  44:   82 08 60 00     and  %g1, 0, %g1
+  48:   84 10 00 01     mov  %g1, %g2
+  4c:   82 10 00 03     mov  %g3, %g1
+  50:   82 10 80 01     or  %g2, %g1, %g1
+  54:   c2 2f a8 87     stb  %g1, [ %fp + 0x887 ]
+  58:   8b 39 70 30     srax  %g5, 0x30, %g5
+  5c:   c2 17 a8 8f     lduh  [ %fp + 0x88f ], %g1
+  60:   82 08 60 00     and  %g1, 0, %g1
+  64:   84 10 00 01     mov  %g1, %g2
+  68:   82 10 00 05     mov  %g5, %g1
+  6c:   82 10 80 01     or  %g2, %g1, %g1
+  70:   c2 37 a8 8f     sth  %g1, [ %fp + 0x88f ]
+  74:   bb 3f 70 20     srax  %i5, 0x20, %i5
+  78:   c2 07 a8 97     ld  [ %fp + 0x897 ], %g1
+  7c:   82 08 60 00     and  %g1, 0, %g1
+  80:   82 10 40 1d     or  %g1, %i5, %g1
+  84:   c2 27 a8 97     st  %g1, [ %fp + 0x897 ]
+  88:   81 cf e0 08     rett  %i7 + 8
+  8c:   01 00 00 00     nop
+  90:   ae 03 c0 17     add  %o7, %l7, %l7
+  94:   81 c3 e0 08     retl
+  98:   01 00 00 00     nop
+
+000000000000009c <main>:
+  9c:   9d e3 bf 00     save  %sp, -256, %sp
+  a0:   2f 00 00 00     sethi  %hi(0), %l7
+  a4:   ae 05 e0 00     add  %l7, 0, %l7        ! 0 <leaf_call>
+  a8:   7f ff ff fa     call  90 <leaf_call+0x90>
+  ac:   01 00 00 00     nop
+  b0:   03 00 00 00     sethi  %hi(0), %g1
+  b4:   82 10 60 00     mov  %g1, %g1   ! 0 <leaf_call>
+  b8:   c2 5d c0 01     ldx  [ %l7 + %g1 ], %g1
+  bc:   c4 58 40 00     ldx  [ %g1 ], %g2
+  c0:   c4 77 a7 e7     stx  %g2, [ %fp + 0x7e7 ]
+  c4:   84 10 20 00     clr  %g2
+  c8:   c0 2f a7 e4     clrb  [ %fp + 0x7e4 ]
+  cc:   82 10 20 01     mov  1, %g1
+  d0:   c2 2f a7 e5     stb  %g1, [ %fp + 0x7e5 ]
+  d4:   82 10 20 02     mov  2, %g1
+  d8:   c2 2f a7 e6     stb  %g1, [ %fp + 0x7e6 ]
+  dc:   82 10 20 03     mov  3, %g1
+  e0:   c2 37 a7 e1     sth  %g1, [ %fp + 0x7e1 ]
+  e4:   82 10 20 04     mov  4, %g1
+  e8:   c2 27 a7 d7     st  %g1, [ %fp + 0x7d7 ]
+  ec:   03 00 00 00     sethi  %hi(0), %g1
+  f0:   82 10 60 00     mov  %g1, %g1   ! 0 <leaf_call>
+  f4:   c2 5d c0 01     ldx  [ %l7 + %g1 ], %g1
+  f8:   d1 00 40 00     ld  [ %g1 ], %f8
+  fc:   d1 27 a7 d3     st  %f8, [ %fp + 0x7d3 ]
+ 100:   03 00 00 00     sethi  %hi(0), %g1
+ 104:   82 10 60 00     mov  %g1, %g1   ! 0 <leaf_call>
+ 108:   c2 5d c0 01     ldx  [ %l7 + %g1 ], %g1
+ 10c:   d1 18 40 00     ldd  [ %g1 ], %f8
+ 110:   d1 3f a7 c7     std  %f8, [ %fp + 0x7c7 ]
+ 114:   82 10 20 07     mov  7, %g1
+ 118:   c2 2f a7 de     stb  %g1, [ %fp + 0x7de ]
+ 11c:   82 10 20 08     mov  8, %g1
+ 120:   c2 2f a7 df     stb  %g1, [ %fp + 0x7df ]
+ 124:   82 10 20 09     mov  9, %g1
+ 128:   c2 2f a7 e0     stb  %g1, [ %fp + 0x7e0 ]
+ 12c:   c2 0f a7 e4     ldub  [ %fp + 0x7e4 ], %g1
+ 130:   82 08 60 ff     and  %g1, 0xff, %g1
+ 134:   85 28 70 08     sllx  %g1, 8, %g2
+ 138:   c2 0f a7 e5     ldub  [ %fp + 0x7e5 ], %g1
+ 13c:   82 08 60 ff     and  %g1, 0xff, %g1
+ 140:   86 10 40 02     or  %g1, %g2, %g3
+ 144:   87 28 f0 30     sllx  %g3, 0x30, %g3
+ 148:   c2 0f a7 e6     ldub  [ %fp + 0x7e6 ], %g1
+ 14c:   88 08 60 ff     and  %g1, 0xff, %g4
+ 150:   89 29 30 38     sllx  %g4, 0x38, %g4
+ 154:   c2 17 a7 e1     lduh  [ %fp + 0x7e1 ], %g1
+ 158:   83 28 70 30     sllx  %g1, 0x30, %g1
+ 15c:   8b 30 70 30     srlx  %g1, 0x30, %g5
+ 160:   8b 29 70 30     sllx  %g5, 0x30, %g5
+ 164:   c2 5f a7 d7     ldx  [ %fp + 0x7d7 ], %g1
+ 168:   85 30 70 20     srlx  %g1, 0x20, %g2
+ 16c:   85 28 b0 20     sllx  %g2, 0x20, %g2
+ 170:   d1 07 a7 d3     ld  [ %fp + 0x7d3 ], %f8
+ 174:   d5 1f a7 c7     ldd  [ %fp + 0x7c7 ], %f10
+ 178:   c2 0f a7 de     ldub  [ %fp + 0x7de ], %g1
+ 17c:   c2 2b a8 af     stb  %g1, [ %sp + 0x8af ]
+ 180:   c2 0f a7 df     ldub  [ %fp + 0x7df ], %g1
+ 184:   c2 2b a8 b0     stb  %g1, [ %sp + 0x8b0 ]
+ 188:   c2 0f a7 e0     ldub  [ %fp + 0x7e0 ], %g1
+ 18c:   c2 2b a8 b1     stb  %g1, [ %sp + 0x8b1 ]
+ 190:   90 10 00 03     mov  %g3, %o0
+ 194:   92 10 00 04     mov  %g4, %o1
+ 198:   94 10 00 05     mov  %g5, %o2
+ 19c:   96 10 00 02     mov  %g2, %o3
+ 1a0:   40 00 00 00     call  1a0 <main+0x104>
+ 1a4:   01 00 00 00     nop
+ 1a8:   82 10 20 00     clr  %g1        ! 0 <leaf_call>
+ 1ac:   83 38 60 00     sra  %g1, 0, %g1
+ 1b0:   b0 10 00 01     mov  %g1, %i0
+ 1b4:   03 00 00 00     sethi  %hi(0), %g1
+ 1b8:   82 10 60 00     mov  %g1, %g1   ! 0 <leaf_call>
+ 1bc:   c2 5d c0 01     ldx  [ %l7 + %g1 ], %g1
+ 1c0:   c6 5f a7 e7     ldx  [ %fp + 0x7e7 ], %g3
+ 1c4:   c4 58 40 00     ldx  [ %g1 ], %g2
+ 1c8:   86 18 c0 02     xor  %g3, %g2, %g3
+ 1cc:   84 10 20 00     clr  %g2
+ 1d0:   82 10 00 03     mov  %g3, %g1
+ 1d4:   02 c8 40 08     brz  %g1, 1f4 <main+0x158>
+ 1d8:   01 00 00 00     nop
+ 1dc:   03 00 00 00     sethi  %hi(0), %g1
+ 1e0:   82 10 60 00     mov  %g1, %g1   ! 0 <leaf_call>
+ 1e4:   c2 5d c0 01     ldx  [ %l7 + %g1 ], %g1
+ 1e8:   90 10 00 01     mov  %g1, %o0
+ 1ec:   40 00 00 00     call  1ec <main+0x150>
+ 1f0:   01 00 00 00     nop
+ 1f4:   81 cf e0 08     rett  %i7 + 8
+ 1f8:   01 00 00 00     nop
+
+
+
 ; vim: ft=asm
 
--- a/doc/manual/callconvs/callconv_sparc64.tex	Wed Feb 16 16:44:11 2022 +0100
+++ b/doc/manual/callconvs/callconv_sparc64.tex	Wed Feb 16 19:26:21 2022 +0100
@@ -1,6 +1,6 @@
 %//////////////////////////////////////////////////////////////////////////////
 %
-% Copyright (c) 2012-2019 Daniel Adler <dadler@uni-goettingen.de>,
+% Copyright (c) 2012-2022 Daniel Adler <dadler@uni-goettingen.de>,
 %                         Tassilo Philipp <tphilipp@potion-studios.com>
 %
 % Permission to use, copy, modify, and distribute this software for any
@@ -22,7 +22,7 @@
 \paragraph{Overview}
 
 The SPARC family of processors is based on the SPARC instruction set architecture, which comes in basically three revisions,
-V7, V8\cite{SPARCV8}\cite{SPARCSysV} and V9\cite{SPARCV9}\cite{SPARCV9SysV}. The former two are 32-bit (see previous chapter) whereas the latter refers to the 64-bit SPARC architecture.
+V7, V8\cite{SPARCV8}\cite{SPARCSysV}\cite{SPARCCD} and V9\cite{SPARCV9}\cite{SPARCV9SysV}\cite{SPARCCD}. The former two are 32-bit (see previous chapter) whereas the latter refers to the 64-bit SPARC architecture.
 SPARC uses big endian byte order, however, V9 supports also little endian byte order, but for data access only, not instruction access.\\
 \\
 There are two proposals, one from Sun and one from Hal, which disagree on how to handle some aspects of this calling convention.\\
@@ -73,6 +73,35 @@
 \item all arguments \textless=\ 64 bit are passed as 64 bit values
 \item minimum stack size is 128 bytes, b/c stack pointer must always point at enough space to store all \%i* and \%l* registers, used when running out of register windows
 \item if needed, register spill area (both, integer and float arguments are spilled in order) is adjacent to parameters
+\item aggregates (struct, union) \textless=\ 16 bytes are passed field-by-field, {\bf however} evaluated as a sequence of 8-byte parameter slots
+\begin{itemize}
+\item fields are left justified in register or stack slots
+\item integers in a slot are passed as such (either via \%o* registers or the stack)
+\item single precision floats (using half of the slot) use even numbered \%f* registers when they occupy the left half, odd numbered ones otherwise (no register skipping logic applied within a slot)
+\item splitting aggregates between registers and stack is allowed
+\end{itemize}
+\item aggregates (struct, union) and types \textgreater\ 16 bytes are passed indirectly, as a pointer to a correctly aligned copy of the data (that copy can be avoided under certain conditions)
+% from spec:
+%Structure or union types up to eight bytes in size are assigned to one parameter array word, and align to eight-byte
+%boundaries.
+%Structure or union types larger than eight bytes, and up to sixteen bytes in size are assigned to two consecutive
+%parameter array words, and align according to the alignment requirements of the structure or at least to an eight-byte
+%boundary.
+%Structure or union types are always left-justified, whether stored in registers or memory. The individual fields of a
+%structure (or containing storage unit in the case of bit fields) are subject to promotion into registers based on their type
+%using the same rules as apply to scalar values (with the addition that a single-precision floating-point number assigned
+%to the left half of an argument slot will be promoted into the corresponding even-numbered float register.). Any union
+%type being passed directly is subject to promotion into the appropriate integer register(s).
+%Note that a sixteen-byte structure with all integral fields assigned to locations %sp+BIAS+168 and %sp+BIAS+176 will
+%be “split,” as the contents of location %sp+BIAS+168 will be promoted to %o5.
+%Structures or unions larger than sixteen bytes are copied by the caller and passed indirectly; the caller will pass the
+%address of a correctly aligned structure value. This sixty-four bit address will occupy one word in the parameter array,
+%and may be promoted to an %o register like any other pointer value. The callee may modify the addressed structure.
+%The caller can omit the copy if such omission cannot be detected. That requires (at least) that:
+%* the original aggregate is already properly aligned,
+%* the original aggregate is not aliased,
+%* the original aggregate is not used after the call, and
+%* no language-specific semantics require the copy.
 \end{itemize}
 
 \paragraph{Return values}
@@ -80,8 +109,37 @@
 \begin{itemize}
 \item results are expected by caller to be returned in \%o0-\%o3 (after reg window restore, meaning callee writes to \%i0-\%i3) for integers
 \item \%d0,\%d2,\%d4,\%d6 are used for floating point values
-\item the fields of structs/unions up to 32b are returned via the respective registers mentioned in the previous bullet points
-\item structs/unions \textgreater= 32b are returned in a space allocated by the caller, with a pointer to it passed as first parameter to the function called (meaning in \%o0)
+\item the fields of aggregates (struct, union) \textless 32 bytes are returned via registers registers mentioned above (which are
+assigned following the same logic as when passing the aggregate as a first argument to a function)
+\item aggregates (struct, union) \textgreater= 32 bytes are returned in a space allocated by the caller, with a pointer to it
+passed as first parameter to the function called (meaning in \%o0)
+% from spec:
+%Structure and union return types up to thirty-two bytes in size are returned in registers. The registers are assigned as if
+%the value was being passed as the first argument to a function with a known prototype.
+%For types with a larger size the caller allocates an area large enough and aligned properly to hold the return value, and
+%passes a pointer to that area as an implicit first argument (of type pointer-to-data) to the callee. This implicit argument
+%logically precedes the first actual argument, and is allocated according to normal argument passing rules (i.e. into %o0).
+%The callee must store the function return value in the result area before control is returned to the caller and after the last
+%use or definition of any variable that might overlap with the result area. If the callee is terminated through any means
+%other than a normal function return (e.g., through a call to the longjmp function), the contents of the result area are
+%undefined.
+%In the common case that the caller immediately assigns the returned value to a program variable, the caller may
+%substitute the address of the assigned program variable in place of the allocated result area and omit the code to do the
+%assignment, as long as this substitution does not change the program’s externally visible behavior.
+%Note also that the caller is required to provide the implicit argument and a properly sized and aligned receiving area
+%even if it does not wish to use the callee’s function result. In that case, the caller may simply pass a pointer to a scratch
+%area.
+%So that compilers are not forced to emit in-line code for structure copy, Section 6.2 defines a set of routines optimized
+%for this purpose. In the case of a routine which had kept its first argument in %i0 and was returning a value pointed to
+%by %i1, epilogue code would take the form:
+%
+%mov %i0, %o0
+%mov %i1, %o1
+%call __align_cpy_n
+%mov size, %o2
+%ret
+%restore %o0, %g0, %o0
+%
 \end{itemize}
 
 \paragraph{Stack layout}
--- a/doc/manual/manual_literature.tex	Wed Feb 16 16:44:11 2022 +0100
+++ b/doc/manual/manual_literature.tex	Wed Feb 16 19:26:21 2022 +0100
@@ -1,6 +1,6 @@
 %//////////////////////////////////////////////////////////////////////////////
 %
-% Copyright (c) 2007-2020 Daniel Adler <dadler@uni-goettingen.de>, 
+% Copyright (c) 2007-2022 Daniel Adler <dadler@uni-goettingen.de>, 
 %                         Tassilo Philipp <tphilipp@potion-studios.com>
 %
 % Permission to use, copy, modify, and distribute this software for any
@@ -150,6 +150,10 @@
 	The SPARC Architecture Manual - Version 9\\
 	\url{http://sparc.org/wp-content/uploads/2014/01/SPARCV9.pdf.gz}
 
+\bibitem{SPARCCD}
+	SPARC Compliance Definition\\
+	\url{https://sparc.org/wp-content/uploads/2014/01/SCD.2.4.1.pdf.gz}
+
 %\bibitem{SPARCRef}
 %	SPARC Assembly Language Reference Manual\\
 %	\url{http://docs.oracle.com/cd/E19120-01/open.solaris/816-1681/index.html}