]> git.ipfire.org Git - thirdparty/LuaJIT.git/commitdiff
Merge branch 'master' into v2.1
authorMike Pall <mike>
Thu, 16 May 2013 18:07:53 +0000 (20:07 +0200)
committerMike Pall <mike>
Thu, 16 May 2013 18:07:53 +0000 (20:07 +0200)
1  2 
src/lj_asm.c
src/lj_asm_arm.h
src/lj_asm_mips.h
src/lj_asm_ppc.h
src/lj_asm_x86.h

diff --cc src/lj_asm.c
index a1e92003a9213334e10e79d2d9ae46d1f8f67f31,316e81d6a857e1b325b18652f61a6427b3e40ab9..7542c77c101292ef5e95cc412b0e3b87b79bce17
@@@ -1033,253 -1065,6 +1033,253 @@@ static void asm_gcstep(ASMState *as, IR
    as->gcsteps = 0x80000000;  /* Prevent implicit GC check further up. */
  }
  
-   lua_assert(n <= CCI_NARGS_MAX);
 +/* -- Buffer operations --------------------------------------------------- */
 +
 +static void asm_tvptr(ASMState *as, Reg dest, IRRef ref);
 +
 +static void asm_bufhdr(ASMState *as, IRIns *ir)
 +{
 +  Reg sb = ra_dest(as, ir, RSET_GPR);
 +  if ((ir->op2 & IRBUFHDR_APPEND)) {
 +    /* Rematerialize const buffer pointer instead of likely spill. */
 +    IRIns *irp = IR(ir->op1);
 +    if (!(ra_hasreg(irp->r) || irp == ir-1 ||
 +        (irp == ir-2 && !ra_used(ir-1)))) {
 +      while (!(irp->o == IR_BUFHDR && !(irp->op2 & IRBUFHDR_APPEND)))
 +      irp = IR(irp->op1);
 +      if (irref_isk(irp->op1)) {
 +      ra_weak(as, ra_allocref(as, ir->op1, RSET_GPR));
 +      ir = irp;
 +      }
 +    }
 +  } else {
 +    Reg tmp = ra_scratch(as, rset_exclude(RSET_GPR, sb));
 +    /* Passing ir isn't strictly correct, but it's an IRT_P32, too. */
 +    emit_storeofs(as, ir, tmp, sb, offsetof(SBuf, p));
 +    emit_loadofs(as, ir, tmp, sb, offsetof(SBuf, b));
 +  }
 +#if LJ_TARGET_X86ORX64
 +  ra_left(as, sb, ir->op1);
 +#else
 +  ra_leftov(as, sb, ir->op1);
 +#endif
 +}
 +
 +static void asm_bufput(ASMState *as, IRIns *ir)
 +{
 +  const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_buf_putstr];
 +  IRRef args[3];
 +  IRIns *irs;
 +  int kchar = -1;
 +  args[0] = ir->op1;  /* SBuf * */
 +  args[1] = ir->op2;  /* GCstr * */
 +  irs = IR(ir->op2);
 +  lua_assert(irt_isstr(irs->t));
 +  if (irs->o == IR_KGC) {
 +    GCstr *s = ir_kstr(irs);
 +    if (s->len == 1) {  /* Optimize put of single-char string constant. */
 +      kchar = strdata(s)[0];
 +      args[1] = ASMREF_TMP1;  /* int, truncated to char */
 +      ci = &lj_ir_callinfo[IRCALL_lj_buf_putchar];
 +    }
 +  } else if (mayfuse(as, ir->op2) && ra_noreg(irs->r)) {
 +    if (irs->o == IR_TOSTR) {  /* Fuse number to string conversions. */
 +      if (irs->op2 == IRTOSTR_NUM) {
 +      args[1] = ASMREF_TMP1;  /* TValue * */
 +      ci = &lj_ir_callinfo[IRCALL_lj_strfmt_putnum];
 +      } else {
 +      lua_assert(irt_isinteger(IR(irs->op1)->t));
 +      args[1] = irs->op1;  /* int */
 +      if (irs->op2 == IRTOSTR_INT)
 +        ci = &lj_ir_callinfo[IRCALL_lj_strfmt_putint];
 +      else
 +        ci = &lj_ir_callinfo[IRCALL_lj_buf_putchar];
 +      }
 +    } else if (irs->o == IR_SNEW) {  /* Fuse string allocation. */
 +      args[1] = irs->op1;  /* const void * */
 +      args[2] = irs->op2;  /* MSize */
 +      ci = &lj_ir_callinfo[IRCALL_lj_buf_putmem];
 +    }
 +  }
 +  asm_setupresult(as, ir, ci);  /* SBuf * */
 +  asm_gencall(as, ci, args);
 +  if (args[1] == ASMREF_TMP1) {
 +    Reg tmp = ra_releasetmp(as, ASMREF_TMP1);
 +    if (kchar == -1)
 +      asm_tvptr(as, tmp, irs->op1);
 +    else
 +      ra_allockreg(as, kchar, tmp);
 +  }
 +}
 +
 +static void asm_bufstr(ASMState *as, IRIns *ir)
 +{
 +  const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_buf_tostr];
 +  IRRef args[1];
 +  args[0] = ir->op1;  /* SBuf *sb */
 +  as->gcsteps++;
 +  asm_setupresult(as, ir, ci);  /* GCstr * */
 +  asm_gencall(as, ci, args);
 +}
 +
 +/* -- Type conversions ---------------------------------------------------- */
 +
 +static void asm_tostr(ASMState *as, IRIns *ir)
 +{
 +  const CCallInfo *ci;
 +  IRRef args[2];
 +  args[0] = ASMREF_L;
 +  as->gcsteps++;
 +  if (ir->op2 == IRTOSTR_NUM) {
 +    args[1] = ASMREF_TMP1;  /* cTValue * */
 +    ci = &lj_ir_callinfo[IRCALL_lj_strfmt_num];
 +  } else {
 +    args[1] = ir->op1;  /* int32_t k */
 +    if (ir->op2 == IRTOSTR_INT)
 +      ci = &lj_ir_callinfo[IRCALL_lj_strfmt_int];
 +    else
 +      ci = &lj_ir_callinfo[IRCALL_lj_strfmt_char];
 +  }
 +  asm_setupresult(as, ir, ci);  /* GCstr * */
 +  asm_gencall(as, ci, args);
 +  if (ir->op2 == IRTOSTR_NUM)
 +    asm_tvptr(as, ra_releasetmp(as, ASMREF_TMP1), ir->op1);
 +}
 +
 +#if LJ_32 && LJ_HASFFI && !LJ_SOFTFP && !LJ_TARGET_X86
 +static void asm_conv64(ASMState *as, IRIns *ir)
 +{
 +  IRType st = (IRType)((ir-1)->op2 & IRCONV_SRCMASK);
 +  IRType dt = (((ir-1)->op2 & IRCONV_DSTMASK) >> IRCONV_DSH);
 +  IRCallID id;
 +  IRRef args[2];
 +  lua_assert((ir-1)->o == IR_CONV && ir->o == IR_HIOP);
 +  args[LJ_BE] = (ir-1)->op1;
 +  args[LJ_LE] = ir->op1;
 +  if (st == IRT_NUM || st == IRT_FLOAT) {
 +    id = IRCALL_fp64_d2l + ((st == IRT_FLOAT) ? 2 : 0) + (dt - IRT_I64);
 +    ir--;
 +  } else {
 +    id = IRCALL_fp64_l2d + ((dt == IRT_FLOAT) ? 2 : 0) + (st - IRT_I64);
 +  }
 +  {
 +#if LJ_TARGET_ARM && !LJ_ABI_SOFTFP
 +    CCallInfo cim = lj_ir_callinfo[id], *ci = &cim;
 +    cim.flags |= CCI_VARARG;  /* These calls don't use the hard-float ABI! */
 +#else
 +    const CCallInfo *ci = &lj_ir_callinfo[id];
 +#endif
 +    asm_setupresult(as, ir, ci);
 +    asm_gencall(as, ci, args);
 +  }
 +}
 +#endif
 +
 +/* -- Memory references --------------------------------------------------- */
 +
 +static void asm_newref(ASMState *as, IRIns *ir)
 +{
 +  const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_tab_newkey];
 +  IRRef args[3];
 +  if (ir->r == RID_SINK)
 +    return;
 +  args[0] = ASMREF_L;     /* lua_State *L */
 +  args[1] = ir->op1;      /* GCtab *t     */
 +  args[2] = ASMREF_TMP1;  /* cTValue *key */
 +  asm_setupresult(as, ir, ci);  /* TValue * */
 +  asm_gencall(as, ci, args);
 +  asm_tvptr(as, ra_releasetmp(as, ASMREF_TMP1), ir->op2);
 +}
 +
 +/* -- Calls --------------------------------------------------------------- */
 +
 +/* Collect arguments from CALL* and CARG instructions. */
 +static void asm_collectargs(ASMState *as, IRIns *ir,
 +                          const CCallInfo *ci, IRRef *args)
 +{
 +  uint32_t n = CCI_XNARGS(ci);
++  lua_assert(n <= CCI_NARGS_MAX*2);  /* Account for split args. */
 +  if ((ci->flags & CCI_L)) { *args++ = ASMREF_L; n--; }
 +  while (n-- > 1) {
 +    ir = IR(ir->op1);
 +    lua_assert(ir->o == IR_CARG);
 +    args[n] = ir->op2 == REF_NIL ? 0 : ir->op2;
 +  }
 +  args[0] = ir->op1 == REF_NIL ? 0 : ir->op1;
 +  lua_assert(IR(ir->op1)->o != IR_CARG);
 +}
 +
 +/* Reconstruct CCallInfo flags for CALLX*. */
 +static uint32_t asm_callx_flags(ASMState *as, IRIns *ir)
 +{
 +  uint32_t nargs = 0;
 +  if (ir->op1 != REF_NIL) {  /* Count number of arguments first. */
 +    IRIns *ira = IR(ir->op1);
 +    nargs++;
 +    while (ira->o == IR_CARG) { nargs++; ira = IR(ira->op1); }
 +  }
 +#if LJ_HASFFI
 +  if (IR(ir->op2)->o == IR_CARG) {  /* Copy calling convention info. */
 +    CTypeID id = (CTypeID)IR(IR(ir->op2)->op2)->i;
 +    CType *ct = ctype_get(ctype_ctsG(J2G(as->J)), id);
 +    nargs |= ((ct->info & CTF_VARARG) ? CCI_VARARG : 0);
 +#if LJ_TARGET_X86
 +    nargs |= (ctype_cconv(ct->info) << CCI_CC_SHIFT);
 +#endif
 +  }
 +#endif
 +  return (nargs | (ir->t.irt << CCI_OTSHIFT));
 +}
 +
 +static void asm_callid(ASMState *as, IRIns *ir, IRCallID id)
 +{
 +  const CCallInfo *ci = &lj_ir_callinfo[id];
 +  IRRef args[2];
 +  args[0] = ir->op1;
 +  args[1] = ir->op2;
 +  asm_setupresult(as, ir, ci);
 +  asm_gencall(as, ci, args);
 +}
 +
 +static void asm_call(ASMState *as, IRIns *ir)
 +{
 +  IRRef args[CCI_NARGS_MAX];
 +  const CCallInfo *ci = &lj_ir_callinfo[ir->op2];
 +  asm_collectargs(as, ir, ci, args);
 +  asm_setupresult(as, ir, ci);
 +  asm_gencall(as, ci, args);
 +}
 +
 +#if !LJ_SOFTFP
 +static void asm_fppow(ASMState *as, IRIns *ir, IRRef lref, IRRef rref);
 +
 +#if !LJ_TARGET_X86ORX64
 +static void asm_fppow(ASMState *as, IRIns *ir, IRRef lref, IRRef rref)
 +{
 +  const CCallInfo *ci = &lj_ir_callinfo[IRCALL_pow];
 +  IRRef args[2];
 +  args[0] = lref;
 +  args[1] = rref;
 +  asm_setupresult(as, ir, ci);
 +  asm_gencall(as, ci, args);
 +}
 +#endif
 +
 +static int asm_fpjoin_pow(ASMState *as, IRIns *ir)
 +{
 +  IRIns *irp = IR(ir->op1);
 +  if (irp == ir-1 && irp->o == IR_MUL && !ra_used(irp)) {
 +    IRIns *irpp = IR(irp->op1);
 +    if (irpp == ir-2 && irpp->o == IR_FPMATH &&
 +      irpp->op2 == IRFPM_LOG2 && !ra_used(irpp)) {
 +      asm_fppow(as, ir, irpp->op1, irp->op2);
 +      return 1;
 +    }
 +  }
 +  return 0;
 +}
 +#endif
 +
  /* -- PHI and loop handling ----------------------------------------------- */
  
  /* Break a PHI cycle by renaming to a free register (evict if needed). */
index 1e024dcd9fb8733a6f3d8c9bbd1c40bb9b355792,a66573c0a3bc0789a71270d1f3101a3446070c91..ddf1480f7b8162fa85b11ae405e48d91be9efd89
@@@ -453,9 -453,18 +453,9 @@@ static void asm_setupresult(ASMState *a
    UNUSED(ci);
  }
  
 -static void asm_call(ASMState *as, IRIns *ir)
 -{
 -  IRRef args[CCI_NARGS_MAX];
 -  const CCallInfo *ci = &lj_ir_callinfo[ir->op2];
 -  asm_collectargs(as, ir, ci, args);
 -  asm_setupresult(as, ir, ci);
 -  asm_gencall(as, ci, args);
 -}
 -
  static void asm_callx(ASMState *as, IRIns *ir)
  {
-   IRRef args[CCI_NARGS_MAX];
+   IRRef args[CCI_NARGS_MAX*2];
    CCallInfo ci;
    IRRef func;
    IRIns *irf;
@@@ -2132,8 -2295,8 +2132,8 @@@ static void asm_tail_prep(ASMState *as
  /* Ensure there are enough stack slots for call arguments. */
  static Reg asm_setup_call_slots(ASMState *as, IRIns *ir, const CCallInfo *ci)
  {
-   IRRef args[CCI_NARGS_MAX];
+   IRRef args[CCI_NARGS_MAX*2];
 -  uint32_t i, nargs = (int)CCI_NARGS(ci);
 +  uint32_t i, nargs = CCI_XNARGS(ci);
    int nslots = 0, ngpr = REGARG_NUMGPR, nfpr = REGARG_NUMFPR, fprodd = 0;
    asm_collectargs(as, ir, ci, args);
    for (i = 0; i < nargs; i++) {
index 5070a7a29d1d0509f3b68ab718bc4adf44a9d5da,9fe7c9c3348a5de3508f6ff5f8055851b6a6fb4f..fe7d55d3d83cd53a136d9f4ccf0bdc2909826d2a
@@@ -326,9 -326,18 +326,9 @@@ static void asm_setupresult(ASMState *a
    }
  }
  
 -static void asm_call(ASMState *as, IRIns *ir)
 -{
 -  IRRef args[CCI_NARGS_MAX];
 -  const CCallInfo *ci = &lj_ir_callinfo[ir->op2];
 -  asm_collectargs(as, ir, ci, args);
 -  asm_setupresult(as, ir, ci);
 -  asm_gencall(as, ci, args);
 -}
 -
  static void asm_callx(ASMState *as, IRIns *ir)
  {
-   IRRef args[CCI_NARGS_MAX];
+   IRRef args[CCI_NARGS_MAX*2];
    CCallInfo ci;
    IRRef func;
    IRIns *irf;
@@@ -1725,8 -1894,8 +1725,8 @@@ static void asm_tail_prep(ASMState *as
  /* Ensure there are enough stack slots for call arguments. */
  static Reg asm_setup_call_slots(ASMState *as, IRIns *ir, const CCallInfo *ci)
  {
-   IRRef args[CCI_NARGS_MAX];
+   IRRef args[CCI_NARGS_MAX*2];
 -  uint32_t i, nargs = (int)CCI_NARGS(ci);
 +  uint32_t i, nargs = CCI_XNARGS(ci);
    int nslots = 4, ngpr = REGARG_NUMGPR, nfpr = REGARG_NUMFPR;
    asm_collectargs(as, ir, ci, args);
    for (i = 0; i < nargs; i++) {
index a4a355470fd30ae3caaf856c559c77af08860457,651fa3187a15368986fbc4869d5e3d3e7c024ed8..1cac6fa98820a69d2113d10838e67bc748691949
@@@ -329,9 -329,18 +329,9 @@@ static void asm_setupresult(ASMState *a
    }
  }
  
 -static void asm_call(ASMState *as, IRIns *ir)
 -{
 -  IRRef args[CCI_NARGS_MAX];
 -  const CCallInfo *ci = &lj_ir_callinfo[ir->op2];
 -  asm_collectargs(as, ir, ci, args);
 -  asm_setupresult(as, ir, ci);
 -  asm_gencall(as, ci, args);
 -}
 -
  static void asm_callx(ASMState *as, IRIns *ir)
  {
-   IRRef args[CCI_NARGS_MAX];
+   IRRef args[CCI_NARGS_MAX*2];
    CCallInfo ci;
    IRRef func;
    IRIns *irf;
@@@ -1916,8 -2092,8 +1916,8 @@@ static void asm_tail_prep(ASMState *as
  /* Ensure there are enough stack slots for call arguments. */
  static Reg asm_setup_call_slots(ASMState *as, IRIns *ir, const CCallInfo *ci)
  {
-   IRRef args[CCI_NARGS_MAX];
+   IRRef args[CCI_NARGS_MAX*2];
 -  uint32_t i, nargs = (int)CCI_NARGS(ci);
 +  uint32_t i, nargs = CCI_XNARGS(ci);
    int nslots = 2, ngpr = REGARG_NUMGPR, nfpr = REGARG_NUMFPR;
    asm_collectargs(as, ir, ci, args);
    for (i = 0; i < nargs; i++)
Simple merge