diff options
Diffstat (limited to 'src/lj_asm_ppc.h')
-rw-r--r-- | src/lj_asm_ppc.h | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/src/lj_asm_ppc.h b/src/lj_asm_ppc.h index 1cac6fa9..10cd79dd 100644 --- a/src/lj_asm_ppc.h +++ b/src/lj_asm_ppc.h | |||
@@ -1009,19 +1009,15 @@ dotypecheck: | |||
1009 | static void asm_cnew(ASMState *as, IRIns *ir) | 1009 | static void asm_cnew(ASMState *as, IRIns *ir) |
1010 | { | 1010 | { |
1011 | CTState *cts = ctype_ctsG(J2G(as->J)); | 1011 | CTState *cts = ctype_ctsG(J2G(as->J)); |
1012 | CTypeID ctypeid = (CTypeID)IR(ir->op1)->i; | 1012 | CTypeID id = (CTypeID)IR(ir->op1)->i; |
1013 | CTSize sz = (ir->o == IR_CNEWI || ir->op2 == REF_NIL) ? | 1013 | CTSize sz; |
1014 | lj_ctype_size(cts, ctypeid) : (CTSize)IR(ir->op2)->i; | 1014 | CTInfo info = lj_ctype_info(cts, id, &sz); |
1015 | const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_mem_newgco]; | 1015 | const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_mem_newgco]; |
1016 | IRRef args[2]; | 1016 | IRRef args[4]; |
1017 | RegSet allow = (RSET_GPR & ~RSET_SCRATCH); | ||
1018 | RegSet drop = RSET_SCRATCH; | 1017 | RegSet drop = RSET_SCRATCH; |
1019 | lua_assert(sz != CTSIZE_INVALID); | 1018 | lua_assert(sz != CTSIZE_INVALID || (ir->o == IR_CNEW && ir->op2 != REF_NIL)); |
1020 | 1019 | ||
1021 | args[0] = ASMREF_L; /* lua_State *L */ | ||
1022 | args[1] = ASMREF_TMP1; /* MSize size */ | ||
1023 | as->gcsteps++; | 1020 | as->gcsteps++; |
1024 | |||
1025 | if (ra_hasreg(ir->r)) | 1021 | if (ra_hasreg(ir->r)) |
1026 | rset_clear(drop, ir->r); /* Dest reg handled below. */ | 1022 | rset_clear(drop, ir->r); /* Dest reg handled below. */ |
1027 | ra_evictset(as, drop); | 1023 | ra_evictset(as, drop); |
@@ -1030,6 +1026,7 @@ static void asm_cnew(ASMState *as, IRIns *ir) | |||
1030 | 1026 | ||
1031 | /* Initialize immutable cdata object. */ | 1027 | /* Initialize immutable cdata object. */ |
1032 | if (ir->o == IR_CNEWI) { | 1028 | if (ir->o == IR_CNEWI) { |
1029 | RegSet allow = (RSET_GPR & ~RSET_SCRATCH); | ||
1033 | int32_t ofs = sizeof(GCcdata); | 1030 | int32_t ofs = sizeof(GCcdata); |
1034 | lua_assert(sz == 4 || sz == 8); | 1031 | lua_assert(sz == 4 || sz == 8); |
1035 | if (sz == 8) { | 1032 | if (sz == 8) { |
@@ -1043,12 +1040,24 @@ static void asm_cnew(ASMState *as, IRIns *ir) | |||
1043 | if (ofs == sizeof(GCcdata)) break; | 1040 | if (ofs == sizeof(GCcdata)) break; |
1044 | ofs -= 4; ir++; | 1041 | ofs -= 4; ir++; |
1045 | } | 1042 | } |
1043 | } else if (ir->op2 != REF_NIL) { /* Create VLA/VLS/aligned cdata. */ | ||
1044 | ci = &lj_ir_callinfo[IRCALL_lj_cdata_newv]; | ||
1045 | args[0] = ASMREF_L; /* lua_State *L */ | ||
1046 | args[1] = ir->op1; /* CTypeID id */ | ||
1047 | args[2] = ir->op2; /* CTSize sz */ | ||
1048 | args[3] = ASMREF_TMP1; /* CTSize align */ | ||
1049 | asm_gencall(as, ci, args); | ||
1050 | emit_loadi(as, ra_releasetmp(as, ASMREF_TMP1), (int32_t)ctype_align(info)); | ||
1051 | return; | ||
1046 | } | 1052 | } |
1053 | |||
1047 | /* Initialize gct and ctypeid. lj_mem_newgco() already sets marked. */ | 1054 | /* Initialize gct and ctypeid. lj_mem_newgco() already sets marked. */ |
1048 | emit_tai(as, PPCI_STB, RID_RET+1, RID_RET, offsetof(GCcdata, gct)); | 1055 | emit_tai(as, PPCI_STB, RID_RET+1, RID_RET, offsetof(GCcdata, gct)); |
1049 | emit_tai(as, PPCI_STH, RID_TMP, RID_RET, offsetof(GCcdata, ctypeid)); | 1056 | emit_tai(as, PPCI_STH, RID_TMP, RID_RET, offsetof(GCcdata, ctypeid)); |
1050 | emit_ti(as, PPCI_LI, RID_RET+1, ~LJ_TCDATA); | 1057 | emit_ti(as, PPCI_LI, RID_RET+1, ~LJ_TCDATA); |
1051 | emit_ti(as, PPCI_LI, RID_TMP, ctypeid); /* Lower 16 bit used. Sign-ext ok. */ | 1058 | emit_ti(as, PPCI_LI, RID_TMP, id); /* Lower 16 bit used. Sign-ext ok. */ |
1059 | args[0] = ASMREF_L; /* lua_State *L */ | ||
1060 | args[1] = ASMREF_TMP1; /* MSize size */ | ||
1052 | asm_gencall(as, ci, args); | 1061 | asm_gencall(as, ci, args); |
1053 | ra_allockreg(as, (int32_t)(sz+sizeof(GCcdata)), | 1062 | ra_allockreg(as, (int32_t)(sz+sizeof(GCcdata)), |
1054 | ra_releasetmp(as, ASMREF_TMP1)); | 1063 | ra_releasetmp(as, ASMREF_TMP1)); |