aboutsummaryrefslogtreecommitdiff
path: root/src/lj_asm_arm.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_asm_arm.h')
-rw-r--r--src/lj_asm_arm.h29
1 files changed, 19 insertions, 10 deletions
diff --git a/src/lj_asm_arm.h b/src/lj_asm_arm.h
index ddf1480f..9b661eb7 100644
--- a/src/lj_asm_arm.h
+++ b/src/lj_asm_arm.h
@@ -1209,19 +1209,16 @@ dotypecheck:
1209static void asm_cnew(ASMState *as, IRIns *ir) 1209static void asm_cnew(ASMState *as, IRIns *ir)
1210{ 1210{
1211 CTState *cts = ctype_ctsG(J2G(as->J)); 1211 CTState *cts = ctype_ctsG(J2G(as->J));
1212 CTypeID ctypeid = (CTypeID)IR(ir->op1)->i; 1212 CTypeID id = (CTypeID)IR(ir->op1)->i;
1213 CTSize sz = (ir->o == IR_CNEWI || ir->op2 == REF_NIL) ? 1213 CTSize sz;
1214 lj_ctype_size(cts, ctypeid) : (CTSize)IR(ir->op2)->i; 1214 CTInfo info = lj_ctype_info(cts, id, &sz);
1215 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_mem_newgco]; 1215 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_mem_newgco];
1216 IRRef args[2]; 1216 IRRef args[4];
1217 RegSet allow = (RSET_GPR & ~RSET_SCRATCH); 1217 RegSet allow = (RSET_GPR & ~RSET_SCRATCH);
1218 RegSet drop = RSET_SCRATCH; 1218 RegSet drop = RSET_SCRATCH;
1219 lua_assert(sz != CTSIZE_INVALID); 1219 lua_assert(sz != CTSIZE_INVALID || (ir->o == IR_CNEW && ir->op2 != REF_NIL));
1220 1220
1221 args[0] = ASMREF_L; /* lua_State *L */
1222 args[1] = ASMREF_TMP1; /* MSize size */
1223 as->gcsteps++; 1221 as->gcsteps++;
1224
1225 if (ra_hasreg(ir->r)) 1222 if (ra_hasreg(ir->r))
1226 rset_clear(drop, ir->r); /* Dest reg handled below. */ 1223 rset_clear(drop, ir->r); /* Dest reg handled below. */
1227 ra_evictset(as, drop); 1224 ra_evictset(as, drop);
@@ -1243,16 +1240,28 @@ static void asm_cnew(ASMState *as, IRIns *ir)
1243 if (ofs == sizeof(GCcdata)) break; 1240 if (ofs == sizeof(GCcdata)) break;
1244 ofs -= 4; ir--; 1241 ofs -= 4; ir--;
1245 } 1242 }
1243 } else if (ir->op2 != REF_NIL) { /* Create VLA/VLS/aligned cdata. */
1244 ci = &lj_ir_callinfo[IRCALL_lj_cdata_newv];
1245 args[0] = ASMREF_L; /* lua_State *L */
1246 args[1] = ir->op1; /* CTypeID id */
1247 args[2] = ir->op2; /* CTSize sz */
1248 args[3] = ASMREF_TMP1; /* CTSize align */
1249 asm_gencall(as, ci, args);
1250 emit_loadi(as, ra_releasetmp(as, ASMREF_TMP1), (int32_t)ctype_align(info));
1251 return;
1246 } 1252 }
1253
1247 /* Initialize gct and ctypeid. lj_mem_newgco() already sets marked. */ 1254 /* Initialize gct and ctypeid. lj_mem_newgco() already sets marked. */
1248 { 1255 {
1249 uint32_t k = emit_isk12(ARMI_MOV, ctypeid); 1256 uint32_t k = emit_isk12(ARMI_MOV, id);
1250 Reg r = k ? RID_R1 : ra_allock(as, ctypeid, allow); 1257 Reg r = k ? RID_R1 : ra_allock(as, id, allow);
1251 emit_lso(as, ARMI_STRB, RID_TMP, RID_RET, offsetof(GCcdata, gct)); 1258 emit_lso(as, ARMI_STRB, RID_TMP, RID_RET, offsetof(GCcdata, gct));
1252 emit_lsox(as, ARMI_STRH, r, RID_RET, offsetof(GCcdata, ctypeid)); 1259 emit_lsox(as, ARMI_STRH, r, RID_RET, offsetof(GCcdata, ctypeid));
1253 emit_d(as, ARMI_MOV|ARMI_K12|~LJ_TCDATA, RID_TMP); 1260 emit_d(as, ARMI_MOV|ARMI_K12|~LJ_TCDATA, RID_TMP);
1254 if (k) emit_d(as, ARMI_MOV^k, RID_R1); 1261 if (k) emit_d(as, ARMI_MOV^k, RID_R1);
1255 } 1262 }
1263 args[0] = ASMREF_L; /* lua_State *L */
1264 args[1] = ASMREF_TMP1; /* MSize size */
1256 asm_gencall(as, ci, args); 1265 asm_gencall(as, ci, args);
1257 ra_allockreg(as, (int32_t)(sz+sizeof(GCcdata)), 1266 ra_allockreg(as, (int32_t)(sz+sizeof(GCcdata)),
1258 ra_releasetmp(as, ASMREF_TMP1)); 1267 ra_releasetmp(as, ASMREF_TMP1));