void dc_callvm_call_ppc64(DCCallVM* in_self, DCpointer target) { DCCallVM_ppc64* self = (DCCallVM_ppc64*) in_self; int size = dcVecSize(&self->mVecHead); if (size < 64) { dcVecSkip(&self->mVecHead, 64-size); } dcCall_ppc64( target, &self->mRegData, dcVecSize(&self->mVecHead) , dcVecData(&self->mVecHead)); }
void dc_callvm_call_x86_plan9(DCCallVM* in_self, DCpointer target) { /* Calls with 32-bit return values have it returned via EAX, so we don't */ /* need to do anything special here. */ DCCallVM_x86* self = (DCCallVM_x86*) in_self; dcCall_x86_plan9(target, dcVecData(&self->mVecHead), dcVecSize(&self->mVecHead)); }
static void dc_callvm_argLongLong_ppc32_sysv(DCCallVM* in_self, DClonglong L) { DCint* p = (DCint*) &L; DCCallVM_ppc32* self = (DCCallVM_ppc32*)in_self; /* fillup integer register file */ if (self->mIntRegs < 7) { /* next free integer register is even (r0, r2, r3) ? */ /* if not, skip one integer */ if (self->mIntRegs & 1) self->mIntRegs++; self->mRegData.mIntData[self->mIntRegs++] = p[0]; self->mRegData.mIntData[self->mIntRegs++] = p[1]; } /* OR push onto stack */ else { /* in case, mIntRegs == 7, set it to 8 */ self->mIntRegs = 8; /* align stack to 8 byte boundary */ dcVecResize(&self->mVecHead , ( dcVecSize(&self->mVecHead) + 7 ) & (-8UL) ); /* push data */ dcVecAppend(&self->mVecHead,&L,sizeof(DClonglong)); } }
static void dc_callvm_argDouble_arm32_thumb_eabi(DCCallVM* in_self, DCdouble x) { DCCallVM_arm32_thumb* self = (DCCallVM_arm32_thumb*)in_self; /* 64 bit values need to be aligned on 8 byte boundaries */ dcVecSkip(&self->mVecHead, dcVecSize(&self->mVecHead) & 4); dcVecAppend(&self->mVecHead, &x, sizeof(DCdouble)); }
static void dc_callvm_argLongLong_mips_o32(DCCallVM* in_self, DClonglong Lv) { DCCallVM_mips_o32* self = (DCCallVM_mips_o32*)in_self; /* 64-bit values need to be aligned on 8 byte boundaries */ dcVecSkip(&self->mVecHead, dcVecSize(&self->mVecHead) & 4); dcVecAppend(&self->mVecHead, &Lv, sizeof(DClonglong)); self->mArgCount += 1; }
DClonglong dc_callvm_call_x86_plan9_ll(DCCallVM* in_self, DCpointer target) { /* Call for 64 bit integer return values is a bit different, call a */ /* different assembler stub that stores the return value in a variable */ /* for us, and return the latter. */ DClonglong ret; DCCallVM_x86* self = (DCCallVM_x86*) in_self; dcCall_x86_plan9_ll(target, dcVecData(&self->mVecHead), dcVecSize(&self->mVecHead), &ret ); return ret; }
static void dc_callvm_argDouble_mips_o32(DCCallVM* in_self, DCdouble x) { DCCallVM_mips_o32* self = (DCCallVM_mips_o32*)in_self; /* 64-bit values need to be aligned on 8 byte boundaries */ dcVecSkip(&self->mVecHead, dcVecSize(&self->mVecHead) & 4); dcVecAppend(&self->mVecHead, &x, sizeof(DCdouble) ); if (self->mArgCount < 2) self->mRegData.doubles[self->mArgCount] = x; self->mArgCount++; }
void dc_callvm_call_ppc32_darwin(DCCallVM* in_self, DCpointer target) { DCCallVM_ppc32* self = (DCCallVM_ppc32*)in_self; dcCall_ppc32_darwin( target, &self->mRegData, DC_MAX(dcVecSize(&self->mVecHead), 8*4), dcVecData(&self->mVecHead) ); }
void dc_callvm_call_mips_n64(DCCallVM* in_self, DCpointer target) { DCCallVM_mips_n64* self = (DCCallVM_mips_n64*)in_self; /* at minimum provide 16-bytes which hold the first four integer register as spill area and are automatically loaded to $4-$7 */ size_t size = DC_MAX(16, ( ( (unsigned) dcVecSize(&self->mVecHead) ) +7UL ) & (-8UL) ); dcCall_mips_n64(target, &self->mRegData, size, dcVecData(&self->mVecHead)); }
void call(DCCallVM* in_p, DCpointer target) { DCCallVM_arm64* p = (DCCallVM_arm64*)in_p; /* ** copy 'size' argument is given in number of 16-byte 'pair' blocks. */ dcCall_arm64(target, dcVecData(&p->mVecHead), ( dcVecSize(&p->mVecHead) + 15 ) & -16, &p->u.S[0]); }
static void dc_callvm_argLongLong_ppc64_ellipsis(DCCallVM* in_self, DClonglong L) { DCCallVM_ppc64* self = (DCCallVM_ppc64*)in_self; if (dcVecSize(&self->mVecHead) == 0) dcVecSkip(&self->mVecHead,(sizeof(DClonglong))*(self->mIntRegs)); if (self->mIntRegs < 8) self->mRegData.mIntData[self->mIntRegs++] = L; /* push on stack */ dcVecAppend(&self->mVecHead,&L,sizeof(DClonglong)); }
static void dc_callvm_argDouble_ppc32_sysv(DCCallVM* in_self, DCdouble d) { DCCallVM_ppc32* self = (DCCallVM_ppc32*)in_self; if (self->mFloatRegs < 8) self->mRegData.mFloatData[self->mFloatRegs++] = d; else /* OR push data on stack */ { /* align stack to 8 byte boundary */ dcVecResize(&self->mVecHead , ( dcVecSize(&self->mVecHead) + 7UL ) & -8UL ); /* AND push data */ dcVecAppend(&self->mVecHead,(DCpointer) &d,sizeof(DCdouble)); } }
static void a_longlong(DCCallVM* in_self, DClonglong x) { DCCallVM_arm32_armhf* p = (DCCallVM_arm32_armhf*)in_self; p->i = (p->i+4) & -8; if (p->i < 16) { * (DClonglong*) dcVecAt(&p->mVecHead, p->i) = x; p->i += 8; } else { /* 64 bit values need to be aligned on 8 byte boundaries */ dcVecSkip(&p->mVecHead, dcVecSize(&p->mVecHead) & 4); dcVecAppend(&p->mVecHead, &x, sizeof(DClonglong)); } }
static void dc_callvm_argLongLong_mips_eabi(DCCallVM* in_self, DClonglong Lv) { DCCallVM_mips_eabi* self = (DCCallVM_mips_eabi*)in_self; if (self->mIntRegs < 7) { DCint* p = (DCint*) &Lv; /* skip odd register (align 64 bit) */ self->mIntRegs += self->mIntRegs & 1; self->mRegData.mIntData[self->mIntRegs++] = p[0]; self->mRegData.mIntData[self->mIntRegs++] = p[1]; } else { self->mIntRegs = 8; /* 64 bit values need to be aligned on 8 byte boundaries */ dcVecSkip(&self->mVecHead, dcVecSize(&self->mVecHead) & 4); dcVecAppend(&self->mVecHead, &Lv, sizeof(DClonglong)); } }
/* Call. */ void dc_callvm_call_x64(DCCallVM* in_self, DCpointer target) { DCCallVM_x64* self = (DCCallVM_x64*)in_self; #if defined(DC_UNIX) dcCall_x64_sysv( #else dcCall_x64_win64( #endif dcVecSize(&self->mVecHead), /* Size of stack data. */ dcVecData(&self->mVecHead), /* Pointer to stack arguments. */ self->mRegData.i, /* Pointer to register arguments (ints on SysV). */ #if defined(DC_UNIX) self->mRegData.f, /* Pointer to floating point register arguments. */ #endif target ); }
static void dc_callvm_argDouble_ppc64_ellipsis(DCCallVM* in_self, DCdouble d) { DCCallVM_ppc64* self = (DCCallVM_ppc64*)in_self; if (dcVecSize(&self->mVecHead) == 0) dcVecSkip(&self->mVecHead,(sizeof(DClonglong))*(self->mIntRegs)); if (self->mFloatRegs < 13) { self->mRegData.mFloatData[self->mFloatRegs++] = d; if (self->mIntRegs < 8) { self->mRegData.mIntData[self->mIntRegs++] = *( (DClonglong*) &d ); } } /* push on stack */ dcVecAppend(&self->mVecHead,(DCpointer) &d,sizeof(DCdouble)); }
static void dc_callvm_argLongLong_ppc64(DCCallVM* in_self, DClonglong L) { DCCallVM_ppc64* self = (DCCallVM_ppc64*)in_self; /* fillup integer register file */ if (self->mIntRegs < 8) { self->mRegData.mIntData[self->mIntRegs++] = L; #if DC__ABI_PPC64_ELF_V == 2 return; #endif } #if DC__ABI_PPC64_ELF_V == 2 if (dcVecSize(&self->mVecHead) == 0) { dcVecSkip(&self->mVecHead,sizeof(DClonglong)*8); } #endif /* push on stack */ dcVecAppend(&self->mVecHead,&L,sizeof(DClonglong)); }
static void a_double(DCCallVM* in_p, DCdouble x) { union { DCdouble d; DCchar b[8]; } v; DCCallVM_arm32_armhf* p = (DCCallVM_arm32_armhf*)in_p; if (p->d < 16) { * (DCdouble*) &p->S[p->d] = x; p->d += 2; if (!(p->s & 1)) { /* if s is even it always equals d. otherwise, s points to an odd float register. */ p->s = p->d; } } else { p->s = 16; /* fp registers all full - need to use stack now: stop filling gaps for single precision, also */ v.d = x; /* 64 bit values need to be aligned on 8 byte boundaries */ dcVecSkip(&p->mVecHead, dcVecSize(&p->mVecHead) & 4); dcVecAppend(&p->mVecHead, &v.b[0], sizeof(DCdouble)); } }
static void dc_callvm_argDouble_ppc64(DCCallVM* in_self, DCdouble d) { DCCallVM_ppc64* self = (DCCallVM_ppc64*)in_self; if (self->mFloatRegs < 13) { self->mRegData.mFloatData[self->mFloatRegs++] = d; if (self->mIntRegs < 8) { self->mRegData.mIntData[self->mIntRegs++] = *( (DClonglong*) &d ); #if DC__ABI_PPC64_ELF_V == 2 return; #endif } } #if DC__ABI_PPC64_ELF_V == 2 if (dcVecSize(&self->mVecHead) == 0) { dcVecSkip(&self->mVecHead,sizeof(DClonglong)*8); } #endif /* push on stack */ dcVecAppend(&self->mVecHead,(DCpointer) &d,sizeof(DCdouble)); }
static void a_double(DCCallVM* in_p, DCdouble x) { DCCallVM_arm32_armhf* p = (DCCallVM_arm32_armhf*)in_p; union { DCdouble d; DCchar b[8]; } v; // ,w; if (p->d < 16) { * (double*) &p->S[p->d] = x; p->d += 2; if (!(p->s & 1)) { /* if s is even it always equals d. otherwise, s points to an odd float register. */ p->s = p->d; } } else { p->s = 16; v.d = x; #if 0 w.b[0] = v.b[7]; w.b[1] = v.b[6]; w.b[2] = v.b[5]; w.b[3] = v.b[4]; w.b[4] = v.b[3]; w.b[5] = v.b[2]; w.b[6] = v.b[1]; w.b[7] = v.b[0]; #endif /* 64 bit values need to be aligned on 8 byte boundaries */ dcVecSkip(&p->mVecHead, dcVecSize(&p->mVecHead) & 4); dcVecAppend(&p->mVecHead, &v.b[0], sizeof(DCdouble)); } }
void dc_callvm_call_x86_sys_int80h_bsd(DCCallVM* in_self, DCpointer target) { DCCallVM_x86* self = (DCCallVM_x86*) in_self; dcCall_x86_sys_int80h_bsd( target, dcVecData(&self->mVecHead), dcVecSize(&self->mVecHead) ); }
DClonglong dc_callvm_call_arm32_thumb_dword(DCCallVM* in_self, DCpointer target) { DCCallVM_arm32_thumb* self = (DCCallVM_arm32_thumb*)in_self; return dcCall_arm32_thumb_dword(target, dcVecData(&self->mVecHead), dcVecSize(&self->mVecHead)); }
/* Call. */ void dc_callvm_call_arm32_thumb(DCCallVM* in_self, DCpointer target) { DCCallVM_arm32_thumb* self = (DCCallVM_arm32_thumb*)in_self; dcCall_arm32_thumb(target, dcVecData(&self->mVecHead), dcVecSize(&self->mVecHead)); }
void call(DCCallVM* in_p, DCpointer target) { DCCallVM_arm32_armhf* p = (DCCallVM_arm32_armhf*)in_p; dcCall_arm32_armhf(target, dcVecData(&p->mVecHead), dcVecSize(&p->mVecHead), &p->S[0]); }
/* Call. */ void dc_callvm_call_mips_eabi(DCCallVM* in_self, DCpointer target) { DCCallVM_mips_eabi* self = (DCCallVM_mips_eabi*)in_self; dcCall_mips_eabi(target, &self->mRegData, dcVecSize(&self->mVecHead), dcVecData(&self->mVecHead)); }
/* call: delegate to default call kernel */ static void dc_callvm_call_sparc(DCCallVM* in_self, DCpointer target) { DCCallVM_sparc* self = (DCCallVM_sparc*)in_self; dcCall_sparc(target, 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_call_x86_win32_this_ms(DCCallVM* in_self, DCpointer target) { DCCallVM_x86* self = (DCCallVM_x86*) in_self; dcCall_x86_win32_msthis( target, dcVecData(&self->mVecHead), dcVecSize(&self->mVecHead) ); }