Affix

 view release on metacpan or  search on metacpan

LICENSE  view on Meta::CPAN

modifying or distributing the Package, you accept this license. Do not
use, modify, or distribute the Package, if you do not accept this
license.

(11)  If your Modified Version has been derived from a Modified
Version made by someone other than you, you are nevertheless required
to ensure that your Modified Version complies with the requirements of
this license.

(12)  This license does not grant you the right to use any trademark,
service mark, tradename, or logo of the Copyright Holder.

(13)  This license includes the non-exclusive, worldwide,
free-of-charge patent license to make, have made, use, offer to sell,
sell, import and otherwise transfer the Package with respect to any
patent claims licensable by the Copyright Holder that are necessarily
infringed by the Package. If you institute patent litigation
(including a cross-claim or counterclaim) against any party alleging
that the Package constitutes direct or contributory patent
infringement, then this Artistic License to you shall terminate on the
date that such litigation is filed.

MANIFEST  view on Meta::CPAN

dyncall/autovar/autovar_ARCH.h
dyncall/autovar/autovar_CC.h
dyncall/autovar/autovar_OS.h
dyncall/autovar/autovar_OSFAMILY.h
dyncall/buildsys/cmake/Modules/FindDynCall.cmake
dyncall/buildsys/cmake/Modules/FindDynCallback.cmake
dyncall/buildsys/cmake/Modules/FindDynLoad.cmake
dyncall/buildsys/cmake/Modules/UseLATEX.cmake
dyncall/buildsys/mk/app.mk
dyncall/buildsys/mk/dirs.mk
dyncall/buildsys/mk/epilog.mk
dyncall/buildsys/mk/lib.mk
dyncall/buildsys/mk/pcc.mk
dyncall/buildsys/mk/prolog.mk
dyncall/buildsys/nmake/common.nmake
dyncall/buildsys/nmake/epilog.nmake
dyncall/buildsys/nmake/prolog.nmake
dyncall/buildsys/nmake/tool_clang.nmake
dyncall/buildsys/nmake/tool_gcc.nmake
dyncall/buildsys/nmake/tool_msvc.nmake
dyncall/buildsys/scripts/batch-build-linux.sh
dyncall/buildsys/scripts/batch-build-minix.sh
dyncall/buildsys/scripts/batch-build-psp.sh
dyncall/buildsys/scripts/conf-nds.bat
dyncall/buildsys/scripts/elf-to-psp-eboot.sh
dyncall/buildsys/scripts/setenv-cross-ios.sh
dyncall/buildsys/scripts/setenv-sdk-ios.sh

MANIFEST  view on Meta::CPAN

dyncall/doc/manual/callconvs/callconv_arm32.tex
dyncall/doc/manual/callconvs/callconv_arm64.tex
dyncall/doc/manual/callconvs/callconv_mips32.tex
dyncall/doc/manual/callconvs/callconv_mips64.tex
dyncall/doc/manual/callconvs/callconv_ppc32.tex
dyncall/doc/manual/callconvs/callconv_ppc64.tex
dyncall/doc/manual/callconvs/callconv_sparc32.tex
dyncall/doc/manual/callconvs/callconv_sparc64.tex
dyncall/doc/manual/callconvs/callconv_x64.tex
dyncall/doc/manual/callconvs/callconv_x86.tex
dyncall/doc/manual/dyncall_logo.eps
dyncall/doc/manual/dyncall_logo.pdf
dyncall/doc/manual/dyncall_logo.svg
dyncall/doc/manual/dyncall_watermark.eps
dyncall/doc/manual/dyncall_watermark.pdf
dyncall/doc/manual/dyncall_watermark.svg
dyncall/doc/manual/manual.tex
dyncall/doc/manual/manual_bindings.tex
dyncall/doc/manual/manual_build.tex
dyncall/doc/manual/manual_cc.tex
dyncall/doc/manual/manual_design.tex
dyncall/doc/manual/manual_devel.tex
dyncall/doc/manual/manual_dyncall_api.tex
dyncall/doc/manual/manual_dyncallback_api.tex
dyncall/doc/manual/manual_dynload_api.tex
dyncall/doc/manual/manual_epilog.tex
dyncall/doc/manual/manual_literature.tex
dyncall/doc/manual/manual_motivation.tex
dyncall/doc/manual/manual_overview.tex
dyncall/doc/manual/manual_tex4ht.cfg
dyncall/doc/manual/manual_title.tex
dyncall/dyncall/CMakeLists.txt
dyncall/dyncall/DynCallConfig.cmake
dyncall/dyncall/Makefile.embedded
dyncall/dyncall/Makefile.generic
dyncall/dyncall/Nmakefile

MANIFEST  view on Meta::CPAN

dyncall/test/hacking-mips/README.txt
dyncall/test/hacking-mips/call.c
dyncall/test/hacking-mips/calls.c
dyncall/test/hacking-mips/common.h
dyncall/test/hacking-mips/dispatch.c
dyncall/test/hacking-mips/f.c
dyncall/test/hacking-mips/f0.c
dyncall/test/hacking-mips/funs.c
dyncall/test/hacking-mips/main.c
dyncall/test/hacking-mips/node.c
dyncall/test/hacking-mips/prolog.c
dyncall/test/hacking-mips/retn.c
dyncall/test/malloc_wx/CMakeLists.txt
dyncall/test/malloc_wx/Makefile.embedded
dyncall/test/malloc_wx/Makefile.generic
dyncall/test/malloc_wx/Nmakefile
dyncall/test/malloc_wx/mkfile
dyncall/test/malloc_wx/test_wx.c
dyncall/test/mkfile
dyncall/test/nm/CMakeLists.txt
dyncall/test/nm/Makefile.embedded

builder/Affix.pm  view on Meta::CPAN

        next if $destfile->is_dir;
        next
            if $destfile->is_file &&
            stat( $destfile->absolute->stringify )->mtime < $header->{Time};
        warn $destfile;
        $destfile->parent->mkpath;
        my $raw = '';
        while ( ( $status = $u->read( my $buff ) ) > 0 ) { $raw .= $buff }
        $destfile->spew_raw($raw);
        $destfile->touch;
        $retval = $destfile->parent if $destfile =~ 'build.log';
    }
    return $retval;
}
1;

dyncall/ChangeLog  view on Meta::CPAN

  o added zero-config (BSD,GNU,SUN) make files (Makefile.embedded)
  o added in/out-of-source configure2 w/ (BSD,GNU) make files (Makefile.generic)
  o added bootstrap lua script (download/build)
  o Nmakefile: more tests included (resolve_self)
  o improved cross-compilation for iOS (upgrade to 4.3 sdk)
  o darwin 8.0 support
  o added 'install' support for Makefile.embedded
buildsys/gmake updates:
  o added support for msvc/x64 tool-chain
  o default settings for build-dir changed to '.'
  o cleanup: removed top-level Make{Prolog,Epilog,Rules} files and updated all sub-projects and tests
  o added support for DESTDIR staging installation
  o added support for manual page installation
buildsys/cmake updates:
  o updated find module scripts (see cmake/Modules)
  o added support for using dyncall as sub-project (via *Config.cmake files)
    see details in README.CMake
  o fixes for msvc and ml
  o fixes for CPack
  o fixes for universal builds on Mac OS X
  o supports SunPro with *.S files.

dyncall/Nmakefile  view on Meta::CPAN

#///////////////////////////////////////////////////
#
#	nmake makefile
#	Nmakefile
#
#///////////////////////////////////////////////////


TOP = .

!INCLUDE $(TOP)\buildsys\nmake\prolog.nmake

DIRS = dyncall dynload dyncallback

tests: dummy 
	!echo Building tests ... && cd test && $(MAKE) /NOLOGO /F Nmakefile && cd ..

doc: dummy 
	!echo Building documentation ... && cd $@/manual && $(MAKE) /NOLOGO /F Nmakefile && cd ..

# Pseudo-targets are always out of date...
dummy:


!INCLUDE $(TOP)\buildsys\nmake\epilog.nmake

dyncall/ToDo  view on Meta::CPAN

1.5:
----
- test atpcs thumb on arm and verify if ellipsis and C++ thiscalls work, if so adapt doc appendix
- test eabi thumb on arm and verify if ellipsis and C++ thiscalls work, if so adapt doc appendix
- new platform matrix
  * check dark green cells and validate in general
- test/thunk win/x64 doesn't output anything decent for stack test (neither sigsegv nor output), which can create a problem for test log file as it'll mess with the subsequent test's output)
- remove test/gen-masm alltogether
- test code: add sparc tests for when out of register windows, meaning multiple layers deep in the call stack
- support platforms without shared libraries so they can be built by just typing `./configure;make` (e.g. minix < 3.2.1)
  * also make sure minix with shared library support builds and works in general (>= 3.2.1) as well as ELF on Minix (>= 3.2.0) to begin with (as that's the base, and we only test on 3.1.8 so far)
- dyncallback's "stack_cleanup" can be removed from non x86 impls... test if they still work
- the CallVM-free functions are per VTable, however the latter can be changed out
  at runtime... which basically changes potentially the deallocator...
  same goes for functions setting the mode. think about how to make this safer - currently
  we have a higher flexibility and we need to potentially clean up from the mode we are in,
  however, this is open to misuse

dyncall/ToDo  view on Meta::CPAN

--------
- dyncall sparc v7/v8: -xO3 on SunPro segfaults in tests (observed years ago)
- callbacks and use of CC signature characters (only x86 has any support for different CCs for callbacks):
  * support for arm (arm/thumb on same platform)
  * check if ellipsis support is needed (is there any need for calling back into an ellipse function?)
  * check if syscalls support is needed (is there any need for calling back into a syscall?)
- think about using 'inline' for all/most dyncall_api.c functions?
- support for where syscalls originate from on OpenBSD: http://undeadly.org/cgi?action=article;sid=20191202105849
- merge arm32_thumb_{gas/apple} and include thumb support for portasm
- x64 verification: return values are passed via RAX and RDX, and XMM0 and XMM1.
- find big endian arm box (also hardfloat), e.g. cubietruck: http://blog.netbsd.org/tnf/entry/working_arm_multiprocessor_support
- test if armhf/thumb is actually working... pulls in arm mode code in dyncall_callvm.c
- dyncall_call_mips_n32.h and dyncall_call_mips_n64.h are pretty much the same, share code
- support for return values: aggregate return values on non-x64
- support for argument values: aggregates on non-x64, vector types, long double (c89)
  * make sure that struct support for ellipsis calls are not forgotten (copy everything by value)
- support for argument values: _Complex (c99)
- support for argument values: Fixed-width integer types (c99) - could be just aliases but would help abstracting it away from library users
- other syscalls
- test MIPS32 eabi big endian (current port works on psp, which is little endian)
- implement MIPS64 N32 (gcc -mabi=n32); both, little and big-endian (looks like NetNBSD on and
  EdgeRouter lite uses this: https://blog.netbsd.org/tnf/entry/hands_on_experience_with_edgerouter)
- MIPS64 n32 softfloat support (-msoft-float)
- implement MIPS64 EABI (gcc -mabi=eabi); both, little and big-endian
- support for Minix/arm
- improve ellipsis test:
  * test not just with one fixed arg, to also simulate alignment problems
  * test return values
  * convert from c++ to c, to have it also on plan9, and more portability

dynload:
--------

dyncall/ToDo  view on Meta::CPAN

    dynload_syms_elf.c:165: error: `DT_HASH' undeclared (first use in this function)
    make: *** [dynload_syms.o] Error 1

dyncallback:
------------
- callback_plain's return value not correct anymore on NDS (maybe just broken testcode?),
  see above under 1.1 items
  * check other platforms also, if asm stub initializes retval space, correctly
- test MIPS32 eabi big endian (current port works on psp, which is little endian)
- implement MIPS64 N32 (gcc -mabi=n32); both, little and big-endian (looks like NetNBSD on and
  EdgeRouter lite uses this: https://blog.netbsd.org/tnf/entry/hands_on_experience_with_edgerouter)
- MIPS64 n32 softfloat support (-msoft-float)
- implement MIPS64 EABI (gcc -mabi=eabi); both, little and big-endian
- support for Minix/arm

bindings:
---------
- release bindings as standalone packages (already done for rbdc as a gem and rdyncall on cran)
  * add note to documentation, where bindings are
- add rdoc documentation to ruby gem
- add pydoc for python

dyncall/buildsys/cmake/Modules/UseLATEX.cmake  view on Meta::CPAN

    istfile ${istfile_line}
    )

  FOREACH(newglossary ${newglossary_lines})
    STRING(REGEX REPLACE
      "@newglossary[ \t]*{([^}]*)}{([^}]*)}{([^}]*)}{([^}]*)}"
      "\\1" glossary_name ${newglossary}
      )
    STRING(REGEX REPLACE
      "@newglossary[ \t]*{([^}]*)}{([^}]*)}{([^}]*)}{([^}]*)}"
      "${LATEX_TARGET}.\\2" glossary_log ${newglossary}
      )
    STRING(REGEX REPLACE
      "@newglossary[ \t]*{([^}]*)}{([^}]*)}{([^}]*)}{([^}]*)}"
      "${LATEX_TARGET}.\\3" glossary_out ${newglossary}
      )
    STRING(REGEX REPLACE
      "@newglossary[ \t]*{([^}]*)}{([^}]*)}{([^}]*)}{([^}]*)}"
      "${LATEX_TARGET}.\\4" glossary_in ${newglossary}
      )
    MESSAGE("${MAKEINDEX_COMPILER} ${MAKEGLOSSARIES_COMPILER_FLAGS} -s ${istfile} -t ${glossary_log} -o ${glossary_out} ${glossary_in}")
    EXEC_PROGRAM(${MAKEINDEX_COMPILER} ARGS ${MAKEGLOSSARIES_COMPILER_FLAGS}
      -s ${istfile} -t ${glossary_log} -o ${glossary_out} ${glossary_in}
      )
  ENDFOREACH(newglossary)
ENDMACRO(LATEX_MAKEGLOSSARIES)

#############################################################################
# Helper macros for establishing LaTeX build.
#############################################################################

MACRO(LATEX_NEEDIT VAR NAME)
  IF (NOT ${VAR})

dyncall/buildsys/nmake/epilog.nmake  view on Meta::CPAN

# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
#//////////////////////////////////////////////////////////////////////////////

#///////////////////////////////////////////////////
#
#	nmake rules
#	epilog.nmake
#
#///////////////////////////////////////////////////


!INCLUDE common.nmake

dyncall/buildsys/nmake/prolog.nmake  view on Meta::CPAN

# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
#//////////////////////////////////////////////////////////////////////////////

#///////////////////////////////////////////////////
#
#	nmake rules
#	prolog.nmake
#
#///////////////////////////////////////////////////


.SILENT:

# Default "build all" target.
all: configure build


dyncall/buildsys/nmake/tool_msvc.nmake  view on Meta::CPAN

CC  =cl
CXX =cl
AR  =lib
!IF "$(BUILD_ARCH)" == "x64"
AS  =ml64
!ELSE IF "$(BUILD_ARCH)" == "x86"
AS  =ml
!ENDIF
LD  =link

ASFLAGS  = /c /nologo

!IF "$(BUILD_CONFIG)" == "debug"
CFLAGS   = /EHsc /GR- /GS- /Od /c /nologo /I$(TOP)\dyncall /I$(TOP)\dyncallback /DEBUG /Z7
LDFLAGS  = /NOLOGO /DEBUG
ARFLAGS  = /NOLOGO /DEBUG
!ELSE
CFLAGS   = /EHsc /GR- /GS- /Ox /c /nologo /I$(TOP)\dyncall /I$(TOP)\dyncallback
LDFLAGS  = /OPT:REF /OPT:ICF /NOLOGO
ARFLAGS  = /NOLOGO
!ENDIF

CXXFLAGS = $(CFLAGS)


.SUFFIXES:
.SUFFIXES: .obj .exe .dll .lib .pdf .c .cpp .asm .tex .cc

dyncall/doc/disas_examples/arm.armhf.disas  view on Meta::CPAN

  10:   e50b100c        str     r1, [fp, #-12]
  14:   e50b2010        str     r2, [fp, #-16]
  18:   e50b3014        str     r3, [fp, #-20]
  1c:   e28bd000        add     sp, fp, #0
  20:   e8bd0800        pop     {fp}
  24:   e12fff1e        bx      lr

00000028 <nonleaf_call>:
;spill here, if needed: push    {r0, r1, r2, r3}  ; |         just for ref, if present this would change below offsets
  28:   e92d4800        push    {fp, lr}          ; |
  2c:   e28db004        add     fp, sp, #4        ; | prolog
  30:   e24dd020        sub     sp, sp, #32       ; |
  34:   e50b0008        str     r0, [fp, #-8]     ; in arg 0 -> temp space in local area
  38:   e50b100c        str     r1, [fp, #-12]    ; in arg 1 -> temp space in local area
  3c:   e50b2010        str     r2, [fp, #-16]    ; in arg 2 -> temp space in local area
  40:   e50b3014        str     r3, [fp, #-20]    ; in arg 3 -> temp space in local area
  44:   e24dd0e8        sub     sp, sp, #232      ; alloca(220) - with padding to guarantee alignment
  48:   e28d3010        add     r3, sp, #16       ; |
  4c:   e2833007        add     r3, r3, #7        ; |
  50:   e1a031a3        lsr     r3, r3, #3        ; | start of (aligned) alloca()'d memory -> r3, leaving room at top of stack for param area
  54:   e1a03183        lsl     r3, r3, #3        ; |

dyncall/doc/disas_examples/arm.armhf.disas  view on Meta::CPAN

  68:   e59b300c        ldr     r3, [fp, #12]     ; arg 5 (fetched from prev frame's param area), and ...
  6c:   e58d3004        str     r3, [sp, #4]      ; ... "pushed" onto stack
  70:   e59b3010        ldr     r3, [fp, #16]     ; arg 6 (fetched from prev frame's param area), and ...
  74:   e58d3008        str     r3, [sp, #8]      ; ... "pushed" onto stack
  78:   e51b000c        ldr     r0, [fp, #-12]    ; arg 0
  7c:   e51b1010        ldr     r1, [fp, #-16]    ; arg 1
  80:   e51b2014        ldr     r2, [fp, #-20]    ; arg 2
  84:   e59b3004        ldr     r3, [fp, #4]      ; arg 3 (fetched from prev frame's param area)
  88:   ebfffffe        bl      0 <leaf_call>     ; return address -> r14/lr, and call
  8c:   e24bd004        sub     sp, fp, #4        ; |
  90:   e8bd8800        pop     {fp, pc}          ; | epilog

00000094 <main>:
  94:   e92d4800        push    {fp, lr}          ; |
  98:   e28db004        add     fp, sp, #4        ; | prolog
  9c:   e24dd010        sub     sp, sp, #16       ; |
  a0:   e3a03004        mov     r3, #4            ; arg 4, and ...
  a4:   e58d3000        str     r3, [sp]          ; ... "pushed" onto stack
  a8:   e3a03005        mov     r3, #5            ; arg 5, and ...
  ac:   e58d3004        str     r3, [sp, #4]      ; ... "pushed" onto stack
  b0:   e3a03006        mov     r3, #6            ; arg 6, and ...
  b4:   e58d3008        str     r3, [sp, #8]      ; ... "pushed" onto stack
  b8:   e3a03007        mov     r3, #7            ; arg 7, and ...
  bc:   e58d300c        str     r3, [sp, #12]     ; ... "pushed" onto stack
  c0:   e3a00000        mov     r0, #0            ; arg 0
  c4:   e3a01001        mov     r1, #1            ; arg 1
  c8:   e3a02002        mov     r2, #2            ; arg 2
  cc:   e3a03003        mov     r3, #3            ; arg 3
  d0:   ebfffffe        bl      28 <nonleaf_call> ; return address -> r14/lr, and call
  d4:   e3a03000        mov     r3, #0            ; return value (0) via r3 ... (a bit unoptimal)
  d8:   e1a00003        mov     r0, r3            ; ... to r0
  dc:   e24bd004        sub     sp, fp, #4        ; |
  e0:   e8bd8800        pop     {fp, pc}          ; | epilog



; ---------- passing structs with only fp parts ---------->
;
; struct A { float a; };
; struct B { float a, b; };
; struct C { float a, b, c; };
; struct D { double a; };
; struct E { double a, b; };

dyncall/doc/disas_examples/arm.armhf.disas  view on Meta::CPAN

  c8:   e24bc044        sub     ip, fp, #68           ; |    read ptr
  cc:   e8bc000f        ldm     ip!, {r0, r1, r2, r3} ; | arg 6 (struct F), entirely via stack (not split)
  d0:   e8ae000f        stmia   lr!, {r0, r1, r2, r3} ; |
  d4:   e89c0003        ldm     ip, {r0, r1}          ; |
  d8:   e88e0003        stm     lr, {r0, r1}          ; /
  dc:   eeb04b46        vmov.f64        d4, d6        ; \ arg 5 (struct E), via fregs    a
  e0:   eeb05b47        vmov.f64        d5, d7        ; /                                b
  e4:   ebfffffe        bl      0 <leaf_call>         ; return address -> r14/lr, and call
  e8:   e3a03000        mov     r3, #0                ; return value (0) via r3 ... (a bit unoptimal)
  ec:   e1a00003        mov     r0, r3                ; ... to r0
  f0:   e24bd004        sub     sp, fp, #4            ; | epilog
  f4:   e8bd8800        pop     {fp, pc}              ; /
  f8:   00000000        .word   0x00000000            ; \           |
  fc:   3ff00000        .word   0x3ff00000            ; |           | 1.0
 100:   3f800000        .word   0x3f800000            ; |           1.f
 104:   00000000        .word   0x00000000            ; | data
 108:   00000008        .word   0x00000008            ; |
 10c:   00000018        .word   0x00000018            ; |
 110:   00000028        .word   0x00000028            ; |


dyncall/doc/disas_examples/arm.armhf.disas  view on Meta::CPAN

  18:   e28b1004        add     r1, fp, #4            ;
  1c:   e881000c        stm     r1, {r2, r3}          ;
  20:   e1a00000        nop                           ;
  24:   e28bd000        add     sp, fp, #0            ;
  28:   e49db004        pop     {fp}                  ;
  2c:   e28dd008        add     sp, sp, #8            ;
  30:   e12fff1e        bx      lr                    ;

00000034 <main>:
  34:   e92d4800        push    {fp, lr}              ; |
  38:   e28db004        add     fp, sp, #4            ; | prolog
  3c:   e24dd090        sub     sp, sp, #144          ; /
  40:   e59f20b4        ldr     r2, [pc, #180]        ; \        read ptr to data after func
  44:   e24b300c        sub     r3, fp, #12           ; |        write ptr to local area
  48:   e8920003        ldm     r2, {r0, r1}          ; | struct A -> local area
  4c:   e8830003        stm     r3, {r0, r1}          ; /
  50:   e59f30a8        ldr     r3, [pc, #168]        ; \      read ptr to data after func
  54:   e24bc01c        sub     ip, fp, #28           ; |      write ptr
  58:   e893000f        ldm     r3, {r0, r1, r2, r3}  ; | struct B -> local area
  5c:   e88c000f        stm     ip, {r0, r1, r2, r3}  ; /
  60:   e59f309c        ldr     r3, [pc, #156]        ; \      read ptr to data after func

dyncall/doc/disas_examples/arm.armhf.disas  view on Meta::CPAN

  d0:   e8930003        ldm     r3, {r0, r1}          ; |                    |
  d4:   e8820003        stm     r2, {r0, r1}          ; | arg 1 (struct B), split via regs and stack as 2 words each
  d8:   e24b301c        sub     r3, fp, #28           ; |
  dc:   e893000c        ldm     r3, {r2, r3}          ; /                    via regs (first half)
  e0:   e24b100c        sub     r1, fp, #12           ; \
  e4:   e8910003        ldm     r1, {r0, r1}          ; | arg 0 (struct A), via regs as 2 words
  e8:   ebfffffe        bl      0 <leaf_call>         ; return address -> r14/lr, and call
  ec:   e3a03000        mov     r3, #0                ; return value (0) via r3 ... (a bit unoptimal)
  f0:   e1a00003        mov     r0, r3                ; ... to r0
  f4:   e24bd004        sub     sp, fp, #4            ; |
  f8:   e8bd8800        pop     {fp, pc}              ; | epilog
  fc:   00000000        .word   0x00000000            ; 0
 100:   00000008        .word   0x00000008            ; 8
 104:   00000018        .word   0x00000018            ; 24
 108:   00000030        .word   0x00000030            ; 48



; ---------- passing 3-field fp-only struct (HVA) which is bigger than 16b ---------->
;
; struct A { double a, b, c; }; /* bigger than 16b */

dyncall/doc/disas_examples/arm.armhf.disas  view on Meta::CPAN

  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

dyncall/doc/disas_examples/arm.armhf.disas  view on Meta::CPAN

  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 ...



; ---------- C++ trivial and non-trivial aggrs as return values ---------->
;
; struct Trivial { int a; };
; struct NonTrivial { int a; NonTrivial() : a(0) {} NonTrivial(const NonTrivial& rhs) : a(rhs.a) { } };

dyncall/doc/disas_examples/arm.armhf.disas  view on Meta::CPAN

   103f4:       e24dd008        sub     sp, sp, #8
   103f8:       e50b0008        str     r0, [fp, #-8]
   103fc:       e51b0008        ldr     r0, [fp, #-8]
   10400:       eb00001f        bl      10484 <_ZN10NonTrivialC1Ev>
   10404:       e51b0008        ldr     r0, [fp, #-8]  ; ptr to retval space -> r0
   10408:       e24bd004        sub     sp, fp, #4
   1040c:       e8bd8800        pop     {fp, pc}

00010410 <f>:
   10410:       e92d4800        push    {fp, lr}       ; |
   10414:       e28db004        add     fp, sp, #4     ; | prolog
   10418:       e24dd010        sub     sp, sp, #16    ; /
   1041c:       e3a03001        mov     r3, #1         ; \ a = 1
   10420:       e50b3008        str     r3, [fp, #-8]  ; /
   10424:       e51b3008        ldr     r3, [fp, #-8]  ; \
   10428:       e283307b        add     r3, r3, #123   ; | a += 123
   1042c:       e50b3008        str     r3, [fp, #-8]  ; |
   10430:       ebffffe6        bl      103d0 <f1>     ; call f1()
   10434:       e1a03000        mov     r3, r0         ; | retval via r0, as small struct
   10438:       e50b300c        str     r3, [fp, #-12] ; /
   1043c:       e51b3008        ldr     r3, [fp, #-8]  ; \
   10440:       e243307b        sub     r3, r3, #123   ; | a -= 123
   10444:       e50b3008        str     r3, [fp, #-8]  ; |
   10448:       e24b3010        sub     r3, fp, #16    ; space to hold non-triv retval -> eax ...
   1044c:       e1a00003        mov     r0, r3         ; ... as hidden first arg (r0)
   10450:       ebffffe5        bl      103ec <_Z2f2v> ; call f2()
   10454:       e51b3008        ldr     r3, [fp, #-8]  ; |
   10458:       e243300c        sub     r3, r3, #12    ; | a -= 12
   1045c:       e50b3008        str     r3, [fp, #-8]  ; /
   10460:       e1a00000        nop                    ; \
   10464:       e24bd004        sub     sp, fp, #4     ; | epilog
   10468:       e8bd8800        pop     {fp, pc}       ; |



; vim: ft=asm68k

dyncall/doc/disas_examples/arm.atpcs_arm.disas  view on Meta::CPAN

  14:   e50b1014        str     r1, [fp, #-20]
  18:   e50b2018        str     r2, [fp, #-24]
  1c:   e50b301c        str     r3, [fp, #-28]
  20:   e24bd00c        sub     sp, fp, #12     ; 0xc
  24:   e89da800        ldmia   sp, {fp, sp, pc}

00000028 <nonleaf_call>:
  28:   e1a0c00d        mov     ip, sp                 ; |
;spill here, if needed: stmdb   sp!, {r0, r1, r2, r3}  ; |         just for ref, if present this would change below offsets
  2c:   e92dd800        stmdb   sp!, {fp, ip, lr, pc}  ; |
  30:   e24cb004        sub     fp, ip, #4             ; | prolog
  34:   e24dd020        sub     sp, sp, #32            ; |
  38:   e50b0010        str     r0, [fp, #-16]         ; in arg 0 -> temp space in local area
  3c:   e50b1014        str     r1, [fp, #-20]         ; in arg 1 -> temp space in local area
  40:   e50b2018        str     r2, [fp, #-24]         ; in arg 2 -> temp space in local area
  44:   e50b301c        str     r3, [fp, #-28]         ; in arg 3 -> temp space in local area
  48:   e24dd0e0        sub     sp, sp, #224           ; alloca(220) - with padding to guarantee alignment
  4c:   e28d200c        add     r2, sp, #12            ; |
  50:   e50b2020        str     r2, [fp, #-32]         ; |        @@@ pointless push of r2 to local area to put it back ...
  54:   e51b2020        ldr     r2, [fp, #-32]         ; |        @@@ ... into r2
  58:   e2823003        add     r3, r2, #3             ; | start of (aligned) alloca()'d memory -> r3, leaving room at top of stack for param area

dyncall/doc/disas_examples/arm.atpcs_arm.disas  view on Meta::CPAN

  7c:   e59b300c        ldr     r3, [fp, #12]          ; arg 5 (fetched from prev frame's param area), and ...
  80:   e58d3004        str     r3, [sp, #4]           ; ... "pushed" onto stack
  84:   e59b3010        ldr     r3, [fp, #16]          ; arg 6 (fetched from prev frame's param area), and ...
  88:   e58d3008        str     r3, [sp, #8]           ; ... "pushed" onto stack
  8c:   e51b0014        ldr     r0, [fp, #-20]         ; arg 0
  90:   e51b1018        ldr     r1, [fp, #-24]         ; arg 1
  94:   e51b201c        ldr     r2, [fp, #-28]         ; arg 2
  98:   e59b3004        ldr     r3, [fp, #4]           ; arg 3 (fetched from prev frame's param area)
  9c:   ebfffffe        bl      9c <nonleaf_call+0x74> ; return address -> r14/lr, and call
  a0:   e24bd00c        sub     sp, fp, #12            ; |
  a4:   e89da800        ldmia   sp, {fp, sp, pc}       ; | epilog

000000a8 <main>:
  a8:   e1a0c00d        mov     ip, sp                 ; |
  ac:   e92dd800        stmdb   sp!, {fp, ip, lr, pc}  ; |
  b0:   e24cb004        sub     fp, ip, #4             ; | prolog
  b4:   e24dd010        sub     sp, sp, #16            ; |
  b8:   e3a03004        mov     r3, #4                 ; arg 4, and ...
  bc:   e58d3000        str     r3, [sp]               ; ... "pushed" onto stack
  c0:   e3a03005        mov     r3, #5                 ; arg 5, and ...
  c4:   e58d3004        str     r3, [sp, #4]           ; ... "pushed" onto stack
  c8:   e3a03006        mov     r3, #6                 ; arg 6, and ...
  cc:   e58d3008        str     r3, [sp, #8]           ; ... "pushed" onto stack
  d0:   e3a03007        mov     r3, #7                 ; arg 7, and ...
  d4:   e58d300c        str     r3, [sp, #12]          ; ... "pushed" onto stack
  d8:   e3a00000        mov     r0, #0                 ; arg 0
  dc:   e3a01001        mov     r1, #1                 ; arg 1
  e0:   e3a02002        mov     r2, #2                 ; arg 2
  e4:   e3a03003        mov     r3, #3                 ; arg 3
  e8:   ebfffffe        bl      e8 <main+0x40>         ; return address -> r14/lr, and call
  ec:   e3a03000        mov     r3, #0                 ; return value via r3, ... (a bit unoptimal)
  f0:   e1a00003        mov     r0, r3                 ; ... to r0
  f4:   e24bd00c        sub     sp, fp, #12            ; |
  f8:   e89da800        ldmia   sp, {fp, sp, pc}       ; | epilog



; output from freebsd-11.0_r260099-raspberrypi w/ clang 3.3

00000000 <leaf_call>:
   0:   e24dd030        sub     sp, sp, #48     ; 0x30
   4:   e58d002c        str     r0, [sp, #44]
   8:   e58d1028        str     r1, [sp, #40]
   c:   e58d2024        str     r2, [sp, #36]

dyncall/doc/disas_examples/arm.atpcs_arm.disas  view on Meta::CPAN

  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

dyncall/doc/disas_examples/arm.atpcs_arm.disas  view on Meta::CPAN

  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 ...



; ---------- C++ trivial and non-trivial aggrs as return values ---------->
;
; struct Trivial { int a; };
; struct NonTrivial { int a; NonTrivial() : a(0) {} NonTrivial(const NonTrivial& rhs) : a(rhs.a) { } };

dyncall/doc/disas_examples/arm.darwin_arm.disas  view on Meta::CPAN

      20:       0c 20 07 e5     str     r2, [r7, #-12]
      24:       0c 30 8d e5     str     r3, [sp, #12]
      28:       08 e0 8d e5     str     lr, [sp, #8]
      2c:       04 c0 8d e5     str     r12, [sp, #4]
      30:       00 90 8d e5     str     r9, [sp]
      34:       07 d0 a0 e1     mov     sp, r7
      38:       80 80 bd e8     pop     {r7, pc}

_nonleaf_call:
      3c:       b0 40 2d e9     push    {r4, r5, r7, lr}      ; |
      40:       08 70 8d e2     add     r7, sp, #8            ; | prolog
      44:       30 d0 4d e2     sub     sp, sp, #48           ; /
      48:       14 90 97 e5     ldr     r9, [r7, #20]         ; \
      4c:       10 c0 97 e5     ldr     r12, [r7, #16]        ; |
      50:       0c e0 97 e5     ldr     lr, [r7, #12]         ; | in args 4,5,6,7 from prev frame's param area -> regs ...
      54:       08 40 97 e5     ldr     r4, [r7, #8]          ; |
      58:       4c 50 00 e3     movw    r5, #76               ; 'L' -> r5
      5c:       0c 00 07 e5     str     r0, [r7, #-12]        ; in arg 0 -> temp space in local area
      60:       10 10 07 e5     str     r1, [r7, #-16]        ; in arg 1 -> temp space in local area
      64:       14 20 07 e5     str     r2, [r7, #-20]        ; in arg 2 -> temp space in local area
      68:       18 30 07 e5     str     r3, [r7, #-24]        ; in arg 3 -> temp space in local area

dyncall/doc/disas_examples/arm.darwin_arm.disas  view on Meta::CPAN

      88:       18 20 17 e5     ldr     r2, [r7, #-24]        ; arg 2
      8c:       1c 30 9d e5     ldr     r3, [sp, #28]         ; arg 3 (fetched from local area previously copied to)
      90:       18 90 9d e5     ldr     r9, [sp, #24]         ; |
      94:       14 c0 9d e5     ldr     r12, [sp, #20]        ; | args 4,5,6 (fetched from local area previously copied to) -> regs, and ...
      98:       10 e0 9d e5     ldr     lr, [sp, #16]         ; /
      9c:       00 90 8d e5     str     r9, [sp]              ; \
      a0:       04 c0 8d e5     str     r12, [sp, #4]         ; | ... "pushed" onto stack
      a4:       08 e0 8d e5     str     lr, [sp, #8]          ; |
      a8:       d4 ff ff eb     bl      #-176 <_leaf_call>    ; return address -> r14/lr, and call
      ac:       08 d0 47 e2     sub     sp, r7, #8            ; |
      b0:       b0 80 bd e8     pop     {r4, r5, r7, pc}      ; | epilog

_main:
      b4:       90 40 2d e9     push    {r4, r7, lr}          ; |
      b8:       04 70 8d e2     add     r7, sp, #4            ; | prolog
      bc:       14 d0 4d e2     sub     sp, sp, #20           ; |
      c0:       00 00 00 e3     movw    r0, #0                ; arg 0
      c4:       01 10 00 e3     movw    r1, #1                ; arg 1
      c8:       02 20 00 e3     movw    r2, #2                ; arg 2
      cc:       03 30 00 e3     movw    r3, #3                ; arg 3
      d0:       04 90 00 e3     movw    r9, #4                ; |
      d4:       05 c0 00 e3     movw    r12, #5               ; |
      d8:       06 e0 00 e3     movw    lr, #6                ; | args 4,5,6,7 in regs ...
      dc:       07 40 00 e3     movw    r4, #7                ; |
      e0:       08 00 07 e5     str     r0, [r7, #-8]         ; unsure... why place arg 0 in local area? @@@
      e4:       00 90 8d e5     str     r9, [sp]              ; |
      e8:       04 c0 8d e5     str     r12, [sp, #4]         ; |
      ec:       08 e0 8d e5     str     lr, [sp, #8]          ; | ... "push" args 4,5,6,7 onto stack
      f0:       0c 40 8d e5     str     r4, [sp, #12]         ; |
      f4:       d0 ff ff eb     bl      #-192 <_nonleaf_call> ; return address -> r14/lr, and call
      f8:       00 00 00 e3     movw    r0, #0                ; return value
      fc:       04 d0 47 e2     sub     sp, r7, #4            ; |
     100:       90 80 bd e8     pop     {r4, r7, pc}          ; | epilog



; ----------------- with spilling ------------->

; #include <stdarg.h>
;
; void leaf_call(int b, int c, int d, int e, int f, int g, int h)
; {
; }

dyncall/doc/disas_examples/arm.darwin_thumb.disas  view on Meta::CPAN

      1a:       cd f8 08 e0     str.w   lr, [sp, #8]
      1e:       cd f8 04 c0     str.w   r12, [sp, #4]
      22:       cd f8 00 90     str.w   r9, [sp]
      26:       07 b0           add     sp, #28
      28:       80 bd           pop     {r7, pc}

_nonleaf_call:
      2a:       83 b0           sub     sp, #12        ; |        space for spill area (b/c pushing was apparently too easy)
      2c:       80 b5           push    {r7, lr}       ; |
      2e:       6f 46           mov     r7, sp         ; |
      30:       8d b0           sub     sp, #52        ; | prolog
      32:       3b 61           str     r3, [r7, #16]  ; |        |
      34:       fa 60           str     r2, [r7, #12]  ; |        | spill (before reg save area)
      36:       b9 60           str     r1, [r7, #8]   ; |        |
      38:       4c 21           movs    r1, #76
      3a:       0b aa           add     r2, sp, #44
      3c:       0c 90           str     r0, [sp, #48]
      3e:       07 f1 08 00     add.w   r0, r7, #8
      42:       10 60           str     r0, [r2]
      44:       0b 98           ldr     r0, [sp, #44]
      46:       02 1d           adds    r2, r0, #4

dyncall/doc/disas_examples/arm64.aapcs.disas  view on Meta::CPAN

  10:   e3 13 00 b9     str     w3, [sp, #16]
  14:   e4 0f 00 b9     str     w4, [sp, #12]
  18:   e5 0b 00 b9     str     w5, [sp, #8]
  1c:   e6 07 00 b9     str     w6, [sp, #4]
  20:   ff 83 00 91     add     sp, sp, #32
  24:   c0 03 5f d6     ret

nonleaf_call:
  28:   ff 83 04 d1     sub     sp, sp, #288         ; |        includes alloca()'d static space, already
  2c:   fc 83 00 f9     str     x28, [sp, #256]      ; |        (unsure why r28 is preserved @@@)
  30:   fd 7b 11 a9     stp     x29, x30, [sp, #272] ; | prolog
  34:   fd 43 04 91     add     x29, sp, #272        ; |        adjust/set frame pointer (since sp was modified first)
  38:   88 09 80 52     mov     w8, #76              ; 'L' -> w8
  3c:   a0 c3 1e b8     stur    w0, [x29, #-20]      ; in arg 0 -> local area (as temp store)
  40:   a1 83 1e b8     stur    w1, [x29, #-24]      ; in arg 1 -> local area (as temp store)
  44:   a2 43 1e b8     stur    w2, [x29, #-28]      ; in arg 2 -> local area (as temp store)
  48:   a3 03 1e b8     stur    w3, [x29, #-32]      ; in arg 3 -> local area (as temp store)
  4c:   a4 c3 1d b8     stur    w4, [x29, #-36]      ; in arg 4 -> local area (as temp store)
  50:   a5 83 1d b8     stur    w5, [x29, #-40]      ; in arg 5 -> local area (as temp store)
  54:   a6 43 1d b8     stur    w6, [x29, #-44]      ; in arg 6 -> local area (as temp store)
  58:   a7 03 1d b8     stur    w7, [x29, #-48]      ; in arg 7 -> local area (as temp store)

dyncall/doc/disas_examples/arm64.aapcs.disas  view on Meta::CPAN

  60:   a0 83 5e b8     ldur    w0, [x29, #-24]      ; arg 0
  64:   a1 43 5e b8     ldur    w1, [x29, #-28]      ; arg 1
  68:   a2 03 5e b8     ldur    w2, [x29, #-32]      ; arg 2
  6c:   a3 c3 5d b8     ldur    w3, [x29, #-36]      ; arg 3
  70:   a4 83 5d b8     ldur    w4, [x29, #-40]      ; arg 4
  74:   a5 43 5d b8     ldur    w5, [x29, #-44]      ; arg 5
  78:   a6 03 5d b8     ldur    w6, [x29, #-48]      ; arg 6
  7c:   e1 ff ff 97     bl      #-124                ; return address -> r30/lr, and call
  80:   fd 7b 51 a9     ldp     x29, x30, [sp, #272] ; |
  84:   fc 83 40 f9     ldr     x28, [sp, #256]      ; |
  88:   ff 83 04 91     add     sp, sp, #288         ; | epilog
  8c:   c0 03 5f d6     ret                          ; |

main:
  90:   ff 83 00 d1     sub     sp, sp, #32          ; |
  94:   fd 7b 01 a9     stp     x29, x30, [sp, #16]  ; | prolog
  98:   fd 43 00 91     add     x29, sp, #16         ; |
  9c:   08 00 80 52     mov     w8, #0               ; clearing r8 (indirect result location pointer)
  a0:   e1 03 00 32     orr     w1, wzr, #0x1        ; arg 1
  a4:   e2 03 1f 32     orr     w2, wzr, #0x2        ; arg 2
  a8:   e3 07 00 32     orr     w3, wzr, #0x3        ; arg 3
  ac:   e4 03 1e 32     orr     w4, wzr, #0x4        ; arg 4
  b0:   a5 00 80 52     mov     w5, #5               ; arg 5
  b4:   e6 07 1f 32     orr     w6, wzr, #0x6        ; arg 6
  b8:   e7 0b 00 32     orr     w7, wzr, #0x7        ; arg 7
  bc:   bf c3 1f b8     stur    wzr, [x29, #-4]      ; unsure... store a zero in local area@@@
  c0:   e0 03 08 2a     mov     w0, w8               ; arg 0 (= 0 set in w8, above)
  c4:   e8 0b 00 b9     str     w8, [sp, #8]         ; temp storing 0 in local area
  c8:   d8 ff ff 97     bl      #-160                ; return address -> r30/lr, and call
  cc:   e0 0b 40 b9     ldr     w0, [sp, #8]         ; return value (unsure why not just using immediate @@@)
  d0:   fd 7b 41 a9     ldp     x29, x30, [sp, #16]  ; |
  d4:   ff 83 00 91     add     sp, sp, #32          ; | epilog
  d8:   c0 03 5f d6     ret                          ; |



; ---------- same with more args so stack is also used ---------->

; #include <stdlib.h>
;
; void leaf_call(int b, int c, int d, int e, int f, int g, int h, int i, int j)
; {

dyncall/doc/disas_examples/arm64.aapcs.disas  view on Meta::CPAN

      1c:       e5 1b 00 b9     str     w5, [sp, #24]
      20:       e6 17 00 b9     str     w6, [sp, #20]
      24:       e7 13 00 b9     str     w7, [sp, #16]
      28:       e8 0f 00 b9     str     w8, [sp, #12]
      2c:       ff c3 00 91     add     sp, sp, #48
      30:       c0 03 5f d6     ret

0000000000000034 nonleaf_call:
      34:       ff 03 05 d1     sub     sp, sp, #320         ; |        includes alloca()'d static space, already
      38:       fc 93 00 f9     str     x28, [sp, #288]      ; |        (unsure why r28 is preserved @@@)
      3c:       fd 7b 13 a9     stp     x29, x30, [sp, #304] ; | prolog
      40:       fd c3 04 91     add     x29, sp, #304        ; /        adjust/set frame pointer (since sp was modified first)
      44:       a8 13 40 b9     ldr     w8, [x29, #16]       ; \
      48:       a9 1b 40 b9     ldr     w9, [x29, #24]       ; | in args 8,9 from prev frame's param area -> regs, no we have args 0-9 all in r0-r9
      4c:       8a 09 80 52     mov     w10, #76             ; 'L' -> w10
      50:       a0 c3 1e b8     stur    w0, [x29, #-20]      ; |
      54:       a1 83 1e b8     stur    w1, [x29, #-24]      ; |
      58:       a2 43 1e b8     stur    w2, [x29, #-28]      ; |
      5c:       a3 03 1e b8     stur    w3, [x29, #-32]      ; |
      60:       a4 c3 1d b8     stur    w4, [x29, #-36]      ; | ... in args 0,1,2,3,4,5,6,7,8,9 -> temp space in local area ...
      64:       a5 83 1d b8     stur    w5, [x29, #-40]      ; |

dyncall/doc/disas_examples/arm64.aapcs.disas  view on Meta::CPAN

      8c:       a4 83 5d b8     ldur    w4, [x29, #-40]      ; arg 4
      90:       a5 43 5d b8     ldur    w5, [x29, #-44]      ; arg 5
      94:       a6 03 5d b8     ldur    w6, [x29, #-48]      ; arg 6
      98:       a7 c3 5c b8     ldur    w7, [x29, #-52]      ; arg 7
      9c:       a8 83 5c b8     ldur    w8, [x29, #-56]      ; arg 8 -> w8, and ...
      a0:       eb 03 00 91     mov     x11, sp              ; ... with help of x11 (why?) ...
      a4:       68 01 00 b9     str     w8, [x11]            ; ... "pushed" onto to of stack
      a8:       d6 ff ff 97     bl      #-168 <leaf_call>    ; return address -> r30/lr, and call
      ac:       fd 7b 53 a9     ldp     x29, x30, [sp, #304] ; |
      b0:       fc 93 40 f9     ldr     x28, [sp, #288]      ; |
      b4:       ff 03 05 91     add     sp, sp, #320         ; | epilog
      b8:       c0 03 5f d6     ret                          ; |

00000000000000bc main:
      bc:       ff c3 00 d1     sub     sp, sp, #48          ; |
      c0:       fd 7b 02 a9     stp     x29, x30, [sp, #32]  ; | prolog
      c4:       fd 83 00 91     add     x29, sp, #32         ; |
      c8:       08 00 80 52     mov     w8, #0               ; clearing r8 (indirect result location pointer)
      cc:       e1 03 00 32     orr     w1, wzr, #0x1        ; arg 1
      d0:       e2 03 1f 32     orr     w2, wzr, #0x2        ; arg 2
      d4:       e3 07 00 32     orr     w3, wzr, #0x3        ; arg 3
      d8:       e4 03 1e 32     orr     w4, wzr, #0x4        ; arg 4
      dc:       a5 00 80 52     mov     w5, #5               ; arg 5
      e0:       e6 07 1f 32     orr     w6, wzr, #0x6        ; arg 6
      e4:       e7 0b 00 32     orr     w7, wzr, #0x7        ; arg 7
      e8:       e9 03 1d 32     orr     w9, wzr, #0x8        ; arg 8 -> r9

dyncall/doc/disas_examples/arm64.aapcs.disas  view on Meta::CPAN

      f0:       bf c3 1f b8     stur    wzr, [x29, #-4]      ; unsure... store a zero in local area@@@
      f4:       e0 03 08 2a     mov     w0, w8               ; arg 0 (= 0 set in w8, above)
      f8:       eb 03 00 91     mov     x11, sp              ; use sp in x11 (why?), to ...
      fc:       69 01 00 b9     str     w9, [x11]            ; ... place arg 8 on top of stack
     100:       eb 03 00 91     mov     x11, sp              ; use sp in x11 (why?), to ... (set again, pointlessly)
     104:       6a 09 00 b9     str     w10, [x11, #8]       ; ... place arg 9 on stack (next to arg 8)
     108:       a8 83 1f b8     stur    w8, [x29, #-8]       ; temp storing 0 in local area @@@ why?
     10c:       ca ff ff 97     bl      #-216 <nonleaf_call> ; return address -> r30/lr, and call
     110:       a0 83 5f b8     ldur    w0, [x29, #-8]       ; |
     114:       fd 7b 42 a9     ldp     x29, x30, [sp, #32]  ; |
     118:       ff c3 00 91     add     sp, sp, #48          ; | epilog
     11c:       c0 03 5f d6     ret                          ; |



; ---------- for spilling ---------->

; #include <stdlib.h>
; #include <stdarg.h>
;
; void leaf_call(int b, int c, int d, int e, int f, int g, int h, int i, int j)

dyncall/doc/disas_examples/arm64.aapcs.disas  view on Meta::CPAN

      1c:       e5 1b 00 b9     str     w5, [sp, #24]
      20:       e6 17 00 b9     str     w6, [sp, #20]
      24:       e7 13 00 b9     str     w7, [sp, #16]
      28:       e8 0f 00 b9     str     w8, [sp, #12]
      2c:       ff c3 00 91     add     sp, sp, #48
      30:       c0 03 5f d6     ret

0000000000000034 nonleaf_call:
      34:       fc 4f be a9     stp     x28, x19, [sp, #-32]! ; |
      38:       fd 7b 01 a9     stp     x29, x30, [sp, #16]   ; |
      3c:       fd 43 00 91     add     x29, sp, #16          ; | prolog
      40:       ff 83 07 d1     sub     sp, sp, #480          ; |
      44:       f3 03 00 91     mov     x19, sp
      48:       67 56 80 3d     str     q7, [x19, #336]       ; |
      4c:       66 52 80 3d     str     q6, [x19, #320]       ; |
      50:       65 4e 80 3d     str     q5, [x19, #304]       ; |
      54:       64 4a 80 3d     str     q4, [x19, #288]       ; |
      58:       63 46 80 3d     str     q3, [x19, #272]       ; | spill all flot regs (on top of spilled integers, below
      5c:       62 42 80 3d     str     q2, [x19, #256]       ; |
      60:       61 3e 80 3d     str     q1, [x19, #240]       ; |
      64:       60 3a 80 3d     str     q0, [x19, #224]       ; /

dyncall/doc/disas_examples/arm64.aapcs.disas  view on Meta::CPAN

      ac:       ac 03 5f f8     ldur    x12, [x29, #-16]
      b0:       a5 83 5f f8     ldur    x5, [x29, #-8]
      b4:       e4 03 0c aa     mov     x4, x12
      b8:       d2 ff ff 97     bl      #-184 <leaf_call>
      bc:       fd 7b 4a a9     ldp     x29, x30, [sp, #160]
      c0:       ff c3 02 91     add     sp, sp, #176
      c4:       c0 03 5f d6     ret

00000000000000c8 main:
      c8:       ff 03 01 d1     sub     sp, sp, #64          ; |
      cc:       fd 7b 03 a9     stp     x29, x30, [sp, #48]  ; | prolog
      d0:       fd c3 00 91     add     x29, sp, #48         ; |
      d4:       08 00 80 52     mov     w8, #0               ; prep arg 0
      d8:       a9 00 80 52     mov     w9, #5               ; |                              i
      dc:       ea 07 1f 32     orr     w10, wzr, #0x6       ; | prep local struct A's data   j
      e0:       eb 0b 40 b2     orr     x11, xzr, #0x7       ; |                              l
      e4:       e1 03 00 32     orr     w1, wzr, #0x1        ; arg 1
      e8:       e2 03 1f 32     orr     w2, wzr, #0x2        ; arg 2
      ec:       e3 07 00 32     orr     w3, wzr, #0x3        ; arg 3
      f0:       e4 03 1e 32     orr     w4, wzr, #0x4        ; arg 4
      f4:       e7 03 1d 32     orr     w7, wzr, #0x8        ; arg 6

dyncall/doc/disas_examples/arm64.aapcs.disas  view on Meta::CPAN

     114:       ed 13 40 f9     ldr     x13, [sp, #32]       ; 2nd dword of struct A -> x13
     118:       e0 03 08 2a     mov     w0, w8               ; arg 0
     11c:       e5 03 0b aa     mov     x5, x11              ; |
     120:       e6 03 0d aa     mov     x6, x13              ; / arg 5 (struct A), passed in regs as 2 dwords
     124:       eb 03 00 91     mov     x11, sp              ; \
     128:       6c 01 00 b9     str     w12, [x11]           ; | arg 7, pushed onto stack
     12c:       e8 17 00 b9     str     w8, [sp, #20]        ; prep return value, temp store on stack local area
     130:       bf ff ff 97     bl      #-260 <nonleaf_call> ; return address -> r30/lr, and call
     134:       e0 17 40 b9     ldr     w0, [sp, #20]        ; return value (unsure why not just using immediate @@@)
     138:       fd 7b 43 a9     ldp     x29, x30, [sp, #48]  ; |
     13c:       ff 03 01 91     add     sp, sp, #64          ; | epilog
     140:       c0 03 5f d6     ret                          ; |



; output from godbolt compiler explorer w/ msvc 19.14

|leaf_call| PROC
|$LN3|
        sub         sp,sp,#0x30
        str         w0,[sp]

dyncall/doc/disas_examples/arm64.aapcs.disas  view on Meta::CPAN

        bl          __security_pop_cookie
        ldp         fp,lr,[sp],#0x10
        ret

        ENDP  ; |nonleaf_call|

|main|  PROC
|$LN3|
        stp         fp,lr,[sp,#-0x10]!     ; |
        mov         fp,sp                  ; |
        bl          __security_push_cookie ; | prolog
        sub         sp,sp,#0x20            ; /
        mov         w8,#5                  ; \
        str         w8,[sp,#0x10]          ; |                               i
        mov         w8,#6                  ; |
        str         w8,[sp,#0x14]          ; | write struct A to local area  j
        mov         x8,#7                  ; |
        str         x8,[sp,#0x18]          ; /                               l
        mov         w8,#9                  ; \
        str         w8,[sp]                ; | arg 7, pushed onto stack
        mov         w7,#8                  ; arg 6
        ldr         x6,[sp,#0x18]          ; |                                                  l
        ldr         x5,[sp,#0x10]          ; | arg 5 (struct A), passed in regs as 2 dwords     i, j
        mov         w4,#4                  ; arg 4
        mov         w3,#3                  ; arg 3
        mov         w2,#2                  ; arg 2
        mov         w1,#1                  ; arg 1
        mov         w0,#0                  ; arg 0
        bl          nonleaf_call           ; return address -> r30/lr, and call
        mov         w0,#0                  ; return value
        add         sp,sp,#0x20            ; |
        bl          __security_pop_cookie  ; | epilog
        ldp         fp,lr,[sp],#0x10       ; |
        ret                                ; |

        ENDP  ; |main|



; ---------- structs by value, complex example (multiple structs) ---------->
;
; struct A { int i, j; float f; };

dyncall/doc/disas_examples/arm64.aapcs.disas  view on Meta::CPAN

      34:       f3 13 00 fd     str     d19, [sp, #32]
      38:       f2 0f 00 fd     str     d18, [sp, #24]
      3c:       f1 0b 00 fd     str     d17, [sp, #16]
      40:       f0 07 00 fd     str     d16, [sp, #8]
      44:       e7 03 00 fd     str     d7, [sp]
      48:       ff 43 01 91     add     sp, sp, #80
      4c:       c0 03 5f d6     ret

0000000000000050 main:
      50:       ff 43 02 d1     sub     sp, sp, #144                  ; |
      54:       fd 7b 08 a9     stp     x29, x30, [sp, #128]          ; | prolog
      58:       fd 03 02 91     add     x29, sp, #128                 ; /
      5c:       e8 03 1f 2a     mov     w8, wzr                       ; \                 |  |
      60:       a8 c3 1f b8     stur    w8, [x29, #-4]                ; |                 |  | zero 4 bytes in local area @@@ struct padding?
      64:       e9 1b 09 32     orr     w9, wzr, #0x3f800000          ; | struct A   1.f  |
      68:       a9 83 1f b8     stur    w9, [x29, #-8]                ; /                 |
      6c:       e9 03 02 32     orr     w9, wzr, #0x40000000          ; \            2.f  |
      70:       a9 03 1f b8     stur    w9, [x29, #-16]               ; |                 |
      74:       09 08 a8 52     mov     w9, #1077936128               ; | struct B   3.f  |
      78:       a9 43 1f b8     stur    w9, [x29, #-12]               ; /                 |
      7c:       09 10 a8 52     mov     w9, #1082130432               ; \            4.f  |

dyncall/doc/disas_examples/arm64.aapcs.disas  view on Meta::CPAN

      f4:       ea 03 00 91     mov     x10, sp                       ; sp in x10, for below indirections (a bit pointless)
      f8:       53 11 00 fd     str     d19, [x10, #32]               ; \
      fc:       52 0d 00 fd     str     d18, [x10, #24]               ; | arg 5 (struct F), via stack
     100:       51 09 00 fd     str     d17, [x10, #16]               ; /
     104:       50 05 00 fd     str     d16, [x10, #8]                ; \ arg 4 (struct E), via stack (not split across regs and stack)
     108:       47 01 00 fd     str     d7, [x10]                     ; |
     10c:       e8 2f 00 b9     str     w8, [sp, #44]                 ; prep return value, temp store on stack local area
     110:       bc ff ff 97     bl      #-272 <leaf_call>             ; return address -> r30/lr, and call
     114:       e0 2f 40 b9     ldr     w0, [sp, #44]                 ; return value (unsure why not just using immediate @@@)
     118:       fd 7b 48 a9     ldp     x29, x30, [sp, #128]          ; |
     11c:       ff 43 02 91     add     sp, sp, #144                  ; | epilog
     120:       c0 03 5f d6     ret                                   ; |



; output from godbolt compiler explorer w/ msvc 19.14

|leaf_call| PROC
|$LN3|
        sub         sp,sp,#0x30
        str         s0,[sp]

dyncall/doc/disas_examples/arm64.aapcs.disas  view on Meta::CPAN

        str         s5,[sp,#0x20]
        str         d6,[sp,#0x10]
        add         sp,sp,#0x30
        ret

        ENDP  ; |leaf_call|

|main|  PROC
|$LN3|
        stp         fp,lr,[sp,#-0x60]! ; |
        mov         fp,sp              ; | prolog
        sub         sp,sp,#0x30        ; /
        fmov        s16,#1             ; \ struct A   1.f  |
        str         s16,[sp,#0x40]     ; /                 |
        fmov        s16,#2             ; \            2.f  |
        str         s16,[sp,#0x48]     ; |                 |
        fmov        s16,#3             ; | struct B   3.f  |
        str         s16,[sp,#0x4C]     ; /                 |
        fmov        s16,#4             ; \            4.f  |
        str         s16,[sp,#0x58]     ; |                 |
        fmov        s16,#5             ; |            5.f  |

dyncall/doc/disas_examples/arm64.aapcs.disas  view on Meta::CPAN

        ldr         d6,[sp,#0x50]      ; arg 3 (struct D), via reg
        ldr         s5,[sp,#0x60]      ; \
        ldr         s4,[sp,#0x5C]      ; | arg 2 (struct C), via reg
        ldr         s3,[sp,#0x58]      ; /
        ldr         s2,[sp,#0x4C]      ; \
        ldr         s1,[sp,#0x48]      ; / arg 1 (struct B), via reg
        ldr         s0,[sp,#0x40]      ; arg 0 (struct A), via reg
        bl          leaf_call          ; return address -> r30/lr, and call
        mov         w0,#0              ; return value
        add         sp,sp,#0x30        ; |
        ldp         fp,lr,[sp],#0x60   ; | epilog
        ret                            ; |

        ENDP  ; |main|



; ---------- returning structs by value ---------->
;
; struct Small { char x; };
; struct Big { long long i,j,k,l; long m; }; /* bigger than 16b */

dyncall/doc/disas_examples/arm64.aapcs.disas  view on Meta::CPAN

;     struct Big b = f1();
;     return b.j + b.k + b.m + s.x;
; }



; output from freebsd-13.0_r348764-arm64 w/ clang 8.0.0

0000000000000000 f0:
       0:       ff 83 00 d1     sub     sp, sp, #32         ; |
       4:       fe 0b 00 f9     str     x30, [sp, #16]      ; | prolog
       8:       08 00 00 90     adrp    x8, #0              ; compute addr to storage map (probably to #132)
       c:       08 01 00 91     add     x8, x8, #0          ; addr offset (pointless)
      10:       e2 03 40 b2     orr     x2, xzr, #0x1       ; @@@ unsure, #1 -> x2
      14:       e9 3f 00 91     add     x9, sp, #15         ; addr to #132 -> x9 @@@?
      18:       e0 03 09 aa     mov     x0, x9              ; @@@ unsure
      1c:       e1 03 08 aa     mov     x1, x8              ; @@@ unsure
      20:       e9 03 00 f9     str     x9, [sp]            ; store addr to #132 to top of stack
      24:       00 00 00 94     bl      #0 <f0+0x24>        ; @@@unsure
      28:       e8 03 40 f9     ldr     x8, [sp]            ; *sp -> x8
      2c:       0a 01 40 39     ldrb    w10, [x8]           ; *x8 -> w10
      30:       e9 03 0a 2a     mov     w9, w10             ; w10 -> w9
      34:       20 1d 40 d3     ubfx    x0, x9, #0, #8      ; return value ("Unsigned Bit Field Extract", copy 8 bits from x9's LSBits starting at bit 0 to x0, and zero extend; = struct in reg)
      38:       fe 0b 40 f9     ldr     x30, [sp, #16]      ; |
      3c:       ff 83 00 91     add     sp, sp, #32         ; | epilog
      40:       c0 03 5f d6     ret                         ; |

0000000000000044 f1:
      44:       ff 03 01 d1     sub     sp, sp, #64         ; |
      48:       fe 1b 00 f9     str     x30, [sp, #48]      ; | prolog
      4c:       09 00 80 52     mov     w9, #0              ; @@@ unsure
      50:       02 05 80 d2     mov     x2, #40             ; @@@ unsure
      54:       6a 80 83 d2     mov     x10, #7171          ; |                                i
      58:       6b 0c 80 d2     mov     x11, #99            ; |                                j
      5c:       4c 0c 80 92     mov     x12, #-99           ; | prep local struct Big's data   k
      60:       ad 83 81 92     mov     x13, #-3102         ; |                                l
      64:       ee 03 7b b2     orr     x14, xzr, #0x20     ; |                                m
      68:       e0 03 08 aa     mov     x0, x8              ; retval: ptr to retval -> x0
      6c:       e1 03 09 2a     mov     w1, w9              ; @@@ unsure
      70:       e8 17 00 f9     str     x8, [sp, #40]       ; ptr to retval -> local area as temp copy

dyncall/doc/disas_examples/arm64.aapcs.disas  view on Meta::CPAN

      94:       48 01 00 f9     str     x8, [x10]           ; |                       i
      98:       eb 0f 40 f9     ldr     x11, [sp, #24]      ; |                       | j
      9c:       4b 05 00 f9     str     x11, [x10, #8]      ; |                       /
      a0:       ec 0b 40 f9     ldr     x12, [sp, #16]      ; | write retval data     \ k
      a4:       4c 09 00 f9     str     x12, [x10, #16]     ; |                       /
      a8:       ed 07 40 f9     ldr     x13, [sp, #8]       ; |                       \ l
      ac:       4d 0d 00 f9     str     x13, [x10, #24]     ; |                       /
      b0:       ee 03 40 f9     ldr     x14, [sp]           ; |                       \ m
      b4:       4e 11 00 f9     str     x14, [x10, #32]     ; /                       /
      b8:       fe 1b 40 f9     ldr     x30, [sp, #48]      ; \
      bc:       ff 03 01 91     add     sp, sp, #64         ; | epilog
      c0:       c0 03 5f d6     ret                         ; |

00000000000000c4 main:
      c4:       ff 43 01 d1     sub     sp, sp, #80         ;
      c8:       fd 7b 04 a9     stp     x29, x30, [sp, #64] ;
      cc:       fd 03 01 91     add     x29, sp, #64        ;
      d0:       a8 17 00 d1     sub     x8, x29, #5         ;
      d4:       e9 43 00 91     add     x9, sp, #16         ;
      d8:       bf c3 1f b8     stur    wzr, [x29, #-4]     ;
      dc:       e8 07 00 f9     str     x8, [sp, #8]        ;

dyncall/doc/disas_examples/mips.eabi.disas  view on Meta::CPAN

  24:   afca0018        sw      t2,24(s8)
  28:   03c0e821        move    sp,s8
  2c:   8fbe0024        lw      s8,36(sp)
  30:   27bd0028        addiu   sp,sp,40
  34:   03e00008        jr      ra
  38:   00000000        nop

0000003c <nonleaf_call>:
  3c:   27bdffd8        addiu   sp,sp,-40     ; |
  40:   afbf0024        sw      ra,36(sp)     ; |
  44:   afbe0020        sw      s8,32(sp)     ; | prolog
  48:   03a0f021        move    s8,sp         ; /         frame pointer (note: with offset to frame start, but static compared to sp)
  4c:   afc40000        sw      a0,0(s8)      ; \
  50:   afc50004        sw      a1,4(s8)      ; |
  54:   afc60008        sw      a2,8(s8)      ; |
  58:   afc7000c        sw      a3,12(s8)     ; |
  5c:   afc80010        sw      t0,16(s8)     ; | in args 0,1,2,3,4,5,6,7 -> temp space in local area
  60:   afc90014        sw      t1,20(s8)     ; |
  64:   afca0018        sw      t2,24(s8)     ; |
  68:   afcb001c        sw      t3,28(s8)     ; |
  6c:   27bdff18        addiu   sp,sp,-232    ; alloca(220) - with padding to guarantee alignment

dyncall/doc/disas_examples/mips.eabi.disas  view on Meta::CPAN

  94:   8fc6000c        lw      a2,12(s8)     ; |
  98:   8fc70010        lw      a3,16(s8)     ; | arg 0,1,2,3,4,5,6 (fetched from local area stored to above)
  9c:   8fc80014        lw      t0,20(s8)     ; |       (t0 = a4)
  a0:   8fc90018        lw      t1,24(s8)     ; |       (t1 = a5)
  a4:   8fca001c        lw      t2,28(s8)     ; |       (t2 = a6)
  a8:   0c000000        jal     0 <leaf_call> ; call and ret addr -> ra
  ac:   00000000        nop                   ; branch delay slot
  b0:   03c0e821        move    sp,s8         ; |
  b4:   8fbf0024        lw      ra,36(sp)     ; |
  b8:   8fbe0020        lw      s8,32(sp)     ; |
  bc:   27bd0028        addiu   sp,sp,40      ; | epilog
  c0:   03e00008        jr      ra            ; |
  c4:   00000000        nop                   ; |       branch delay slot

000000c8 <main>:
  c8:   27bdfff8        addiu   sp,sp,-8      ; |
  cc:   afbf0004        sw      ra,4(sp)      ; |
  d0:   afbe0000        sw      s8,0(sp)      ; | prolog
  d4:   03a0f021        move    s8,sp         ; |         frame pointer (note: with offset to frame start, but static compared to sp)
  d8:   00002021        move    a0,zero       ; arg 0
  dc:   24050001        li      a1,1          ; arg 1
  e0:   24060002        li      a2,2          ; arg 2
  e4:   24070003        li      a3,3          ; arg 3
  e8:   24080004        li      t0,4          ; arg 4 (t0 = a4)
  ec:   24090005        li      t1,5          ; arg 5 (t1 = a5)
  f0:   240a0006        li      t2,6          ; arg 6 (t2 = a6)
  f4:   240b0007        li      t3,7          ; arg 7 (t3 = a7)
  f8:   0c000000        jal     0 <leaf_call> ; call and ret addr -> ra
  fc:   00000000        nop                   ; branch delay slot
 100:   00001021        move    v0,zero       ; return value
 104:   03c0e821        move    sp,s8         ; |
 108:   8fbf0004        lw      ra,4(sp)      ; |
 10c:   8fbe0000        lw      s8,0(sp)      ; |
 110:   27bd0008        addiu   sp,sp,8       ; | epilog
 114:   03e00008        jr      ra            ; |
 118:   00000000        nop                   ; |       branch delay slot



; ------------- as above but more args to use stack params ----------->

; #include <stdlib.h>
; 
; void leaf_call(int b, int c, int d, int e, int f, int g, int h, int i, int j)

dyncall/doc/disas_examples/mips.eabi.disas  view on Meta::CPAN

  28:   afcb001c        sw      t3,28(s8)
  2c:   03c0e821        move    sp,s8
  30:   8fbe0024        lw      s8,36(sp)
  34:   27bd0028        addiu   sp,sp,40
  38:   03e00008        jr      ra
  3c:   00000000        nop

00000040 <nonleaf_call>:
  40:   27bdffd0        addiu   sp,sp,-48     ; |
  44:   afbf002c        sw      ra,44(sp)     ; |
  48:   afbe0028        sw      s8,40(sp)     ; | prolog
  4c:   03a0f021        move    s8,sp         ; /         frame pointer (note: with offset to frame start, but static compared to sp)
  50:   afc40008        sw      a0,8(s8)      ; \
  54:   afc5000c        sw      a1,12(s8)     ; |
  58:   afc60010        sw      a2,16(s8)     ; |
  5c:   afc70014        sw      a3,20(s8)     ; |
  60:   afc80018        sw      t0,24(s8)     ; | in args 0,1,2,3,4,5,6,7 -> temp space in local area
  64:   afc9001c        sw      t1,28(s8)     ; |
  68:   afca0020        sw      t2,32(s8)     ; |
  6c:   afcb0024        sw      t3,36(s8)     ; |
  70:   27bdff18        addiu   sp,sp,-232    ; alloca(220) - with padding to guarantee alignment

dyncall/doc/disas_examples/mips.eabi.disas  view on Meta::CPAN

  a4:   8fc70018        lw      a3,24(s8)     ; | arg 0,1,2,3,4,5,6 (fetched from local area stored to above)
  a8:   8fc8001c        lw      t0,28(s8)     ; |       (t0 = a4)
  ac:   8fc90020        lw      t1,32(s8)     ; |       (t1 = a5)
  b0:   8fca0024        lw      t2,36(s8)     ; |       (t2 = a6)
  b4:   8fcb0030        lw      t3,48(s8)     ; |       (t3 = a7)
  b8:   0c000000        jal     0 <leaf_call> ; call and ret addr -> ra
  bc:   00000000        nop                   ; branch delay slot
  c0:   03c0e821        move    sp,s8         ; |
  c4:   8fbf002c        lw      ra,44(sp)     ; |
  c8:   8fbe0028        lw      s8,40(sp)     ; |
  cc:   27bd0030        addiu   sp,sp,48      ; | epilog
  d0:   03e00008        jr      ra            ; |
  d4:   00000000        nop                   ; |       branch delay slot

000000d8 <main>:
  d8:   27bdfff0        addiu   sp,sp,-16     ; |
  dc:   afbf000c        sw      ra,12(sp)     ; |
  e0:   afbe0008        sw      s8,8(sp)      ; | prolog
  e4:   03a0f021        move    s8,sp         ; |         frame pointer (note: with offset to frame start, but static compared to sp)
  e8:   24020008        li      v0,8          ; arg 8
  ec:   afa20000        sw      v0,0(sp)      ; ... "pushed" onto stack
  f0:   24020009        li      v0,9          ; arg 9
  f4:   afa20004        sw      v0,4(sp)      ; ... "pushed" onto stack
  f8:   00002021        move    a0,zero       ; arg 0
  fc:   24050001        li      a1,1          ; arg 1
 100:   24060002        li      a2,2          ; arg 2
 104:   24070003        li      a3,3          ; arg 3
 108:   24080004        li      t0,4          ; arg 4 (t0 = a4)
 10c:   24090005        li      t1,5          ; arg 5 (t1 = a5)
 110:   240a0006        li      t2,6          ; arg 6 (t2 = a6)
 114:   240b0007        li      t3,7          ; arg 7 (t3 = a7)
 118:   0c000000        jal     0 <leaf_call> ; call and ret addr -> ra
 11c:   00000000        nop                   ; branch delay slot
 120:   00001021        move    v0,zero       ; return value
 124:   03c0e821        move    sp,s8         ; |
 128:   8fbf000c        lw      ra,12(sp)     ; |
 12c:   8fbe0008        lw      s8,8(sp)      ; |
 130:   27bd0010        addiu   sp,sp,16      ; | epilog
 134:   03e00008        jr      ra            ; |
 138:   00000000        nop                   ; |       branch delay slot



; ------------- with var args to see spilling ----------->

; #include <stdlib.h>
; #include <stdarg.h>
; 

dyncall/doc/disas_examples/mips.eabi.disas  view on Meta::CPAN

  28:   afcb001c        sw      t3,28(s8)
  2c:   03c0e821        move    sp,s8
  30:   8fbe0024        lw      s8,36(sp)
  34:   27bd0028        addiu   sp,sp,40
  38:   03e00008        jr      ra
  3c:   00000000        nop

00000040 <nonleaf_call>:
  40:   27bdffa0        addiu   sp,sp,-96     ; |         leaving 32b extra space adjacent to prev frame's param area for spilling
  44:   afbf003c        sw      ra,60(sp)     ; |
  48:   afbe0038        sw      s8,56(sp)     ; | prolog
  4c:   03a0f021        move    s8,sp         ; /         frame pointer (note: with offset to frame start, but static compared to sp)
  50:   afc50044        sw      a1,68(s8)     ; \
  54:   afc60048        sw      a2,72(s8)     ; |
  58:   afc7004c        sw      a3,76(s8)     ; |
  5c:   afc80050        sw      t0,80(s8)     ; | in args 1,2,3,4,5,6,7 -> spill area in current frame (adjacent to prev frame's param area)
  60:   afc90054        sw      t1,84(s8)     ; |
  64:   afca0058        sw      t2,88(s8)     ; |
  68:   afcb005c        sw      t3,92(s8)     ; |
  6c:   afc40030        sw      a0,48(s8)     ; in arg 0 -> temp space in local area
  70:   27c20060        addiu   v0,s8,96      ; v0 initialized to point ...

dyncall/doc/disas_examples/mips.eabi.disas  view on Meta::CPAN

 164:   8fc70014        lw      a3,20(s8)     ; | arg 0,1,2,3,4,5,6 (fetched from local area stored to above)
 168:   8fc80018        lw      t0,24(s8)     ; |       (t0 = a4)
 16c:   8fc9001c        lw      t1,28(s8)     ; |       (t1 = a5)
 170:   8fca0020        lw      t2,32(s8)     ; |       (t2 = a6)
 174:   8fcb0024        lw      t3,36(s8)     ; |       (t3 = a7)
 178:   0c000000        jal     0 <leaf_call> ; call and ret addr -> ra
 17c:   00000000        nop                   ; branch delay slot
 180:   03c0e821        move    sp,s8         ; |
 184:   8fbf003c        lw      ra,60(sp)     ; |
 188:   8fbe0038        lw      s8,56(sp)     ; |
 18c:   27bd0060        addiu   sp,sp,96      ; | epilog
 190:   03e00008        jr      ra            ; |
 194:   00000000        nop                     |       branch delay slot

00000198 <main>:
 198:   27bdfff0        addiu   sp,sp,-16     ; |
 19c:   afbf000c        sw      ra,12(sp)     ; |
 1a0:   afbe0008        sw      s8,8(sp)      ; | prolog
 1a4:   03a0f021        move    s8,sp         ; |         frame pointer (note: with offset to frame start, but static compared to sp)
 1a8:   24020008        li      v0,8          ; arg 8
 1ac:   afa20000        sw      v0,0(sp)      ; ... "pushed" onto stack
 1b0:   24020009        li      v0,9          ; arg 9
 1b4:   afa20004        sw      v0,4(sp)      ; ... "pushed" onto stack
 1b8:   00002021        move    a0,zero       ; arg 0
 1bc:   24050001        li      a1,1          ; arg 1
 1c0:   24060002        li      a2,2          ; arg 2
 1c4:   24070003        li      a3,3          ; arg 3
 1c8:   24080004        li      t0,4          ; arg 4 (t0 = a4)
 1cc:   24090005        li      t1,5          ; arg 5 (t1 = a5)
 1d0:   240a0006        li      t2,6          ; arg 6 (t2 = a6)
 1d4:   240b0007        li      t3,7          ; arg 7 (t3 = a7)
 1d8:   0c000000        jal     0 <leaf_call> ; call and ret addr -> ra
 1dc:   00000000        nop                   ; branch delay slot
 1e0:   00001021        move    v0,zero       ; return value
 1e4:   03c0e821        move    sp,s8         ; |
 1e8:   8fbf000c        lw      ra,12(sp)     ; |
 1ec:   8fbe0008        lw      s8,8(sp)      ; |
 1f0:   27bd0010        addiu   sp,sp,16      ; | epilog
 1f4:   03e00008        jr      ra            ; |
 1f8:   00000000        nop                   ; |       branch delay slot



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

; #include <stdlib.h>
; #include <stdarg.h>
; 

dyncall/doc/disas_examples/mips.eabi.disas  view on Meta::CPAN

  2c:   e7ce0020        swc1    $f14,32(s8)
  30:   03c0e821        move    sp,s8
  34:   8fbe002c        lw      s8,44(sp)
  38:   27bd0030        addiu   sp,sp,48
  3c:   03e00008        jr      ra
  40:   00000000        nop

00000044 <nonleaf_call>:
  44:   27bdffa8        addiu   sp,sp,-88     ; |         leaving 32b extra space adjacent to prev frame's param area for spilling
  48:   afbf0034        sw      ra,52(sp)     ; |
  4c:   afbe0030        sw      s8,48(sp)     ; | prolog
  50:   03a0f021        move    s8,sp         ; /         frame pointer (note: with offset to frame start, but static compared to sp)
  54:   afc5003c        sw      a1,60(s8)     ; \
  58:   afc60040        sw      a2,64(s8)     ; |
  5c:   afc70044        sw      a3,68(s8)     ; |
  60:   afc80048        sw      t0,72(s8)     ; | in args 1,2,3,4,5 (spread out over 7 param regs) -> spill area in current frame (adjacent to prev frame's param area)
  64:   afc9004c        sw      t1,76(s8)     ; |            this one is just padding
  68:   afca0050        sw      t2,80(s8)     ; |            |
  6c:   afcb0054        sw      t3,84(s8)     ; |            | this is arg 5, passed as a double, spilled like integers
  70:   afc40028        sw      a0,40(s8)     ; in arg 0 -> temp space in local area
  74:   27c20058        addiu   v0,s8,88      ; v0 initialized to point ...

dyncall/doc/disas_examples/mips.eabi.disas  view on Meta::CPAN

 1c4:   c7cc0010        lwc1    $f12,16(s8)   ; arg 4 (float, fetched from local area stored to above)
 1c8:   c7cd0014        lwc1    $f13,20(s8)   ; arg 5 (float, fetched from local area stored to above)
 1cc:   8fc80018        lw      t0,24(s8)     ; arg 6 (int, fetched from local area stored to above, t0 = a4)
 1d0:   8fc9001c        lw      t1,28(s8)     ; arg 7 (int, fetched from local area stored to above, t1 = a5)
 1d4:   c7ce0020        lwc1    $f14,32(s8)   ; arg 9 (float, fetched from local area stored to above)
 1d8:   0c000000        jal     0 <leaf_call> ; call and ret addr -> ra
 1dc:   00000000        nop                   ; branch delay slot
 1e0:   03c0e821        move    sp,s8         ; |
 1e4:   8fbf0034        lw      ra,52(sp)     ; |
 1e8:   8fbe0030        lw      s8,48(sp)     ; |
 1ec:   27bd0058        addiu   sp,sp,88      ; | epilog
 1f0:   03e00008        jr      ra            ; |
 1f4:   00000000        nop                   ; |       branch delay slot

000001f8 <main>:
 1f8:   27bdffe0        addiu   sp,sp,-32     ; |
 1fc:   afbf001c        sw      ra,28(sp)     ; |
 200:   afbe0018        sw      s8,24(sp)     ; | prolog
 204:   03a0f021        move    s8,sp         ; /         frame pointer (note: with offset to frame start, but static compared to sp)
 208:   8f8a0000        lw      t2,0(gp)      ; \
 20c:   8f8b0004        lw      t3,4(gp)      ; / arg 5 (t1,t2 = a4,a5), as double b/c of vararg, effectively skipping t1 (=a5)
 210:   8f820008        lw      v0,8(gp)      ; \
 214:   8f83000c        lw      v1,12(gp)     ; | arg 6, as double b/c of vararg, via v0 and v1 ...
 218:   afa20000        sw      v0,0(sp)      ; |
 21c:   afa30004        sw      v1,4(sp)      ; | ... "pushed" onto stack
 220:   24020007        li      v0,7          ; arg 7
 224:   afa20008        sw      v0,8(sp)      ; ... "pushed" onto stack
 228:   24020008        li      v0,8          ; arg 8

dyncall/doc/disas_examples/mips.eabi.disas  view on Meta::CPAN

 244:   24050001        li      a1,1          ; arg 1
 248:   24060002        li      a2,2          ; arg 2
 24c:   24070003        li      a3,3          ; arg 3
 250:   24080004        li      t0,4          ; arg 4 (t0 = a4)
 254:   0c000000        jal     0 <leaf_call> ; call and ret addr -> ra
 258:   00000000        nop                   ; branch delay slot
 25c:   00001021        move    v0,zero       ; return value
 260:   03c0e821        move    sp,s8         ; |
 264:   8fbf001c        lw      ra,28(sp)     ; |
 268:   8fbe0018        lw      s8,24(sp)     ; |
 26c:   27bd0020        addiu   sp,sp,32      ; | epilog
 270:   03e00008        jr      ra            ; |
 274:   00000000        nop                   ; |       branch delay slot



; --------------------- further notes ------------------->

; when passing less arguments than stack params, involving an ellipsis, spill area still spills all registers,
; excluding named ones, e.g.:
;

dyncall/doc/disas_examples/mips.o32.disas  view on Meta::CPAN

  24:   afc70014        sw      a3,20(s8)
  28:   03c0e821        move    sp,s8
  2c:   8fbe0000        lw      s8,0(sp)
  30:   03e00008        jr      ra
  34:   27bd0008        addiu   sp,sp,8

00000038 <nonleaf_call>:
  38:   3c1c0000        lui     gp,0x0     ; |
  3c:   279c0000        addiu   gp,gp,0    ; |
  40:   0399e021        addu    gp,gp,t9   ; |
  44:   27bdffc8        addiu   sp,sp,-56  ; | prolog
  48:   afbf0034        sw      ra,52(sp)  ; |
  4c:   afbe0030        sw      s8,48(sp)  ; |
  50:   03a0f021        move    s8,sp      ; |         frame pointer (note: with offset to frame start, but static compared to sp)
  54:   afbc0020        sw      gp,32(sp)  ; /
  58:   afc40038        sw      a0,56(s8)  ; \
  5c:   afc5003c        sw      a1,60(s8)  ; |
  60:   afc60040        sw      a2,64(s8)  ; | spill first 4 args into prev frame's reserved spill space in param area (although not actually needing to spill, here but just do a temp copy, but space is reserved for them anyways)
  64:   afc70044        sw      a3,68(s8)  ; |
  68:   27bdff18        addiu   sp,sp,-232 ; alloca(220) - with padding to guarantee alignment
  6c:   27a20020        addiu   v0,sp,32   ; |

dyncall/doc/disas_examples/mips.o32.disas  view on Meta::CPAN

  ac:   8fc4003c        lw      a0,60(s8)  ; arg 0 (fetched from spill area of prev frame)
  b0:   8fc50040        lw      a1,64(s8)  ; arg 1 (fetched from spill area of prev frame)
  b4:   8fc60044        lw      a2,68(s8)  ; arg 2 (fetched from spill area of prev frame)
  b8:   8fc70048        lw      a3,72(s8)  ; arg 3 (fetched from prev frame's param area)
  bc:   8f990000        lw      t9,0(gp)   ; func to call -> t9
  c0:   0320f809        jalr    t9         ; call and ret addr -> ra
  c4:   00000000        nop                ; branch delay slot
  c8:   8fdc0020        lw      gp,32(s8)  ; |
  cc:   03c0e821        move    sp,s8      ; |
  d0:   8fbf0034        lw      ra,52(sp)  ; |
  d4:   8fbe0030        lw      s8,48(sp)  ; | epilog
  d8:   03e00008        jr      ra         ; |
  dc:   27bd0038        addiu   sp,sp,56   ; |

000000e0 <main>:
  e0:   3c1c0000        lui     gp,0x0     ; |
  e4:   279c0000        addiu   gp,gp,0    ; |
  e8:   0399e021        addu    gp,gp,t9   ; |
  ec:   27bdffd0        addiu   sp,sp,-48  ; | prolog
  f0:   afbf002c        sw      ra,44(sp)  ; |
  f4:   afbe0028        sw      s8,40(sp)  ; |
  f8:   03a0f021        move    s8,sp      ; |         frame pointer (note: with offset to frame start, but static compared to sp)
  fc:   afbc0020        sw      gp,32(sp)  ; |
 100:   24020004        li      v0,4       ; arg 4, and ...
 104:   afa20010        sw      v0,16(sp)  ; ... "pushed" onto stack
 108:   24020005        li      v0,5       ; arg 5, and ...
 10c:   afa20014        sw      v0,20(sp)  ; ... "pushed" onto stack
 110:   24020006        li      v0,6       ; arg 6, and ...
 114:   afa20018        sw      v0,24(sp)  ; ... "pushed" onto stack
 118:   24020007        li      v0,7       ; arg 7, and ...
 11c:   afa2001c        sw      v0,28(sp)  ; ... "pushed" onto stack
 120:   00002021        move    a0,zero    ; arg 0
 124:   24050001        li      a1,1       ; arg 1
 128:   24060002        li      a2,2       ; arg 2
 12c:   24070003        li      a3,3       ; arg 3
 130:   8f990000        lw      t9,0(gp)   ; func to call -> t9
 134:   0320f809        jalr    t9         ; call and ret addr -> ra
 138:   00000000        nop                ; branch delay slot
 13c:   8fdc0020        lw      gp,32(s8)  ; |
 140:   00001021        move    v0,zero    ; :        return value: not part of epilog, but unordered (branch delay slot style)
 144:   03c0e821        move    sp,s8      ; |
 148:   8fbf002c        lw      ra,44(sp)  ; | epilog
 14c:   8fbe0028        lw      s8,40(sp)  ; |
 150:   03e00008        jr      ra         ; |
 154:   27bd0030        addiu   sp,sp,48   ; |



; output from netbsd-5.0.2-pmax_mipsel_o32 w/ gcc 4.1.3 ----->
; nearly the same, equivalent to above except non-optimal use of branch delay slots and $gp preserving in leaf call

00000000 <leaf_call>:

dyncall/doc/disas_examples/mips.o32.disas  view on Meta::CPAN

  e4:   03c0e821        move    sp,s8
  e8:   8fbf009c        lw      ra,156(sp)
  ec:   8fbe0098        lw      s8,152(sp)
  f0:   03e00008        jr      ra
  f4:   27bd00a0        addiu   sp,sp,160

000000f8 <main>:
  f8:   3c1c0000        lui     gp,0x0    ; |
  fc:   279c0000        addiu   gp,gp,0   ; |
 100:   0399e021        addu    gp,gp,t9  ; |
 104:   27bdffb0        addiu   sp,sp,-80 ; | prolog
 108:   afbf004c        sw      ra,76(sp) ; |
 10c:   afbe0048        sw      s8,72(sp) ; |
 110:   03a0f021        move    s8,sp     ; |         frame pointer (note: with offset to frame start, but static compared to sp)
 114:   afbc0030        sw      gp,48(sp) ; /
 118:   8f820000        lw      v0,0(gp)  ; \                               \
 11c:   24420000        addiu   v0,v0,0   ; |                               | field j -> v0
 120:   8c420000        lw      v0,0(v0)  ; |                               /
 124:   8f830000        lw      v1,0(gp)  ; |                               \
 128:   24630000        addiu   v1,v1,0   ; |                               | field j -> v1
 12c:   8c630004        lw      v1,4(v1)  ; | prep local struct A data ...  /

dyncall/doc/disas_examples/mips.o32.disas  view on Meta::CPAN

 188:   24020009        li      v0,9      ; push arg 7 ...
 18c:   afa2002c        sw      v0,44(sp) ; ... onto stack
 190:   00002021        move    a0,zero   ; arg 0
 194:   24050001        li      a1,1      ; arg 1
 198:   24060002        li      a2,2      ; arg 2
 19c:   24070003        li      a3,3      ; arg 3
 1a0:   8f990000        lw      t9,0(gp)  ; func to call -> t9
 1a4:   0320f809        jalr    t9        ; call and ret addr -> ra
 1a8:   00000000        nop               ; branch delay slot
 1ac:   8fdc0030        lw      gp,48(s8) ; |
 1b0:   00001021        move    v0,zero   ; :        return value: not part of epilog, but unordered (branch delay slot style)
 1b4:   03c0e821        move    sp,s8     ; |
 1b8:   8fbf004c        lw      ra,76(sp) ; | epilog
 1bc:   8fbe0048        lw      s8,72(sp) ; |
 1c0:   03e00008        jr      ra        ; |
 1c4:   27bd0050        addiu   sp,sp,80  ; |
        ...



; output from freebsd-12.0_r333647-malta_mipsebhf w/ gcc 4.2.1 *and* -mhard-float ----->

00000000 <leaf_call>:

dyncall/doc/disas_examples/mips.o32.disas  view on Meta::CPAN

  e4:   03c0e821        move    sp,s8
  e8:   8fbf009c        lw      ra,156(sp)
  ec:   8fbe0098        lw      s8,152(sp)
  f0:   03e00008        jr      ra
  f4:   27bd00a0        addiu   sp,sp,160

000000f8 <main>:
  f8:   3c1c0000        lui     gp,0x0    ; |
  fc:   279c0000        addiu   gp,gp,0   ; |
 100:   0399e021        addu    gp,gp,t9  ; |
 104:   27bdffb0        addiu   sp,sp,-80 ; | prolog
 108:   afbf004c        sw      ra,76(sp) ; |
 10c:   afbe0048        sw      s8,72(sp) ; |
 110:   03a0f021        move    s8,sp     ; |         frame pointer (note: with offset to frame start, but static compared to sp)
 114:   afbc0030        sw      gp,48(sp) ; /
 118:   8f820000        lw      v0,0(gp)  ; \                               \
 11c:   24420000        addiu   v0,v0,0   ; |                               | field j -> v0
 120:   8c420000        lw      v0,0(v0)  ; |                               /
 124:   8f830000        lw      v1,0(gp)  ; |                               \
 128:   24630000        addiu   v1,v1,0   ; |                               | field j -> v1
 12c:   8c630004        lw      v1,4(v1)  ; | prep local struct A data ...  /

dyncall/doc/disas_examples/mips.o32.disas  view on Meta::CPAN

 188:   24020009        li      v0,9      ; push arg 7 ...
 18c:   afa2002c        sw      v0,44(sp) ; ... onto stack
 190:   00002021        move    a0,zero   ; arg 0
 194:   24050001        li      a1,1      ; arg 1
 198:   24060002        li      a2,2      ; arg 2
 19c:   24070003        li      a3,3      ; arg 3
 1a0:   8f990000        lw      t9,0(gp)  ; func to call -> t9
 1a4:   0320f809        jalr    t9        ; call and ret addr -> ra
 1a8:   00000000        nop               ; branch delay slot
 1ac:   8fdc0030        lw      gp,48(s8) ; |
 1b0:   00001021        move    v0,zero   ; :        return value: not part of epilog, but unordered (branch delay slot style)
 1b4:   03c0e821        move    sp,s8     ; |
 1b8:   8fbf004c        lw      ra,76(sp) ; | epilog
 1bc:   8fbe0048        lw      s8,72(sp) ; |
 1c0:   03e00008        jr      ra        ; |
 1c4:   27bd0050        addiu   sp,sp,80  ; |
        ...



; ---------- structs by value, complex example (multiple structs) ---------->
;
; struct A { int i, j; float f; };

dyncall/doc/disas_examples/mips.o32.disas  view on Meta::CPAN

 12c:   03c0e821        move    sp,s8
 130:   8fbf00c4        lw      ra,196(sp)
 134:   8fbe00c0        lw      s8,192(sp)
 138:   03e00008        jr      ra
 13c:   27bd00c8        addiu   sp,sp,200

00000140 <main>:
 140:   3c1c0000        lui     gp,0x0     ; |
 144:   279c0000        addiu   gp,gp,0    ; |
 148:   0399e021        addu    gp,gp,t9   ; |
 14c:   27bdff58        addiu   sp,sp,-168 ; | prolog
 150:   afbf00a4        sw      ra,164(sp) ; |
 154:   afbe00a0        sw      s8,160(sp) ; |
 158:   03a0f021        move    s8,sp      ; |         frame pointer (note: with offset to frame start, but static compared to sp)
 15c:   afbc0058        sw      gp,88(sp)  ; /
 160:   8f820000        lw      v0,0(gp)   ; \                                       |
 164:   24420030        addiu   v0,v0,48   ; |                                       | field j -> v0
 168:   8c420000        lw      v0,0(v0)   ; |                                       /
 16c:   8f830000        lw      v1,0(gp)   ; | prep (first) local struct A data ...  \
 170:   24630030        addiu   v1,v1,48   ; |                                       | field j -> v1
 174:   8c630004        lw      v1,4(v1)   ; |                                       /

dyncall/doc/disas_examples/mips.o32.disas  view on Meta::CPAN

 2b8:   8fc20098        lw      v0,152(s8) ; |                          | f (via stack, first slot after save area)
 2bc:   afa20010        sw      v0,16(sp)  ; |                          |   note that 20(sp) isn't used, so sizeof(struct A) is probably a padded 16
 2c0:   8fc60090        lw      a2,144(s8) ; | arg 2 (first struct A)     i (via reg)
 2c4:   8fc70094        lw      a3,148(s8) ; |                            j (via reg)
 2c8:   00002021        move    a0,zero    ; arg 0
 2cc:   24050001        li      a1,1       ; arg 1
 2d0:   8f990000        lw      t9,0(gp)   ; func to call -> t9
 2d4:   0320f809        jalr    t9         ; call and ret addr -> ra
 2d8:   00000000        nop                ; branch delay slot
 2dc:   8fdc0058        lw      gp,88(s8)  ; |
 2e0:   00001021        move    v0,zero    ; :        return value: not part of epilog, but unordered (branch delay slot style)
 2e4:   03c0e821        move    sp,s8      ; |
 2e8:   8fbf00a4        lw      ra,164(sp) ; | epilog
 2ec:   8fbe00a0        lw      s8,160(sp) ; |
 2f0:   03e00008        jr      ra         ; |
 2f4:   27bd00a8        addiu   sp,sp,168  ; |
        ...



; output from freebsd-12.0_r333647-malta_mipsebhf w/ gcc 4.2.1 *and* -mhard-float ----->

00000000 <leaf_call>:

dyncall/doc/disas_examples/mips.o32.disas  view on Meta::CPAN

 12c:   03c0e821        move    sp,s8
 130:   8fbf00c4        lw      ra,196(sp)
 134:   8fbe00c0        lw      s8,192(sp)
 138:   03e00008        jr      ra
 13c:   27bd00c8        addiu   sp,sp,200

00000140 <main>:
 140:   3c1c0000        lui     gp,0x0     ; |
 144:   279c0000        addiu   gp,gp,0    ; |
 148:   0399e021        addu    gp,gp,t9   ; |
 14c:   27bdff58        addiu   sp,sp,-168 ; | prolog
 150:   afbf00a4        sw      ra,164(sp) ; |
 154:   afbe00a0        sw      s8,160(sp) ; |
 158:   03a0f021        move    s8,sp      ; |         frame pointer (note: with offset to frame start, but static compared to sp)
 15c:   afbc0058        sw      gp,88(sp)  ; /
 160:   8f820000        lw      v0,0(gp)   ; \                                       |
 164:   24420030        addiu   v0,v0,48   ; |                                       | field j -> v0
 168:   8c420000        lw      v0,0(v0)   ; |                                       /
 16c:   8f830000        lw      v1,0(gp)   ; | prep (first) local struct A data ...  \
 170:   24630030        addiu   v1,v1,48   ; |                                       | field j -> v1
 174:   8c630004        lw      v1,4(v1)   ; |                                       /

dyncall/doc/disas_examples/mips.o32.disas  view on Meta::CPAN

 2b8:   8fc20098        lw      v0,152(s8) ; |                          | f (via stack, first slot after save area)
 2bc:   afa20010        sw      v0,16(sp)  ; |                          |   note that 20(sp) isn't used, so sizeof(struct A) is probably a padded 16
 2c0:   8fc60090        lw      a2,144(s8) ; | arg 2 (first struct A)     i (via reg)
 2c4:   8fc70094        lw      a3,148(s8) ; |                            j (via reg)
 2c8:   00002021        move    a0,zero    ; arg 0
 2cc:   24050001        li      a1,1       ; arg 1
 2d0:   8f990000        lw      t9,0(gp)   ; func to call -> t9
 2d4:   0320f809        jalr    t9         ; call and ret addr -> ra
 2d8:   00000000        nop                ; branch delay slot
 2dc:   8fdc0058        lw      gp,88(s8)  ; |
 2e0:   00001021        move    v0,zero    ; :        return value: not part of epilog, but unordered (branch delay slot style)
 2e4:   03c0e821        move    sp,s8      ; |
 2e8:   8fbf00a4        lw      ra,164(sp) ; | epilog
 2ec:   8fbe00a0        lw      s8,160(sp) ; |
 2f0:   03e00008        jr      ra         ; |
 2f4:   27bd00a8        addiu   sp,sp,168  ; |
        ...



; ---------- returning structs by value ---------->
; 
; struct Small { char x; };

dyncall/doc/disas_examples/mips.o32.disas  view on Meta::CPAN

;     return b.j + b.k + b.m + s.x;
; }



; output from freebsd-12.0_r333647-malta_mipsebhf w/ gcc 4.2.1 ----->

00000000 <f0>:
   0:   3c1c0000        lui     gp,0x0    ; |
   4:   279c0000        addiu   gp,gp,0   ; |
   8:   0399e021        addu    gp,gp,t9  ; | prolog
   c:   27bdffe8        addiu   sp,sp,-24 ; |
  10:   afbe0010        sw      s8,16(sp) ; |
  14:   03a0f021        move    s8,sp     ; |
  18:   00801021        move    v0,a0     ; hidden first arg (ptr to struct ret) -> v0
  1c:   2403ff84        li      v1,-124   ; | put together local struct
  20:   a3c30008        sb      v1,8(s8)  ; /
  24:   93c30008        lbu     v1,8(s8)  ; read struct data from local area ...
  28:   a0430000        sb      v1,0(v0)  ; ... and write to return value area
  2c:   03c0e821        move    sp,s8     ; \
  30:   8fbe0010        lw      s8,16(sp) ; |
  34:   03e00008        jr      ra        ; | epilog
  38:   27bd0018        addiu   sp,sp,24  ; |

0000003c <f1>:
  3c:   3c1c0000        lui     gp,0x0    ; |
  40:   279c0000        addiu   gp,gp,0   ; |
  44:   0399e021        addu    gp,gp,t9  ; |
  48:   27bdffb0        addiu   sp,sp,-80 ; |
  4c:   afbf0048        sw      ra,72(sp) ; | prolog
  50:   afbe0044        sw      s8,68(sp) ; |
  54:   afb00040        sw      s0,64(sp) ; |
  58:   03a0f021        move    s8,sp     ; |
  5c:   afbc0010        sw      gp,16(sp) ; |
  60:   00808021        move    s0,a0     ; hidden first arg (ptr to struct ret) -> s0
  64:   27c20018        addiu   v0,s8,24  ;
  68:   8f830000        lw      v1,0(gp)  ;
  6c:   24630000        addiu   v1,v1,0   ;
  70:   24060028        li      a2,40     ;
  74:   00402021        move    a0,v0     ;

dyncall/doc/disas_examples/mips.o32.disas  view on Meta::CPAN

  88:   8fdc0010        lw      gp,16(s8) ;
  8c:   02001021        move    v0,s0     ;
  90:   27c30018        addiu   v1,s8,24  ;
  94:   24060028        li      a2,40     ;
  98:   00402021        move    a0,v0     ;
  9c:   00602821        move    a1,v1     ;
  a0:   8f990000        lw      t9,0(gp)  ;
  a4:   0320f809        jalr    t9        ;
  a8:   00000000        nop               ;
  ac:   8fdc0010        lw      gp,16(s8) ; |
  b0:   02001021        move    v0,s0     ; :        return value (hidden ptr): not part of epilog, but unordered (branch delay slot style)
  b4:   03c0e821        move    sp,s8     ; |
  b8:   8fbf0048        lw      ra,72(sp) ; |
  bc:   8fbe0044        lw      s8,68(sp) ; | epilog
  c0:   8fb00040        lw      s0,64(sp) ; |
  c4:   03e00008        jr      ra        ; |
  c8:   27bd0050        addiu   sp,sp,80  ; |

000000cc <main>:
  cc:   3c1c0000        lui     gp,0x0    ; |
  d0:   279c0000        addiu   gp,gp,0   ; |
  d4:   0399e021        addu    gp,gp,t9  ; |
  d8:   27bdffb0        addiu   sp,sp,-80 ; |
  dc:   afbf004c        sw      ra,76(sp) ; | prolog
  e0:   afbe0048        sw      s8,72(sp) ; |
  e4:   03a0f021        move    s8,sp     ; |
  e8:   afbc0010        sw      gp,16(sp) ; /
  ec:   27c20018        addiu   v0,s8,24  ; \
  f0:   00402021        move    a0,v0     ; | hidden first arg (ptr to space for ret val)
  f4:   8f990000        lw      t9,0(gp)  ; func to call (f0) -> t9
  f8:   0320f809        jalr    t9        ; call and ret addr -> ra
  fc:   00000000        nop               ; branch delay slot
 100:   8fdc0010        lw      gp,16(s8) ; restore gp @@@ unsure why?
 104:   27c20020        addiu   v0,s8,32  ; |

dyncall/doc/disas_examples/mips.o32.disas  view on Meta::CPAN

 128:   8fc30034        lw      v1,52(s8) ; |                |
 12c:   8fc20030        lw      v0,48(s8) ; |                | b.j -> v0 & v1
 130:   00601021        move    v0,v1     ; | return value   v0 = (int)b.k
 134:   00821821        addu    v1,a0,v0  ; |                (int)b.j + (int)b.k -> v1
 138:   8fc20040        lw      v0,64(s8) ; |                b.m -> v0
 13c:   00621821        addu    v1,v1,v0  ; |                ((int)b.j + (int)b.k) + b.m -> v1
 140:   83c20018        lb      v0,24(s8) ; |                s.x -> v0
 144:   00621021        addu    v0,v1,v0  ; /                (((int)b.j + (int)b.k) + b.m) + s.x -> v0
 148:   03c0e821        move    sp,s8     ; \
 14c:   8fbf004c        lw      ra,76(sp) ; |
 150:   8fbe0048        lw      s8,72(sp) ; | epilog
 154:   03e00008        jr      ra        ; |
 158:   27bd0050        addiu   sp,sp,80  ; |
 15c:   00000000        nop               ; |



; output from freebsd-12.0_r333647-malta_mipsebhf w/ gcc 4.2.1 *and* -mhard-float ----->

00000000 <f0>:
   0:   3c1c0000        lui     gp,0x0

dyncall/doc/disas_examples/mips.o32.disas  view on Meta::CPAN

  24:   afc70014        sw      a3,20(s8)
  28:   03c0e821        move    sp,s8
  2c:   8fbe0000        lw      s8,0(sp)
  30:   03e00008        jr      ra
  34:   27bd0008        addiu   sp,sp,8

00000038 <main>:
  38:   3c1c0000        lui     gp,0x0     ; |
  3c:   279c0000        addiu   gp,gp,0    ; |
  40:   0399e021        addu    gp,gp,t9   ; |
  44:   27bdff60        addiu   sp,sp,-160 ; | prolog
  48:   afbf009c        sw      ra,156(sp) ; |
  4c:   afbe0098        sw      s8,152(sp) ; |
  50:   03a0f021        move    s8,sp      ; |         frame pointer (note: with offset to frame start, but static compared to sp)
  54:   afbc0048        sw      gp,72(sp)  ; /
  58:   8f820000        lw      v0,0(gp)   ; \
  5c:   24420044        addiu   v0,v0,68   ; | prep local struct A data ...
  60:   8c420000        lw      v0,0(v0)   ; /
  64:   afc20094        sw      v0,148(s8) ; ... and write to local area
  68:   8f820000        lw      v0,0(gp)   ; \
  6c:   2442003c        addiu   v0,v0,60   ; |

dyncall/doc/disas_examples/mips.o32.disas  view on Meta::CPAN

 1e0:   afa20010        sw      v0,16(sp)  ; | arg 2 (struct C)            b (via stack)
 1e4:   afa30014        sw      v1,20(sp)  ; |                             c (via stack)
 1e8:   8fc70080        lw      a3,128(s8) ; |                             a (via reg)
 1ec:   8fc40094        lw      a0,148(s8) ; arg 0 (struct A, via reg)
 1f0:   8fc5008c        lw      a1,140(s8) ; | arg 1 (struct B, via regs)  a
 1f4:   8fc60090        lw      a2,144(s8) ; |                             b
 1f8:   8f990000        lw      t9,0(gp)   ; func to call -> t9
 1fc:   0320f809        jalr    t9         ; call and ret addr -> ra
 200:   00000000        nop                ; branch delay slot
 204:   8fdc0048        lw      gp,72(s8)  ; |
 208:   00001021        move    v0,zero    ; :        return value: not part of epilog, but unordered (branch delay slot style)
 20c:   03c0e821        move    sp,s8      ; |
 210:   8fbf009c        lw      ra,156(sp) ; | epilog
 214:   8fbe0098        lw      s8,152(sp) ; |
 218:   03e00008        jr      ra         ; |
 21c:   27bd00a0        addiu   sp,sp,160  ; |



; output from freebsd-12.0_r333647-malta_mipsebhf w/ gcc 4.2.1 *and* -mhard-float ----->

00000000 <leaf_call>:
   0:   3c1c0000        lui     gp,0x0

dyncall/doc/disas_examples/mips.o32.disas  view on Meta::CPAN

  24:   afc70014        sw      a3,20(s8)
  28:   03c0e821        move    sp,s8
  2c:   8fbe0000        lw      s8,0(sp)
  30:   03e00008        jr      ra
  34:   27bd0008        addiu   sp,sp,8

00000038 <main>:
  38:   3c1c0000        lui     gp,0x0      ; |
  3c:   279c0000        addiu   gp,gp,0     ; |
  40:   0399e021        addu    gp,gp,t9    ; |
  44:   27bdff60        addiu   sp,sp,-160  ; | prolog
  48:   afbf009c        sw      ra,156(sp)  ; |
  4c:   afbe0098        sw      s8,152(sp)  ; |
  50:   03a0f021        move    s8,sp       ; |         frame pointer (note: with offset to frame start, but static compared to sp)
  54:   afbc0048        sw      gp,72(sp)   ; /
  58:   8f810000        lw      at,0(gp)    ; \
  5c:   24210044        addiu   at,at,68    ; | prep local struct A (single float field) data ...
  60:   c4200000        lwc1    $f0,0(at)   ; /
  64:   e7c00094        swc1    $f0,148(s8) ; ... and write to local area
  68:   8f820000        lw      v0,0(gp)    ; \
  6c:   2442003c        addiu   v0,v0,60    ; |

dyncall/doc/disas_examples/mips.o32.disas  view on Meta::CPAN

 1c8:   afa20010        sw      v0,16(sp)   ; | arg 2 (struct C)            b (via stack)
 1cc:   afa30014        sw      v1,20(sp)   ; |                             c (via stack)
 1d0:   8fc70080        lw      a3,128(s8)  ; |                             a (via reg)
 1d4:   8fc40094        lw      a0,148(s8)  ; arg 0 (struct A, via reg)
 1d8:   8fc5008c        lw      a1,140(s8)  ; | arg 1 (struct B, via regs)  a
 1dc:   8fc60090        lw      a2,144(s8)  ; |                             b
 1e0:   8f990000        lw      t9,0(gp)    ; func to call -> t9
 1e4:   0320f809        jalr    t9          ; call and ret addr -> ra
 1e8:   00000000        nop                 ; branch delay slot
 1ec:   8fdc0048        lw      gp,72(s8)   ; |
 1f0:   00001021        move    v0,zero     ; :        return value: not part of epilog, but unordered (branch delay slot style)
 1f4:   03c0e821        move    sp,s8       ; |
 1f8:   8fbf009c        lw      ra,156(sp)  ; | epilog
 1fc:   8fbe0098        lw      s8,152(sp)  ; |
 200:   03e00008        jr      ra          ; |
 204:   27bd00a0        addiu   sp,sp,160   ; |
        ...                                  
                                             
                                             
                                             
; ---------- single-field structs by values (and small array fields) ---------->
;
; struct C { char c; };

dyncall/doc/disas_examples/mips.o32.disas  view on Meta::CPAN

  4008cc:       ac400000        sw      zero,0(v0)    ; return val
  4008d0:       03c0e821        move    sp,s8
  4008d4:       8fbe0000        lw      s8,0(sp)
  4008d8:       03e00008        jr      ra
  4008dc:       27bd0008        addiu   sp,sp,8

004008e0 <_Z2f2v>:
  4008e0:       3c1c0002        lui     gp,0x2        ; |
  4008e4:       279c82e0        addiu   gp,gp,-32032  ; |
  4008e8:       0399e021        addu    gp,gp,t9      ; |
  4008ec:       27bdffd8        addiu   sp,sp,-40     ; | prolog
  4008f0:       afbf0020        sw      ra,32(sp)     ; |
  4008f4:       afbe001c        sw      s8,28(sp)     ; |
  4008f8:       afb00018        sw      s0,24(sp)     ; |
  4008fc:       03a0f021        move    s8,sp         ; |         frame pointer (note: with offset to frame start, but static compared to sp)
  400900:       afbc0010        sw      gp,16(sp)     ;
  400904:       00808021        move    s0,a0         ;
  400908:       02001021        move    v0,s0         ;
  40090c:       00402021        move    a0,v0         ;
  400910:       8f998060        lw      t9,-32672(gp) ;
  400914:       0320f809        jalr    t9            ;
  400918:       00000000        nop                   ;
  40091c:       8fdc0010        lw      gp,16(s8)     ;
  400920:       02001021        move    v0,s0         ; ptr to retval space -> v0
  400924:       03c0e821        move    sp,s8         ; |
  400928:       8fbf0020        lw      ra,32(sp)     ; |
  40092c:       8fbe001c        lw      s8,28(sp)     ; |
  400930:       8fb00018        lw      s0,24(sp)     ; | epilog
  400934:       03e00008        jr      ra            ; |
  400938:       27bd0028        addiu   sp,sp,40      ; |

0040093c <f>:
  40093c:       3c1c0002        lui     gp,0x2        ;
  400940:       279c8284        addiu   gp,gp,-32124  ;
  400944:       0399e021        addu    gp,gp,t9      ;
  400948:       27bdffd0        addiu   sp,sp,-48     ;
  40094c:       afbf002c        sw      ra,44(sp)     ;
  400950:       afbe0028        sw      s8,40(sp)     ;

dyncall/doc/disas_examples/mips64.n64.disas  view on Meta::CPAN

  70:   03c0e82d        move    sp,s8
  74:   dfbe0028        ld      s8,40(sp)
  78:   dfbc0020        ld      gp,32(sp)
  7c:   03e00008        jr      ra
  80:   67bd0030        daddiu  sp,sp,48
  84:   00000000        nop

0000000000000088 <nonleaf_call>:
  88:   67bdff90        daddiu  sp,sp,-112 ; |
  8c:   ffbf0060        sd      ra,96(sp)  ; |
  90:   ffbe0058        sd      s8,88(sp)  ; | prolog
  94:   ffbc0050        sd      gp,80(sp)  ; |
  98:   03a0f02d        move    s8,sp      ; |
  9c:   3c1c0000        lui     gp,0x0     ; @@@ unsure
  a0:   0399e02d        daddu   gp,gp,t9   ; @@@ unsure
  a4:   679c0000        daddiu  gp,gp,0    ; @@@ unsure
  a8:   0080102d        move    v0,a0      ; |
  ac:   00a0182d        move    v1,a1      ; |
  b0:   00c0202d        move    a0,a2      ; | pointlessly (?) moving a{0,1} to v{0,1} respectively,
  b4:   00e0282d        move    a1,a3      ; | and all last 6 a? registers two regs down, freeing up
  b8:   0100302d        move    a2,a4      ; | a{6,7}, which aren't used for anything though

dyncall/doc/disas_examples/mips64.n64.disas  view on Meta::CPAN

 144:   8fc90018        lw      a5,24(s8)  ; arg 5
 148:   8fca001c        lw      a6,28(s8)  ; arg 6
 14c:   0040202d        move    a0,v0      ; arg 0
 150:   0060282d        move    a1,v1      ; arg 1
 154:   df990000        ld      t9,0(gp)   ; addr of callee -> t9
 158:   0320f809        jalr    t9         ; return address -> ra, and call
 15c:   00000000        nop                ; branch delay slot
 160:   03c0e82d        move    sp,s8      ; |
 164:   dfbf0060        ld      ra,96(sp)  ; |
 168:   dfbe0058        ld      s8,88(sp)  ; |
 16c:   dfbc0050        ld      gp,80(sp)  ; | epilog
 170:   03e00008        jr      ra         ; |
 174:   67bd0070        daddiu  sp,sp,112  ; |         branch delay slot style

0000000000000178 <main>:
 178:   67bdffe0        daddiu  sp,sp,-32  ; |
 17c:   ffbf0010        sd      ra,16(sp)  ; |
 180:   ffbe0008        sd      s8,8(sp)   ; | prolog
 184:   ffbc0000        sd      gp,0(sp)   ; |
 188:   03a0f02d        move    s8,sp      ; |
 18c:   3c1c0000        lui     gp,0x0     ; @@@ unsure
 190:   0399e02d        daddu   gp,gp,t9   ; @@@ unsure
 194:   679c0000        daddiu  gp,gp,0    ; @@@ unsure
 198:   0000202d        move    a0,zero    ; arg 0
 19c:   24050001        li      a1,1       ; arg 1
 1a0:   24060002        li      a2,2       ; arg 2
 1a4:   24070003        li      a3,3       ; arg 3
 1a8:   24080004        li      a4,4       ; arg 4
 1ac:   24090005        li      a5,5       ; arg 5
 1b0:   240a0006        li      a6,6       ; arg 6
 1b4:   240b0007        li      a7,7       ; arg 7
 1b8:   df990000        ld      t9,0(gp)   ; address of callee -> t9
 1bc:   0320f809        jalr    t9         ; return address -> ra, and call
 1c0:   00000000        nop                ; branch delay slot
 1c4:   0000102d        move    v0,zero    ; return value
 1c8:   03c0e82d        move    sp,s8      ; |
 1cc:   dfbf0010        ld      ra,16(sp)  ; |
 1d0:   dfbe0008        ld      s8,8(sp)   ; |
 1d4:   dfbc0000        ld      gp,0(sp)   ; | epilog
 1d8:   03e00008        jr      ra         ; |
 1dc:   67bd0020        daddiu  sp,sp,32   ; |         branch delay slot style



; output from debian-sid_20150616-malta_mips64el_n64 w/ gcc 4.9.2

0000000000000000 <leaf_call>:
   0:   67bdffd0        daddiu  sp,sp,-48
   4:   ffbe0028        sd      s8,40(sp)

dyncall/doc/disas_examples/mips64.n64.disas  view on Meta::CPAN

  58:   afc20018        sw      v0,24(s8)
  5c:   03c0e82d        move    sp,s8
  60:   dfbe0028        ld      s8,40(sp)
  64:   67bd0030        daddiu  sp,sp,48
  68:   03e00008        jr      ra
  6c:   00200825        move    at,at

0000000000000070 <nonleaf_call>:
  70:   67bdffc0        daddiu  sp,sp,-64  ; |
  74:   ffbf0038        sd      ra,56(sp)  ; |
  78:   ffbe0030        sd      s8,48(sp)  ; | prolog
  7c:   ffbc0028        sd      gp,40(sp)  ; |
  80:   03a0f02d        move    s8,sp      ; |
  84:   3c1c0000        lui     gp,0x0     ; @@@ unsure
  88:   0399e02d        daddu   gp,gp,t9   ; @@@ unsure
  8c:   679c0000        daddiu  gp,gp,0    ; @@@ unsure
  90:   0080702d        move    t2,a0      ; |
  94:   00a0682d        move    t1,a1      ; |
  98:   00c0602d        move    t0,a2      ; | pointlessly (?) moving regs around, freeing effectively
  9c:   00e0302d        move    a2,a3      ; | some registers for use below, still unnecessary though
  a0:   0100282d        move    a1,a4      ; | with different code below

dyncall/doc/disas_examples/mips64.n64.disas  view on Meta::CPAN

 128:   8fc2001c        lw      v0,28(s8)  ; prep arg 5 (pointlessly) to move to a5 below
 12c:   0060482d        move    a5,v1      ; arg 5
 130:   0040502d        move    a6,v0      ; arg 6
 134:   df820000        ld      v0,0(gp)   ; addr of callee ...
 138:   0040c82d        move    t9,v0      ; ... -> t9
 13c:   0320f809        jalr    t9         ; return address -> ra, and call
 140:   00200825        move    at,at      ; branch delay slot (effectively nop)
 144:   03c0e82d        move    sp,s8      ; |
 148:   dfbf0038        ld      ra,56(sp)  ; |
 14c:   dfbe0030        ld      s8,48(sp)  ; |
 150:   dfbc0028        ld      gp,40(sp)  ; | epilog
 154:   67bd0040        daddiu  sp,sp,64   ; |
 158:   03e00008        jr      ra         ; |
 15c:   00200825        move    at,at      ; |         branch delay slot (effectively nop)

0000000000000160 <main>:
 160:   67bdffe0        daddiu  sp,sp,-32  ; |
 164:   ffbf0018        sd      ra,24(sp)  ; |
 168:   ffbe0010        sd      s8,16(sp)  ; | prolog
 16c:   ffbc0008        sd      gp,8(sp)   ; |
 170:   03a0f02d        move    s8,sp      ; |
 174:   3c1c0000        lui     gp,0x0     ; @@@ unsure
 178:   0399e02d        daddu   gp,gp,t9   ; @@@ unsure
 17c:   679c0000        daddiu  gp,gp,0    ; @@@ unsure
 180:   0000202d        move    a0,zero    ; arg 0
 184:   24050001        li      a1,1       ; arg 1
 188:   24060002        li      a2,2       ; arg 2
 18c:   24070003        li      a3,3       ; arg 3
 190:   24080004        li      a4,4       ; arg 4

dyncall/doc/disas_examples/mips64.n64.disas  view on Meta::CPAN

 198:   240a0006        li      a6,6       ; arg 6
 19c:   240b0007        li      a7,7       ; arg 7
 1a0:   df820000        ld      v0,0(gp)   ; address of callee, to ...
 1a4:   0040c82d        move    t9,v0      ; ... t9
 1a8:   0320f809        jalr    t9         ; return address -> ra, and call
 1ac:   00200825        move    at,at      ; branch delay slot (effectively nop)
 1b0:   0000102d        move    v0,zero    ; return value
 1b4:   03c0e82d        move    sp,s8      ; |
 1b8:   dfbf0018        ld      ra,24(sp)  ; |
 1bc:   dfbe0010        ld      s8,16(sp)  ; |
 1c0:   dfbc0008        ld      gp,8(sp)   ; | epilog
 1c4:   67bd0020        daddiu  sp,sp,32   ; |
 1c8:   03e00008        jr      ra         ; |
 1cc:   00200825        move    at,at      ; |         branch delay slot (effectively nop)



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

; #include <stdlib.h>
; #include <stdarg.h>

dyncall/doc/disas_examples/mips64.n64.disas  view on Meta::CPAN

  58:   afc2001c        sw      v0,28(s8)
  5c:   03c0e82d        move    sp,s8
  60:   dfbe0028        ld      s8,40(sp)
  64:   67bd0030        daddiu  sp,sp,48
  68:   03e00008        jr      ra
  6c:   00200825        move    at,at

0000000000000070 <nonleaf_call>:
  70:   67bdff50        daddiu  sp,sp,-176  ; |         leaving 64b extra space adjacent to prev frame's param area for spilling
  74:   ffbf0068        sd      ra,104(sp)  ; |
  78:   ffbe0060        sd      s8,96(sp)   ; | prolog
  7c:   ffbc0058        sd      gp,88(sp)   ; |
  80:   03a0f02d        move    s8,sp       ; |
  84:   3c1c0000        lui     gp,0x0      ; @@@ unsure
  88:   0399e02d        daddu   gp,gp,t9    ; @@@ unsure
  8c:   679c0000        daddiu  gp,gp,0     ; @@@ unsure
  90:   ffc50078        sd      a1,120(s8)  ; |
  94:   ffc60080        sd      a2,128(s8)  ; |
  98:   ffc70088        sd      a3,136(s8)  ; |
  9c:   ffc80090        sd      a4,144(s8)  ; | in args 1,2,3,4,5,6,7 -> spill area in current frame (adjacent to prev frame's param area)
  a0:   ffc90098        sd      a5,152(s8)  ; |

dyncall/doc/disas_examples/mips64.n64.disas  view on Meta::CPAN

 1e0:   c7d10024        lwc1    $f17,36(s8) ; arg 5 (so skipping f12-f15)
 1e4:   0100502d        move    a6,a4       ; arg 6 (from a4 used as temp reg, pointlessly)
 1e8:   0060582d        move    a7,v1       ; arg 7
 1ec:   df820000        ld      v0,0(gp)    ; address of callee, to ...
 1f0:   0040c82d        move    t9,v0       ; ... t9
 1f4:   0320f809        jalr    t9          ; return address -> ra, and call
 1f8:   00200825        move    at,at       ; branch delay slot (effectively nop)
 1fc:   03c0e82d        move    sp,s8       ; |
 200:   dfbf0068        ld      ra,104(sp)  ; |
 204:   dfbe0060        ld      s8,96(sp)   ; |
 208:   dfbc0058        ld      gp,88(sp)   ; | epilog
 20c:   67bd00b0        daddiu  sp,sp,176   ; |
 210:   03e00008        jr      ra          ; |
 214:   00200825        move    at,at       ; |         branch delay slot (effectively nop)

0000000000000218 <main>:
 218:   67bdffd0        daddiu  sp,sp,-48   ; |
 21c:   ffbf0028        sd      ra,40(sp)   ; |
 220:   ffbe0020        sd      s8,32(sp)   ; | prolog
 224:   ffbc0018        sd      gp,24(sp)   ; |
 228:   03a0f02d        move    s8,sp       ; |
 22c:   3c1c0000        lui     gp,0x0      ; unsure@@@
 230:   0399e02d        daddu   gp,gp,t9    ; unsure@@@
 234:   679c0000        daddiu  gp,gp,0     ; unsure@@@
 238:   df820000        ld      v0,0(gp)    ; arg 6 (float promoted to double), from static data (0 b/c objdmp is from .o, not final linked exec), ...
 23c:   d4410000        ldc1    $f1,0(v0)   ; ... to f1
 240:   df820000        ld      v0,0(gp)    ; arg 5 (float promoted to double), from static data (0 b/c objdmp is from .o, not final linked exec), ...
 244:   d4400000        ldc1    $f0,0(v0)   ; ... to f0
 248:   24020008        li      v0,8        ; arg 8, ...

dyncall/doc/disas_examples/mips64.n64.disas  view on Meta::CPAN

 274:   442a0000        dmfc1   a6,$f0      ; arg 6 (note: passed in a6 b/c vararg)
 278:   240b0007        li      a7,7        ; arg 7
 27c:   df820000        ld      v0,0(gp)    ; address of callee, to ...
 280:   0040c82d        move    t9,v0       ; ... t9
 284:   0320f809        jalr    t9          ; return address -> ra, and call
 288:   00200825        move    at,at       ; branch delay slot (effectively nop)
 28c:   03c0e82d        move    sp,s8       ; |
 290:   dfbf0028        ld      ra,40(sp)   ; |
 294:   dfbe0020        ld      s8,32(sp)   ; |
 298:   dfbc0018        ld      gp,24(sp)   ; |
 29c:   67bd0030        daddiu  sp,sp,48    ; | epilog
 2a0:   03e00008        jr      ra          ; |
 2a4:   00200825        move    at,at       ; |         branch delay slot (effectively nop)
 2a8:   00200825        move    at,at       ; |         ? @@@
 2ac:   00200825        move    at,at       ; |         ? @@@



; ---------- simple float arg (uses fp regs on hard-float) ---------->
;
; float f(float f) { return f; }

dyncall/doc/disas_examples/ppc.darwin.disas  view on Meta::CPAN

      1c:       90 fe 00 58     stw 7, 88(30)
      20:       91 1e 00 5c     stw 8, 92(30)
      24:       91 3e 00 60     stw 9, 96(30)
      28:       80 21 00 00     lwz 1, 0(1)
      2c:       bb c1 ff f8     lmw 30, -8(1)
      30:       4e 80 00 20     blr

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

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



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

; #include <stdlib.h>
; 
; void leaf_call(int b, int c, int d, int e, int f, int g, int h, int i, int j)

dyncall/doc/disas_examples/ppc.darwin.disas  view on Meta::CPAN

      20:       91 1e 00 5c     stw 8, 92(30)
      24:       91 3e 00 60     stw 9, 96(30)
      28:       91 5e 00 64     stw 10, 100(30)
      2c:       80 21 00 00     lwz 1, 0(1)
      30:       bb c1 ff f8     lmw 30, -8(1)
      34:       4e 80 00 20     blr

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

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



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

; #include <stdlib.h>
; #include <stdarg.h>
; 

dyncall/doc/disas_examples/ppc.darwin.disas  view on Meta::CPAN

      24:       91 3e 00 60     stw 9, 96(30)
      28:       91 5e 00 64     stw 10, 100(30)
      2c:       d0 7e 00 68     stfs 3, 104(30)
      30:       80 21 00 00     lwz 1, 0(1)
      34:       bb c1 ff f8     lmw 30, -8(1)
      38:       4e 80 00 20     blr

_nonleaf_call:
      3c:       7c 08 02 a6     mflr 0          ; |
      40:       bf c1 ff f8     stmw 30, -8(1)  ; |
      44:       90 01 00 08     stw 0, 8(1)     ; | prolog
      48:       94 21 ff 70     stwu 1, -144(1) ; |
      4c:       7c 3e 0b 78     mr 30, 1        ; /
      50:       90 9e 00 ac     stw 4, 172(30)  ; \
      54:       90 be 00 b0     stw 5, 176(30)  ; |
      58:       90 de 00 b4     stw 6, 180(30)  ; |
      5c:       90 fe 00 b8     stw 7, 184(30)  ; |
      60:       91 1e 00 bc     stw 8, 188(30)  ; | in args ,1,2,3,4,5,6,7 -> spill area in prev frame
      64:       91 3e 00 c0     stw 9, 192(30)  ; |
      68:       91 5e 00 c4     stw 10, 196(30) ; |
      6c:       90 7e 00 a8     stw 3, 168(30)  ; |                  <- this is in arg 0, the only named arg

dyncall/doc/disas_examples/ppc.darwin.disas  view on Meta::CPAN

     134:       90 1e 00 74     stw 0, 116(30)  ; | in arg 8
     138:       80 09 00 00     lwz 0, 0(9)     ; |
     13c:       90 1e 00 64     stw 0, 100(30)  ; /
     140:       81 3e 00 74     lwz 9, 116(30)  ; \
     144:       80 5e 00 74     lwz 2, 116(30)  ; |
     148:       38 02 00 08     addi 0, 2, 8    ; |
     14c:       90 1e 00 74     stw 0, 116(30)  ; | in arg 9 (float, promoted to double)
     150:       c8 09 00 00     lfd 0, 0(9)     ; |
     154:       fc 00 00 18     frsp 0, 0       ; |
     158:       d0 1e 00 70     stfs 0, 112(30) ; /
     15c:       80 01 00 00     lwz 0, 0(1)     ; fetch back-chain ptr (parent frame's sp) from stack of top by prolog -> gpr0, and ...
     160:       94 01 ff 10     stwu 0, -240(1) ; ... update it further up the stack for alloca
     164:       38 41 00 50     addi 2, 1, 80   ; |
     168:       38 02 00 0f     addi 0, 2, 15   ; | start of alloca()'d memory -> gpr2, by ...
     16c:       54 00 e1 3e     srwi 0, 0, 4    ; | ... using gpr0 as helper to align to 16b, l
     170:       54 02 20 36     slwi 2, 0, 4    ; |
     174:       38 00 00 4c     li 0, 76        ; 'L' -> gpr0, and ...
     178:       98 02 00 00     stb 0, 0(2)     ; ... store in local area (of alloca()'d space)
     17c:       80 7e 00 50     lwz 3, 80(30)   ; arg 0
     180:       80 9e 00 54     lwz 4, 84(30)   ; arg 1
     184:       80 be 00 58     lwz 5, 88(30)   ; arg 2
     188:       80 de 00 5c     lwz 6, 92(30)   ; arg 3
     18c:       c0 3e 00 68     lfs 1, 104(30)  ; arg 4 (float)
     190:       c0 5e 00 6c     lfs 2, 108(30)  ; arg 5 (float)
     194:       81 3e 00 60     lwz 9, 96(30)   ; arg 6
     198:       81 5e 00 64     lwz 10, 100(30) ; arg 7
     19c:       c0 7e 00 70     lfs 3, 112(30)  ; arg 8 (float)
     1a0:       4b ff fe 61     bl .+67108448   ; call and put return address -> lr
     1a4:       80 21 00 00     lwz 1, 0(1)     ; |
     1a8:       80 01 00 08     lwz 0, 8(1)     ; |
     1ac:       7c 08 03 a6     mtlr 0          ; | epilog
     1b0:       bb c1 ff f8     lmw 30, -8(1)   ; |
     1b4:       4e 80 00 20     blr             ; |

_main:
     1b8:       7c 08 02 a6     mflr 0          ; |
     1bc:       bf c1 ff f8     stmw 30, -8(1)  ; |
     1c0:       90 01 00 08     stw 0, 8(1)     ; | prolog
     1c4:       94 21 ff 90     stwu 1, -112(1) ; |
     1c8:       7c 3e 0b 78     mr 30, 1        ; |
     1cc:       42 9f 00 05     bcl 20, 31, .+4 ; ppc way to get PC in ...
     1d0:       7f e8 02 a6     mflr 31         ; ... gpr31
     1d4:       38 00 00 07     li 0, 7         ; arg 7, ...
     1d8:       90 01 00 3c     stw 0, 60(1)    ; ... "pushed" onto stack
     1dc:       38 00 00 08     li 0, 8         ; arg 8, ...
     1e0:       90 01 00 40     stw 0, 64(1)    ; ... "pushed" onto stack
     1e4:       3c 40 40 22     lis 2, 16418    ; | arg 9, top-half (double b/c of vararg), and ...
     1e8:       38 60 00 00     li 3, 0         ; | ... bottom-half ...

dyncall/doc/disas_examples/ppc.darwin.disas  view on Meta::CPAN

     234:       3c 5f 00 00     addis 2, 31, 0  ; PC -> gpr2, to ...
     238:       c8 02 00 a0     lfd 0, 160(2)   ; ... load some static data (arg 6, the 2nd float) stored right after this function -> gpr0
     23c:       7d 6a 5b 78     mr 10, 11       ; arg 6, top-half
     240:       fc 40 00 90     fmr 2, 0        ; arg 5 in 2nd fp reg
     244:       c8 01 00 44     lfd 0, 68(1)    ; arg 9, ...
     248:       fc 60 00 90     fmr 3, 0        ; ... -> 3rd fp reg
     24c:       4b ff fd f1     bl .+67108336   ; call and put return address -> lr
     250:       7c 03 03 78     mr 3, 0         ; return value @@@unsure why gpr0 is guaranteed to be 0 here
     254:       80 21 00 00     lwz 1, 0(1)     ; |
     258:       80 01 00 08     lwz 0, 8(1)     ; |
     25c:       7c 08 03 a6     mtlr 0          ; | epilog
     260:       bb c1 ff f8     lmw 30, -8(1)   ; |
     264:       4e 80 00 20     blr             ; |



; ---------- structs by value ---------->
;
; struct A { int i, j; long long l; };
;
; void leaf_call(int b, int c, int d, int e, struct A f, int g, int h)

dyncall/doc/disas_examples/ppc.darwin.disas  view on Meta::CPAN

00000144	li	r3,0x0             ; arg 0
00000148	li	r4,0x1             ; arg 1
0000014c	li	r5,0x2             ; arg 2
00000150	li	r6,0x3             ; arg 3
00000154	li	r7,0x4             ; arg 4
00000158	bl	0x38               ; call and put return address -> lr
0000015c	li	r0,0x0             ; return value (pointlessly) via gpr0 ...
00000160	or	r3,r0,r0           ; ... to gpr3
00000164	lwz	r1,0x0(r1)         ; |
00000168	lwz	r0,0x8(r1)         ; |
0000016c	mtspr	lr,r0          ; | epilog
00000170	lmw	r30,0xfff8(r1)     ; |
00000174	blr                    ; |



; ---------- single-field structs by value (of different sizes) ---------->
;
; struct C { char c;   }; // <= 2 bytes, but normal alignment as passed like a char
; struct S { short s;  }; // <= 2 bytes, but normal alignment as passed like a short
; struct I { int i;    };

dyncall/doc/disas_examples/ppc.darwin.disas  view on Meta::CPAN

00000014	sth	r5,0x60(r30)
00000018	stw	r6,0x64(r30)
0000001c	stfs	f1,0x68(r30)
00000020	stfd	f2,0x20(r30)
00000024	lwz	r1,0x0(r1)
00000028	lmw	r30,0xfff8(r1)
0000002c	blr
_main:
00000030	mfspr	r0,lr          ; |
00000034	stmw	r30,0xfff8(r1) ; |
00000038	stw	r0,0x8(r1)         ; | prolog
0000003c	stwu	r1,0xff80(r1)  ; |
00000040	or	r30,r1,r1          ; |
00000044	bcl	20,31,0x48         ; ppc way to get PC in ...
00000048	mfspr	r31,lr         ; ... gpr31
0000004c	li	r0,0x0             ; |                          \
00000050	stb	r0,0x40(r30)       ; |                          |
00000054	li	r0,0x1             ; |                          | C2
00000058	stb	r0,0x41(r30)       ; |                          /
0000005c	li	r0,0x2             ; | local area struct init   \ C
00000060	stb	r0,0x42(r30)       ; |                          /

dyncall/doc/disas_examples/ppc.darwin.disas  view on Meta::CPAN

000000bc	lhz	r5,0x44(r30)       ; arg 2 (struct S)
000000c0	lwz	r6,0x48(r30)       ; arg 3 (struct I)
000000c4	lfs	f1,0x4c(r30)       ; arg 4 (struct F, int arg reg r7 then skipped)
000000c8	lfd	f2,0x50(r30)       ; arg 5 (struct D, int arg regs r8 and r9 then skipped)
000000cc	lwz	r10,0x34(r1)       ; arg 6 (struct C3, fetched from local area)
000000d0	bl	0x0                ; call and put return address -> lr
000000d4	li	r0,0x0             ; return value (pointlessly) via gpr0 ...
000000d8	or	r3,r0,r0           ; ... to gpr3
000000dc	lwz	r1,0x0(r1)         ; |
000000e0	lwz	r0,0x8(r1)         ; |
000000e4	mtspr	lr,r0          ; | epilog
000000e8	lmw	r30,0xfff8(r1)     ; |
000000ec	blr                    ; |



; ---------- structs by value, complex example (multiple structs) ---------->
;
; struct A { int i, j; float f; };
; struct B { double d; long long l; };
;

dyncall/doc/disas_examples/ppc.sysv.disas  view on Meta::CPAN

  20:   91 1f 00 1c     stw     r8,28(r31)
  24:   91 3f 00 20     stw     r9,32(r31)
  28:   81 61 00 00     lwz     r11,0(r1)
  2c:   83 eb ff fc     lwz     r31,-4(r11)
  30:   7d 61 5b 78     mr      r1,r11
  34:   4e 80 00 20     blr

00000038 <nonleaf_call>:
  38:   94 21 ff c0     stwu    r1,-64(r1)             ; |           open frame and store sp at top of stack
  3c:   7c 08 02 a6     mflr    r0                     ; |           lr -> gpr0
  40:   93 e1 00 3c     stw     r31,60(r1)             ; | prolog    store gpr31
  44:   90 01 00 44     stw     r0,68(r1)              ; |           store lr
  48:   7c 3f 0b 78     mr      r31,r1                 ; /           sp -> gpr31, latter used for some fixed addressing below
  4c:   90 7f 00 08     stw     r3,8(r31)              ; \
  50:   90 9f 00 0c     stw     r4,12(r31)             ; |
  54:   90 bf 00 10     stw     r5,16(r31)             ; |
  58:   90 df 00 14     stw     r6,20(r31)             ; |
  5c:   90 ff 00 18     stw     r7,24(r31)             ; | all in args -> temp space in local area
  60:   91 1f 00 1c     stw     r8,28(r31)             ; |
  64:   91 3f 00 20     stw     r9,32(r31)             ; |
  68:   91 5f 00 24     stw     r10,36(r31)            ; |
  6c:   80 01 00 00     lwz     r0,0(r1)               ; fetch sp saved on stack of top by prolog -> gpr0, and ...
  70:   94 01 ff 10     stwu    r0,-240(r1)            ; ... update it further up the stack for alloca(220) - with padding to guarantee alignment
  74:   39 21 00 08     addi    r9,r1,8                ; |
  78:   91 3f 00 28     stw     r9,40(r31)             ; |
  7c:   81 3f 00 28     lwz     r9,40(r31)             ; |
  80:   38 09 00 0f     addi    r0,r9,15               ; | start of alloca()'d memory -> gpr9, by ...
  84:   54 00 e1 3e     rlwinm  r0,r0,28,4,31          ; | ... using gpr0 as helper to align to 16b, leaving at least 8b at top of stock
  88:   54 00 20 36     rlwinm  r0,r0,4,0,27           ; |
  8c:   90 1f 00 28     stw     r0,40(r31)             ; |
  90:   81 3f 00 28     lwz     r9,40(r31)             ; |
  94:   38 00 00 4c     li      r0,76                  ; 'L' -> gpr0, and ...

dyncall/doc/disas_examples/ppc.sysv.disas  view on Meta::CPAN

  a0:   80 9f 00 10     lwz     r4,16(r31)             ; arg 1
  a4:   80 bf 00 14     lwz     r5,20(r31)             ; arg 2
  a8:   80 df 00 18     lwz     r6,24(r31)             ; arg 3
  ac:   80 ff 00 1c     lwz     r7,28(r31)             ; arg 4
  b0:   81 1f 00 20     lwz     r8,32(r31)             ; arg 5
  b4:   81 3f 00 24     lwz     r9,36(r31)             ; arg 6
  b8:   48 00 00 01     bl      b8 <nonleaf_call+0x80> ; call and put return address -> lr
  bc:   81 61 00 00     lwz     r11,0(r1)              ; |
  c0:   80 0b 00 04     lwz     r0,4(r11)              ; |
  c4:   7c 08 03 a6     mtlr    r0                     ; |
  c8:   83 eb ff fc     lwz     r31,-4(r11)            ; | epilog
  cc:   7d 61 5b 78     mr      r1,r11                 ; |
  d0:   4e 80 00 20     blr                            ; |

000000d4 <main>:
  d4:   94 21 ff f0     stwu    r1,-16(r1)             ; |
  d8:   7c 08 02 a6     mflr    r0                     ; |
  dc:   93 e1 00 0c     stw     r31,12(r1)             ; | prolog
  e0:   90 01 00 14     stw     r0,20(r1)              ; |
  e4:   7c 3f 0b 78     mr      r31,r1                 ; |
  e8:   38 60 00 00     li      r3,0                   ; arg 0
  ec:   38 80 00 01     li      r4,1                   ; arg 1
  f0:   38 a0 00 02     li      r5,2                   ; arg 2
  f4:   38 c0 00 03     li      r6,3                   ; arg 3
  f8:   38 e0 00 04     li      r7,4                   ; arg 4
  fc:   39 00 00 05     li      r8,5                   ; arg 5
 100:   39 20 00 06     li      r9,6                   ; arg 6
 104:   39 40 00 07     li      r10,7                  ; arg 7
 108:   48 00 00 01     bl      108 <main+0x34>        ; call and put return address -> lr
 10c:   38 00 00 00     li      r0,0                   ; return value (pointlessly) via gpr0 ...
 110:   7c 03 03 78     mr      r3,r0                  ; ... to gpr3
 114:   81 61 00 00     lwz     r11,0(r1)              ; |
 118:   80 0b 00 04     lwz     r0,4(r11)              ; |
 11c:   7c 08 03 a6     mtlr    r0                     ; |
 120:   83 eb ff fc     lwz     r31,-4(r11)            ; | epilog
 124:   7d 61 5b 78     mr      r1,r11                 ; |
 128:   4e 80 00 20     blr                            ; |



; output from netbsd-4.0.1-macppc w/ gcc 4.1.2

00000000 <leaf_call>:
   0:   94 21 ff c0     stwu    r1,-64(r1)
   4:   93 e1 00 3c     stw     r31,60(r1)

dyncall/doc/disas_examples/ppc.sysv.disas  view on Meta::CPAN

  20:   91 3f 00 20     stw     r9,32(r31)
  24:   91 5f 00 24     stw     r10,36(r31)
  28:   81 61 00 00     lwz     r11,0(r1)
  2c:   83 eb ff fc     lwz     r31,-4(r11)
  30:   7d 61 5b 78     mr      r1,r11
  34:   4e 80 00 20     blr

00000038 <main>:
  38:   94 21 ff e0     stwu    r1,-32(r1)     ; |
  3c:   7c 08 02 a6     mflr    r0             ; |
  40:   93 e1 00 1c     stw     r31,28(r1)     ; | prolog
  44:   90 01 00 24     stw     r0,36(r1)      ; |
  48:   7c 3f 0b 78     mr      r31,r1         ; /
  4c:   39 20 00 00     li      r9,0           ; \
  50:   39 40 00 05     li      r10,5          ; |
  54:   91 21 00 08     stw     r9,8(r1)       ; | arg 5 via stack
  58:   91 41 00 0c     stw     r10,12(r1)     ; |
  5c:   38 60 00 00     li      r3,0           ; arg 0
  60:   38 a0 00 00     li      r5,0           ; |
  64:   38 c0 00 01     li      r6,1           ; | arg 1 (note that r4 is skipped)
  68:   38 e0 00 02     li      r7,2           ; arg 2
  6c:   39 00 00 03     li      r8,3           ; arg 3
  70:   39 20 00 00     li      r9,0           ; |
  74:   39 40 00 04     li      r10,4          ; | arg 4
  78:   48 00 00 01     bl      78 <main+0x40> ; call and put return address -> lr
  7c:   38 00 00 01     li      r0,1           ; return value (pointlessly) via gpr0 ...
  80:   7c 03 03 78     mr      r3,r0          ; ... to gpr3
  84:   81 61 00 00     lwz     r11,0(r1)      ; |
  88:   80 0b 00 04     lwz     r0,4(r11)      ; |
  8c:   7c 08 03 a6     mtlr    r0             ; |
  90:   83 eb ff fc     lwz     r31,-4(r11)    ; | epilog
  94:   7d 61 5b 78     mr      r1,r11         ; |
  98:   4e 80 00 20     blr                    ; |



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

; #include <stdlib.h>
; #include <stdarg.h>
; 

dyncall/doc/disas_examples/ppc.sysv.disas  view on Meta::CPAN

 458:   81 61 00 00     lwz     r11,0(r1)
 45c:   80 0b 00 04     lwz     r0,4(r11)
 460:   7c 08 03 a6     mtlr    r0
 464:   83 eb ff fc     lwz     r31,-4(r11)
 468:   7d 61 5b 78     mr      r1,r11
 46c:   4e 80 00 20     blr

00000470 <main>:
 470:   94 21 ff f0     stwu    r1,-16(r1)      ; |
 474:   7c 08 02 a6     mflr    r0              ; |
 478:   93 e1 00 0c     stw     r31,12(r1)      ; | prolog
 47c:   90 01 00 14     stw     r0,20(r1)       ; |
 480:   7c 3f 0b 78     mr      r31,r1          ; /
 484:   3d 20 00 00     lis     r9,0            ; \ prep arg 5 (float, but double in reg & ellipsis), load from 0 b/c objdump is from .o, not finally linked exec
 488:   c8 09 00 00     lfd     f0,0(r9)        ; /
 48c:   3d 20 00 00     lis     r9,0            ; \ prep arg 6 (float, but double in reg & ellipsis), load from 0 b/c objdump is from .o, not finally linked exec
 490:   c9 a9 00 08     lfd     f13,8(r9)       ; /
 494:   3d 20 00 00     lis     r9,0            ; \ prep arg 9 (float, but double in reg & ellipsis), load from 0 b/c objdump is from .o, not finally linked exec
 498:   c9 89 00 10     lfd     f12,16(r9)      ; /
 49c:   38 60 00 00     li      r3,0            ; arg 0
 4a0:   38 80 00 01     li      r4,1            ; arg 1

dyncall/doc/disas_examples/ppc.sysv.disas  view on Meta::CPAN

 4b8:   39 00 00 07     li      r8,7            ; arg 7
 4bc:   39 20 00 08     li      r9,8            ; arg 8
 4c0:   fc 60 60 90     fmr     f3,f12          ; arg 9
 4c4:   4c c6 32 42     crset   4*cr1+eq        ; set CR bit for ellipsis call
 4c8:   48 00 00 01     bl      4c8 <main+0x58> ; call and put return address -> lr
 4cc:   38 00 00 00     li      r0,0            ; return value (pointlessly) via gpr0 ...
 4d0:   7c 03 03 78     mr      r3,r0           ; ... to gpr3
 4d4:   81 61 00 00     lwz     r11,0(r1)       ; |
 4d8:   80 0b 00 04     lwz     r0,4(r11)       ; |
 4dc:   7c 08 03 a6     mtlr    r0              ; |
 4e0:   83 eb ff fc     lwz     r31,-4(r11)     ; | epilog
 4e4:   7d 61 5b 78     mr      r1,r11          ; |
 4e8:   4e 80 00 20     blr                     ; |



; ---------- structs by value ---------->
;
; struct A { int i, j; long long l; };
;
; void leaf_call(int b, int c, int d, int e, struct A f, int g, int h)

dyncall/doc/disas_examples/ppc.sysv.disas  view on Meta::CPAN

  88:   91 0b 00 0c     stw     r8,12(r11)     ;
  8c:   7d 63 5b 78     mr      r3,r11         ;
  90:   81 61 00 00     lwz     r11,0(r1)      ;
  94:   83 eb ff fc     lwz     r31,-4(r11)    ;
  98:   7d 61 5b 78     mr      r1,r11         ;
  9c:   4e 80 00 20     blr                    ;

000000a0 <main>:
  a0:   94 21 ff c0     stwu    r1,-64(r1)     ; |           open frame and store sp at top of stack
  a4:   7c 08 02 a6     mflr    r0             ; |           lr -> gpr0
  a8:   93 e1 00 3c     stw     r31,60(r1)     ; | prolog    store gpr31
  ac:   90 01 00 44     stw     r0,68(r1)      ; |           store lr
  b0:   7c 3f 0b 78     mr      r31,r1         ; /           sp -> gpr31, latter used for some fixed addressing below
  b4:   38 1f 00 28     addi    r0,r31,40      ; \
  b8:   7c 03 03 78     mr      r3,r0          ; | space to retval -> gpr3 (hidden arg)
  bc:   4c c6 31 82     crclr   4*cr1+eq       ; :
  c0:   48 00 00 01     bl      c0 <main+0x20> ; call f0()
  c4:   88 1f 00 28     lbz     r0,40(r31)     ;
  c8:   98 1f 00 08     stb     r0,8(r31)      ;
  cc:   38 1f 00 10     addi    r0,r31,16      ; |
  d0:   7c 03 03 78     mr      r3,r0          ; | space to retval -> gpr3 (hidden arg)
  d4:   4c c6 31 82     crclr   4*cr1+eq       ; :
  d8:   48 00 00 01     bl      d8 <main+0x38> ; call f1()
  dc:   81 3f 00 18     lwz     r9,24(r31)     ;
  e0:   88 1f 00 08     lbz     r0,8(r31)      ;
  e4:   54 00 06 3e     clrlwi  r0,r0,24       ;
  e8:   7c 09 02 14     add     r0,r9,r0       ;
  ec:   7c 03 03 78     mr      r3,r0          ;
  f0:   81 61 00 00     lwz     r11,0(r1)      ; |
  f4:   80 0b 00 04     lwz     r0,4(r11)      ; |
  f8:   7c 08 03 a6     mtlr    r0             ; |
  fc:   83 eb ff fc     lwz     r31,-4(r11)    ; | epilog
 100:   7d 61 5b 78     mr      r1,r11         ; |
 104:   4e 80 00 20     blr                    ; |



; output from netbsd-4.0.1-macppc w/ gcc 4.1.2 (demonstrates default (non-LSB) aggr return values)

018007a0 <f0>:
 18007a0:       94 21 ff d0     stwu    r1,-48(r1)
 18007a4:       93 e1 00 2c     stw     r31,44(r1)

dyncall/doc/disas_examples/ppc.sysv.disas  view on Meta::CPAN

 1800820:       91 0b 00 0c     stw     r8,12(r11)
 1800824:       7d 63 5b 78     mr      r3,r11
 1800828:       81 61 00 00     lwz     r11,0(r1)
 180082c:       83 eb ff fc     lwz     r31,-4(r11)
 1800830:       7d 61 5b 78     mr      r1,r11
 1800834:       4e 80 00 20     blr

01800838 <main>:
 1800838:       94 21 ff c0     stwu    r1,-64(r1)   ; |           open frame and store sp at top of stack
 180083c:       7c 08 02 a6     mflr    r0           ; |           lr -> gpr0
 1800840:       93 e1 00 3c     stw     r31,60(r1)   ; | prolog    store gpr31
 1800844:       90 01 00 44     stw     r0,68(r1)    ; |           store lr
 1800848:       7c 3f 0b 78     mr      r31,r1       ; |           sp -> gpr31, latter used for some fixed addressing below
 180084c:       4b ff ff 55     bl      18007a0 <f0> ; call f0()
 1800850:       7c 60 1b 78     mr      r0,r3        ; |           NOTE: ret val is returned via gpr3
 1800854:       98 1f 00 08     stb     r0,8(r31)    ; / ret val
 1800858:       38 1f 00 10     addi    r0,r31,16    ; \
 180085c:       7c 03 03 78     mr      r3,r0        ; | space to retval -> gpr3 (hidden arg)
 1800860:       4c c6 31 82     crclr   4*cr1+eq     ; :
 1800864:       4b ff ff 69     bl      18007cc <f1> ; call f0()
 1800868:       81 3f 00 18     lwz     r9,24(r31)   ;

dyncall/doc/disas_examples/ppc.sysv.disas  view on Meta::CPAN

1000043c:       80 0b 00 04     lwz     r0,4(r11)
10000440:       7c 08 03 a6     mtlr    r0
10000444:       83 ab ff f4     lwz     r29,-12(r11)
10000448:       83 eb ff fc     lwz     r31,-4(r11)
1000044c:       7d 61 5b 78     mr      r1,r11
10000450:       4e 80 00 20     blr

10000454 <f>:
10000454:       94 21 ff d0     stwu    r1,-48(r1)        ; |           open frame and store sp at top of stack
10000458:       7c 08 02 a6     mflr    r0                ; |           lr -> gpr0
1000045c:       93 e1 00 2c     stw     r31,44(r1)        ; | prolog    store gpr31
10000460:       90 01 00 34     stw     r0,52(r1)         ; |           store lr
10000464:       7c 3f 0b 78     mr      r31,r1            ; /           sp -> gpr31, latter used for some fixed addressing below
10000468:       38 00 00 01     li      r0,1              ; \ a = 1
1000046c:       90 1f 00 08     stw     r0,8(r31)         ; /
10000470:       81 3f 00 08     lwz     r9,8(r31)         ; \
10000474:       38 09 00 7b     addi    r0,r9,123         ; | a += 123
10000478:       90 1f 00 08     stw     r0,8(r31)         ; /
1000047c:       38 1f 00 18     addi    r0,r31,24         ; \
10000480:       7c 03 03 78     mr      r3,r0             ; | space to retval -> gpr3 (hidden arg); NOTE: this follows the LSB definition
10000484:       4b ff ff 5d     bl      100003e0 <f1>     ; call f1()

dyncall/doc/disas_examples/ppc64.elfabi.disas  view on Meta::CPAN

  30:	91 3f 00 a0 	stw     r9,160(r31)
  34:	e8 21 00 00 	ld      r1,0(r1)
  38:	eb e1 ff f8 	ld      r31,-8(r1)
  3c:	4e 80 00 20 	blr
	...
  48:	80 01 00 01 	lwz     r0,1(r1)

000000000000004c <.nonleaf_call>:
  4c:	7c 08 02 a6 	mflr    r0                       ; |
  50:	fb e1 ff f8 	std     r31,-8(r1)               ; |
  54:	f8 01 00 10 	std     r0,16(r1)                ; | prolog
  58:	f8 21 ff 71 	stdu    r1,-144(r1)              ; |
  5c:	7c 3f 0b 78 	mr      r31,r1                   ; use gpr31 as sort of frame pointer, below
  60:	7c 60 1b 78 	mr      r0,r3                    ; in arg 0 -> gpr0
  64:	7c 8b 23 78 	mr      r11,r4                   ; in arg 1 -> gpr11
  68:	90 1f 00 c0 	stw     r0,192(r31)              ; |
  6c:	91 7f 00 c8 	stw     r11,200(r31)             ; |
  70:	90 bf 00 d0 	stw     r5,208(r31)              ; |
  74:	90 df 00 d8 	stw     r6,216(r31)              ; |
  78:	90 ff 00 e0 	stw     r7,224(r31)              ; | all in args -> spill area in prev frame (jump over own frame (144) + linkage area of prev frame (48) = 192)
  7c:	91 1f 00 e8 	stw     r8,232(r31)              ; |
  80:	91 3f 00 f0 	stw     r9,240(r31)              ; |
  84:	91 5f 00 f8 	stw     r10,248(r31)             ; |
  88:	e8 01 00 00 	ld      r0,0(r1)                 ; fetch back-chain ptr (parent frame's sp) from stack of top by prolog -> gpr0, and ...
  8c:	f8 01 ff 11 	stdu    r0,-240(r1)              ; ... update it further up the stack for alloca(220) - with padding to guarantee alignment
  90:	39 21 00 70 	addi    r9,r1,112                ; |
  94:	f9 3f 00 70 	std     r9,112(r31)              ; |
  98:	e9 3f 00 70 	ld      r9,112(r31)              ; |
  9c:	38 09 00 0f 	addi    r0,r9,15                 ; | start of alloca()'d memory -> gpr9, by ...
  a0:	78 00 e1 02 	rldicl  r0,r0,60,4               ; | ... using gpr0 as helper to align to 16b, leaving at least 112b at top of stack
  a4:	78 00 26 e4 	rldicr  r0,r0,4,59               ; |
  a8:	f8 1f 00 70 	std     r0,112(r31)              ; |
  ac:	e9 3f 00 70 	ld      r9,112(r31)              ; |
  b0:	38 00 00 4c 	li      r0,76                    ; 'L' -> gpr0, and ...

dyncall/doc/disas_examples/ppc64.elfabi.disas  view on Meta::CPAN

  f0:	7d 03 43 78 	mr      r3,r8                    ; arg 0
  f4:	7c e4 3b 78 	mr      r4,r7                    ; arg 1
  f8:	7c c5 33 78 	mr      r5,r6                    ; arg 2
  fc:	7d 26 4b 78 	mr      r6,r9                    ; arg 3
 100:	7d 67 5b 78 	mr      r7,r11                   ; arg 4
 104:	7d 48 53 78 	mr      r8,r10                   ; arg 5
 108:	7c 09 03 78 	mr      r9,r0                    ; arg 6
 10c:	48 00 00 01 	bl      10c <.nonleaf_call+0xc0> ; call and put return address -> lr
 110:	e8 21 00 00 	ld      r1,0(r1)                 ; |
 114:	e8 01 00 10 	ld      r0,16(r1)                ; |
 118:	7c 08 03 a6 	mtlr    r0                       ; | epilog
 11c:	eb e1 ff f8 	ld      r31,-8(r1)               ; |
 120:	4e 80 00 20 	blr                              ; |
 124:	00 00 00 00 	.long 0x0                        ; data
 128:	00 00 00 01 	.long 0x1                        ; data
 12c:	80 01 00 01 	lwz     r0,1(r1)                 ; unsure@@@. data?

0000000000000130 <.main>:
 130:	7c 08 02 a6 	mflr    r0                       ; |             lr -> gpr0
 134:	fb e1 ff f8 	std     r31,-8(r1)               ; |             preseve gpr31 (as used in func as helper addr)
 138:	f8 01 00 10 	std     r0,16(r1)                ; | prolog      store lr
 13c:	f8 21 ff 81 	stdu    r1,-128(r1)              ; |             open frame
 140:	7c 3f 0b 78 	mr      r31,r1                   ; use gpr31 as sort of frame pointer, below
 144:	38 60 00 00 	li      r3,0                     ; arg 0
 148:	38 80 00 01 	li      r4,1                     ; arg 1
 14c:	38 a0 00 02 	li      r5,2                     ; arg 2
 150:	38 c0 00 03 	li      r6,3                     ; arg 3
 154:	38 e0 00 04 	li      r7,4                     ; arg 4
 158:	39 00 00 05 	li      r8,5                     ; arg 5
 15c:	39 20 00 06 	li      r9,6                     ; arg 6
 160:	39 40 00 07 	li      r10,7                    ; arg 7
 164:	48 00 00 01 	bl      164 <.main+0x34>         ; call and put return address -> lr
 168:	38 00 00 00 	li      r0,0                     ; return value ...
 16c:	7c 03 03 78 	mr      r3,r0                    ; ... in gpr3
 170:	e8 21 00 00 	ld      r1,0(r1)                 ; |
 174:	e8 01 00 10 	ld      r0,16(r1)                ; |
 178:	7c 08 03 a6 	mtlr    r0                       ; | epilog
 17c:	eb e1 ff f8 	ld      r31,-8(r1)               ; |
 180:	4e 80 00 20 	blr                              ; |
 184:	00 00 00 00 	.long 0x0                        ; data
 188:	00 00 00 01 	.long 0x1                        ; data
 18c:	80 01 00 01 	lwz     r0,1(r1)                 ; unsure@@@. data?



; ------------- ints and floats, var args, struct return value (meaning implicit first param), more than 8 params (11, with implicit return value ptr) ----------->

dyncall/doc/disas_examples/ppc64.elfabi.disas  view on Meta::CPAN

  38:	91 1f 00 90 	stw     r8,144(r31)
  3c:	90 1f 00 a8 	stw     r0,168(r31)
  40:	e8 21 00 00 	ld      r1,0(r1)
  44:	eb e1 ff f8 	ld      r31,-8(r1)
  48:	4e 80 00 20 	blr
	...
  54:	80 01 00 01 	lwz     r0,1(r1)

0000000000000058 <.nonleaf_call>:
  58:	fb e1 ff f8 	std     r31,-8(r1)       ; |
  5c:	f8 21 ff 91 	stdu    r1,-112(r1)      ; | prolog
  60:	7c 3f 0b 78 	mr      r31,r1           ; use gpr31 as sort of frame pointer, below
  64:	7c 8b 23 78 	mr      r11,r4           ; in arg 1 (first explicit arg, b/c of struct return value ptr being arg0) -> r11
  68:	7c a8 2b 78 	mr      r8,r5            ; in arg 2 -> r8 (free reg, was skipped for float param)
  6c:	d0 3f 00 b8 	stfs    f1,184(r31)      ; |                  in arg 3 (float) -> prev frame's spill area: 184 = 112 (frame) + 48 (prev frame's linkage area) + 8 (arg 0 = return value ptr) + 16 (first two explicit args)
  70:	d0 5f 00 c8 	stfs    f2,200(r31)      ; |                  in arg 5 (float) -> prev frame's spill area
  74:	f9 5f 00 d8 	std     r10,216(r31)     ; |                  in arg 7 (float, also held in gpr reg b/c vararg) -> prev frame's spill area
  78:	7d 20 4b 78 	mr      r0,r9            ; | spilling         in arg 6 in gpr0 (spilled below)
  7c:	91 7f 00 a8 	stw     r11,168(r31)     ; |                  in arg 1 (int) -> prev frame's spill area
  80:	91 1f 00 b0 	stw     r8,176(r31)      ; |                  in arg 2 (int) -> prev frame's spill area
  84:	90 ff 00 c0 	stw     r7,192(r31)      ; |                  in arg 4 (int) -> prev frame's spill area

dyncall/doc/disas_examples/ppc64.elfabi.disas  view on Meta::CPAN

  a0:	90 1f 00 50 	stw     r0,80(r31)       ; |
  a4:	38 1f 00 d8 	addi    r0,r31,216       ;
  a8:	f8 1f 00 40 	std     r0,64(r31)       ;     .
  ac:	7f e0 00 08 	trap                     ;     .
	...                                          ;     .
  b8:	80 01 00 01 	lwz     r0,1(r1)         ;

00000000000000bc <.main>:
  bc:	7c 08 02 a6 	mflr    r0               ; |             lr -> gpr0
  c0:	fb e1 ff f8 	std     r31,-8(r1)       ; |             preseve gpr31 (as used in func as helper addr)
  c4:	f8 01 00 10 	std     r0,16(r1)        ; | prolog      store lr
  c8:	f8 21 ff 41 	stdu    r1,-192(r1)      ; |             open frame
  cc:	7c 3f 0b 78 	mr      r31,r1           ; use gpr31 as sort of frame pointer, below
  d0:	39 61 00 30 	addi    r11,r1,48        ; ptr to param area -> r11
  d4:	e9 22 00 00 	ld      r9,0(r2)         ; prep arg 3 (=explicit arg 2, b/c of implicit return value pointer), ... 
  d8:	c1 a9 00 00 	lfs     f13,0(r9)        ; ... load from static data -> f13
  dc:	e9 22 00 08 	ld      r9,8(r2)         ; prep arg 5, ...
  e0:	c1 89 00 00 	lfs     f12,0(r9)        ; ... load from static data -> f12
  e4:	e9 22 00 10 	ld      r9,16(r2)        ; prep arg 7, ...
  e8:	c8 09 00 00 	lfd     f0,0(r9)         ; ... load from static data -> f0
  ec:	d8 1f 00 a0 	stfd    f0,160(r31)      ; |

dyncall/doc/disas_examples/ppc64.elfabi.disas  view on Meta::CPAN

 148:	fc 40 60 90 	fmr     f2,f12           ; arg 5 (float, in 2nd double reg)
 14c:	39 20 00 05 	li      r9,5             ; arg 6 (skipping gpr8 b/c of float arg, vararg)
 150:	fc 60 58 90 	fmr     f3,f11           ; arg 7 (float, in 3rd double reg, promoted to double anyways b/c vararg)
 154:	fc 80 50 90 	fmr     f4,f10           ; arg 8 (float, in 4th double reg, promoted to double anyways b/c vararg)
 158:	fc a0 00 90 	fmr     f5,f0            ; arg 10 (float, in 5th double reg, promoted to double anyways b/c vararg)
 15c:	48 00 00 01 	bl      15c <.main+0xa0> ; call and put return address -> lr
 160:	38 00 00 00 	li      r0,0             ; return value ...
 164:	7c 03 03 78 	mr      r3,r0            ; ... in gpr3
 168:	e8 21 00 00 	ld      r1,0(r1)         ; |
 16c:	e8 01 00 10 	ld      r0,16(r1)        ; |
 170:	7c 08 03 a6 	mtlr    r0               ; | epilog
 174:	eb e1 ff f8 	ld      r31,-8(r1)       ; |
 178:	4e 80 00 20 	blr                      ; |
 17c:	00 00 00 00 	.long 0x0                ; data
 180:	00 00 00 01 	.long 0x1                ; data
 184:	80 01 00 01 	lwz     r0,1(r1)         ; unsure@@@. data?



; ---------- structs by value ---------->
;

dyncall/doc/disas_examples/ppc64.elfabi.disas  view on Meta::CPAN

 11c:	eb a1 ff e8 	ld      r29,-24(r1)
 120:	eb e1 ff f8 	ld      r31,-8(r1)
 124:	4e 80 00 20 	blr
 128:	00 00 00 00 	.long 0x0
 12c:	00 00 00 01 	.long 0x1
 130:	80 03 00 01 	lwz     r0,1(r3)

0000000000000134 <.main>:
 134:	7c 08 02 a6 	mflr    r0               ; |             lr -> gpr0
 138:	fb e1 ff f8 	std     r31,-8(r1)       ; |             preseve gpr31 (as used in func as helper addr)
 13c:	f8 01 00 10 	std     r0,16(r1)        ; | prolog      store lr
 140:	f8 21 ff 61 	stdu    r1,-160(r1)      ; |             open frame
 144:	7c 3f 0b 78 	mr      r31,r1           ; use gpr31 as sort of frame pointer, below
 148:	e9 22 00 00 	ld      r9,0(r2)         ; |
 14c:	e9 49 00 08 	ld      r10,8(r9)        ; | fetch local struct data's 2 doublewords (r2 = TOC ptr) -> r9/r10, and ...
 150:	e9 29 00 00 	ld      r9,0(r9)         ; |
 154:	f9 3f 00 80 	std     r9,128(r31)      ; | ... write to local area on stack
 158:	f9 5f 00 88 	std     r10,136(r31)     ; /
 15c:	38 00 00 09 	li      r0,9             ; \ arg 7, ...
 160:	f8 01 00 70 	std     r0,112(r1)       ; | ... "pushed" onto stack
 164:	38 60 00 00 	li      r3,0             ; arg 0

dyncall/doc/disas_examples/ppc64.elfabi.disas  view on Meta::CPAN

 170:	38 c0 00 03 	li      r6,3             ; arg 3
 174:	38 e0 00 04 	li      r7,4             ; arg 4
 178:	e9 1f 00 80 	ld      r8,128(r31)      ; |
 17c:	e9 3f 00 88 	ld      r9,136(r31)      ; | arg 5 (struct, fetch from local area, pass as 2 doublewords)
 180:	39 40 00 08 	li      r10,8            ; arg 6
 184:	48 00 00 01 	bl      184 <.main+0x50> ; call and put return address -> lr
 188:	38 00 00 00 	li      r0,0             ; return value ...
 18c:	7c 03 03 78 	mr      r3,r0            ; ... in gpr3
 190:	e8 21 00 00 	ld      r1,0(r1)         ; |
 194:	e8 01 00 10 	ld      r0,16(r1)        ; |
 198:	7c 08 03 a6 	mtlr    r0               ; | epilog
 19c:	eb e1 ff f8 	ld      r31,-8(r1)       ; |
 1a0:	4e 80 00 20 	blr                      ; |
 1a4:	00 00 00 00 	.long 0x0                ; data
 1a8:	00 00 00 01 	.long 0x1                ; data
 1ac:	80 01 00 01 	lwz     r0,1(r1)         ; unsure@@@. data?



; ---------- structs by value, complex example (multiple structs) ---------->
;

dyncall/doc/disas_examples/ppc64.elfabi.disas  view on Meta::CPAN

 140:	eb a1 ff e8 	ld      r29,-24(r1)
 144:	eb e1 ff f8 	ld      r31,-8(r1)
 148:	4e 80 00 20 	blr
 14c:	00 00 00 00 	.long 0x0
 150:	00 00 00 01 	.long 0x1
 154:	80 04 00 01 	lwz     r0,1(r4)

0000000000000158 <.main>:
 158:	7c 08 02 a6 	mflr    r0               ; |             lr -> gpr0
 15c:	fb e1 ff f8 	std     r31,-8(r1)       ; |             preseve gpr31 (as used in func as helper addr)
 160:	f8 01 00 10 	std     r0,16(r1)        ; | prolog      store lr
 164:	f8 21 ff 11 	stdu    r1,-240(r1)      ; |             open frame
 168:	7c 3f 0b 78 	mr      r31,r1           ; use gpr31 as sort of frame pointer, below
 16c:	e9 22 00 00 	ld      r9,0(r2)         ; |
 170:	e8 09 00 00 	ld      r0,0(r9)         ; | fetch local first struct A data's 2 doublewords (r2 = TOC ptr) -> r9/r10, and ...
 174:	81 29 00 08 	lwz     r9,8(r9)         ; |
 178:	f8 1f 00 d0 	std     r0,208(r31)      ; | ... write to local area on stack
 17c:	91 3f 00 d8 	stw     r9,216(r31)      ; /
 180:	e9 22 00 08 	ld      r9,8(r2)         ; \
 184:	e9 49 00 08 	ld      r10,8(r9)        ; | fetch local first struct B data's 2 doublewords (r2 = TOC ptr) -> r9/r10, and ...
 188:	e9 29 00 00 	ld      r9,0(r9)         ; |

dyncall/doc/disas_examples/ppc64.elfabi.disas  view on Meta::CPAN

 204:	39 3f 00 c0 	addi    r9,r31,192       ; \
 208:	e8 e9 00 00 	ld      r7,0(r9)         ; | arg 3 (first struct B, fetch from local area, pass as 2 doublewords)
 20c:	e9 09 00 08 	ld      r8,8(r9)         ; |
 210:	39 20 00 07 	li      r9,7             ; arg 4
 214:	39 40 00 08 	li      r10,8            ; arg 5
 218:	48 00 00 01 	bl      218 <.main+0xc0> ; call and put return address -> lr
 21c:	38 00 00 00 	li      r0,0             ; return value ...
 220:	7c 03 03 78 	mr      r3,r0            ; ... in gpr3
 224:	e8 21 00 00 	ld      r1,0(r1)         ; |
 228:	e8 01 00 10 	ld      r0,16(r1)        ; |
 22c:	7c 08 03 a6 	mtlr    r0               ; | epilog
 230:	eb e1 ff f8 	ld      r31,-8(r1)       ; |
 234:	4e 80 00 20 	blr                      ; |
 238:	00 00 00 00 	.long 0x0                ; data
 23c:	00 00 00 01 	.long 0x1                ; data
 240:	80 01 00 01 	lwz     r0,1(r1)         ; unsure@@@. data?



; ---------- returning qwords ---------->
;

dyncall/doc/disas_examples/ppc64.elfabi.disas  view on Meta::CPAN

;         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)                         ; | prolog
    10000830:   7c 3f 0b 78     mr      r31,r1                             ; use gpr31 as sort of frame pointer, below
    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)                         ; | epilog
    10000840:   4e 80 00 20     blr                                        ; |
    10000844:   00 00 00 00     .long 0x0                                  ; data
    10000848:   00 09 00 00     .long 0x90000                              ; data
    1000084c:   80 01 00 01     lwz     r0,1(r1)                           ; unsure@@@. data?

0000000010000850 <.f2>:
    10000850:   fb e1 ff f8     std     r31,-8(r1)                         ; |
    10000854:   f8 21 ff c1     stdu    r1,-64(r1)                         ; | prolog
    10000858:   7c 3f 0b 78     mr      r31,r1                             ; use gpr31 as sort of frame pointer, below
    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)                         ; | epilog
    10000868:   4e 80 00 20     blr                                        ; |
    1000086c:   00 00 00 00     .long 0x0                                  ; data
    10000870:   00 09 00 00     .long 0x90000                              ; data
    10000874:   80 01 00 01     lwz     r0,1(r1)                           ; unsure@@@. data?

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)                        ;

dyncall/doc/disas_examples/sparc.sparc.disas  view on Meta::CPAN

   8:   f2 27 a0 48     st  %i1, [ %fp + 0x48 ]
   c:   f4 27 a0 4c     st  %i2, [ %fp + 0x4c ]
  10:   f6 27 a0 50     st  %i3, [ %fp + 0x50 ]
  14:   f8 27 a0 54     st  %i4, [ %fp + 0x54 ]
  18:   fa 27 a0 58     st  %i5, [ %fp + 0x58 ]
  1c:   81 e8 00 00     restore
  20:   81 c3 e0 08     retl
  24:   01 00 00 00     nop

00000028 <nonleaf_call>:
  28:   9d e3 bf 88     save  %sp, -120, %sp         ; prolog
  2c:   f0 27 a0 44     st  %i0, [ %fp + 0x44 ]      ; |
  30:   f2 27 a0 48     st  %i1, [ %fp + 0x48 ]      ; |
  34:   f4 27 a0 4c     st  %i2, [ %fp + 0x4c ]      ; | write input to prev frame's spill area
  38:   f6 27 a0 50     st  %i3, [ %fp + 0x50 ]      ; |   (e.g. offset = 68 for i0, jumping over i*/l* save area and aggregate return pointer)
  3c:   f8 27 a0 54     st  %i4, [ %fp + 0x54 ]      ; |
  40:   fa 27 a0 58     st  %i5, [ %fp + 0x58 ]      ; |
  44:   9c 03 bf 20     add  %sp, -224, %sp          ; alloca(220) - with 4b padding (multiple of 8), and ...
  48:   82 03 a0 64     add  %sp, 0x64, %g1          ; ... at least 100b at top of stack, via ...
  4c:   c2 27 bf f4     st  %g1, [ %fp + -12 ]       ; ... local space (pointlessly) ...
  50:   c4 07 bf f4     ld  [ %fp + -12 ], %g2       ; ... to g2

dyncall/doc/disas_examples/sparc.sparc.disas  view on Meta::CPAN

  74:   c2 23 a0 5c     st  %g1, [ %sp + 0x5c ]      ; ... "pushed" onto stack
  78:   d0 07 a0 48     ld  [ %fp + 0x48 ], %o0      ; |
  7c:   d2 07 a0 4c     ld  [ %fp + 0x4c ], %o1      ; |
  80:   d4 07 a0 50     ld  [ %fp + 0x50 ], %o2      ; |
  84:   d6 07 a0 54     ld  [ %fp + 0x54 ], %o3      ; | arg 0,1,2,3,4 (fetched from prev frame's spill area)
  88:   d8 07 a0 58     ld  [ %fp + 0x58 ], %o4      ; |
  8c:   da 07 a0 5c     ld  [ %fp + 0x5c ], %o5      ; arg 5 (fetched from prev frame's stack param area)
  90:   40 00 00 00     call  90 <nonleaf_call+0x68> ; call leaf_call (objdump not from final link but .o)
  94:   01 00 00 00     nop                          ; branch delay slot
  98:   81 e8 00 00     restore                      ; |
  9c:   81 c3 e0 08     retl                         ; | epilog
  a0:   01 00 00 00     nop                          ; |            branch delay slot

000000a4 <main>:
  a4:   9d e3 bf 90     save  %sp, -112, %sp         ; prolog
  a8:   82 10 20 06     mov  6, %g1                  ; arg 6, ...
  ac:   c2 23 a0 5c     st  %g1, [ %sp + 0x5c ]      ; ... "pushed" onto stack
  b0:   82 10 20 07     mov  7, %g1                  ; arg 7, ...
  b4:   c2 23 a0 60     st  %g1, [ %sp + 0x60 ]      ; ... "pushed" onto stack
  b8:   90 10 20 00     clr  %o0                     ; arg 0
  bc:   92 10 20 01     mov  1, %o1                  ; arg 1
  c0:   94 10 20 02     mov  2, %o2                  ; arg 2
  c4:   96 10 20 03     mov  3, %o3                  ; arg 3
  c8:   98 10 20 04     mov  4, %o4                  ; arg 4
  cc:   9a 10 20 05     mov  5, %o5                  ; arg 5
  d0:   40 00 00 00     call  d0 <main+0x2c>         ; call nonleaf_call (objdump not from final link but .o)
  d4:   01 00 00 00     nop                          ; branch delay slot
  d8:   82 10 20 00     clr  %g1     ! 0 <leaf_call> ; |
  dc:   b0 10 00 01     mov  %g1, %i0                ; / return value
  e0:   81 e8 00 00     restore                      ; \
  e4:   81 c3 e0 08     retl                         ; | epilog
  e8:   01 00 00 00     nop                          ; |            branch delay slot



; output from netbsd-6.0-sparc w/ gcc 4.5.3

00000000 <leaf_call>:
   0:   9d e3 bf a0     save  %sp, -96, %sp
   4:   f0 27 a0 44     st  %i0, [ %fp + 0x44 ]
   8:   f2 27 a0 48     st  %i1, [ %fp + 0x48 ]

dyncall/doc/disas_examples/sparc.sparc.disas  view on Meta::CPAN

   8:   f2 27 a0 48     st  %i1, [ %fp + 0x48 ]
   c:   f4 27 a0 4c     st  %i2, [ %fp + 0x4c ]
  10:   f6 27 a0 50     st  %i3, [ %fp + 0x50 ]
  14:   f8 27 a0 54     st  %i4, [ %fp + 0x54 ]
  18:   fa 27 a0 58     st  %i5, [ %fp + 0x58 ]
  1c:   81 e8 00 00     restore
  20:   81 c3 e0 08     retl
  24:   01 00 00 00     nop

00000028 <nonleaf_call>:
  28:   9d e3 bf 78     save  %sp, -136, %sp            ; prolog
  2c:   e0 07 a0 40     ld  [ %fp + 0x40 ], %l0         ; pointer to struct to return -> l0
  30:   f0 27 a0 44     st  %i0, [ %fp + 0x44 ]         ; |
  34:   f2 27 a0 48     st  %i1, [ %fp + 0x48 ]         ; |
  38:   f4 27 a0 4c     st  %i2, [ %fp + 0x4c ]         ; |
  3c:   f6 27 a0 50     st  %i3, [ %fp + 0x50 ]         ; | write input to prev frame's spill area
  40:   f8 27 a0 54     st  %i4, [ %fp + 0x54 ]         ; |
  44:   fa 27 a0 58     st  %i5, [ %fp + 0x58 ]         ; /
  48:   c2 07 a0 48     ld  [ %fp + 0x48 ], %g1         ; \
  4c:   c2 27 bf ec     st  %g1, [ %fp + -20 ]          ; |
  50:   c2 07 a0 50     ld  [ %fp + 0x50 ], %g1         ; | in arg 1,3,5 (the ints to be returned in struct), ...

dyncall/doc/disas_examples/sparc.sparc.disas  view on Meta::CPAN

  ac:   40 00 00 00     call  ac <nonleaf_call+0x84>    ; call leaf_call (objdump not from final link but .o)
  b0:   01 00 00 00     nop                             ; branch delay slot
  b4:   c2 07 bf ec     ld  [ %fp + -20 ], %g1          ; |
  b8:   c2 24 00 00     st  %g1, [ %l0 ]                ; |
  bc:   c2 07 bf f0     ld  [ %fp + -16 ], %g1          ; |
  c0:   c2 24 20 04     st  %g1, [ %l0 + 4 ]            ; | store struct elements
  c4:   c2 07 bf f4     ld  [ %fp + -12 ], %g1          ; |
  c8:   c2 24 20 08     st  %g1, [ %l0 + 8 ]            ; |
  cc:   b0 10 00 10     mov  %l0, %i0                   ; return value (pointer to struct)
  d0:   81 e8 00 00     restore                         ; |
  d4:   81 c3 e0 0c     jmp  %o7 + 0xc                  ; | epilog
  d8:   01 00 00 00     nop                             ; |            branch delay slot

000000dc <main>:
  dc:   9d e3 bf 80     save  %sp, -128, %sp            ; prolog
  e0:   03 00 00 00     sethi  %hi(0), %g1              ; |
  e4:   82 10 60 00     mov  %g1, %g1   ! 0 <leaf_call> ; | prep arg 2, load from static data into f8 (addr = 0 b/c objdumped .o, not final linked)
  e8:   d1 00 40 00     ld  [ %g1 ], %f8                ; /
  ec:   03 00 00 00     sethi  %hi(0), %g1              ; \
  f0:   82 10 60 00     mov  %g1, %g1   ! 0 <leaf_call> ; | prep arg 4, load from static data into f9 (addr = 0 b/c objdumped .o, not final linked)
  f4:   d3 00 40 00     ld  [ %g1 ], %f9                ; |
  f8:   82 10 20 06     mov  6, %g1                     ; arg 6, ...
  fc:   c2 23 a0 5c     st  %g1, [ %sp + 0x5c ]         ; ... "pushed" onto stack
 100:   82 10 20 07     mov  7, %g1                     ; arg 7, ...
 104:   c2 23 a0 60     st  %g1, [ %sp + 0x60 ]         ; ... "pushed" onto stack

dyncall/doc/disas_examples/sparc.sparc.disas  view on Meta::CPAN

 120:   96 10 20 03     mov  3, %o3                     ; arg 3
 124:   d3 27 bf f8     st  %f9, [ %fp + -8 ]           ; | arg 4, from f9 via temp space ...
 128:   d8 07 bf f8     ld  [ %fp + -8 ], %o4           ; | ... to o4
 12c:   9a 10 20 05     mov  5, %o5                     ; arg 5
 130:   40 00 00 00     call  130 <main+0x54>           ; call nonleaf_call (objdump not from final link but .o)
 134:   01 00 00 00     nop                             ; branch delay slot
 138:   00 00 00 0c     unimp  0xc                      ; sparc convention for returned aggregates: use unimp with field (here 0xc) specifiying size of returned struct (see sparc manual explanation)
 13c:   82 10 20 00     clr  %g1                        ; |
 140:   b0 10 00 01     mov  %g1, %i0                   ; / return value
 144:   81 e8 00 00     restore                         ; \
 148:   81 c3 e0 08     retl                            ; | epilog
 14c:   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)

dyncall/doc/disas_examples/sparc64.sparc64.disas  view on Meta::CPAN

  1c:   ca 27 a8 87     st  %g5, [ %fp + 0x887 ]
  20:   c8 27 a8 8f     st  %g4, [ %fp + 0x88f ]
  24:   c6 27 a8 97     st  %g3, [ %fp + 0x897 ]
  28:   c4 27 a8 9f     st  %g2, [ %fp + 0x89f ]
  2c:   c2 27 a8 a7     st  %g1, [ %fp + 0x8a7 ]
  30:   01 00 00 00     nop
  34:   81 cf e0 08     rett  %i7 + 8
  38:   01 00 00 00     nop

000000000000003c <nonleaf_call>:
  3c:   9d e3 bf 40     save  %sp, -192, %sp         ; prolog
  40:   8a 10 00 19     mov  %i1, %g5                ; |
  44:   88 10 00 1a     mov  %i2, %g4                ; |
  48:   86 10 00 1b     mov  %i3, %g3                ; |
  4c:   84 10 00 1c     mov  %i4, %g2                ; |
  50:   82 10 00 1d     mov  %i5, %g1                ; |
  54:   f0 27 a8 7f     st  %i0, [ %fp + 0x87f ]     ; | write input to prev frame's spill area (e.g. offset = 128 for i0, jumping over i*/l* save area)
  58:   ca 27 a8 87     st  %g5, [ %fp + 0x887 ]     ; | (pointlessly using an extra reg copy to g* for most)
  5c:   c8 27 a8 8f     st  %g4, [ %fp + 0x88f ]     ; | 
  60:   c6 27 a8 97     st  %g3, [ %fp + 0x897 ]     ; |
  64:   c4 27 a8 9f     st  %g2, [ %fp + 0x89f ]     ; |

dyncall/doc/disas_examples/sparc64.sparc64.disas  view on Meta::CPAN

  c4:   c2 73 a8 af     stx  %g1, [ %sp + 0x8af ]    ; ... "pushed" onto stack
  c8:   9a 10 00 1c     mov  %i4, %o5                ; |
  cc:   98 10 00 1d     mov  %i5, %o4                ; |
  d0:   96 10 00 05     mov  %g5, %o3                ; |
  d4:   94 10 00 04     mov  %g4, %o2                ; | arg 0,1,2,3,4 (fetched from prev frame's spill area)
  d8:   92 10 00 03     mov  %g3, %o1                ; |
  dc:   90 10 00 02     mov  %g2, %o0                ; |
  e0:   40 00 00 00     call  e0 <nonleaf_call+0xa4> ; call leaf_call (objdump not from final link but .o)
  e4:   01 00 00 00     nop                          ; branch delay slot
  e8:   01 00 00 00     nop                          ;
  ec:   81 cf e0 08     rett  %i7 + 8                ; | epilog
  f0:   01 00 00 00     nop                          ; |            branch delay slot

00000000000000f4 <main>:
  f4:   9d e3 bf 40     save  %sp, -192, %sp         ; prolog
  f8:   82 10 20 07     mov  7, %g1                  ; arg 7, ...
  fc:   c2 73 a8 b7     stx  %g1, [ %sp + 0x8b7 ]    ; ... "pushed" onto stack
 100:   82 10 20 06     mov  6, %g1                  ; arg 6, ...
 104:   c2 73 a8 af     stx  %g1, [ %sp + 0x8af ]    ; ... "pushed" onto stack
 108:   9a 10 20 05     mov  5, %o5                  ; arg 5
 10c:   98 10 20 04     mov  4, %o4                  ; arg 4
 110:   96 10 20 03     mov  3, %o3                  ; arg 3
 114:   94 10 20 02     mov  2, %o2                  ; arg 2
 118:   92 10 20 01     mov  1, %o1                  ; arg 1
 11c:   90 10 20 00     clr  %o0                     ; arg 0
 120:   40 00 00 00     call  120 <main+0x2c>        ; 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



; output from freebsd-11.0-sparc64 w/ gcc 4.2.1

0000000000000000 <leaf_call>:
   0:   9d e3 bf 40     save  %sp, -192, %sp
   4:   82 10 00 18     mov  %i0, %g1
   8:   84 10 00 19     mov  %i1, %g2

dyncall/doc/disas_examples/sparc64.sparc64.disas  view on Meta::CPAN

; {
;     struct aggr st = nonleaf_call(0, 1, 2.f, 3, 4.f, 5, 6, 7.f);
;     return 0;
; }



; output from netbsd-7.1-sparc64 w/ gcc 4.8.5

0000000000000000 <leaf_call>:
   0:   9d e3 bf 50     save  %sp, -176, %sp            ; prolog
   4:   88 10 00 18     mov  %i0, %g4                   ; |
   8:   c7 27 a8 87     st  %f3, [ %fp + 0x887 ]        ; |
   c:   86 10 00 1a     mov  %i2, %g3                   ; |
  10:   cf 27 a8 97     st  %f7, [ %fp + 0x897 ]        ; |
  14:   84 10 00 1c     mov  %i4, %g2                   ; | write input to prev frame's spill area (e.g. offset = 128 for i0, jumping over i*/l* save area)
  18:   82 10 00 1d     mov  %i5, %g1                   ; | (pointlessly using an extra reg copy to g* for most)
  1c:   db 27 a8 af     st  %f13, [ %fp + 0x8af ]       ; | note: float args are spilled as are all others
  20:   c8 27 a8 7f     st  %g4, [ %fp + 0x87f ]        ; | 
  24:   c6 27 a8 8f     st  %g3, [ %fp + 0x88f ]        ; |
  28:   c4 27 a8 9f     st  %g2, [ %fp + 0x89f ]        ; |
  2c:   c2 27 a8 a7     st  %g1, [ %fp + 0x8a7 ]        ; /
  30:   81 cf e0 08     rett  %i7 + 8                   ; \ trap epilog
  34:   01 00 00 00     nop                             ; |              branch delay slot

0000000000000038 <nonleaf_call>:
  38:   9d e3 bf 20     save  %sp, -224, %sp            ; prolog
  3c:   88 10 00 18     mov  %i0, %g4                   ; |
  40:   86 10 00 19     mov  %i1, %g3                   ; |
  44:   cb 27 a8 8f     st  %f5, [ %fp + 0x88f ]        ; |
  48:   84 10 00 1b     mov  %i3, %g2                   ; |
  4c:   d3 27 a8 9f     st  %f9, [ %fp + 0x89f ]        ; | write input to prev frame's spill area (e.g. offset = 128 for i0, jumping over i*/l* save area)
  50:   82 10 00 1d     mov  %i5, %g1                   ; | (pointlessly using an extra reg copy to g* for most)
  54:   c8 27 a8 7f     st  %g4, [ %fp + 0x87f ]        ; | note: float args are spilled as are all others
  58:   c6 27 a8 87     st  %g3, [ %fp + 0x887 ]        ; | 
  5c:   c4 27 a8 97     st  %g2, [ %fp + 0x897 ]        ; |
  60:   c2 27 a8 a7     st  %g1, [ %fp + 0x8a7 ]        ; |

dyncall/doc/disas_examples/sparc64.sparc64.disas  view on Meta::CPAN

  80:   c2 77 a7 e7     stx  %g1, [ %fp + 0x7e7 ]       ; ... store to local space (0x7e7 - bias = -24)
  84:   c2 5f a7 e7     ldx  [ %fp + 0x7e7 ], %g1       ; reread to start iteration (pointlessly)
  88:   84 00 60 04     add  %g1, 4, %g2                ; point read ptr in g2 to first unnamed param (int)
  8c:   c4 00 80 00     ld  [ %g2 ], %g2                ; in arg 6 (fetched from prev frame's stack param area), ...
  90:   c4 27 a7 fb     st  %g2, [ %fp + 0x7fb ]        ; ... copied to local space (0x7fb - bias = -4) helper var (probably int g)
  94:   82 00 60 08     add  %g1, 8, %g1                ; point read ptr in g1 to second unnamed param (float, promoted to double), ...
  98:   c2 77 a7 e7     stx  %g1, [ %fp + 0x7e7 ]       ; ... store in local space (0x7fb - bias = -24)
  9c:   91 d0 20 05     ta  5                           ; trap - not sure what else is involved (objdump was made from .o, not finally linked exec) - maybe just b/c objdump skipped this for the output?

00000000000000a0 <main>:
  a0:   9d e3 bf 30     save  %sp, -208, %sp            ; prolog
  a4:   03 00 00 00     sethi  %hi(0), %g1              ; |
  a8:   82 10 60 00     mov  %g1, %g1   ! 0 <leaf_call> ; |
  ac:   83 28 70 0c     sllx  %g1, 0xc, %g1             ; | prep arg 2, load from static data into f11 (addr = 0 b/c objdumped .o, not final linked)
  b0:   82 10 60 00     mov  %g1, %g1                   ; |
  b4:   d7 00 40 00     ld  [ %g1 ], %f11               ; /
  b8:   03 00 00 00     sethi  %hi(0), %g1              ; \
  bc:   82 10 60 00     mov  %g1, %g1   ! 0 <leaf_call> ; | prep arg 4, load from static data into f10 (addr = 0 b/c objdumped .o, not final linked)
  c0:   83 28 70 0c     sllx  %g1, 0xc, %g1             ; |
  c4:   82 10 60 00     mov  %g1, %g1                   ; |
  c8:   d5 00 40 00     ld  [ %g1 ], %f10               ; |

dyncall/doc/disas_examples/sparc64.sparc64.disas  view on Meta::CPAN

 13c:   84 10 c0 02     or  %g3, %g2, %g2               ; |
 140:   c4 27 a7 f7     st  %g2, [ %fp + 0x7f7 ]        ; /
 144:   83 38 70 20     srax  %g1, 0x20, %g1            ; \
 148:   c4 07 a7 fb     ld  [ %fp + 0x7fb ], %g2        ; |
 14c:   84 08 a0 00     and  %g2, 0, %g2                ; | store 3rd struct field (int) by g1 >> 32 (and then some other operations unnecessary here)
 150:   82 10 80 01     or  %g2, %g1, %g1               ; |
 154:   c2 27 a7 fb     st  %g1, [ %fp + 0x7fb ]        ; /
 158:   82 10 20 00     clr  %g1                        ; \
 15c:   83 38 60 00     sra  %g1, 0, %g1                ; / return value
 160:   b0 10 00 01     mov  %g1, %i0                   ; \
 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)
; {

dyncall/doc/disas_examples/sparc64.sparc64.disas  view on Meta::CPAN

 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       ; |

dyncall/doc/disas_examples/sparc64.sparc64.disas  view on Meta::CPAN

 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)

dyncall/doc/disas_examples/sparc64.sparc64.disas  view on Meta::CPAN

 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>         ; |

dyncall/doc/disas_examples/sparc64.sparc64.disas  view on Meta::CPAN

 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; };

dyncall/doc/disas_examples/sparc64.sparc64.disas  view on Meta::CPAN

  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                                     ; /
  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 ]                ; /

dyncall/doc/disas_examples/sparc64.sparc64.disas  view on Meta::CPAN

 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



; ---------- passing structs with only fp parts ---------->
;
; struct A { float a; };
; struct B { float a, b; };
; struct C { float a, b, c; };
; struct D { double a; };

dyncall/doc/disas_examples/sparc64.sparc64.disas  view on Meta::CPAN

  38:   e1 27 a8 8f     st  %f16, [ %fp + 0x88f ]
  3c:   e3 27 a8 93     st  %f17, [ %fp + 0x893 ]
  40:   e5 27 a8 97     st  %f18, [ %fp + 0x897 ]
  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 be b0     save  %sp, -336, %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                                     ; /
  6c:   03 00 00 00     sethi  %hi(0), %g1                      ; \
  70:   82 10 60 00     mov  %g1, %g1   ! 0 <leaf_call>         ; |
  74:   c2 5d c0 01     ldx  [ %l7 + %g1 ], %g1                 ; | put together local struct A
  78:   d1 00 40 00     ld  [ %g1 ], %f8                        ; |
  7c:   d1 27 a7 e3     st  %f8, [ %fp + 0x7e3 ]                ; /
  80:   03 00 00 00     sethi  %hi(0), %g1                      ; \

dyncall/doc/disas_examples/sparc64.sparc64.disas  view on Meta::CPAN

 1b0:   87 a0 00 2e     fmovs  %f14, %f3                        ; /                    second float
 1b4:   89 a0 00 2f     fmovs  %f15, %f4                        ; \                    first float
 1b8:   8b a0 00 30     fmovs  %f16, %f5                        ; | arg 2 (struct C)   second float
 1bc:   8d a0 00 31     fmovs  %f17, %f6                        ; /                    third float
 1c0:   91 a0 00 52     fmovd  %f18, %f8                        ; arg 3  (entire struct D, single field double)
 1c4:   40 00 00 00     call  1c4 <main+0x16c>                  ; call nonleaf_call (objdump not from final link but .o)
 1c8:   01 00 00 00     nop                                     ; branch delay slot
 1cc:   82 10 20 00     clr  %g1        ! 0 <leaf_call>         ; \
 1d0:   83 38 60 00     sra  %g1, 0, %g1                        ; / return value
 1d4:   b0 10 00 01     mov  %g1, %i0                           ; \
 1d8:   81 cf e0 08     rett  %i7 + 8                           ; | epilog
 1dc:   01 00 00 00     nop                                     ; |            branch delay slot



; ---------- passing only unions with only fp parts ---------->
;
; union A { float a; };
; union B { float a, b; };
; union C { float a, b, c; };
; union D { double a; };

dyncall/doc/disas_examples/sparc64.sparc64.disas  view on Meta::CPAN

  4c:   82 08 60 00     and  %g1, 0, %g1
  50:   82 10 40 04     or  %g1, %g4, %g1
  54:   c2 27 a8 8f     st  %g1, [ %fp + 0x88f ]
  58:   81 cf e0 08     rett  %i7 + 8
  5c:   01 00 00 00     nop
  60:   ae 03 c0 17     add  %o7, %l7, %l7
  64:   81 c3 e0 08     retl
  68:   01 00 00 00     nop

000000000000006c <main>:
  6c:   9d e3 bf 10     save  %sp, -240, %sp                    ; prolog
  70:   2f 00 00 00     sethi  %hi(0), %l7                      ; |
  74:   ae 05 e0 00     add  %l7, 0, %l7        ! 0 <leaf_call> ; | @@@ unsure, call to some code stub adding o7 to l7
  78:   7f ff ff fa     call  60 <leaf_call+0x60>               ; |
  7c:   01 00 00 00     nop                                     ; /
  80:   03 00 00 00     sethi  %hi(0), %g1                      ; \
  84:   82 10 60 00     mov  %g1, %g1   ! 0 <leaf_call>         ; |
  88:   c2 5d c0 01     ldx  [ %l7 + %g1 ], %g1                 ; | put together local union A
  8c:   d1 00 40 00     ld  [ %g1 ], %f8                        ; |
  90:   d1 27 a7 e3     st  %f8, [ %fp + 0x7e3 ]                ; /
  94:   03 00 00 00     sethi  %hi(0), %g1                      ; \

dyncall/doc/disas_examples/sparc64.sparc64.disas  view on Meta::CPAN

 128:   90 10 00 03     mov  %g3, %o0                           ; arg 0      |
 12c:   92 10 00 02     mov  %g2, %o1                           ; arg 1      | note: all left-justified
 130:   94 10 00 01     mov  %g1, %o2                           ; arg 2      |
 134:   96 10 00 04     mov  %g4, %o3                           ; arg 3
 138:   98 10 00 05     mov  %g5, %o4                           ; arg 4
 13c:   40 00 00 00     call  13c <main+0xd0>                   ; call nonleaf_call (objdump not from final link but .o)
 140:   01 00 00 00     nop                                     ; branch delay slot
 144:   82 10 20 00     clr  %g1        ! 0 <leaf_call>         ; \
 148:   83 38 60 00     sra  %g1, 0, %g1                        ; / return value
 14c:   b0 10 00 01     mov  %g1, %i0                           ; \
 150:   81 cf e0 08     rett  %i7 + 8                           ; | epilog
 154:   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()

dyncall/doc/disas_examples/x64.sysv.disas  view on Meta::CPAN

   d:   89 55 f4                mov    %edx,-0xc(%rbp)
  10:   89 4d f0                mov    %ecx,-0x10(%rbp)
  13:   44 89 45 ec             mov    %r8d,-0x14(%rbp)
  17:   44 89 4d e8             mov    %r9d,-0x18(%rbp)
  1b:   89 45 e4                mov    %eax,-0x1c(%rbp)
  1e:   5d                      pop    %rbp
  1f:   c3                      retq

0000000000000020 <nonleaf_call>:
  20:   55                      push   %rbp                 ; |
  21:   48 89 e5                mov    %rsp,%rbp            ; | prolog
  24:   48 83 ec 40             sub    $0x40,%rsp           ; |           open frame *with* static alloca() size included
  28:   8b 45 18                mov    0x18(%rbp),%eax      ; unsure... get stack param from prev frame into some scratch reg... but why? see below @@@
  2b:   44 8b 55 10             mov    0x10(%rbp),%r10d     ; unsure... get stack param from prev frame into some scratch reg... but why? see below @@@
  2f:   89 7d fc                mov    %edi,-0x4(%rbp)      ; in arg 0 -> local area (as temp store)
  32:   89 75 f8                mov    %esi,-0x8(%rbp)      ; in arg 1 -> local area (as temp store)
  35:   89 55 f4                mov    %edx,-0xc(%rbp)      ; in arg 2 -> local area (as temp store)
  38:   89 4d f0                mov    %ecx,-0x10(%rbp)     ; in arg 3 -> local area (as temp store)
  3b:   44 89 45 ec             mov    %r8d,-0x14(%rbp)     ; in arg 4 -> local area (as temp store)
  3f:   44 89 4d e8             mov    %r9d,-0x18(%rbp)     ; in arg 5 -> local area (as temp store)
  43:   c6 45 d0 4c             movb   $0x4c,-0x30(%rbp)    ; 'L' -> local area (of alloca()'d space)

dyncall/doc/disas_examples/x64.sysv.disas  view on Meta::CPAN

  4d:   8b 55 f0                mov    -0x10(%rbp),%edx     ; arg 2
  50:   8b 4d ec                mov    -0x14(%rbp),%ecx     ; arg 3
  53:   44 8b 45 e8             mov    -0x18(%rbp),%r8d     ; arg 4
  57:   44 8b 4d 10             mov    0x10(%rbp),%r9d      ; arg 5 (fetched from prev frame's param area - behind return addr on 16b aligned stack)
  5b:   44 8b 5d 18             mov    0x18(%rbp),%r11d     ; arg 6 (fetched from prev frame's param area), and ...
  5f:   44 89 1c 24             mov    %r11d,(%rsp)         ; ... "pushed" onto stack
  63:   44 89 55 cc             mov    %r10d,-0x34(%rbp)    ; unsure... write something to local area @@@?
  67:   89 45 c8                mov    %eax,-0x38(%rbp)     ; unsure... write something to local area @@@?
  6a:   e8 91 ff ff ff          callq  0 <leaf_call>        ; push return addr and call
  6f:   48 83 c4 40             add    $0x40,%rsp           ; |
  73:   5d                      pop    %rbp                 ; | epilog
  74:   c3                      retq                        ; |
  75:   66 66 2e 0f 1f 84 00    nopw   %cs:0x0(%rax,%rax,1) ; garbage data
  7c:   00 00 00 00                                         ; garbage data

0000000000000080 <main>:
  80:   55                      push   %rbp                 ; |
  81:   48 89 e5                mov    %rsp,%rbp            ; | prolog
  84:   48 83 ec 20             sub    $0x20,%rsp           ; |
  88:   31 ff                   xor    %edi,%edi            ; arg 0
  8a:   be 01 00 00 00          mov    $0x1,%esi            ; arg 1
  8f:   ba 02 00 00 00          mov    $0x2,%edx            ; arg 2
  94:   b9 03 00 00 00          mov    $0x3,%ecx            ; arg 3
  99:   41 b8 04 00 00 00       mov    $0x4,%r8d            ; arg 4
  9f:   41 b9 05 00 00 00       mov    $0x5,%r9d            ; arg 5
  a5:   b8 06 00 00 00          mov    $0x6,%eax            ; unsure... see below @@@?
  aa:   41 ba 07 00 00 00       mov    $0x7,%r10d           ; unsure... see below @@@?
  b0:   c7 45 fc 00 00 00 00    movl   $0x0,-0x4(%rbp)      ; unsure... write 0 to local area @@@?
  b7:   c7 04 24 06 00 00 00    movl   $0x6,(%rsp)          ; "push" arg6 onto stack
  be:   c7 44 24 08 07 00 00 00 movl   $0x7,0x8(%rsp)       ; "push" arg7 onto stack
  c6:   44 89 55 f8             mov    %r10d,-0x8(%rbp)     ; unsure... write something to local area @@@?
  ca:   89 45 f4                mov    %eax,-0xc(%rbp)      ; unsure... write something to local area @@@?
  cd:   e8 4e ff ff ff          callq  20 <nonleaf_call>    ; push return addr and call
  d2:   31 c0                   xor    %eax,%eax            ; return value
  d4:   48 83 c4 20             add    $0x20,%rsp           ; |
  d8:   5d                      pop    %rbp                 ; | epilog
  d9:   c3                      retq                        ; |



; output from arch_linux-2011.08.19-x64 w/ gcc 4.6.1 (w/ alloca(220) instead of 10)

0000000000000000 <leaf_call>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   89 7d fc                mov    %edi,-0x4(%rbp)

dyncall/doc/disas_examples/x64.sysv.disas  view on Meta::CPAN

  201936:       89 75 e8                      mov    %esi,-0x18(%rbp)
  201939:       89 55 e4                      mov    %edx,-0x1c(%rbp)
  20193c:       89 4d e0                      mov    %ecx,-0x20(%rbp)
  20193f:       5d                            pop    %rbp
  201940:       c3                            retq
  201941:       66 2e 0f 1f 84 00 00 00 00 00 nopw   %cs:0x0(%rax,%rax,1)
  20194b:       0f 1f 44 00 00                nopl   0x0(%rax,%rax,1)

0000000000201950 <nonleaf_call>:
  201950:       55                            push   %rbp                   ; |
  201951:       48 89 e5                      mov    %rsp,%rbp              ; | prolog
  201954:       53                            push   %rbx                   ; |
  201955:       48 81 ec 18 01 00 00          sub    $0x118,%rsp            ; |           open frame *with* static alloca() size included
  20195c:       8b 45 20                      mov    0x20(%rbp),%eax        ; unsure... stack param from prev frame into some scratch reg... but why? see below @@@
  20195f:       4c 8d 55 10                   lea    0x10(%rbp),%r10        ; ptr to struct on stack -> r10
  201963:       89 7d f4                      mov    %edi,-0xc(%rbp)        ; |
  201966:       89 75 f0                      mov    %esi,-0x10(%rbp)       ; |
  201969:       89 55 ec                      mov    %edx,-0x14(%rbp)       ; |
  20196c:       89 4d e8                      mov    %ecx,-0x18(%rbp)       ; | in args (regs) -> local area (as temp store, mem order 8,4,3,2,1,0)
  20196f:       44 89 45 e4                   mov    %r8d,-0x1c(%rbp)       ; |
  201973:       44 89 4d e0                   mov    %r9d,-0x20(%rbp)       ; |

dyncall/doc/disas_examples/x64.sysv.disas  view on Meta::CPAN

  2019a3:       44 89 8d f8 fe ff ff          mov    %r9d,-0x108(%rbp)      ; 'free' r9, temp store content
  2019aa:       4d 89 d1                      mov    %r10,%r9               ; arg 4 (A.l)
  2019ad:       8b 9d fc fe ff ff             mov    -0x104(%rbp),%ebx      ; |
  2019b3:       89 1c 24                      mov    %ebx,(%rsp)            ; / arg 5 (fetch from temp store, pushed)   pointless, could've been pushed, directly
  2019b6:       8b 9d f8 fe ff ff             mov    -0x108(%rbp),%ebx      ; \
  2019bc:       89 5c 24 08                   mov    %ebx,0x8(%rsp)         ; | arg 6 (fetch from temp store, pushed)   pointless, could've been pushed, directly
  2019c0:       89 85 f4 fe ff ff             mov    %eax,-0x10c(%rbp)      ; unsure... write something to local area @@@?
  2019c6:       e8 55 ff ff ff                callq  201920 <leaf_call>     ; push return addr and call
  2019cb:       48 81 c4 18 01 00 00          add    $0x118,%rsp            ; |
  2019d2:       5b                            pop    %rbx                   ; |
  2019d3:       5d                            pop    %rbp                   ; | epilog
  2019d4:       c3                            retq                          ; |
  2019d5:       66 2e 0f 1f 84 00 00 00 00 00 nopw   %cs:0x0(%rax,%rax,1)   ; garbage data
  2019df:       90                            nop                           ; garbage data

00000000002019e0 <main>:
  2019e0:       55                            push   %rbp                   ; |
  2019e1:       48 89 e5                      mov    %rsp,%rbp              ; | prolog
  2019e4:       48 83 ec 30                   sub    $0x30,%rsp             ; |
  2019e8:       31 ff                         xor    %edi,%edi              ; arg 0
  2019ea:       c7 45 fc 00 00 00 00          movl   $0x0,-0x4(%rbp)        ; unsure... write 0 to local area @@@?
  2019f1:       c7 45 e8 05 00 00 00          movl   $0x5,-0x18(%rbp)       ; |                              field i
  2019f8:       c7 45 ec 06 00 00 00          movl   $0x6,-0x14(%rbp)       ; | fill struct A (local area)   field j
  2019ff:       48 c7 45 f0 07 00 00 00       movq   $0x7,-0x10(%rbp)       ; |                              field l
  201a07:       be 01 00 00 00                mov    $0x1,%esi              ; arg 1
  201a0c:       ba 02 00 00 00                mov    $0x2,%edx              ; arg 2
  201a11:       b9 03 00 00 00                mov    $0x3,%ecx              ; arg 3
  201a16:       41 b8 04 00 00 00             mov    $0x4,%r8d              ; arg 4
  201a1c:       48 8d 45 e8                   lea    -0x18(%rbp),%rax       ; |
  201a20:       4c 8b 08                      mov    (%rax),%r9             ; |
  201a23:       4c 89 0c 24                   mov    %r9,(%rsp)             ; | arg 5 (struct, pushed onto stack, as not enough regs)
  201a27:       48 8b 40 08                   mov    0x8(%rax),%rax         ; |
  201a2b:       48 89 44 24 08                mov    %rax,0x8(%rsp)         ; |
  201a30:       41 b9 08 00 00 00             mov    $0x8,%r9d              ; arg 6 (in reg)
  201a36:       c7 44 24 10 09 00 00 00       movl   $0x9,0x10(%rsp)        ; arg 7 (pushed)
  201a3e:       e8 0d ff ff ff                callq  201950 <nonleaf_call>  ; push return addr and call
  201a43:       31 c0                         xor    %eax,%eax              ; return value
  201a45:       48 83 c4 30                   add    $0x30,%rsp             ; |
  201a49:       5d                            pop    %rbp                   ; | epilog
  201a4a:       c3                            retq                          ; |


; ---------- structs by value, complex example (multiple structs, partly passed via regs) ---------->
;
; #include <stdlib.h>
;
; struct A { int i, j; float f; };
; struct B { double d; long long l; };
;

dyncall/doc/disas_examples/x64.sysv.disas  view on Meta::CPAN

  20198c:   44 89 45 a4                   mov    %r8d,-0x5c(%rbp)
  201990:   5d                            pop    %rbp
  201991:   c3                            retq
  201992:   66 2e 0f 1f 84 00 00 00 00 00 nopw   %cs:0x0(%rax,%rax,1)
  20199c:   0f 1f 40 00                   nopl   0x0(%rax)

00000000002019a0 <nonleaf_call>:
  2019a0:   55                            push   %rbp                     ; |
  2019a1:   48 89 e5                      mov    %rsp,%rbp                ; |
  2019a4:   41 57                         push   %r15                     ; |
  2019a6:   41 56                         push   %r14                     ; | prolog
  2019a8:   41 54                         push   %r12                     ; |
  2019aa:   53                            push   %rbx                     ; |
  2019ab:   48 81 ec 70 01 00 00          sub    $0x170,%rsp              ; |           open frame *with* static alloca() size included
  2019b2:   8b 45 38                      mov    0x38(%rbp),%eax          ; unsure... get last (15) stack param from prev frame into some scratch reg... but why? see below @@@
  2019b5:   44 8b 55 30                   mov    0x30(%rbp),%r10d         ; unsure... get one to last (14) stack param from prev frame into some scratch reg... but why? see below @@@
  2019b9:   4c 8d 5d 20                   lea    0x20(%rbp),%r11          ; ptr to struct B on stack -> rbx
  2019bd:   48 8d 5d 10                   lea    0x10(%rbp),%rbx          ; ptr to struct A on stack -> r11
  2019c1:   48 89 55 c0                   mov    %rdx,-0x40(%rbp)         ; |                    \                                                 i, j
  2019c5:   f3 0f 11 45 c8                movss  %xmm0,-0x38(%rbp)        ; |                    / reassemble first struct A in mem (local area)   f
  2019ca:   48 8b 55 c0                   mov    -0x40(%rbp),%rdx         ; .                    \                 pointless reload of rdx w/ same val from same addr

dyncall/doc/disas_examples/x64.sysv.disas  view on Meta::CPAN

  201a69:   44 8b b5 9c fe ff ff          mov    -0x164(%rbp),%r14d       ; \
  201a70:   44 89 74 24 10                mov    %r14d,0x10(%rsp)         ; / arg 7 (pushed, aligned)
  201a75:   44 8b b5 98 fe ff ff          mov    -0x168(%rbp),%r14d       ; \
  201a7c:   44 89 74 24 18                mov    %r14d,0x18(%rsp)         ; / arg 8 (pushed, aligned)
  201a81:   89 85 94 fe ff ff             mov    %eax,-0x16c(%rbp)        ; unsure... write something to local area @@@?
  201a87:   44 89 95 90 fe ff ff          mov    %r10d,-0x170(%rbp)       ; unsure... write something to local area @@@?
  201a8e:   e8 ad fe ff ff                callq  201940 <leaf_call>       ; push return addr and call
  201a93:   48 81 c4 70 01 00 00          add    $0x170,%rsp              ; |
  201a9a:   5b                            pop    %rbx                     ; |
  201a9b:   41 5c                         pop    %r12                     ; |
  201a9d:   41 5e                         pop    %r14                     ; | epilog
  201a9f:   41 5f                         pop    %r15                     ; |
  201aa1:   5d                            pop    %rbp                     ; |
  201aa2:   c3                            retq                            ; |
  201aa3:   66 2e 0f 1f 84 00 00 00 00 00 nopw   %cs:0x0(%rax,%rax,1)     ; garbage data
  201aad:   0f 1f 00                      nopl   (%rax)                   ; garbage data

0000000000201ab0 <main>:
  201ab0:   55                            push   %rbp                     ; |
  201ab1:   48 89 e5                      mov    %rsp,%rbp                ; | prolog
  201ab4:   48 81 ec 80 00 00 00          sub    $0x80,%rsp               ; |
  201abb:   31 ff                         xor    %edi,%edi                ; arg 0
  201abd:   f2 0f 10 05 2b ea ff ff       movsd  -0x15d5(%rip),%xmm0      ; not arg: prep to fill struct B field d (12.0)
  201ac5:   f3 0f 10 0d 2f ea ff ff       movss  -0x15d1(%rip),%xmm1      ; not arg: prep to fill struct A field f (11.f)
  201acd:   f2 0f 10 15 13 ea ff ff       movsd  -0x15ed(%rip),%xmm2      ; not arg: prep to fill struct B field d (5.0)
  201ad5:   f3 0f 10 1d 1b ea ff ff       movss  -0x15e5(%rip),%xmm3      ; not arg: prep to fill struct A field f (4.f)
  201add:   c7 45 fc 00 00 00 00          movl   $0x0,-0x4(%rbp)          ; unsure... write 0 to local area @@@?
  201ae4:   c7 45 f0 02 00 00 00          movl   $0x2,-0x10(%rbp)         ; \                                    field i
  201aeb:   c7 45 f4 03 00 00 00          movl   $0x3,-0xc(%rbp)          ; | fill first struct A (local area)   field j
  201af2:   f3 0f 11 5d f8                movss  %xmm3,-0x8(%rbp)         ; /                                    field f

dyncall/doc/disas_examples/x64.sysv.disas  view on Meta::CPAN

  201b69:   48 8d 45 c0                   lea    -0x40(%rbp),%rax         ; \                                              \
  201b6d:   4c 8b 10                      mov    (%rax),%r10              ; |                                              | d (aligned)
  201b70:   4c 89 54 24 10                mov    %r10,0x10(%rsp)          ; | arg 7   (last struct B, *pushed* by value)   /
  201b75:   48 8b 40 08                   mov    0x8(%rax),%rax           ; |                                              \ l
  201b79:   48 89 44 24 18                mov    %rax,0x18(%rsp)          ; /                                              /
  201b7e:   c7 44 24 20 0e 00 00 00       movl   $0xe,0x20(%rsp)          ; arg 8 (pushed, aligned)
  201b86:   c7 44 24 28 0f 00 00 00       movl   $0xf,0x28(%rsp)          ; arg 9 (pushed, aligned)
  201b8e:   e8 0d fe ff ff                callq  2019a0 <nonleaf_call>    ; push return addr and call
  201b93:   31 c0                         xor    %eax,%eax                ; return value
  201b95:   48 81 c4 80 00 00 00          add    $0x80,%rsp               ; |
  201b9c:   5d                            pop    %rbp                     ; | epilog
  201b9d:   c3                            retq                            ; |



; ---------- returning tiny struct by value (passes via regs) ---------->
;
; struct A { unsigned char a; };
;
; struct A call(unsigned char c)
; {

dyncall/doc/disas_examples/x64.sysv.disas  view on Meta::CPAN

;     struct A a = call(123);
;     return 0;
; }



; output from freebsd-12.2-x64 w/ clang 10.0.1

00000000002018f0 <call>:
  2018f0:       55                              push   %rbp                 ; |
  2018f1:       48 89 e5                        mov    %rsp,%rbp            ; | prolog
  2018f4:       40 88 7d f7                     mov    %dil,-0x9(%rbp)      ; in arg 0 -> local area, ...             | a bit pointless, could've been
  2018f8:       8a 45 f7                        mov    -0x9(%rbp),%al       ; ... from local area -> eax, then ...    | moved to -0x8(%rbp) directly
  2018fb:       88 45 f8                        mov    %al,-0x8(%rbp)       ; ... to struct in local area
  2018fe:       8a 45 f8                        mov    -0x8(%rbp),%al       ; return value
  201901:       5d                              pop    %rbp                 ; | epilog
  201902:       c3                              retq                        ; |
  201903:       66 2e 0f 1f 84 00 00 00 00 00   nopw   %cs:0x0(%rax,%rax,1) ; garbage data
  20190d:       0f 1f 00                        nopl   (%rax)               ; garbage data

0000000000201910 <main>:
  201910:       55                              push   %rbp                 ; |
  201911:       48 89 e5                        mov    %rsp,%rbp            ; | prolog
  201914:       48 83 ec 10                     sub    $0x10,%rsp           ; |
  201918:       c7 45 fc 00 00 00 00            movl   $0x0,-0x4(%rbp)      ; @@@ unsure, clears dword of local area
  20191f:       bf 7b 00 00 00                  mov    $0x7b,%edi           ; arg 0 (123)
  201924:       e8 c7 ff ff ff                  callq  2018f0 <call>        ; push return addr and call
  201929:       31 c9                           xor    %ecx,%ecx            ; return value prep (a bit pointless)
  20192b:       88 45 f8                        mov    %al,-0x8(%rbp)       ; write struct data to local area (123)
  20192e:       89 c8                           mov    %ecx,%eax            ; return value
  201930:       48 83 c4 10                     add    $0x10,%rsp           ; |
  201934:       5d                              pop    %rbp                 ; | epilog
  201935:       c3                              retq                        ; |



; output from freebsd-12.2-x64 w/ gcc 10.3.0

00000000004007a5 <call>:
  4007a5:       55                      push   %rbp                ; |
  4007a6:       48 89 e5                mov    %rsp,%rbp           ; | prolog
  4007a9:       89 f8                   mov    %edi,%eax           ; in arg 0 ...
  4007ab:       88 45 fc                mov    %al,-0x4(%rbp)      ; ... -> struct in local area
  4007ae:       0f b6 45 fc             movzbl -0x4(%rbp),%eax     ; return value (entire struct in eax)
  4007b2:       5d                      pop    %rbp                ; | epilog
  4007b3:       c3                      retq                       ; |

00000000004007b4 <main>:
  4007b4:       55                      push   %rbp                ; |
  4007b5:       48 89 e5                mov    %rsp,%rbp           ; | prolog
  4007b8:       48 83 ec 10             sub    $0x10,%rsp          ; |
  4007bc:       bf 7b 00 00 00          mov    $0x7b,%edi          ; arg 0 (123)
  4007c1:       e8 df ff ff ff          callq  4007a5 <call>       ; push return addr and call
  4007c6:       88 45 ff                mov    %al,-0x1(%rbp)      ; write struct data to local area (123)
  4007c9:       b8 00 00 00 00          mov    $0x0,%eax           ; return value
  4007ce:       c9                      leaveq                     ; |
  4007cf:       c3                      retq                       ; | epilog



; ---------- 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" {
; 

dyncall/doc/disas_examples/x64.sysv.disas  view on Meta::CPAN

;         f2(n);
;         a -= 12;
;     }
; }



; output from freebsd-12.2-x64 w/ clang 10.0.1

0000000000000000 <f1>:
   0:   55                      push   %rbp             ; | prolog
   1:   48 89 e5                mov    %rsp,%rbp        ; |
   4:   89 7d f8                mov    %edi,-0x8(%rbp)  ; local copy of trivial struct
   7:   5d                      pop    %rbp             ; |
   8:   c3                      retq                    ; | epilog

0000000000000010 <f2>:
  10:   55                      push   %rbp             ; | prolog
  11:   48 89 e5                mov    %rsp,%rbp        ; /
  14:   5d                      pop    %rbp             ; \         note: no local copy as non-trivial
  15:   c3                      retq                    ; | epilog

0000000000000020 <f>:
  20:   55                      push   %rbp             ; |
  21:   48 89 e5                mov    %rsp,%rbp        ; | prolog
  24:   48 83 ec 20             sub    $0x20,%rsp       ; /
  28:   48 8d 7d f0             lea    -0x10(%rbp),%rdi ; \ this ptr (NULL)
  2c:   e8 00 00 00 00          callq  31 <f+0x11>      ; | NonTrivial::NonTrivial() / ctor
  31:   c7 45 ec 01 00 00 00    movl   $0x1,-0x14(%rbp) ; a = 1
  38:   8b 45 ec                mov    -0x14(%rbp),%eax ; |
  3b:   83 c0 7b                add    $0x7b,%eax       ; | a += 123
  3e:   89 45 ec                mov    %eax,-0x14(%rbp) ; /
  41:   8b 45 f8                mov    -0x8(%rbp),%eax  ; \
  44:   89 45 e8                mov    %eax,-0x18(%rbp) ; / local copy of t (struct Trivial)
  47:   8b 7d e8                mov    -0x18(%rbp),%edi ; f1 arg 0 (struct Trivial), via reg as small struct

dyncall/doc/disas_examples/x64.sysv.disas  view on Meta::CPAN

  55:   89 45 ec                mov    %eax,-0x14(%rbp) ; /
  58:   48 8d 7d e0             lea    -0x20(%rbp),%rdi ; \               ptr to dest of copy of n
  5c:   48 8d 75 f0             lea    -0x10(%rbp),%rsi ; | copy n        ptr to n
  60:   e8 00 00 00 00          callq  65 <f+0x45>      ; /               NonTrivial::NonTrivial(const NonTrivial&) / copy ctor
  65:   48 8d 7d e0             lea    -0x20(%rbp),%rdi ; f2 arg 0 (ptr to copy of struct NonTrivial), via ptr as non-trivial
  69:   e8 00 00 00 00          callq  6e <f+0x4e>      ; call f2(struct NonTrivial)
  6e:   8b 45 ec                mov    -0x14(%rbp),%eax ; |
  71:   83 e8 0c                sub    $0xc,%eax        ; | a -= 12
  74:   89 45 ec                mov    %eax,-0x14(%rbp) ; /
  77:   48 83 c4 20             add    $0x20,%rsp       ; \
  7b:   5d                      pop    %rbp             ; | epilog
  7c:   c3                      retq                    ; |

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



; ---------- C++ trivial and non-trivial aggrs as return values ---------->
;
; struct Trivial { int a; };
; struct NonTrivial { int a; NonTrivial() : a(0) {} NonTrivial(const NonTrivial& rhs) : a(rhs.a) { } };

dyncall/doc/disas_examples/x64.sysv.disas  view on Meta::CPAN

  2019fe:       48 89 4d f8             mov    %rcx,-0x8(%rbp)
  201a02:       48 89 45 f0             mov    %rax,-0x10(%rbp)
  201a06:       e8 85 00 00 00          callq  201a90 <_ZN10NonTrivialC2Ev>
  201a0b:       48 8b 45 f0             mov    -0x10(%rbp),%rax
  201a0f:       48 83 c4 10             add    $0x10,%rsp
  201a13:       5d                      pop    %rbp
  201a14:       c3                      retq

0000000000201a20 <f>:
  201a20:       55                      push   %rbp             ; |
  201a21:       48 89 e5                mov    %rsp,%rbp        ; | prolog
  201a24:       48 83 ec 10             sub    $0x10,%rsp       ; |
  201a28:       c7 45 fc 01 00 00 00    movl   $0x1,-0x4(%rbp)  ; a = 1
  201a2f:       8b 45 fc                mov    -0x4(%rbp),%eax  ; |
  201a32:       83 c0 7b                add    $0x7b,%eax       ; | a += 123
  201a35:       89 45 fc                mov    %eax,-0x4(%rbp)  ; |
  201a38:       e8 83 ff ff ff          callq  2019c0 <f1>      ; call f1()
  201a3d:       89 45 f8                mov    %eax,-0x8(%rbp)  ; retval via reg, as small struct
  201a40:       8b 45 fc                mov    -0x4(%rbp),%eax  ; |
  201a43:       83 e8 7b                sub    $0x7b,%eax       ; | a -= 123
  201a46:       89 45 fc                mov    %eax,-0x4(%rbp)  ; |
  201a49:       48 8d 7d f0             lea    -0x10(%rbp),%rdi ; ptr to space to hold non-triv retval
  201a4d:       e8 9e ff ff ff          callq  2019f0 <_Z2f2v>  ; call f2()
  201a52:       8b 45 fc                mov    -0x4(%rbp),%eax  ; |
  201a55:       83 e8 0c                sub    $0xc,%eax        ; | a-= 12
  201a58:       89 45 fc                mov    %eax,-0x4(%rbp)  ; /
  201a5b:       48 83 c4 10             add    $0x10,%rsp       ; \
  201a5f:       5d                      pop    %rbp             ; | epilog
  201a60:       c3                      retq                    ; |




; ---------- structs by value, struct passed as vararg ---------->
;
; #include <stdlib.h>
; #include <stdarg.h>
;

dyncall/doc/disas_examples/x64.sysv.disas  view on Meta::CPAN

   a:   89 55 f4                mov    %edx,-0xc(%rbp)          ;
   d:   89 4d f0                mov    %ecx,-0x10(%rbp)         ;
  10:   5d                      pop    %rbp                     ;
  11:   c3                      retq                            ;
  12:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)     ;
  19:   00 00 00                                                ;
  1c:   0f 1f 40 00             nopl   0x0(%rax)                ;

0000000000000020 <nonleaf_call>:
  20:   55                      push   %rbp                     ; |
  21:   48 89 e5                mov    %rsp,%rbp                ; | prolog
  24:   53                      push   %rbx                     ; |
  25:   48 81 ec 28 02 00 00    sub    $0x228,%rsp              ; |           open frame *with* static alloca() size included
  2c:   84 c0                   test   %al,%al                  ; test how many used xmm regs (= 0)
  2e:   0f 29 bd f0 fe ff ff    movaps %xmm7,-0x110(%rbp)       ; |
  35:   0f 29 b5 e0 fe ff ff    movaps %xmm6,-0x120(%rbp)       ; |
  3c:   0f 29 ad d0 fe ff ff    movaps %xmm5,-0x130(%rbp)       ; |
  43:   0f 29 a5 c0 fe ff ff    movaps %xmm4,-0x140(%rbp)       ; | spill xmm regs onto stack (none used by call, though)
  4a:   0f 29 9d b0 fe ff ff    movaps %xmm3,-0x150(%rbp)       ; |
  51:   0f 29 95 a0 fe ff ff    movaps %xmm2,-0x160(%rbp)       ; |
  58:   0f 29 8d 90 fe ff ff    movaps %xmm1,-0x170(%rbp)       ; |

dyncall/doc/disas_examples/x64.sysv.disas  view on Meta::CPAN

 3d2:   45 89 4b 08             mov    %r9d,0x8(%r11)           ; 'push' arg 5, 'frees' r9 implicitly
 3d6:   45 89 03                mov    %r8d,(%r11)              ; 'push' arg 6, 'frees' r8 implicitly
 3d9:   45 31 c0                xor    %r8d,%r8d                ; |
 3dc:   44 88 85 df fd ff ff    mov    %r8b,-0x221(%rbp)        ; | number of used xmm registers (0) -> temp store (see below)
 3e3:   49 89 c0                mov    %rax,%r8                 ; arg 4 (A.i, A.j)  |
 3e6:   4d 89 d1                mov    %r10,%r9                 ; arg 4 (A.l)       | struct passed in regs, regardless of it being a vararg
 3e9:   8a 85 df fd ff ff       mov    -0x221(%rbp),%al         ; number of used xmm registers (upper bound, req for varargs)
 3ef:   e8 00 00 00 00          callq  3f4 <nonleaf_call+0x3d4> ; push return addr and call
 3f4:   48 8d 65 f8             lea    -0x8(%rbp),%rsp          ; |
 3f8:   5b                      pop    %rbx                     ; |
 3f9:   5d                      pop    %rbp                     ; | epilog
 3fa:   c3                      retq                            ; |
 3fb:   0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)         ; garbage data

0000000000000400 <main>:
 400:   55                      push   %rbp                     ; |
 401:   48 89 e5                mov    %rsp,%rbp                ; | prolog
 404:   48 83 ec 30             sub    $0x30,%rsp               ; |
 408:   31 ff                   xor    %edi,%edi                ; arg 0
 40a:   c7 45 fc 00 00 00 00    movl   $0x0,-0x4(%rbp)          ; unsure... write 0 to local area @@@?
 411:   c7 45 e8 05 00 00 00    movl   $0x5,-0x18(%rbp)         ; |                              field i
 418:   c7 45 ec 06 00 00 00    movl   $0x6,-0x14(%rbp)         ; | fill struct A (local area)   field j
 41f:   48 c7 45 f0 07 00 00 00 movq   $0x7,-0x10(%rbp)         ; |                              field l
 427:   be 01 00 00 00          mov    $0x1,%esi                ; arg 1
 42c:   ba 02 00 00 00          mov    $0x2,%edx                ; arg 2
 431:   b9 03 00 00 00          mov    $0x3,%ecx                ; arg 3
 436:   41 b8 04 00 00 00       mov    $0x4,%r8d                ; arg 4

dyncall/doc/disas_examples/x64.sysv.disas  view on Meta::CPAN

 440:   4c 8b 08                mov    (%rax),%r9               ; |
 443:   4c 89 0c 24             mov    %r9,(%rsp)               ; | arg 5 (struct, pushed onto stack, as not enough regs)
 447:   48 8b 40 08             mov    0x8(%rax),%rax           ; |
 44b:   48 89 44 24 08          mov    %rax,0x8(%rsp)           ; |
 450:   41 b9 08 00 00 00       mov    $0x8,%r9d                ; arg 6 (in reg)
 456:   c7 44 24 10 09 00 00 00 movl   $0x9,0x10(%rsp)          ; arg 7 (pushed)
 45e:   b0 00                   mov    $0x0,%al                 ; number of used xmm registers (upper bound, req for varargs)
 460:   e8 00 00 00 00          callq  465 <main+0x65>          ; push return addr and call
 465:   31 c0                   xor    %eax,%eax                ; return value
 467:   48 83 c4 30             add    $0x30,%rsp               ; |
 46b:   5d                      pop    %rbp                     ; | epilog
 46c:   c3                      retq                            ; |



; vim: ft=asm

dyncall/doc/disas_examples/x64.win.disas  view on Meta::CPAN

e$ = 128
f$ = 136
g$ = 144
h$ = 152
nonleaf_call PROC
        mov     DWORD PTR [rsp+32], r9d   ; | |
        mov     DWORD PTR [rsp+24], r8d   ; | |
        mov     DWORD PTR [rsp+16], edx   ; | | spill
        mov     DWORD PTR [rsp+8], ecx    ; | |
        push    rdi                       ; |
        sub     rsp, 80                   ; | prolog
        mov     BYTE PTR x$[rsp], 76      ; 'L' -> local area (of local array's space)
        lea     rax, QWORD PTR x$[rsp+1]  ; |
        mov     rdi, rax                  ; |
        xor     eax, eax                  ; | zero-init rest of local array's space
        mov     ecx, 9                    ; |
        rep stosb                         ; |
        mov     eax, DWORD PTR h$[rsp]    ; arg 6 (fetched from caller's frame param area), and ...
        mov     DWORD PTR [rsp+48], eax   ; ... "pushed" onto stack
        mov     eax, DWORD PTR g$[rsp]    ; arg 5 (fetched from caller's frame param area), and ...
        mov     DWORD PTR [rsp+40], eax   ; ... "pushed" onto stack
        mov     eax, DWORD PTR f$[rsp]    ; arg 4 (fetched from caller's frame param area), and ...
        mov     DWORD PTR [rsp+32], eax   ; ... "pushed" onto stack
        mov     r9d, DWORD PTR e$[rsp]    ; arg 3
        mov     r8d, DWORD PTR d$[rsp]    ; arg 2
        mov     edx, DWORD PTR c$[rsp]    ; arg 1
        mov     ecx, DWORD PTR b$[rsp]    ; arg 0
        call    leaf_call                 ; push return addr and call
        add     rsp, 80                   ; |
        pop     rdi                       ; | epilog
        ret     0                         ; |
nonleaf_call ENDP

main    PROC
        sub     rsp, 72                   ; prolog
        mov     DWORD PTR [rsp+56], 7     ; "push" arg 7 onto stack
        mov     DWORD PTR [rsp+48], 6     ; "push" arg 6 onto stack
        mov     DWORD PTR [rsp+40], 5     ; "push" arg 5 onto stack
        mov     DWORD PTR [rsp+32], 4     ; "push" arg 4 onto stack
        mov     r9d, 3                    ; arg 3
        mov     r8d, 2                    ; arg 2
        mov     edx, 1                    ; arg 1
        xor     ecx, ecx                  ; arg 0
        call    nonleaf_call              ; push return addr and call
        xor     eax, eax                  ; return value
        add     rsp, 72                   ; |
        ret     0                         ; | epilog
main    ENDP



; ---------- structs by value, struct never in reg or on reg arg boundary ---------->
;
; 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)
; {

dyncall/doc/disas_examples/x64.win.disas  view on Meta::CPAN

; }



; output from godbolt compiler explorer w/ msvc 19.0

r$ = 0
c$ = 32
call    PROC
        mov     BYTE PTR [rsp+8], cl   ; |         spill
        sub     rsp, 24                ; | prolog
        movzx   eax, BYTE PTR c$[rsp]  ; in arg 0 (fetched from spill area) -> eax, then ...
        mov     BYTE PTR r$[rsp], al   ; ... -> struct in local area (top of stack, as leaf call and thus no reserved spill area)
        movzx   eax, BYTE PTR r$[rsp]  ; reget same value into eax to return (small) struct via reg (a bit pointless to refetch)
        add     rsp, 24                ; |
        ret     0                      ; | epilog
call    ENDP

a$ = 32
main    PROC
        sub     rsp, 56                ; prolog
        mov     cl, 123                ; arg 0
        call    call                   ; push return addr and call
        mov     BYTE PTR a$[rsp], al   ; write struct data to local area (123)
        xor     eax, eax               ; return value
        add     rsp, 56                ; |
        ret     0                      ; | epilog
main    ENDP



; ---------- 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" {

dyncall/doc/disas_examples/x64.win.disas  view on Meta::CPAN

        ret     0
f2      ENDP

a$ = 32
n$ = 36
t$ = 40
$T1 = 44
$T2 = 48
f       PROC
$LN3:
        sub     rsp, 72                                    ; prolog
        lea     rcx, QWORD PTR n$[rsp]                     ; \ this ptr (NULL)
        call    NonTrivial::NonTrivial(void)               ; | NonTrivial::NonTrivial() / ctor
        mov     DWORD PTR a$[rsp], 1                       ; a = 1
        mov     eax, DWORD PTR a$[rsp]                     ; |
        add     eax, 123                                   ; | a += 123
        mov     DWORD PTR a$[rsp], eax                     ; /
        mov     ecx, DWORD PTR t$[rsp]                     ; f1 arg 0 (struct Trivial), via reg as small struct
        call    f1                                         ; call f1(struct Trivial)
        mov     eax, DWORD PTR a$[rsp]                     ; |
        sub     eax, 123                                   ; | a -= 123

dyncall/doc/disas_examples/x64.win.disas  view on Meta::CPAN

        mov     QWORD PTR $T2[rsp], rax                    ; ... @@@
        lea     rdx, QWORD PTR n$[rsp]                     ; \               ptr to dest of copy of n
        mov     rcx, QWORD PTR $T2[rsp]                    ; | copy n        ptr to n
        call    NonTrivial::NonTrivial(NonTrivial const &) ; /               NonTrivial::NonTrivial(const NonTrivial&) / copy ctor
        mov     rcx, rax                                   ; f2 arg 0 (ptr to copy of struct NonTrivial), via ptr as non-trivial
        call    f2                                         ; call f2(struct NonTrivial)
        mov     eax, DWORD PTR a$[rsp]                     ; |
        sub     eax, 12                                    ; | a -= 12
        mov     DWORD PTR a$[rsp], eax                     ; /
        add     rsp, 72                                    ; \
        ret     0                                          ; | epilog
f       ENDP



; ---------- C++ trivial and non-trivial aggrs as return values ---------->
;
; struct Trivial { int a; };
; struct NonTrivial { int a; NonTrivial() : a(0) {} NonTrivial(const NonTrivial& rhs) : a(rhs.a) { } };
; 
; extern "C" {

dyncall/doc/disas_examples/x64.win.disas  view on Meta::CPAN

        add     rsp, 40
        ret     0
NonTrivial f2(void) ENDP

a$ = 32
$T1 = 36
t$ = 40
n$ = 44
f       PROC
$LN3:
        sub     rsp, 56                 ; prolog
        mov     DWORD PTR a$[rsp], 1    ; a = 1
        mov     eax, DWORD PTR a$[rsp]  ; |
        add     eax, 123                ; | a += 123
        mov     DWORD PTR a$[rsp], eax  ; |
        call    f1                      ; call f1()
        mov     DWORD PTR $T1[rsp], eax ;
        mov     eax, DWORD PTR $T1[rsp] ;
        mov     DWORD PTR t$[rsp], eax  ;
        mov     eax, DWORD PTR a$[rsp]  ; |
        sub     eax, 123                ; | a -= 123
        mov     DWORD PTR a$[rsp], eax  ; |
        lea     rcx, QWORD PTR n$[rsp]  ; ptr to space to hold non-triv retval
        call    NonTrivial f2(void)     ; call f2()
        mov     eax, DWORD PTR a$[rsp]  ; |
        sub     eax, 12                 ; | a -= 12
        mov     DWORD PTR a$[rsp], eax  ; /
        add     rsp, 56                 ; \ epilog
        ret     0                       ; |
f       ENDP                             



; ---------- structs by value, struct passed as vararg ---------->
;
; #include <stdlib.h>
; #include <stdarg.h>
;

dyncall/doc/disas_examples/x86.cdecl.disas  view on Meta::CPAN

; output from arch_linux-2011.08.19-x86 w/ gcc 4.6.1

00000000 <leaf_call>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   5d                      pop    %ebp
   4:   c3                      ret

00000005 <nonleaf_call>:
   5:   55                      push   %ebp                   ; |
   6:   89 e5                   mov    %esp,%ebp              ; | prolog
   8:   83 ec 38                sub    $0x38,%esp             ; /
   b:   b8 10 00 00 00          mov    $0x10,%eax             ; \                     |
  10:   83 e8 01                sub    $0x1,%eax              ; |                     | creative way to move 250 to eax
  13:   05 eb 00 00 00          add    $0xeb,%eax             ; |                     /
  18:   c7 45 f4 10 00 00 00    movl   $0x10,-0xc(%ebp)       ; | size comp wtf?      \
  1f:   ba 00 00 00 00          mov    $0x0,%edx              ; |                     |
  24:   f7 75 f4                divl   -0xc(%ebp)             ; |                     | obviously fastest way to round to multiple of 16
  27:   6b c0 10                imul   $0x10,%eax,%eax        ; |                     |
  2a:   29 c4                   sub    %eax,%esp              ; alloca(220) with size containing some padding computed above
  2c:   8d 44 24 1c             lea    0x1c(%esp),%eax        ; |

dyncall/doc/disas_examples/x86.cdecl.disas  view on Meta::CPAN

  51:   8b 45 18                mov    0x18(%ebp),%eax        ; | read in args 1-7 from prev frame's param area, and ...
  54:   89 44 24 0c             mov    %eax,0xc(%esp)         ; | ... "push" onto stack as arg 0-6
  58:   8b 45 14                mov    0x14(%ebp),%eax        ; |
  5b:   89 44 24 08             mov    %eax,0x8(%esp)         ; |
  5f:   8b 45 10                mov    0x10(%ebp),%eax        ; |
  62:   89 44 24 04             mov    %eax,0x4(%esp)         ; |
  66:   8b 45 0c                mov    0xc(%ebp),%eax         ; |
  69:   89 04 24                mov    %eax,(%esp)            ; |
  6c:   e8 fc ff ff ff          call   6d <nonleaf_call+0x68> ; push return address and call leaf_call (objdump not from final link but .o)
  71:   c9                      leave                         ; |
  72:   c3                      ret                           ; | epilog

00000073 <main>:
  73:   55                      push   %ebp                   ; |
  74:   89 e5                   mov    %esp,%ebp              ; |
  76:   83 e4 f0                and    $0xfffffff0,%esp       ; | prolog
  79:   83 ec 20                sub    $0x20,%esp             ; |
  7c:   c7 44 24 1c 07 00 00 00 movl   $0x7,0x1c(%esp)        ; arg 7 -> stack
  84:   c7 44 24 18 06 00 00 00 movl   $0x6,0x18(%esp)        ; arg 6 -> stack
  8c:   c7 44 24 14 05 00 00 00 movl   $0x5,0x14(%esp)        ; arg 5 -> stack
  94:   c7 44 24 10 04 00 00 00 movl   $0x4,0x10(%esp)        ; arg 4 -> stack
  9c:   c7 44 24 0c 03 00 00 00 movl   $0x3,0xc(%esp)         ; arg 3 -> stack
  a4:   c7 44 24 08 02 00 00 00 movl   $0x2,0x8(%esp)         ; arg 2 -> stack
  ac:   c7 44 24 04 01 00 00 00 movl   $0x1,0x4(%esp)         ; arg 1 -> stack
  b4:   c7 04 24 00 00 00 00    movl   $0x0,(%esp)            ; arg 0 -> stack
  bb:   e8 fc ff ff ff          call   bc <main+0x49>         ; push return address and call nonleaf_call (objdump not from final link but .o)
  c0:   b8 00 00 00 00          mov    $0x0,%eax              ; return value
  c5:   c9                      leave                         ; |
  c6:   c3                      ret                           ; | epilog



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

_leaf_call:
   0:   55                      pushl  %ebp
   1:   89 e5                   movl   %esp, %ebp
   3:   83 ec 08                subl   $8, %esp
   6:   c9                      leave
   7:   c3                      retl

_nonleaf_call:
   8:   55                      pushl  %ebp                 ; |
   9:   89 e5                   movl   %esp, %ebp           ; | prolog
   b:   83 ec 28                subl   $40, %esp            ; |
   e:   81 ec e0 00 00 00       subl   $224, %esp           ; alloca(220) - with 4b padding
  14:   8d 44 24 20             leal   32(%esp), %eax       ; |
  18:   c6 00 4c                movb   $76, (%eax)          ; / 'L' -> alloca()'d space
  1b:   8b 45 24                movl   36(%ebp), %eax       ; \
  1e:   89 44 24 18             movl   %eax, 24(%esp)       ; |
  22:   8b 45 20                movl   32(%ebp), %eax       ; |
  25:   89 44 24 14             movl   %eax, 20(%esp)       ; |
  29:   8b 45 1c                movl   28(%ebp), %eax       ; |
  2c:   89 44 24 10             movl   %eax, 16(%esp)       ; |
  30:   8b 45 18                movl   24(%ebp), %eax       ; | read in args 1-7 from prev frame's param area, and ...
  33:   89 44 24 0c             movl   %eax, 12(%esp)       ; | ... "push" onto stack as arg 0-6
  37:   8b 45 14                movl   20(%ebp), %eax       ; |
  3a:   89 44 24 08             movl   %eax, 8(%esp)        ; |
  3e:   8b 45 10                movl   16(%ebp), %eax       ; |
  41:   89 44 24 04             movl   %eax, 4(%esp)        ; |
  45:   8b 45 0c                movl   12(%ebp), %eax       ; |
  48:   89 04 24                movl   %eax, (%esp)         ; |
  4b:   e8 b0 ff ff ff          calll  -80 <_leaf_call>     ; push return address and call
  50:   c9                      leave                       ; |
  51:   c3                      retl                        ; | epilog
  52:   90                      nop                         ;
  53:   90                      nop                         ;

_main:
  54:   55                      pushl  %ebp                 ; |
  55:   89 e5                   movl   %esp, %ebp           ; | prolog
  57:   83 ec 28                subl   $40, %esp            ; |
  5a:   c7 44 24 1c 07 00 00 00 movl   $7, 28(%esp)         ; arg 7 -> stack
  62:   c7 44 24 18 06 00 00 00 movl   $6, 24(%esp)         ; arg 6 -> stack
  6a:   c7 44 24 14 05 00 00 00 movl   $5, 20(%esp)         ; arg 5 -> stack
  72:   c7 44 24 10 04 00 00 00 movl   $4, 16(%esp)         ; arg 4 -> stack
  7a:   c7 44 24 0c 03 00 00 00 movl   $3, 12(%esp)         ; arg 3 -> stack
  82:   c7 44 24 08 02 00 00 00 movl   $2, 8(%esp)          ; arg 2 -> stack
  8a:   c7 44 24 04 01 00 00 00 movl   $1, 4(%esp)          ; arg 1 -> stack
  92:   c7 04 24 00 00 00 00    movl   $0, (%esp)           ; arg 0 -> stack
  99:   e8 6a ff ff ff          calll  -150 <_nonleaf_call> ; push return address and call
  9e:   b8 00 00 00 00          movl   $0, %eax             ; return value
  a3:   c9                      leave                       ; |
  a4:   c3                      retl                        ; | epilog



; output from freebsd-9.3-x86 w/ gcc 4.2.1

00000000 <leaf_call>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   5d                      pop    %ebp
   4:   c3                      ret
   5:   8d 74 26 00             lea    0x0(%esi),%esi
   9:   8d bc 27 00 00 00 00    lea    0x0(%edi),%edi

00000010 <nonleaf_call>:
  10:   55                      push   %ebp                   ; |
  11:   89 e5                   mov    %esp,%ebp              ; | prolog
  13:   83 ec 28                sub    $0x28,%esp             ; |
  16:   81 ec f0 00 00 00       sub    $0xf0,%esp             ; alloca(220) - with padding for 16b alignment
  1c:   8d 44 24 1c             lea    0x1c(%esp),%eax        ; |
  20:   89 45 fc                mov    %eax,-0x4(%ebp)        ; |
  23:   8b 45 fc                mov    -0x4(%ebp),%eax        ; |
  26:   83 c0 0f                add    $0xf,%eax              ; | start of alloca()'d memory -> eax, by ...
  29:   c1 e8 04                shr    $0x4,%eax              ; | ... using ebx and 2 pointless store/reads in local space as helper to align to 16b
  2c:   c1 e0 04                shl    $0x4,%eax              ; |
  2f:   89 45 fc                mov    %eax,-0x4(%ebp)        ; |
  32:   8b 45 fc                mov    -0x4(%ebp),%eax        ; |

dyncall/doc/disas_examples/x86.cdecl.disas  view on Meta::CPAN

  4d:   8b 45 18                mov    0x18(%ebp),%eax        ; | read in args 1-7 from prev frame's param area, and ...
  50:   89 44 24 0c             mov    %eax,0xc(%esp)         ; | ... "push" onto stack as arg 0-6
  54:   8b 45 14                mov    0x14(%ebp),%eax        ; |
  57:   89 44 24 08             mov    %eax,0x8(%esp)         ; |
  5b:   8b 45 10                mov    0x10(%ebp),%eax        ; |
  5e:   89 44 24 04             mov    %eax,0x4(%esp)         ; |
  62:   8b 45 0c                mov    0xc(%ebp),%eax         ; |
  65:   89 04 24                mov    %eax,(%esp)            ; |
  68:   e8 fc ff ff ff          call   69 <nonleaf_call+0x59> ; push return address and call leaf_call (objdump not from final link but .o)
  6d:   c9                      leave                         ; |
  6e:   c3                      ret                           ; | epilog
  6f:   90                      nop                           ;

00000070 <main>:
  70:   8d 4c 24 04             lea    0x4(%esp),%ecx         ; |
  74:   83 e4 f0                and    $0xfffffff0,%esp       ; |
  77:   ff 71 fc                pushl  -0x4(%ecx)             ; |
  7a:   55                      push   %ebp                   ; | prolog
  7b:   89 e5                   mov    %esp,%ebp              ; |
  7d:   51                      push   %ecx                   ; |
  7e:   83 ec 24                sub    $0x24,%esp             ; |
  81:   c7 44 24 1c 07 00 00 00 movl   $0x7,0x1c(%esp)        ; arg 7 -> stack
  89:   c7 44 24 18 06 00 00 00 movl   $0x6,0x18(%esp)        ; arg 6 -> stack
  91:   c7 44 24 14 05 00 00 00 movl   $0x5,0x14(%esp)        ; arg 5 -> stack
  99:   c7 44 24 10 04 00 00 00 movl   $0x4,0x10(%esp)        ; arg 4 -> stack
  a1:   c7 44 24 0c 03 00 00 00 movl   $0x3,0xc(%esp)         ; arg 3 -> stack
  a9:   c7 44 24 08 02 00 00 00 movl   $0x2,0x8(%esp)         ; arg 2 -> stack
  b1:   c7 44 24 04 01 00 00 00 movl   $0x1,0x4(%esp)         ; arg 1 -> stack
  b9:   c7 04 24 00 00 00 00    movl   $0x0,(%esp)            ; arg 0 -> stack
  c0:   e8 fc ff ff ff          call   c1 <main+0x51>         ; push return address and call leaf_call (objdump not from final link but .o)
  c5:   b8 00 00 00 00          mov    $0x0,%eax              ; return value
  ca:   83 c4 24                add    $0x24,%esp             ; |
  cd:   59                      pop    %ecx                   ; |
  ce:   5d                      pop    %ebp                   ; | epilog
  cf:   8d 61 fc                lea    -0x4(%ecx),%esp        ; |
  d2:   c3                      ret                           ; |



; output from gentoo_linux-20191029-x86 w/ gcc 8.3.0

00000000 <leaf_call>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp

dyncall/doc/disas_examples/x86.cdecl.disas  view on Meta::CPAN

  80:   74 05                   je     87 <nonleaf_call+0x77>
  82:   e8 fc ff ff ff          call   83 <nonleaf_call+0x73>
  87:   c9                      leave
  88:   c3                      ret

00000089 <main>:
  89:   8d 4c 24 04             lea    0x4(%esp),%ecx    ; |
  8d:   83 e4 f0                and    $0xfffffff0,%esp  ; |
  90:   ff 71 fc                pushl  -0x4(%ecx)        ; |
  93:   55                      push   %ebp              ; |
  94:   89 e5                   mov    %esp,%ebp         ; | prolog (with some stack protection check call, I think)
  96:   51                      push   %ecx              ; |
  97:   83 ec 04                sub    $0x4,%esp         ; |
  9a:   e8 fc ff ff ff          call   9b <main+0x12>    ; |       unsure@@@ call of stackguard stuff, maybe?. (objdump not from final link but .o)
  9f:   05 01 00 00 00          add    $0x1,%eax         ; |       ??? add 1 to ret val from unknown call
  a4:   6a 07                   push   $0x7              ; arg 7 -> stack
  a6:   6a 06                   push   $0x6              ; arg 6 -> stack
  a8:   6a 05                   push   $0x5              ; arg 5 -> stack
  aa:   6a 04                   push   $0x4              ; arg 4 -> stack
  ac:   6a 03                   push   $0x3              ; arg 3 -> stack
  ae:   6a 02                   push   $0x2              ; arg 2 -> stack
  b0:   6a 01                   push   $0x1              ; arg 1 -> stack
  b2:   6a 00                   push   $0x0              ; arg 0 -> stack
  b4:   e8 fc ff ff ff          call   b5 <main+0x2c>    ; push return address and call nonleaf_call (objdump not from final link but .o)
  b9:   83 c4 20                add    $0x20,%esp        ; ???
  bc:   b8 00 00 00 00          mov    $0x0,%eax         ; return value
  c1:   8b 4d fc                mov    -0x4(%ebp),%ecx   ; |           ???
  c4:   c9                      leave                    ; |
  c5:   8d 61 fc                lea    -0x4(%ecx),%esp   ; | epilog    ???
  c8:   c3                      ret                      ; |



; output from haiku w/ gcc 4.4.4

00000000 <leaf_call>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   5d                      pop    %ebp

dyncall/doc/disas_examples/x86.cdecl.disas  view on Meta::CPAN

; 	return 0;
; }



; output from godbolt compiler explorer w/ msvc 19.0

$T1 = 8
_a$ = 12
_leaf_call PROC
        push    ebp                        ; | prolog
        mov     ebp, esp                   ; /
        mov     eax, DWORD PTR _a$[ebp]    ; \
        add     eax, 1                     ; |  get struct's x (from stack args), add 1 and write back
        mov     DWORD PTR _a$[ebp], eax    ; /
        mov     ecx, DWORD PTR $T1[ebp]    ; get ptr to retval struct passed as hidden arg (+8 to skip retval and saved ebp)
        mov     edx, DWORD PTR _a$[ebp]    ; |
        mov     DWORD PTR [ecx], edx       ; |
        mov     eax, DWORD PTR _a$[ebp+4]  ; |
        mov     DWORD PTR [ecx+4], eax     ; | copy modified (b/c of x+=1) struct arg to space of retval
        mov     edx, DWORD PTR _a$[ebp+8]  ; |
        mov     DWORD PTR [ecx+8], edx     ; |
        mov     eax, DWORD PTR _a$[ebp+12] ; |
        mov     DWORD PTR [ecx+12], eax    ; |
        mov     eax, DWORD PTR $T1[ebp]    ; return value (= ptr to struct that was passed-in as hidden arg)
        pop     ebp                        ; |
        ret     0                          ; | epilog
_leaf_call ENDP

$T1 = -32
_a$ = -16
_main   PROC
        push    ebp                        ; |
        mov     ebp, esp                   ; | prolog
        sub     esp, 32                    ; /         32 = 16b local area for struct + 16b space used for retval struct
        mov     DWORD PTR _a$[ebp], 9      ; \                               int x
        mov     eax, 99                    ; |                               |
        mov     WORD PTR _a$[ebp+4], ax    ; | struct values (local area)    | short y
        mov     BYTE PTR _a$[ebp+6], 23    ; |                               char z
        mov     DWORD PTR _a$[ebp+8], 12   ; |                               |
        mov     DWORD PTR _a$[ebp+12], 0   ; /                               | long long t
        push    0                          ; \
        push    7                          ; | arg 7
        push    6                          ; arg 6

dyncall/doc/disas_examples/x86.cdecl.disas  view on Meta::CPAN

        mov     edx, DWORD PTR _a$[ebp+8]  ; |
        mov     DWORD PTR [ecx+8], edx     ; |
        mov     eax, DWORD PTR _a$[ebp+12] ; |
        mov     DWORD PTR [ecx+12], eax    ; /
        lea     ecx, DWORD PTR $T1[ebp]    ; \ ptr to space used for struct retval (pushed as hidden first arg)
        push    ecx                        ; |
        call    _leaf_call                 ; push return address and call
        add     esp, 56                    ; |
        xor     eax, eax                   ; : return value
        mov     esp, ebp                   ; |
        pop     ebp                        ; | epilog
        ret     0                          ; |
_main   ENDP



; ---------- 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) { } };
;

dyncall/doc/disas_examples/x86.fastcall_borland.disas  view on Meta::CPAN

;
; ...
; TTest t = DoTest();



; from http://codeverge.com/embarcadero.cppbuilder.cpp/does-fastcall-have-any-bearing-on/1043767

DoTest():
  push ebp                     ; |
  mov ebp,esp                  ; | prolog
  add esp,-0x0c                ; |
  mov [ebp-0x04],eax           ; pointer to hidden param in eax -> local area
  mov [ebp-0x0c],0x00000001    ; val 1 -> local area
  mov [ebp-0x08],0x00000002    ; val 2 -> local area
  mov eax,[ebp-0x04]           ; refetch eax (pointlessly)
  mov edx,[ebp-0x0c]           ; get val 1 in edx and ...
  mov [eax],edx                ; ... store at *eax
  mov edx,[ebp-0x08]           ; get val 2 in edx and ...
  mov [eax+0x04],edx           ; ... store at *(eax + 4)
  mov eax, [ebp-0x04]          ; return value
  mov esp,ebp                  ; |
  pop ebp                      ; | epilog
  ret                          ; |



; vim: ft=asm

dyncall/doc/disas_examples/x86.fastcall_gnu.disas  view on Meta::CPAN

; 	nonleaf_call(0, 1, 2, 3, 4, 5, 6, 7);
; 	return 0;
; }



; output from alpine_linux-3.11.3-x86 w/ gcc 9.2.0 (w/ flags to simplify: -fno-stack-protector -fno-pic)

00001205 <leaf_call>:
    1205:       55                      push   %ebp                ; |
    1206:       89 e5                   mov    %esp,%ebp           ; | prolog
    1208:       83 ec 08                sub    $0x8,%esp           ; |
    120b:       89 4d fc                mov    %ecx,-0x4(%ebp)     ;
    120e:       89 55 f8                mov    %edx,-0x8(%ebp)     ;
    1211:       90                      nop                        ;
    1212:       c9                      leave                      ; |
    1213:       c2 14 00                ret    $0x14               ; | epilog

00001216 <nonleaf_call>:
    1216:       55                      push   %ebp                ; |
    1217:       89 e5                   mov    %esp,%ebp           ; | prolog
    1219:       83 ec 18                sub    $0x18,%esp          ; /
    121c:       89 4d f4                mov    %ecx,-0xc(%ebp)     ; in arg 0 -> local area on stack
    121f:       89 55 f0                mov    %edx,-0x10(%ebp)    ; in arg 1 -> local area on stack
    1222:       b8 10 00 00 00          mov    $0x10,%eax          ; |
    1227:       83 e8 01                sub    $0x1,%eax           ; |
    122a:       05 e8 00 00 00          add    $0xe8,%eax          ; |
    122f:       b9 10 00 00 00          mov    $0x10,%ecx          ; | alloca (seems like 220 is rounded up for stack alignment purposes)
    1234:       ba 00 00 00 00          mov    $0x0,%edx           ; |
    1239:       f7 f1                   div    %ecx                ; |
    123b:       6b c0 10                imul   $0x10,%eax,%eax     ; |

dyncall/doc/disas_examples/x86.fastcall_gnu.disas  view on Meta::CPAN

    1257:       ff 75 18                pushl  0x18(%ebp)          ; |
    125a:       ff 75 14                pushl  0x14(%ebp)          ; | read in args 3-7 from prev frame's param area, and ...
    125d:       ff 75 10                pushl  0x10(%ebp)          ; | ... push onto stack as arg 2-6
    1260:       ff 75 0c                pushl  0xc(%ebp)           ; |
    1263:       8b 55 08                mov    0x8(%ebp),%edx      ; arg 1 (via reg, read in arg 2 from prev frame's param area)
    1266:       89 c1                   mov    %eax,%ecx           ; arg 0 (via reg)
    1268:       e8 98 ff ff ff          call   1205 <leaf_call>    ; push return address and call
    126d:       83 c4 0c                add    $0xc,%esp           ; @@@ restore esp to what it was before pushing args
    1270:       90                      nop                        ;
    1271:       c9                      leave                      ; |
    1272:       c2 18 00                ret    $0x18               ; | epilog

00001275 <main>:
    1275:       8d 4c 24 04             lea    0x4(%esp),%ecx      ; |
    1279:       83 e4 f0                and    $0xfffffff0,%esp    ; |        @@@? alignment?
    127c:       ff 71 fc                pushl  -0x4(%ecx)          ; | prolog
    127f:       55                      push   %ebp                ; |
    1280:       89 e5                   mov    %esp,%ebp           ; |
    1282:       51                      push   %ecx                ; preserve ecx (so it can be used for passing arg 0)
    1283:       83 ec 04                sub    $0x4,%esp           ; @@@ unsure why, alignment?
    1286:       83 ec 08                sub    $0x8,%esp           ; @@@ unsure why, alignment? pointless
    1289:       6a 07                   push   $0x7                ; arg 7
    128b:       6a 06                   push   $0x6                ; arg 6
    128d:       6a 05                   push   $0x5                ; arg 5
    128f:       6a 04                   push   $0x4                ; arg 4
    1291:       6a 03                   push   $0x3                ; arg 3
    1293:       6a 02                   push   $0x2                ; arg 2
    1295:       ba 01 00 00 00          mov    $0x1,%edx           ; arg 1 (via reg)
    129a:       b9 00 00 00 00          mov    $0x0,%ecx           ; arg 0 (via reg)
    129f:       e8 72 ff ff ff          call   1216 <nonleaf_call> ; push return address and call
    12a4:       83 c4 08                add    $0x8,%esp           ; @@@ restore one of the two "sub...esp"s above
    12a7:       b8 00 00 00 00          mov    $0x0,%eax           ; return value
    12ac:       8b 4d fc                mov    -0x4(%ebp),%ecx     ; restore ecx
    12af:       c9                      leave                      ; |
    12b0:       8d 61 fc                lea    -0x4(%ecx),%esp     ; | epilog
    12b3:       c3                      ret                        ; |



; ---------- vararg call (shows that all args are pushed) ---------->

; void __attribute__((fastcall)) leaf_call(int a, short b, char c, ...)
; {
; }
;

dyncall/doc/disas_examples/x86.fastcall_gnu.disas  view on Meta::CPAN

;   leaf_call(a, 1, 2, 3, 4, 5, 6, 7LL);
;   return 0;
; }



; output from alpine_linux-3.11.3-x86 w/ gcc 9.2.0 (w/ flags to simplify: -fno-stack-protector -fno-pic)

00001205 <leaf_call>:
    1205:       55                      push   %ebp              ; |
    1206:       89 e5                   mov    %esp,%ebp         ; | prolog
    1208:       83 ec 20                sub    $0x20,%esp        ; |
    120b:       89 4d fc                mov    %ecx,-0x4(%ebp)   ; ptr to retval space for struct (hidden first arg) -> local area
    120e:       8b 45 18                mov    0x18(%ebp),%eax   ;
    1211:       8b 55 24                mov    0x24(%ebp),%edx   ;
    1214:       66 89 45 f8             mov    %ax,-0x8(%ebp)    ;
    1218:       8b 45 1c                mov    0x1c(%ebp),%eax   ;
    121b:       89 45 f0                mov    %eax,-0x10(%ebp)  ;
    121e:       8b 45 20                mov    0x20(%ebp),%eax   ;
    1221:       89 45 f4                mov    %eax,-0xc(%ebp)   ;
    1224:       89 d0                   mov    %edx,%eax         ;

dyncall/doc/disas_examples/x86.fastcall_gnu.disas  view on Meta::CPAN

    1241:       8b 55 08                mov    0x8(%ebp),%edx    ; |
    1244:       89 10                   mov    %edx,(%eax)       ; |
    1246:       8b 55 0c                mov    0xc(%ebp),%edx    ; |
    1249:       89 50 04                mov    %edx,0x4(%eax)    ; | copy struct from param area in prev frame to retval space
    124c:       8b 55 10                mov    0x10(%ebp),%edx   ; |
    124f:       89 50 08                mov    %edx,0x8(%eax)    ; |
    1252:       8b 55 14                mov    0x14(%ebp),%edx   ; |
    1255:       89 50 0c                mov    %edx,0xc(%eax)    ; |
    1258:       8b 45 fc                mov    -0x4(%ebp),%eax   ; return value (passed-in hidden ptr)
    125b:       c9                      leave                    ; |
    125c:       c2 34 00                ret    $0x34             ; | epilog

0000125f <main>:
    125f:       8d 4c 24 04             lea    0x4(%esp),%ecx    ; |
    1263:       83 e4 f0                and    $0xfffffff0,%esp  ; |
    1266:       ff 71 fc                pushl  -0x4(%ecx)        ; | prolog
    1269:       55                      push   %ebp              ; |
    126a:       89 e5                   mov    %esp,%ebp         ; |
    126c:       51                      push   %ecx              ; preserve ecx (so it can be used for passing arg 0)
    126d:       83 ec 24                sub    $0x24,%esp        ; reserve stack space for struct (local area)
    1270:       c7 45 e8 09 00 00 00    movl   $0x9,-0x18(%ebp)  ; |                               int x
    1277:       66 c7 45 ec 63 00       movw   $0x63,-0x14(%ebp) ; |                               short y
    127d:       c6 45 ee 17             movb   $0x17,-0x12(%ebp) ; | struct values (local area)    char z
    1281:       c7 45 f0 0c 00 00 00    movl   $0xc,-0x10(%ebp)  ; |                               |
    1288:       c7 45 f4 00 00 00 00    movl   $0x0,-0xc(%ebp)   ; |                               | long long t
    128f:       8d 45 d8                lea    -0x28(%ebp),%eax  ; ptr to space used for struct retval (passed as hidden first arg) -> eax

dyncall/doc/disas_examples/x86.fastcall_gnu.disas  view on Meta::CPAN

    12a7:       ff 75 f4                pushl  -0xc(%ebp)        ; |
    12aa:       ff 75 f0                pushl  -0x10(%ebp)       ; | arg 0 (struct by value, pushed onto stack)
    12ad:       ff 75 ec                pushl  -0x14(%ebp)       ; |
    12b0:       ff 75 e8                pushl  -0x18(%ebp)       ; |
    12b3:       89 c1                   mov    %eax,%ecx         ; ptr to free space for call's retval (struct), hidden first arg
    12b5:       e8 4b ff ff ff          call   1205 <leaf_call>  ; push return address and call
    12ba:       83 c4 04                add    $0x4,%esp         ; @@@ restore esp to what it was before pushing args
    12bd:       b8 00 00 00 00          mov    $0x0,%eax         ; return value
    12c2:       8b 4d fc                mov    -0x4(%ebp),%ecx   ; restore ecx
    12c5:       c9                      leave                    ; |
    12c6:       8d 61 fc                lea    -0x4(%ecx),%esp   ; | epilog
    12c9:       c3                      ret                      ; |



; ---------- small struct returned by value (shows it's never returned via regs) ---------->

; struct A { short x; short y; };
;
; struct A __attribute__((fastcall)) leaf_call(int a, int b)
; {

dyncall/doc/disas_examples/x86.fastcall_gnu.disas  view on Meta::CPAN

; 	leaf_call(99, 2);
; 	return 0;
; }



; output from alpine_linux-3.11.3-x86 w/ gcc 9.2.0 (w/ flags to simplify: -fno-stack-protector -fno-pic)

00001205 <leaf_call>:
    1205:       55                      push   %ebp             ; |
    1206:       89 e5                   mov    %esp,%ebp        ; | prolog
    1208:       83 ec 18                sub    $0x18,%esp       ; |
    120b:       89 4d ec                mov    %ecx,-0x14(%ebp) ; ptr to retval space for struct (hidden first arg) -> local area
    120e:       89 55 e8                mov    %edx,-0x18(%ebp) ; in arg 0 -> local area
    1211:       66 c7 45 fc 0d 00       movw   $0xd,-0x4(%ebp)  ; |
    1217:       66 c7 45 fe 0f 00       movw   $0xf,-0x2(%ebp)  ; | struct values (local area)
    121d:       8b 45 ec                mov    -0x14(%ebp),%eax ; ptr to retval space for struct (fetched from local area) -> eax
    1220:       8b 55 fc                mov    -0x4(%ebp),%edx  ; |
    1223:       89 10                   mov    %edx,(%eax)      ; | copy struct in local area to retval space
    1225:       8b 45 ec                mov    -0x14(%ebp),%eax ; return value (passed-in hidden ptr)
    1228:       c9                      leave                   ; |
    1229:       c2 04 00                ret    $0x4             ; | epilog

0000122c <main>:
    122c:       55                      push   %ebp             ; |
    122d:       89 e5                   mov    %esp,%ebp        ; | prolog
    122f:       83 ec 04                sub    $0x4,%esp        ; |
    1232:       8d 45 fc                lea    -0x4(%ebp),%eax  ; ptr to space used for struct retval (passed as hidden first arg)
    1235:       6a 02                   push   $0x2             ; arg 1
    1237:       ba 63 00 00 00          mov    $0x63,%edx       ; arg 0 (via reg)
    123c:       89 c1                   mov    %eax,%ecx        ; ptr to free space for call's retval (struct), hidden first arg
    123e:       e8 c2 ff ff ff          call   1205 <leaf_call> ; push return address and call
    1243:       b8 00 00 00 00          mov    $0x0,%eax        ; return value
    1248:       c9                      leave                   ; |
    1249:       c3                      ret                     ; | epilog



; ---------- 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) { }

dyncall/doc/disas_examples/x86.fastcall_ms.disas  view on Meta::CPAN

_a$ = -8
_b$ = -4
_c$ = 8
_d$ = 12
_e$ = 16
_f$ = 20
_g$ = 24
_h$ = 28
@nonleaf_call@32 PROC
        push    ebp                      ; |
        mov     ebp, esp                 ; | prolog
        sub     esp, 8                   ; |
        mov     DWORD PTR _b$[ebp], edx  ; in arg 1 -> local area on stack
        mov     DWORD PTR _a$[ebp], ecx  ; in arg 0 -> local area on stack
        mov     ecx, 220                 ; |
        call    @alloca@4                ; | call alloca(220)   (ecx = arg)
        mov     BYTE PTR [eax], 76       ; 'L' -> alloca()'d space (pointed to by alloca's retval in eax)
        mov     eax, DWORD PTR _h$[ebp]  ; |
        push    eax                      ; |
        mov     ecx, DWORD PTR _g$[ebp]  ; |
        push    ecx                      ; |
        mov     edx, DWORD PTR _f$[ebp]  ; | read in args 3-7 from prev frame's param area, and ...
        push    edx                      ; | ... "push" onto stack as arg 2-6
        mov     eax, DWORD PTR _e$[ebp]  ; |
        push    eax                      ; |
        mov     ecx, DWORD PTR _d$[ebp]  ; |
        push    ecx                      ; |
        mov     edx, DWORD PTR _c$[ebp]  ; arg 1        | read from prev frame's param
        mov     ecx, DWORD PTR _b$[ebp]  ; arg 0        | area and put in regs
        call    @leaf_call@28            ; push return address and call
        mov     esp, ebp                 ; |
        pop     ebp                      ; | epilog
        ret     24                       ; |
@nonleaf_call@32 ENDP

_main   PROC
        push    ebp                      ; | prolog
        mov     ebp, esp                 ; |
        push    7                        ; arg 7
        push    6                        ; arg 6
        push    5                        ; arg 5
        push    4                        ; arg 4
        push    3                        ; arg 3
        push    2                        ; arg 2
        mov     edx, 1                   ; arg 1 (via reg)
        xor     ecx, ecx                 ; arg 0 (via reg)
        call    @nonleaf_call@32         ; push return address and call
        xor     eax, eax                 ; return value
        pop     ebp                      ; |
        ret     0                        ; | epilog
_main   ENDP



; ---------- structs by value (arg and return value), struct arg not fitting in regs ---------->
;
; struct A { int x; short y; char z; long long t; };
;
; struct A leaf_call(struct A a, short b, long long c, char d, int e, int f, int g, long long h)
; {

dyncall/doc/disas_examples/x86.fastcall_ms.disas  view on Meta::CPAN

_d$ = -4
$T1 = 8
_a$ = 12
_c$ = 28
_e$ = 36
_f$ = 40
_g$ = 44
_h$ = 48
@leaf_call@52 PROC
        push    ebp                        ; |
        mov     ebp, esp                   ; | prolog
        sub     esp, 8                     ; |
        mov     BYTE PTR _d$[ebp], dl      ; in arg 3 -> local area on stack
        mov     WORD PTR _b$[ebp], cx      ; in arg 1 -> local area on stack
        mov     eax, DWORD PTR _a$[ebp]    ; \
        add     eax, 1                     ; |  get struct's x (from stack args), add 1 and write back
        mov     DWORD PTR _a$[ebp], eax    ; /
        mov     ecx, DWORD PTR $T1[ebp]    ; get ptr to retval struct passed as hidden arg (+8 to skip retval and saved ebp)
        mov     edx, DWORD PTR _a$[ebp]    ; |
        mov     DWORD PTR [ecx], edx       ; |
        mov     eax, DWORD PTR _a$[ebp+4]  ; |
        mov     DWORD PTR [ecx+4], eax     ; | copy modified (b/c of x+=1) struct arg to space of retval
        mov     edx, DWORD PTR _a$[ebp+8]  ; |
        mov     DWORD PTR [ecx+8], edx     ; |
        mov     eax, DWORD PTR _a$[ebp+12] ; |
        mov     DWORD PTR [ecx+12], eax    ; |
        mov     eax, DWORD PTR $T1[ebp]    ; return value (= ptr to struct that was passed-in as hidden arg)
        mov     esp, ebp                   ; |
        pop     ebp                        ; | epilog
        ret     48                         ; |
@leaf_call@52 ENDP

$T1 = -32
_a$ = -16
_main   PROC
        push    ebp                        ; |
        mov     ebp, esp                   ; | prolog
        sub     esp, 32                    ; /         32 = 16b local area for struct + 16b space used for retval struct
        mov     DWORD PTR _a$[ebp], 9      ; \                               int x
        mov     eax, 99                    ; |                               |
        mov     WORD PTR _a$[ebp+4], ax    ; | struct values (local area)    | short y
        mov     BYTE PTR _a$[ebp+6], 23    ; |                               char z
        mov     DWORD PTR _a$[ebp+8], 12   ; |                               |
        mov     DWORD PTR _a$[ebp+12], 0   ; /                               | long long t
        push    0                          ; \
        push    7                          ; | arg 7
        push    6                          ; arg 6

dyncall/doc/disas_examples/x86.fastcall_ms.disas  view on Meta::CPAN

        mov     DWORD PTR [ecx+8], edx     ; |
        mov     eax, DWORD PTR _a$[ebp+12] ; |
        mov     DWORD PTR [ecx+12], eax    ; /
        lea     ecx, DWORD PTR $T1[ebp]    ; \ ptr to space used for struct retval (pushed as hidden first arg)
        push    ecx                        ; |
        mov     dl, 3                      ; arg 3 (via reg)
        mov     ecx, 1                     ; arg 1 (via reg)
        call    @leaf_call@52              ; push return address and call
        xor     eax, eax                   ; return value
        mov     esp, ebp                   ; |
        pop     ebp                        ; | epilog
        ret     0                          ; |
_main   ENDP



; ---------- C++ trivial and non-trivial aggrs passed to C funcs ---------->
;
; struct Trivial { int a; };
; struct NonTrivial {
;         int a;

dyncall/doc/disas_examples/x86.plan9call.disas  view on Meta::CPAN

; }



; output from plan9-4th_edition-x86 w/ 8c x.c && 8l -a x.8

001020                        (1) TEXT leaf_call+0(SB),$0
001020    c3                  (3)       RET                         ,

001021                        (5) TEXT nonleaf_call+0(SB),$28
001021    83ec1c              (5)       SUBL                        $28,SP             ; prolog (note, there is no register save area at all)
001024    8b442424            (7)       MOVL                        b+36(FP),AX        ; |
001028    890424              (7)       MOVL                        AX,(SP)            ; |
00102b    8b442428            (7)       MOVL                        c+40(FP),AX        ; |
00102f    89442404            (7)       MOVL                        AX,4(SP)           ; |
001033    8b44242c            (7)       MOVL                        d+44(FP),AX        ; |
001037    89442408            (7)       MOVL                        AX,8(SP)           ; | fetch in args from prev frame's param area ...
00103b    8b442430            (7)       MOVL                        e+48(FP),AX        ; | ... and "push" onto stack
00103f    8944240c            (7)       MOVL                        AX,12(SP)          ; |
001043    8b442434            (7)       MOVL                        f+52(FP),AX        ; |
001047    89442410            (7)       MOVL                        AX,16(SP)          ; |
00104b    8b442438            (7)       MOVL                        g+56(FP),AX        ; |
00104f    89442414            (7)       MOVL                        AX,20(SP)          ; |
001053    e8c8ffffff          (7)       CALL                        ,1020+leaf_call    ; push return address and call
001058    b878000000          (8)       MOVL                        $120,AX            ; return value: 'x' -> eax
00105d    83c41c              (8)       ADDL                        $28,SP             ; |
001060    c3                  (8)       RET                         ,                  ; | epilog

001061                        (11) TEXT main+0(SB),$32
001061    83ec20              (11)      SUBL                        $32,SP             ; prolog (note, there is no register save area at all)
001064    c7042400000000      (13)      MOVL                        $0,(SP)            ; arg 0 -> "push" onto stack
00106b    b801000000          (13)      MOVL                        $1,AX              ; arg 1 -> eax, then ...
001070    89442404            (13)      MOVL                        AX,4(SP)           ; ... "pushed" onto stack
001074    b802000000          (13)      MOVL                        $2,AX              ; arg 2 -> eax, then ...
001079    89442408            (13)      MOVL                        AX,8(SP)           ; ... "pushed" onto stack
00107d    b803000000          (13)      MOVL                        $3,AX              ;    .
001082    8944240c            (13)      MOVL                        AX,12(SP)          ;    .
001086    b804000000          (13)      MOVL                        $4,AX              ;    .
00108b    89442410            (13)      MOVL                        AX,16(SP)          ;    .
00108f    b805000000          (13)      MOVL                        $5,AX              ;    .
001094    89442414            (13)      MOVL                        AX,20(SP)          ;    .
001098    b806000000          (13)      MOVL                        $6,AX              ; arg 6 -> eax, then ...
00109d    89442418            (13)      MOVL                        AX,24(SP)          ; ... "pushed" onto stack
0010a1    e87bffffff          (13)      CALL                        ,1021+nonleaf_call ; push return address and call
0010a6    31c0                (14)      MOVL                        $0,AX              ; return value
0010a8    83c420              (14)      ADDL                        $32,SP             ; |
0010ab    c3                  (14)      RET                         ,                  ; | epilog



; ---------- 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)
; {
; }

dyncall/doc/disas_examples/x86.plan9call.disas  view on Meta::CPAN

; }



; output from plan9-4th_edition-x86 w/ 8c x.c && 8l -a x.8

001020                        (3)  TEXT    leaf_call+0(SB),$0
001020   c3                   (5)       RET                         ,

001021                        (7)  TEXT    nonleaf_call+0(SB),$148
001021   81ec94000000         (7)       SUBL                        $148,SP            ; prolog (note, there is no register save area at all)
001027   8d842494000000       (10)      LEAL                        l+148(SP),AX       ; |
00102e   89442430             (10)      MOVL                        AX,l+48(SP)        ; |                            loop's write ptr (stored at beginning of char[100] space)
001032   83442430fc           (10)      ADDL                        $-4,l+48(SP)       ; |                              decr loop ptr in memory
001037   8b442430             (10)      MOVL                        l+48(SP),AX        ; |                              ptr -> eax
00103b   c70000000000         (10)      MOVL                        $0,(AX)            ; | zero-init char[100] space    write a 0
001041   837c243000           (10)      CMPL                        l+48(SP),$0        ; |                              cmp if done
001046   75ea                 (10)      JNE                         ,1032              ; |                              loop
001048   c64424304c           (10)      MOVB                        $76,l+48(SP)       ; 'L' -> local area (beginning of char[100] space)
00104d   8b84249c000000       (11)      MOVL                        b+156(FP),AX       ; |
001054   890424               (11)      MOVL                        AX,(SP)            ; |

dyncall/doc/disas_examples/x86.plan9call.disas  view on Meta::CPAN

001083   b904000000           (11)      MOVL                        $4,CX              ; |                                    rep counter (4, for dwords = 16b = sizeof(struct A))
001088   fc                   (11)      CLD                         ,                  ; | copy struct to next call's stack
001089   f3                   (11)      REP                         ,                  ; |
00108a   a5                   (11)      MOVSL                       ,                  ; /
00108b   8b8424bc000000       (11)      MOVL                        g+188(FP),AX       ; \
001092   89442420             (11)      MOVL                        AX,32(SP)          ; | fetch remaining in args (ints after struct) from prev frame's param area ...
001096   8b8424c0000000       (11)      MOVL                        h+192(FP),AX       ; | ... and "push" onto stack
00109d   89442424             (11)      MOVL                        AX,36(SP)          ; |
0010a1   e87affffff           (11)      CALL                        ,1020+leaf_call    ; push return address and call
0010a6   81c494000000         (11)      ADDL                        $148,SP            ; |
0010ac   c3                   (11)      RET                         ,                  ; | epilog

0010ad                        (14) TEXT    main+0(SB),$52
0010ad   83ec34               (14)      SUBL                        $52,SP             ; prolog (note, there is no register save area at all)
0010b0   c7042400000000       (16)      MOVL                        $0,(SP)            ; arg 0 -> "push" onto stack
0010b7   b801000000           (16)      MOVL                        $1,AX              ; arg 1 -> eax, then ...
0010bc   89442404             (16)      MOVL                        AX,4(SP)           ; ... "pushed" onto stack
0010c0   b802000000           (16)      MOVL                        $2,AX              ; arg 2 -> eax, then ...
0010c5   89442408             (16)      MOVL                        AX,8(SP)           ; ... "pushed" onto stack
0010c9   b803000000           (16)      MOVL                        $3,AX              ;    .
0010ce   8944240c             (16)      MOVL                        AX,12(SP)          ;    .
0010d2   b804000000           (16)      MOVL                        $4,AX              ;    .
0010d7   89442410             (16)      MOVL                        AX,16(SP)          ;    .
0010db   8d442414             (16)      LEAL                        20(SP),AX          ; get ptr to next (unused) stack bytes -> eax ...

dyncall/doc/disas_examples/x86.plan9call.disas  view on Meta::CPAN

0010f8   8b442430             (16)      MOVL                        .safe+48(SP),AX    ; |
0010fc   c7400807000000       (16)      MOVL                        $7,8(AX)           ; |
001103   c7400c00000000       (16)      MOVL                        $0,12(AX)          ; |                    msbytes of long long
00110a   b808000000           (16)      MOVL                        $8,AX              ; arg 6 -> eax, then ...
00110f   89442424             (16)      MOVL                        AX,36(SP)          ; ... "pushed" onto stack
001113   b809000000           (16)      MOVL                        $9,AX              ; arg 7 -> eax, then ...
001118   89442428             (16)      MOVL                        AX,40(SP)          ; ... "pushed" onto stack
00111c   e800ffffff           (16)      CALL                        ,1021+nonleaf_call ; push return address and call
001121   31c0                 (17)      MOVL                        $0,AX              ; return value
001123   83c434               (17)      ADDL                        $52,SP             ; |
001126   c3                   (17)      RET                         ,                  ; | epilog



; ---------- 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)
; {

dyncall/doc/disas_examples/x86.plan9call.disas  view on Meta::CPAN


; output from plan9-4th_edition-x86 w/ 8c x.c && 8l -a x.8

001020                  (2)     TEXT f1+0(SB),$0
001020 8b442404         (4)     MOVL                 .ret+4(FP),AX   ; ptr to retval space -> eax
001024 c700031c0000     (4)     MOVL                 $7171,(AX)      ; |
00102a c7400400000000   (4)     MOVL                 $0,4(AX)        ; | return value
001031 c3               (4)     RET                  ,

001032                  (7)     TEXT main+0(SB),$16
001032 83ec10           (7)     SUBL                 $16,SP          ; prolog
001035 8d4c2408         (9)     LEAL                 .safe+8(SP),CX  ; | ptr to space for return value ...
001039 890c24           (9)     MOVL                 CX,(SP)         ; | ... pushed as implicit first arg
00103c e8dfffffff       (9)     CALL                 ,1020+f1        ; push return address and call
001041 8b442408         (9)     MOVL                 .safe+8(SP),AX  ; return value
001045 8b54240c         (9)     MOVL                 .safe+12(SP),DX ; @@@ unsure, b/c we have a cast
001049 83c410           (9)     ADDL                 $16,SP          ; |
00104c c3               (9)     RET                  ,               ; | epilog



; ---------- returning structs by value ---------->
;
; struct Small { char x; };
; struct Big { long long i; long j; };
;
; struct Small f0()
; {

dyncall/doc/disas_examples/x86.plan9call.disas  view on Meta::CPAN

;     struct Small s = f0();
;     struct Big b = f1();
;     return b.j + s.x;
; }



; output from plan9-4th_edition-x86 w/ 8c x.c && 8l -a x.8

001020                  (5)     TEXT f0+0 (SB),$16
001020 83ec08           (5)     SUBL                $8,SP          ; prolog
001023 c644240484       (7)     MOVB                $-124,s+4(SP)  ; struct data in  local area (s.x)
001028 8b7c240c         (8)     MOVL                .ret+12(FP),DI ; \
00102c 8d742404         (8)     LEAL                s+4(SP),SI     ; |
001030 b901000000       (8)     MOVL                $1,CX          ; | copy struct in local area to return
001035 fc               (8)     CLD                 ,              ; | value (pointed to by implicit first arg)
001036 f3               (8)     REP                 ,              ; |
001037 a5               (8)     MOVSL               ,              ; /
001038 83c408           (8)     ADDL                $8,SP          ; \
00103b c3               (8)     RET                 ,              ; | epilog

00103c                  (11)    TEXT f1+0(SB),$16
00103c 83ec10           (11)    SUBL                $16,SP         ; prolog
00103f c7442404031c0000 (13)    MOVL                $7171,b+4(SP)  ; |                               |
001047 c744240800000000 (13)    MOVL                $0,b+8(SP)     ; | struct data in local area     | b.i
00104f c744240ce8000000 (13)    MOVL                $232,b+12(SP)  ; /                               b.j
001057 8b7c2414         (14)    MOVL                .ret+20(FP),DI ; \
00105b 8d742404         (14)    LEAL                b+4(SP),SI     ; |
00105f b903000000       (14)    MOVL                $3,CX          ; | copy struct in local area to return
001064 fc               (14)    CLD                 ,              ; | value (pointed to by implicit first arg)
001065 f3               (14)    REP                 ,              ; |
001066 a5               (14)    MOVSL               ,              ; /
001067 83c410           (14)    ADDL                $16,SP         ; \
00106a c3               (14)    RET                 ,              ; | epilog

00106b                  (17)    TEXT main+0(SB),$28
00106b 83ec1c           (17)    SUBL                $28,SP         ; prolog
00106e 8d442418         (19)    LEAL                s+24(SP),AX    ; | ptr to space for return value ...
001072 890424           (19)    MOVL                AX,(SP)        ; | ... pushed as implicit first arg
001075 e8a6ffffff       (19)    CALL                ,1020+f0       ; push return address and call
00107a 8d44240c         (20)    LEAL                b+12(SP),AX    ; | ptr to space for return value ...
00107e 890424           (20)    MOVL                AX,(SP)        ; | ... pushed as implicit first arg
001081 e8b6ffffff       (20)    CALL                ,103c+f1       ; push return address and call
001086 0fbe442418       (21)    MOVBLSX             s+24(SP),AX    ; |
00108b 03442414         (21)    ADDL                b+20(SP),AX    ; / return value
00108f 83c41c           (21)    ADDL                $28,SP         ; \
001092 c3               (21)    RET                 ,              ; | epilog



; vim: ft=asm



( run in 1.130 second using v1.01-cache-2.11-cpan-49f99fa48dc )