Mercurial > pub > dyncall > dyncall
diff dyncall/dyncall_call_sparc_v9.S @ 0:3e629dc19168
initial from svn dyncall-1745
author | Daniel Adler |
---|---|
date | Thu, 19 Mar 2015 22:24:28 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dyncall/dyncall_call_sparc_v9.S Thu Mar 19 22:24:28 2015 +0100 @@ -0,0 +1,222 @@ +/* + + Package: dyncall + Library: dyncall + File: dyncall/dyncall_call_sparc_v9.S + Description: Call kernel for sparc64 v9 ABI. + License: + + Copyright (c) 2011-2015 Daniel Adler <dadler@uni-goettingen.de> + + Permission to use, copy, modify, and distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + 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. + +*/ + + +#define BIAS 2047 +.global dcCall_v9 + /* dcCall_sparc64( DCCallVM* , void * target ) */ + /* o0 o1 */ +dcCall_v9: + or %o0, %g0, %o3 /* o3: callvm */ + or %o1, %g0, %o0 /* o0: target */ + ldx [%o3+24], %o1 /* o1: mVecSize */ + add %o3, 32, %o2 /* o2: stack */ + /* Compute a matching stack size (approximate): o3 = align(o1+136,16) */ + + add %o1, (16+1+6)*8+15, %o3 + and %o3, -16, %o3 + neg %o3 /* o3: -stacksize */ + save %sp, %o3, %sp + + ldd [%i2+8*0 ],%f0 /* Load double-precision float registers. */ + ldd [%i2+8*1 ],%f2 + ldd [%i2+8*2 ],%f4 + ldd [%i2+8*3 ],%f6 + ldd [%i2+8*4 ],%f8 + ldd [%i2+8*5 ],%f10 + ldd [%i2+8*6 ],%f12 + ldd [%i2+8*7 ],%f14 + ldd [%i2+8*8 ],%f16 + ldd [%i2+8*9 ],%f18 + ldd [%i2+8*10],%f20 + ldd [%i2+8*11],%f22 + ldd [%i2+8*12],%f24 + ldd [%i2+8*13],%f26 + ldd [%i2+8*14],%f28 + ldd [%i2+8*15],%f30 + ldx [%i2+8*0],%o0 /* Load output registers. */ + ldx [%i2+8*1],%o1 + ldx [%i2+8*2],%o2 + ldx [%i2+8*3],%o3 + ldx [%i2+8*4],%o4 + ldx [%i2+8*5],%o5 + sub %i1, 48, %i1 + cmp %i1, 0 + ble .do_call + nop + /* Copy loop: */ + add %i2, 48, %i2 /* skip homing area */ + or %g0, %g0, %l0 /* l0 = offset initialized to 0. */ + add %sp, BIAS+((16+6)*8), %l2 /* l2 = argument area on stack space (7th word). (64+4+6*4 = byte offset 92). */ +.next: + ldx [%i2+%l0],%l1 /* Read from arg buffer(%i2) to %l1. */ + stx %l1, [%l2+%l0] /* Write %l1 to stack space(%l2). */ + add %l0, 8, %l0 /* Increment offset. */ + sub %i1, 8, %i1 /* Decrement copy size. */ + cmp %i1, 0 + bgt .next + nop +.do_call: + call %i0 /* Call target. */ + nop + or %o0, %g0, %i0 + jmpl %i7 + 8, %g0 + restore + +/* + or %o0, %g0, %i0 + or %o1, %g0, %i1 + or %o2, %g0, %i2 + or %o3, %g0, %i3 + return %i7 + 8 + nop + +Changes from v8: +- fundamental data types + - (un)signed int: 8,16,32,64 + - float: 32,64,128 +- float: IEEE 754 compilant + 32 32-bit float registers f0,f1,..,f31 + 32 64-bit float registers f0,f2,..,f62 + 16 128-bit float registers f0,f4,..,f60 + +Description: +We need to raise up a dynamic stack frame. +Therefore we need to compute the stack size. We do this first, +in the context of the caller as a leaf function (using o3 as scratch for addition). +Then we raise the frame, ending up in o0-o3 is then i0-i3. + + +Stack Layout: + BIAS = 2047 + + BIAS+XX: should be 16 byte aligned. + ... + 136: argument overflow area + 128: 1 extended word for struct/union poiner return value + BIAS+ 0: 16 extended words for registers (in/local) save area [register window] + + +Function Argument Passing: +- integer %o0..%o5 (caller view). +- floating-point %f0 .. %f15 +- continuous memory starting at %sp+BIAS+136 (caller view). + +Register Usage: +%fp0..%fp31 : floating-point arguments. +%sp or %o6 : stack pointer, always 8 (or 16?)-byte aligned. +%fp or %i6 : frame pointer. +%i0 and %o0 : integer and pointer return values. +%i7 and %o7 : return address. (caller puts return address to %o7, callee uses %i7) +%fp0 and %fp1: return value (float). +%i0..%i5 : input argument registers +%o0..%o5 : output argument registers +%g0 : always zero, writes to it have no effect. + +Register Mappings: +r0-7 -> globals +r8-15 -> outs +r16-r23 -> locals +r24-r31 -> ins + +Integer Register Overview Table: +ID Class Name Description +------------------------------------------------------------------------------ +0 globals g0 always zero, writes to it have no effect +1 g1 +2 g2 +3 g3 +4 g4 +5 g5 +6 g6 +7 g7 +8 out o0 [int/ptr] arg 0 and return +9 o1 arg 1 +10 o2 arg 2 +11 o3 arg 3 +12 o4 arg 4 +13 o5 arg 5 +14 o6 stack pointer +15 o7 +16 local l0 scratch +17 l1 +18 l2 +19 l3 +20 l4 +21 l5 +22 l6 +23 l7 +24 in i0 [int/pt] arg 0 and return +25 i1 +26 i2 +27 i3 +28 i4 +29 i5 +30 i6 frame pointer +31 i7 +*/ + +/* --------------------------------------------------------------------------- + +call kernel for sparc64 v9 abi +tested on sparc64/linux/debian [gcc54.fsffrance.org - thanx to the farm!] + +new C Interface: + void dcCall_sparc (DCCallVM* callvm, DCpointer target); + %i0 %1 + +see dyncall_call_sparc.S for details. + +old C Interface: + void dcCall_sparc (DCpointer target, DCsize size, DCpointer data); + %i0 , %i1 , %i2 +Input: + i0 target + i1 size + i2 data + +*/ + +#if 0 + + +#define REGSIZE 8 + + + +#define SHEAD ((16+6)*8) +#define ALIGN 16 +#define IREGS 6 +#define FREGS 16 +#define SREGS 16 +#define IBASE 0 +#define FBASE (IREGS*8) + +// #define DHEAD ((IREGS+FREGS)*8)+SREGS*4 + +CALLVM_regdata = 72 +CALLVM_size = 208 +CALLVM_buffer = 216 + +#endif