Beispiel #1
0
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));
}
Beispiel #2
0
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));
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}
Beispiel #7
0
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));
}
Beispiel #10
0
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]);
}
Beispiel #11
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));
}
Beispiel #12
0
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));
  }
}
Beispiel #15
0
/* 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
  );
}
Beispiel #16
0
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));
}
Beispiel #17
0
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));
  }
}
Beispiel #19
0
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));
  }
}
Beispiel #21
0
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));
}
Beispiel #26
0
/* 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));
}
Beispiel #27
0
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));
}
Beispiel #28
0
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) );
}