aboutsummaryrefslogtreecommitdiff
path: root/src/lj_asm_x86.h
diff options
context:
space:
mode:
authorMike Pall <mike>2021-07-19 16:23:12 +0200
committerMike Pall <mike>2021-07-19 16:23:12 +0200
commit6df650fe3fa0e06d9645524918a9935e3a282156 (patch)
treebc3487e71038a93d0f44afb4fd68f92c0553cec0 /src/lj_asm_x86.h
parent71db0cf04357391beb01732af691a4df25298911 (diff)
downloadluajit-6df650fe3fa0e06d9645524918a9935e3a282156.tar.gz
luajit-6df650fe3fa0e06d9645524918a9935e3a282156.tar.bz2
luajit-6df650fe3fa0e06d9645524918a9935e3a282156.zip
String buffers, part 3a: Add IR_TMPREF for passing TValues to helpers.
Sponsored by fmad.io.
Diffstat (limited to 'src/lj_asm_x86.h')
-rw-r--r--src/lj_asm_x86.h79
1 files changed, 45 insertions, 34 deletions
diff --git a/src/lj_asm_x86.h b/src/lj_asm_x86.h
index 715e1535..b8abf9d6 100644
--- a/src/lj_asm_x86.h
+++ b/src/lj_asm_x86.h
@@ -216,6 +216,16 @@ static void asm_fuseahuref(ASMState *as, IRRef ref, RegSet allow)
216#endif 216#endif
217 } 217 }
218 break; 218 break;
219 case IR_TMPREF:
220#if LJ_GC64
221 as->mrm.ofs = (int32_t)dispofs(as, &J2G(as->J)->tmptv);
222 as->mrm.base = RID_DISPATCH;
223 as->mrm.idx = RID_NONE;
224#else
225 as->mrm.ofs = igcptr(&J2G(as->J)->tmptv);
226 as->mrm.base = as->mrm.idx = RID_NONE;
227#endif
228 return;
219 default: 229 default:
220 lj_assertA(ir->o == IR_HREF || ir->o == IR_NEWREF || ir->o == IR_UREFO || 230 lj_assertA(ir->o == IR_HREF || ir->o == IR_NEWREF || ir->o == IR_UREFO ||
221 ir->o == IR_KKPTR, 231 ir->o == IR_KKPTR,
@@ -1050,47 +1060,48 @@ static void asm_strto(ASMState *as, IRIns *ir)
1050/* -- Memory references --------------------------------------------------- */ 1060/* -- Memory references --------------------------------------------------- */
1051 1061
1052/* Get pointer to TValue. */ 1062/* Get pointer to TValue. */
1053static void asm_tvptr(ASMState *as, Reg dest, IRRef ref) 1063static void asm_tvptr(ASMState *as, Reg dest, IRRef ref, MSize mode)
1054{ 1064{
1055 IRIns *ir = IR(ref); 1065 if ((mode & IRTMPREF_IN1)) {
1056 if (irt_isnum(ir->t)) { 1066 IRIns *ir = IR(ref);
1057 /* For numbers use the constant itself or a spill slot as a TValue. */ 1067 if (irt_isnum(ir->t)) {
1058 if (irref_isk(ref)) 1068 if (irref_isk(ref) && !(mode & IRTMPREF_OUT1)) {
1059 emit_loada(as, dest, ir_knum(ir)); 1069 /* Use the number constant itself as a TValue. */
1060 else 1070 emit_loada(as, dest, ir_knum(ir));
1061 emit_rmro(as, XO_LEA, dest|REX_64, RID_ESP, ra_spill(as, ir)); 1071 return;
1062 } else { 1072 }
1063 /* Otherwise use g->tmptv to hold the TValue. */ 1073 emit_rmro(as, XO_MOVSDto, ra_alloc1(as, ref, RSET_FPR), dest, 0);
1064#if LJ_GC64
1065 if (irref_isk(ref)) {
1066 TValue k;
1067 lj_ir_kvalue(as->J->L, &k, ir);
1068 emit_movmroi(as, dest, 4, k.u32.hi);
1069 emit_movmroi(as, dest, 0, k.u32.lo);
1070 } else { 1074 } else {
1071 /* TODO: 64 bit store + 32 bit load-modify-store is suboptimal. */ 1075#if LJ_GC64
1072 Reg src = ra_alloc1(as, ref, rset_exclude(RSET_GPR, dest)); 1076 if (irref_isk(ref)) {
1073 if (irt_is64(ir->t)) { 1077 TValue k;
1074 emit_u32(as, irt_toitype(ir->t) << 15); 1078 lj_ir_kvalue(as->J->L, &k, ir);
1075 emit_rmro(as, XO_ARITHi, XOg_OR, dest, 4); 1079 emit_movmroi(as, dest, 4, k.u32.hi);
1080 emit_movmroi(as, dest, 0, k.u32.lo);
1076 } else { 1081 } else {
1077 /* Currently, no caller passes integers that might end up here. */ 1082 /* TODO: 64 bit store + 32 bit load-modify-store is suboptimal. */
1078 emit_movmroi(as, dest, 4, (irt_toitype(ir->t) << 15)); 1083 Reg src = ra_alloc1(as, ref, rset_exclude(RSET_GPR, dest));
1084 if (irt_is64(ir->t)) {
1085 emit_u32(as, irt_toitype(ir->t) << 15);
1086 emit_rmro(as, XO_ARITHi, XOg_OR, dest, 4);
1087 } else {
1088 emit_movmroi(as, dest, 4, (irt_toitype(ir->t) << 15));
1089 }
1090 emit_movtomro(as, REX_64IR(ir, src), dest, 0);
1079 } 1091 }
1080 emit_movtomro(as, REX_64IR(ir, src), dest, 0);
1081 }
1082#else 1092#else
1083 if (!irref_isk(ref)) { 1093 if (!irref_isk(ref)) {
1084 Reg src = ra_alloc1(as, ref, rset_exclude(RSET_GPR, dest)); 1094 Reg src = ra_alloc1(as, ref, rset_exclude(RSET_GPR, dest));
1085 emit_movtomro(as, REX_64IR(ir, src), dest, 0); 1095 emit_movtomro(as, REX_64IR(ir, src), dest, 0);
1086 } else if (!irt_ispri(ir->t)) { 1096 } else if (!irt_ispri(ir->t)) {
1087 emit_movmroi(as, dest, 0, ir->i); 1097 emit_movmroi(as, dest, 0, ir->i);
1088 } 1098 }
1089 if (!(LJ_64 && irt_islightud(ir->t))) 1099 if (!(LJ_64 && irt_islightud(ir->t)))
1090 emit_movmroi(as, dest, 4, irt_toitype(ir->t)); 1100 emit_movmroi(as, dest, 4, irt_toitype(ir->t));
1091#endif 1101#endif
1092 emit_loada(as, dest, &J2G(as->J)->tmptv); 1102 }
1093 } 1103 }
1104 emit_loada(as, dest, &J2G(as->J)->tmptv); /* g->tmptv holds the TValue(s). */
1094} 1105}
1095 1106
1096static void asm_aref(ASMState *as, IRIns *ir) 1107static void asm_aref(ASMState *as, IRIns *ir)