# HG changeset patch # User cslag # Date 1437303934 -7200 # Node ID 7ca57dbefed4dde0ef5e2a3eda45d34cf9782dd0 # Parent b8ea1d2a34a325273f6333fec3304e37019cc40e - ppc64 update from Masanori diff -r b8ea1d2a34a3 -r 7ca57dbefed4 ChangeLog --- a/ChangeLog Thu Jul 09 20:51:11 2015 +0200 +++ b/ChangeLog Sun Jul 19 13:05:34 2015 +0200 @@ -3,7 +3,7 @@ Version 0.9 (upcoming) dyncall: o ARM64 support (AAPCS64 on Linux, Apple's derived version on iOS) - o PPC64 support (thanks Masanori!) + o PPC64 support, including syscalls (thanks Masanori!) o introduced dcArgF and dcVArgF for flexible/convenient argument binding (works like dcCallF/dcVCallF but without the function call) o added -fPIC by default for FreeBSD o PPC32 linux syscall support diff -r b8ea1d2a34a3 -r 7ca57dbefed4 README --- a/README Thu Jul 09 20:51:11 2015 +0200 +++ b/README Sun Jul 19 13:05:34 2015 +0200 @@ -10,7 +10,7 @@ - 'dynload' for loading code. The package provides abstractions to the Application Binary Interface -of various hardware platforms such as x86, AMD64, ARM32/64, PowerPCC32/64, +of various hardware platforms such as x86, AMD64, ARM32/64, PowerPC32/64, MIPS32/64 and SPARC32/64. Our releases are thoroughly tested across all supported platforms using a diff -r b8ea1d2a34a3 -r 7ca57dbefed4 doc/manual/callconvs/callconv_ppc64.tex --- a/doc/manual/callconvs/callconv_ppc64.tex Thu Jul 09 20:51:11 2015 +0200 +++ b/doc/manual/callconvs/callconv_ppc64.tex Sun Jul 19 13:05:34 2015 +0200 @@ -34,7 +34,7 @@ \paragraph{\product{dyncall} support} -\product{Dyncall} supports PowerPC (64bit) Big Endian and Little Endian ELF ABIs on System V systems (Linux, etc.). Mac OS X is not supported. +\product{Dyncall} supports PowerPC (64bit) Big Endian and Little Endian ELF ABIs on System V systems (Linux, etc.), including syscalls. Mac OS X is not supported. \subsubsection{PPC64 ELF ABI} diff -r b8ea1d2a34a3 -r 7ca57dbefed4 dyncall/dyncall.h --- a/dyncall/dyncall.h Thu Jul 09 20:51:11 2015 +0200 +++ b/dyncall/dyncall.h Sun Jul 19 13:05:34 2015 +0200 @@ -29,6 +29,7 @@ dyncall C API REVISION + 2015/07/08 added SYS_PPC64 system call 2015/01/16 added SYS_PPC32 system call 2007/12/11 initial @@ -83,6 +84,7 @@ #define DC_CALL_SYS_X86_INT80H_LINUX 201 #define DC_CALL_SYS_X86_INT80H_BSD 202 #define DC_CALL_SYS_PPC32 210 +#define DC_CALL_SYS_PPC64 211 /* Error codes. */ diff -r b8ea1d2a34a3 -r 7ca57dbefed4 dyncall/dyncall_call_ppc64.S --- a/dyncall/dyncall_call_ppc64.S Thu Jul 09 20:51:11 2015 +0200 +++ b/dyncall/dyncall_call_ppc64.S Sun Jul 19 13:05:34 2015 +0200 @@ -23,7 +23,7 @@ */ -#include "../portasm/portasm-ppc.S" +#include "../portasm/portasm-ppc64.S" /* Call Kernel Implementations for PowerPC64. @@ -37,6 +37,7 @@ dcCall_ppc64(DCpointer target, struct DCRegData* pRegData, DCsize stacksize, DCptr stackdata); ChangeLog: + 2015-07-08: Added support for system calls 2014-08-07: Initial Support */ @@ -60,7 +61,6 @@ - Parameter Area (min. v1:64 Bytes v2:0 Byte) - Frame Header Area (v1:48 Bytes v2:32 Bytes) - Frame structure: on entry, parent frame layout: @@ -92,25 +92,9 @@ #endif .text - .global dcCall_ppc64 - .type dcCall_ppc64, @function -#if DC__ABI_PPC64_ELF_V != 2 - .section .opd, "aw" - .align 3 -#endif - -dcCall_ppc64: -#if DC__ABI_PPC64_ELF_V != 2 - .quad .dcCall_ppc64, .TOC.@tocbase, 0 - .previous - .global .dcCall_ppc64 - -.dcCall_ppc64: -#else -0: addis r2, r12,.TOC.-0b@ha - addi r2, r2,.TOC.-0b@l - .localentry dcCall_ppc64,.-dcCall_ppc64 -#endif +.align 2 +GLOBAL_C(dcCall_ppc64) +ENTRY_C(dcCall_ppc64) mflr r0 /* r0 = return address */ std r0,16(r1) /* store r0 to link-area */ std r31,-8(r1) @@ -195,3 +179,32 @@ mtlr r0 /* setup link register */ blr /* return */ +.align 2 +GLOBAL_C(dcCall_ppc64_syscall) +ENTRY_C(dcCall_ppc64_syscall) + mflr r0 /* r0 = return address */ + std r0,16(r1) /* store r0 to link-area */ + std r31,-8(r1) + li r0, -STACK_MIN + stdux r1,r1,r0 /* store r1 and decrement */ + + mr r0, r3 /* r0 = syscall number ( passed as 'target function' ) */ + mr r11, r4 /* r11 = reg data */ + + /* load 5 integer registers */ + ld r3 , 0(r11) + ld r4 , 8(r11) + ld r5 ,16(r11) + ld r6 ,24(r11) + ld r7 ,32(r11) + + sc /* system call */ + + /* epilog */ + + ld r2,TOC_SAVE(r1) + ld r1, 0(r1) /* restore stack */ + ld r31,-8(r1) + ld r0,16(r1) /* r0 = return address */ + mtlr r0 /* setup link register */ + blr /* return */ diff -r b8ea1d2a34a3 -r 7ca57dbefed4 dyncall/dyncall_callvm_ppc64.c --- a/dyncall/dyncall_callvm_ppc64.c Thu Jul 09 20:51:11 2015 +0200 +++ b/dyncall/dyncall_callvm_ppc64.c Sun Jul 19 13:05:34 2015 +0200 @@ -29,8 +29,10 @@ SUPPORTED CALLING CONVENTIONS ppc64/linux + ppc64/syscall REVISION + 2015/07/08 added syscall 2014/08/07 initial support */ @@ -209,6 +211,12 @@ dcCall_ppc64( target, &self->mRegData, dcVecSize(&self->mVecHead) , dcVecData(&self->mVecHead)); } +void dc_callvm_call_ppc64_syscall(DCCallVM* in_self, DCpointer target) +{ + DCCallVM_ppc64* self = (DCCallVM_ppc64*) in_self; + dcCall_ppc64_syscall( target, &self->mRegData, dcVecSize(&self->mVecHead) , dcVecData(&self->mVecHead)); +} + void dc_callvm_mode_ppc64(DCCallVM* in_self, DCint mode); DCCallVM_vt gVT_ppc64 = @@ -269,6 +277,34 @@ }; #endif +DCCallVM_vt gVT_ppc64_syscall = +{ + &dc_callvm_free_ppc64 +, &dc_callvm_reset_ppc64 +, &dc_callvm_mode_ppc64 +, &dc_callvm_argBool_ppc64 +, &dc_callvm_argChar_ppc64 +, &dc_callvm_argShort_ppc64 +, &dc_callvm_argInt_ppc64 +, &dc_callvm_argLong_ppc64 +, &dc_callvm_argLongLong_ppc64 +, &dc_callvm_argFloat_ppc64 +, &dc_callvm_argDouble_ppc64 +, &dc_callvm_argPointer_ppc64 +, NULL /* argStruct */ +, (DCvoidvmfunc*) &dc_callvm_call_ppc64_syscall +, (DCboolvmfunc*) &dc_callvm_call_ppc64_syscall +, (DCcharvmfunc*) &dc_callvm_call_ppc64_syscall +, (DCshortvmfunc*) &dc_callvm_call_ppc64_syscall +, (DCintvmfunc*) &dc_callvm_call_ppc64_syscall +, (DClongvmfunc*) &dc_callvm_call_ppc64_syscall +, (DClonglongvmfunc*) &dc_callvm_call_ppc64_syscall +, (DCfloatvmfunc*) &dc_callvm_call_ppc64_syscall +, (DCdoublevmfunc*) &dc_callvm_call_ppc64_syscall +, (DCpointervmfunc*) &dc_callvm_call_ppc64_syscall +, NULL /* callStruct */ +}; + void dc_callvm_mode_ppc64(DCCallVM* in_self, DCint mode) { DCCallVM_ppc64* self = (DCCallVM_ppc64*) in_self; @@ -290,6 +326,11 @@ break; #endif + case DC_CALL_SYS_DEFAULT: + case DC_CALL_SYS_PPC64: + vt = &gVT_ppc64_syscall; + break; + default: self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; return; diff -r b8ea1d2a34a3 -r 7ca57dbefed4 dyncall/dyncall_value.h --- a/dyncall/dyncall_value.h Thu Jul 09 20:51:11 2015 +0200 +++ b/dyncall/dyncall_value.h Sun Jul 19 13:05:34 2015 +0200 @@ -48,20 +48,31 @@ union DCValue_ { +#if defined (DC__Arch_PPC32) && defined(DC__Endian_BIG) DCbool B; -#if defined (DC__Arch_PPC32) && defined(DC__Endian_BIG) struct { DCchar c_pad[3]; DCchar c; }; struct { DCuchar C_pad[3]; DCuchar C; }; struct { DCshort s_pad; DCshort s; }; struct { DCshort S_pad; DCshort S; }; + DCint i; + DCuint I; +#elif defined (DC__Arch_PPC64) && defined(DC__Endian_BIG) + struct { DCbool B_pad; DCbool B; }; + struct { DCchar c_pad[7]; DCchar c; }; + struct { DCuchar C_pad[7]; DCuchar C; }; + struct { DCshort s_pad[3]; DCshort s; }; + struct { DCshort S_pad[3]; DCshort S; }; + struct { DCint i_pad; DCint i; }; + struct { DCint I_pad; DCuint I; }; #else + DCbool B; DCchar c; DCuchar C; DCshort s; DCushort S; -#endif DCint i; DCuint I; +#endif DClong j; DCulong J; DClonglong l; diff -r b8ea1d2a34a3 -r 7ca57dbefed4 dyncallback/dyncall_callback_ppc64.S --- a/dyncallback/dyncall_callback_ppc64.S Thu Jul 09 20:51:11 2015 +0200 +++ b/dyncallback/dyncall_callback_ppc64.S Sun Jul 19 13:05:34 2015 +0200 @@ -22,150 +22,121 @@ */ -#include "../portasm/portasm-ppc.S" - -/* Callback Thunk Entry code for PowerPC 64-bit. */ - -/* Stack Frame Layout: - - 296 DCValue ( 8 ) - 112 DCArgs ( 64+104+8+4+4 = 184 ) - 48 Parameter area ( 8*8 = 64 ) - 0 Linkage area ( 48 ) - - -*/ - -/* Constants. */ -INT_REGS = 8 -FLOAT_REGS = 13 -SIZEOF_GPR = 8 -SIZEOF_FPR = 8 +#include "../portasm/portasm-ppc64.S" -/* Linkage area. */ -LINK_SP = 0 -LINK_CR = 8 -LINK_LR = 16 -LINK_OFFSET = 0 -#if DC__ABI_PPC64_ELF_V == 2 -LINK_TOC = 24 -LINK_SIZE = 32 -#else -LINK_TOC = 40 -LINK_SIZE = 48 -#endif -/* Parameter area. */ -PAR_OFFSET = LINK_SIZE -#if DC__ABI_PPC64_ELF_V == 2 -PAR_SIZE = 0 -#else -PAR_SIZE = 64 -#endif -/* local struct DCArgs */ -ARGS_OFFSET = (PAR_OFFSET+PAR_SIZE) -ARGS_SIZE = (SIZEOF_GPR*INT_REGS)+(SIZEOF_FPR*FLOAT_REGS) + 8 + 4 * 4 -/* local struct DCValue */ -RESULT_OFFSET = (ARGS_OFFSET+ARGS_SIZE) -RESULT_SIZE = 8 -/* additional locals (reg 30/31) */ -LOCALS_OFFSET = (RESULT_OFFSET+RESULT_SIZE) -LOCALS_SIZE = 2*SIZEOF_GPR -/* total */ -FRAME_SIZE = ( (LOCALS_OFFSET+LOCALS_SIZE)+15 & (-16) ) +.text +.align 2 /* struct DCCallback */ -#if DC__ABI_PPC64_ELF_V == 2 -DCB_THUNK = 0 + +#if DC__ABI_PPC64_ELF_V != 2 +DCB_THUNK = 0 /* v1 */ +DCB_HANDLER = 64 +DCB_STACKCLEAN = 72 +DCB_USERDATA = 80 +#else +DCB_THUNK = 0 /* v2 */ DCB_HANDLER = 48 DCB_STACKCLEAN = 56 DCB_USERDATA = 64 -#else -DCB_THUNK = 0 -DCB_HANDLER = 64 -DCB_STACKCLEAN = 72 -DCB_USERDATA = 80 #endif /* struct DCArgs */ -DCA_IARRAY = 0 -DCA_FARRAY = SIZEOF_GPR*INT_REGS -DCA_SP = DCA_FARRAY + SIZEOF_FPR*FLOAT_REGS -DCA_ICOUNT = DCA_SP + 8 -DCA_FCOUNT = DCA_ICOUNT + 4 + +ARGS_IREGS = 0 +ARGS_FREGS = ARGS_IREGS + 8*8 +ARGS_SP = ARGS_FREGS + 8*13 +ARGS_ICNT = ARGS_SP + 8 +ARGS_FCNT = ARGS_ICNT + 4 +ARGS_SIZE = ARGS_FCNT + 4 /* struct DCValue */ -DCV_INT = 0 -DCV_FLOAT = 0 -DCV_SIZE = 8 + +RESULT_SIZE = 8 + +/* Stack Offsets */ -iregfile = ARGS_OFFSET+DCA_IARRAY -fregfile = ARGS_OFFSET+DCA_FARRAY -save_sp = ARGS_OFFSET+DCA_SP -icount = ARGS_OFFSET+DCA_ICOUNT -fcount = ARGS_OFFSET+DCA_FCOUNT +SP_PREV = 0 +SP_CR = SP_PREV + 8 +SP_LR = SP_CR + 8 +#if DC__ABI_PPC64_ELF_V != 2 +SP_TOC = 40 +SP_PAR = 48 +PAR_SZ = 64 +#else +SP_TOC = 24 +SP_PAR = 32 +PAR_SZ = 0 +#endif +SP_ARGS = SP_PAR + PAR_SZ +SP_IREGS = SP_ARGS + ARGS_IREGS +SP_FREGS = SP_ARGS + ARGS_FREGS +SP_SP = SP_ARGS + ARGS_SP +SP_ICNT = SP_ARGS + ARGS_ICNT +SP_FCNT = SP_ARGS + ARGS_FCNT +SP_RESULT = SP_ARGS + ARGS_SIZE +SP_LOCAL = SP_RESULT + RESULT_SIZE /* additional locals (reg 30/31) */ +SP_SIZE = SP_LOCAL + 2*8 -/* - Thunk entry: - R2 = DCCallback* +#define ALIGN(M,X) ( M+(X-1) & (-X) ) + +FRAMESIZE = ALIGN(SP_SIZE,16) + +GLOBAL_C(dcCallbackThunkEntry) +ENTRY_C(dcCallbackThunkEntry) + +/* -------------------------------------------------------------------------- + +Input: + r1 Stack Pointer + r3-r10 Integer Arguments + f1-f8 Floating-point Arguments + r11 Thunk Pointer + */ -.text - .global dcCallbackThunkEntry - .type dcCallbackThunkEntry, @function -#if DC__ABI_PPC64_ELF_V != 2 - .section .opd, "aw" - .align 3 -#endif -dcCallbackThunkEntry: -#if DC__ABI_PPC64_ELF_V != 2 - .quad .dcCallbackThunkEntry, .TOC.@tocbase, 0 - .previous - .global .dcCallbackThunkEntry - -.dcCallbackThunkEntry: -#endif mflr r0 - std r0, 16(r1) /* store return address */ - std r31, -8(r1) /* store preserved registers (r31) */ - addi r12, r1, PAR_OFFSET /* temporary r12 = parameter area on callers stack frame */ - stdu r1, -FRAME_SIZE(r1) /* save callers stack pointer and make new stack frame. */ + std r0, SP_LR(r1) /* store return address */ + std r31, -8(r1) /* store preserved registers (r31) */ + addi r12, r1, SP_PAR /* temporary r12 = parameter area on callers stack frame */ + stdu r1, -FRAMESIZE(r1) /* save callers stack pointer and make new stack frame. */ - std r3, iregfile+0*8(r1) /* spill 8 integer parameter registers */ - std r4, iregfile+1*8(r1) - std r5, iregfile+2*8(r1) - std r6, iregfile+3*8(r1) - std r7, iregfile+4*8(r1) - std r8, iregfile+5*8(r1) - std r9, iregfile+6*8(r1) - std r10,iregfile+7*8(r1) - stfd f1, fregfile+ 0*8(r1) /* spill 13 float parameter registers */ - stfd f2, fregfile+ 1*8(r1) - stfd f3, fregfile+ 2*8(r1) - stfd f4, fregfile+ 3*8(r1) - stfd f5, fregfile+ 4*8(r1) - stfd f6, fregfile+ 5*8(r1) - stfd f7, fregfile+ 6*8(r1) - stfd f8, fregfile+ 7*8(r1) - stfd f9, fregfile+ 8*8(r1) - stfd f10,fregfile+ 9*8(r1) - stfd f11,fregfile+10*8(r1) - stfd f12,fregfile+11*8(r1) - stfd f13,fregfile+12*8(r1) + std r3, SP_IREGS + 0*8(r1) /* spill 8 integer parameter registers */ + std r4, SP_IREGS + 1*8(r1) + std r5, SP_IREGS + 2*8(r1) + std r6, SP_IREGS + 3*8(r1) + std r7, SP_IREGS + 4*8(r1) + std r8, SP_IREGS + 5*8(r1) + std r9, SP_IREGS + 6*8(r1) + std r10,SP_IREGS + 7*8(r1) + stfd f1, SP_FREGS + 0*8(r1) /* spill 13 float parameter registers */ + stfd f2, SP_FREGS + 1*8(r1) + stfd f3, SP_FREGS + 2*8(r1) + stfd f4, SP_FREGS + 3*8(r1) + stfd f5, SP_FREGS + 4*8(r1) + stfd f6, SP_FREGS + 5*8(r1) + stfd f7, SP_FREGS + 6*8(r1) + stfd f8, SP_FREGS + 7*8(r1) + stfd f9, SP_FREGS + 8*8(r1) + stfd f10,SP_FREGS + 9*8(r1) + stfd f11,SP_FREGS +10*8(r1) + stfd f12,SP_FREGS +11*8(r1) + stfd f13,SP_FREGS +12*8(r1) /* initialize struct DCCallback */ - std r12,save_sp(r1) /* init stack pointer */ + std r12,SP_SP(r1) /* init stack pointer */ xor r0, r0, r0 /* init register counters */ - std r0, icount(r1) - std r0, fcount(r1) - std r0, RESULT_OFFSET(r1) + std r0, SP_ICNT(r1) + std r0, SP_FCNT(r1) + std r0, SP_RESULT(r1) /* init result object */ /* invoke callback handler */ - mr r3, r11 /* arg 1: DCCallback* pcb */ - addi r4, r1, ARGS_OFFSET /* arg 2: DCArgs* args */ - addi r5, r1, RESULT_OFFSET /* arg 3: DCValue* result */ + mr r3, r11 /* arg 1: DCCallback* pcb (r11 is thunk pointer) */ + addi r4, r1, SP_ARGS /* arg 2: DCArgs* args */ + addi r5, r1, SP_RESULT /* arg 3: DCValue* result */ ld r6, DCB_USERDATA(r11) /* arg 4: void* userdata */ /* branch-and-link to DCCallback.handler */ ld r12, DCB_HANDLER(r11) - std r2, LINK_TOC(r1) + std r2, SP_TOC(r1) #if DC__ABI_PPC64_ELF_V != 2 ld r2, 8(r12) ld r0, 0(r12) @@ -175,41 +146,25 @@ #endif bctrl - addi r0, r1, RESULT_OFFSET /* r0 = DCValue* */ - /* switch on base result type */ - cmpi cr0, r3, 'B - beq .i64 - cmpi cr0, r3, 'i - beq .i64 - cmpi cr0, r3, 'c - beq .i64 - cmpi cr0, r3, 's - beq .i64 - cmpi cr0, r3, 'l - beq .i64 + /* check result type */ cmpi cr0, r3, 'f beq .f32 cmpi cr0, r3, 'd beq .f64 - cmpi cr0, r3, 'p - beq .i64 -.void: /* ignore result (void call) */ - b .end -.i64: /* result is 64-bit long long result */ - ld r3, RESULT_OFFSET + DCV_INT(r1) - b .end -.f32: /* result is C float result */ - lfs f1, RESULT_OFFSET + DCV_FLOAT(r1) - b .end -.f64: /* result is C double result */ - lfd f1, RESULT_OFFSET + DCV_FLOAT(r1) +.i64: + ld r3, SP_RESULT(r1) b .end .end: - ld r2, LINK_TOC(r1) - ld r1, 0(r1) /* restore stack pointer */ - ld r31, -8(r1) /* restore preserved registers */ - ld r0, 16(r1) /* load link register with return address */ + ld r2, SP_TOC(r1) + ld r1, SP_PREV(r1) /* restore stack pointer */ + ld r31, -8(r1) /* restore preserved registers */ + ld r0, SP_LR(r1) /* load link register with return address */ mtlr r0 - blr /* branch back to link register */ - + blr /* branch back to link register */ +.f32: + lfs f1, SP_RESULT(r1) + b .end +.f64: + lfd f1, SP_RESULT(r1) + b .end diff -r b8ea1d2a34a3 -r 7ca57dbefed4 dyncallback/dyncall_thunk_ppc64.c --- a/dyncallback/dyncall_thunk_ppc64.c Thu Jul 09 20:51:11 2015 +0200 +++ b/dyncallback/dyncall_thunk_ppc64.c Sun Jul 19 13:05:34 2015 +0200 @@ -31,9 +31,34 @@ void dcbInitThunk(DCThunk* p, void (*entry)()) { -#if DC__ABI_PPC64_ELF_V == 2 +#if DC__ABI_PPC64_ELF_V != 2 /* - ppc64 thunk code: + ppc64 thunk code: (v1) + oris r11, r2, HI16(p) + ori r11,r11, LO16(p) + ld r12,48(r11) + ld r2,56(r11) + mtctr r12 + bctr + */ + + p->thunk_entry = (void *)&(p->code_load_hi); + p->toc_thunk = ((long)(p->thunk_entry) & 0xffffffff00000000UL); + + p->code_load_hi = 0x644bU; /* oris r11, r2, HI16(p) */ + p->addr_self_hi = HI16(p); + p->code_load_lo = 0x616bU; /* ori r11,r11, LO16(p) */ + p->addr_self_lo = LO16(p); + p->code_jump[0] = 0xe98b0030U; /* ld r12,48(r11) */ + p->code_jump[1] = 0xe84b0038U; /* ld r2,56(r11) */ + p->code_jump[2] = 0x7d8903a6U; /* mtclr r12 */ + p->code_jump[3] = 0x4e800420U; /* bctr */ + p->addr_entry = (void *)*((long *)entry); + p->toc_entry = *((long *)(entry + 8)); + +#else + /* + ppc64 thunk code: (v2) lis r11, HIST16(p) ori r11,r11, HIER16(p) rldicr r11,r11,32,31 @@ -57,31 +82,6 @@ p->code_jump[1] = 0x7d8903a6U; /* mtclr r12 */ p->code_jump[2] = 0x4e800420U; /* bctr */ p->addr_entry = (void *)(entry); - -#else - /* - ppc64 thunk code: - oris r11, r2, HI16(p) - ori r11,r11, LO16(p) - ld r12,48(r11) - ld r2,56(r11) - mtctr r12 - bctr - */ - - p->thunk_entry = (void *)&(p->code_load_hi); - p->toc_thunk = ((long)(p->thunk_entry) & 0xffffffff00000000UL); - - p->code_load_hi = 0x644bU; /* oris r11, r2, HI16(p) */ - p->addr_self_hi = HI16(p); - p->code_load_lo = 0x616bU; /* ori r11,r11, LO16(p) */ - p->addr_self_lo = LO16(p); - p->code_jump[0] = 0xe98b0030U; /* ld r12,48(r11) */ - p->code_jump[1] = 0xe84b0038U; /* ld r2,56(r11) */ - p->code_jump[2] = 0x7d8903a6U; /* mtclr r12 */ - p->code_jump[3] = 0x4e800420U; /* bctr */ - p->addr_entry = (void *)*((long *)entry); - p->toc_entry = *((long *)(entry + 8)); #endif } diff -r b8ea1d2a34a3 -r 7ca57dbefed4 dyncallback/dyncall_thunk_ppc64.h --- a/dyncallback/dyncall_thunk_ppc64.h Thu Jul 09 20:51:11 2015 +0200 +++ b/dyncallback/dyncall_thunk_ppc64.h Sun Jul 19 13:05:34 2015 +0200 @@ -25,8 +25,20 @@ #ifndef DYNCALL_THUNK_PPC64_H #define DYNCALL_THUNK_PPC64_H -#if DC__ABI_PPC64_ELF_V == 2 -struct DCThunk_ +#if DC__ABI_PPC64_ELF_V != 2 +struct DCThunk_ /* v1 */ +{ + void (*thunk_entry)(); /* offset: 0 */ + long toc_thunk; /* offset: 8 */ + unsigned short code_load_hi, addr_self_hi; /* offset: 16 */ + unsigned short code_load_lo, addr_self_lo; /* offset: 20 */ + unsigned int code_jump[6]; /* offset: 24 */ + void (*addr_entry)(); /* offset: 48 */ + long toc_entry; /* offset: 56 */ +}; +#define DCTHUNK_SIZE_PPC64 64 +#else +struct DCThunk_ /* v2 */ { unsigned short addr_self_hist, code_load_hist; /* offset: 0 */ unsigned short addr_self_hier, code_load_hier; /* offset: 4 */ @@ -37,18 +49,6 @@ void (*addr_entry)(); /* offset: 40 */ }; #define DCTHUNK_SIZE_PPC64 48 -#else -struct DCThunk_ -{ - void (*thunk_entry)(); /* offset: 0 */ - long toc_thunk; /* offset: 8 */ - unsigned short code_load_hi, addr_self_hi; /* offset: 16 */ - unsigned short code_load_lo, addr_self_lo; /* offset: 20 */ - unsigned int code_jump[6]; /* offset: 24 */ - void (*addr_entry)(); /* offset: 48 */ - long toc_entry; /* offset: 56 */ -}; -#define DCTHUNK_SIZE_PPC64 64 #endif #endif /* DYNCALL_THUNK_PPC64_H */ diff -r b8ea1d2a34a3 -r 7ca57dbefed4 portasm/portasm-ppc64.S --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/portasm/portasm-ppc64.S Sun Jul 19 13:05:34 2015 +0200 @@ -0,0 +1,119 @@ +/* + + Package: dyncall + Library: portasm + File: portasm/portasm-ppc64.S + Description: Portable Assembler Macros for ppc64 + License: + + Copyright (c) 2014-2015 Masanori Mitsugi + + 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. + +*/ + + +#include "../autovar/autovar_OS.h" + +#if DC__ABI_PPC64_ELF_V != 2 /* v1 */ +#define GLOBAL_C(X) \ +.global X; \ +.type X, @function; \ +.section .opd, "aw"; \ +.align 3; +#else /* v2 */ +#define GLOBAL_C(X) \ +.global X; \ +.type X, @function; +#endif + +#if DC__ABI_PPC64_ELF_V != 2 /* v1 */ +#define ENTRY_C(X) \ +X: \ +.quad .X, .TOC.@tocbase, 0; \ +.previous; \ +.global .X; \ +.X: +#else /* v2 */ +#define ENTRY_C(X) \ +X: \ +0: \ +addis r2, r12,.TOC.-0b@ha; \ +addi r2, r2,.TOC.-0b@l; \ +.localentry X,.-X; +#endif + +#define r0 0 +#define r1 1 +#define r2 2 +#define r3 3 +#define r4 4 +#define r5 5 +#define r6 6 +#define r7 7 +#define r8 8 +#define r9 9 +#define r10 10 +#define r11 11 +#define r12 12 +#define r13 13 +#define r14 14 +#define r15 15 +#define r16 16 +#define r17 17 +#define r18 18 +#define r19 19 +#define r20 20 +#define r21 21 +#define r22 22 +#define r23 23 +#define r24 24 +#define r25 25 +#define r26 26 +#define r27 27 +#define r28 28 +#define r29 29 +#define r30 30 +#define r31 31 +#define f0 0 +#define f1 1 +#define f2 2 +#define f3 3 +#define f4 4 +#define f5 5 +#define f6 6 +#define f7 7 +#define f8 8 +#define f9 9 +#define f10 10 +#define f11 11 +#define f12 12 +#define f13 13 +#define f14 14 +#define f15 15 +#define f16 16 +#define f17 17 +#define f18 18 +#define f19 19 +#define f20 20 +#define f21 21 +#define f22 22 +#define f23 23 +#define f24 24 +#define f25 25 +#define f26 26 +#define f27 27 +#define f28 28 +#define f29 29 +#define f30 30 +#define f31 31 diff -r b8ea1d2a34a3 -r 7ca57dbefed4 test/callback_plain/callback_plain.c --- a/test/callback_plain/callback_plain.c Thu Jul 09 20:51:11 2015 +0200 +++ b/test/callback_plain/callback_plain.c Sun Jul 19 13:05:34 2015 +0200 @@ -52,6 +52,7 @@ if(arg3 == 3) ++*ud; if(arg4 == 1.82) ++*ud; if(arg5 == 9909) ++*ud; + result->s = 1234; return 's'; } diff -r b8ea1d2a34a3 -r 7ca57dbefed4 test/callback_suite/handler.c --- a/test/callback_suite/handler.c Thu Jul 09 20:51:11 2015 +0200 +++ b/test/callback_suite/handler.c Sun Jul 19 13:05:34 2015 +0200 @@ -65,22 +65,6 @@ /* currently, no void result is supported by the suite */ GetReferenceResult(output, ch); -#if defined(DC__Arch_PPC64) && defined(DC__Endian_BIG) - switch (ch) { - case DC_SIGCHAR_BOOL: output->l = ((long long)output->B); break; - case DC_SIGCHAR_CHAR: output->l = ((long long)output->c); break; - case DC_SIGCHAR_UCHAR: output->l = ((long long)output->C); break; - case DC_SIGCHAR_SHORT: output->l = ((long long)output->s); break; - case DC_SIGCHAR_USHORT: output->l = ((long long)output->S); break; - case DC_SIGCHAR_INT: output->l = ((long long)output->i); break; - case DC_SIGCHAR_UINT: output->l = ((long long)output->I); break; - case DC_SIGCHAR_LONG: output->l = ((long long)output->j); break; - case DC_SIGCHAR_ULONG: output->l = ((long long)output->J); break; - case DC_SIGCHAR_ULONGLONG:output->l = ((long long)output->L); break; - case DC_SIGCHAR_FLOAT: output->d = ((double)output->f); break; - } -#endif - switch(ch) { case DC_SIGCHAR_BOOL: return 'B'; case DC_SIGCHAR_CHAR: return 'c';