diff options
Diffstat (limited to 'src/lj_asm_mips.h')
-rw-r--r-- | src/lj_asm_mips.h | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/src/lj_asm_mips.h b/src/lj_asm_mips.h index fe7d55d3..3d061eb4 100644 --- a/src/lj_asm_mips.h +++ b/src/lj_asm_mips.h | |||
@@ -975,19 +975,15 @@ dotypecheck: | |||
975 | static void asm_cnew(ASMState *as, IRIns *ir) | 975 | static void asm_cnew(ASMState *as, IRIns *ir) |
976 | { | 976 | { |
977 | CTState *cts = ctype_ctsG(J2G(as->J)); | 977 | CTState *cts = ctype_ctsG(J2G(as->J)); |
978 | CTypeID ctypeid = (CTypeID)IR(ir->op1)->i; | 978 | CTypeID id = (CTypeID)IR(ir->op1)->i; |
979 | CTSize sz = (ir->o == IR_CNEWI || ir->op2 == REF_NIL) ? | 979 | CTSize sz; |
980 | lj_ctype_size(cts, ctypeid) : (CTSize)IR(ir->op2)->i; | 980 | CTInfo info = lj_ctype_info(cts, id, &sz); |
981 | const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_mem_newgco]; | 981 | const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_mem_newgco]; |
982 | IRRef args[2]; | 982 | IRRef args[4]; |
983 | RegSet allow = (RSET_GPR & ~RSET_SCRATCH); | ||
984 | RegSet drop = RSET_SCRATCH; | 983 | RegSet drop = RSET_SCRATCH; |
985 | lua_assert(sz != CTSIZE_INVALID); | 984 | lua_assert(sz != CTSIZE_INVALID || (ir->o == IR_CNEW && ir->op2 != REF_NIL)); |
986 | 985 | ||
987 | args[0] = ASMREF_L; /* lua_State *L */ | ||
988 | args[1] = ASMREF_TMP1; /* MSize size */ | ||
989 | as->gcsteps++; | 986 | as->gcsteps++; |
990 | |||
991 | if (ra_hasreg(ir->r)) | 987 | if (ra_hasreg(ir->r)) |
992 | rset_clear(drop, ir->r); /* Dest reg handled below. */ | 988 | rset_clear(drop, ir->r); /* Dest reg handled below. */ |
993 | ra_evictset(as, drop); | 989 | ra_evictset(as, drop); |
@@ -996,6 +992,7 @@ static void asm_cnew(ASMState *as, IRIns *ir) | |||
996 | 992 | ||
997 | /* Initialize immutable cdata object. */ | 993 | /* Initialize immutable cdata object. */ |
998 | if (ir->o == IR_CNEWI) { | 994 | if (ir->o == IR_CNEWI) { |
995 | RegSet allow = (RSET_GPR & ~RSET_SCRATCH); | ||
999 | int32_t ofs = sizeof(GCcdata); | 996 | int32_t ofs = sizeof(GCcdata); |
1000 | lua_assert(sz == 4 || sz == 8); | 997 | lua_assert(sz == 4 || sz == 8); |
1001 | if (sz == 8) { | 998 | if (sz == 8) { |
@@ -1010,12 +1007,24 @@ static void asm_cnew(ASMState *as, IRIns *ir) | |||
1010 | if (ofs == sizeof(GCcdata)) break; | 1007 | if (ofs == sizeof(GCcdata)) break; |
1011 | ofs -= 4; if (LJ_BE) ir++; else ir--; | 1008 | ofs -= 4; if (LJ_BE) ir++; else ir--; |
1012 | } | 1009 | } |
1010 | } else if (ir->op2 != REF_NIL) { /* Create VLA/VLS/aligned cdata. */ | ||
1011 | ci = &lj_ir_callinfo[IRCALL_lj_cdata_newv]; | ||
1012 | args[0] = ASMREF_L; /* lua_State *L */ | ||
1013 | args[1] = ir->op1; /* CTypeID id */ | ||
1014 | args[2] = ir->op2; /* CTSize sz */ | ||
1015 | args[3] = ASMREF_TMP1; /* CTSize align */ | ||
1016 | asm_gencall(as, ci, args); | ||
1017 | emit_loadi(as, ra_releasetmp(as, ASMREF_TMP1), (int32_t)ctype_align(info)); | ||
1018 | return; | ||
1013 | } | 1019 | } |
1020 | |||
1014 | /* Initialize gct and ctypeid. lj_mem_newgco() already sets marked. */ | 1021 | /* Initialize gct and ctypeid. lj_mem_newgco() already sets marked. */ |
1015 | emit_tsi(as, MIPSI_SB, RID_RET+1, RID_RET, offsetof(GCcdata, gct)); | 1022 | emit_tsi(as, MIPSI_SB, RID_RET+1, RID_RET, offsetof(GCcdata, gct)); |
1016 | emit_tsi(as, MIPSI_SH, RID_TMP, RID_RET, offsetof(GCcdata, ctypeid)); | 1023 | emit_tsi(as, MIPSI_SH, RID_TMP, RID_RET, offsetof(GCcdata, ctypeid)); |
1017 | emit_ti(as, MIPSI_LI, RID_RET+1, ~LJ_TCDATA); | 1024 | emit_ti(as, MIPSI_LI, RID_RET+1, ~LJ_TCDATA); |
1018 | emit_ti(as, MIPSI_LI, RID_TMP, ctypeid); /* Lower 16 bit used. Sign-ext ok. */ | 1025 | emit_ti(as, MIPSI_LI, RID_TMP, id); /* Lower 16 bit used. Sign-ext ok. */ |
1026 | args[0] = ASMREF_L; /* lua_State *L */ | ||
1027 | args[1] = ASMREF_TMP1; /* MSize size */ | ||
1019 | asm_gencall(as, ci, args); | 1028 | asm_gencall(as, ci, args); |
1020 | ra_allockreg(as, (int32_t)(sz+sizeof(GCcdata)), | 1029 | ra_allockreg(as, (int32_t)(sz+sizeof(GCcdata)), |
1021 | ra_releasetmp(as, ASMREF_TMP1)); | 1030 | ra_releasetmp(as, ASMREF_TMP1)); |
@@ -1197,11 +1206,16 @@ static void asm_arithov(ASMState *as, IRIns *ir) | |||
1197 | 1206 | ||
1198 | static void asm_mulov(ASMState *as, IRIns *ir) | 1207 | static void asm_mulov(ASMState *as, IRIns *ir) |
1199 | { | 1208 | { |
1200 | #if LJ_DUALNUM | 1209 | Reg dest = ra_dest(as, ir, RSET_GPR); |
1201 | #error "NYI: MULOV" | 1210 | Reg tmp, right, left = ra_alloc2(as, ir, RSET_GPR); |
1202 | #else | 1211 | right = (left >> 8); left &= 255; |
1203 | UNUSED(as); UNUSED(ir); lua_assert(0); /* Unused in single-number mode. */ | 1212 | tmp = ra_scratch(as, rset_exclude(rset_exclude(rset_exclude(RSET_GPR, left), |
1204 | #endif | 1213 | right), dest)); |
1214 | asm_guard(as, MIPSI_BNE, RID_TMP, tmp); | ||
1215 | emit_dta(as, MIPSI_SRA, RID_TMP, dest, 31); | ||
1216 | emit_dst(as, MIPSI_MFHI, tmp, 0, 0); | ||
1217 | emit_dst(as, MIPSI_MFLO, dest, 0, 0); | ||
1218 | emit_dst(as, MIPSI_MULT, 0, left, right); | ||
1205 | } | 1219 | } |
1206 | 1220 | ||
1207 | #if LJ_HASFFI | 1221 | #if LJ_HASFFI |