diff options
Diffstat (limited to 'src/lj_asm.c')
-rw-r--r-- | src/lj_asm.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c index 358ace6e..1304c180 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c | |||
@@ -1071,6 +1071,70 @@ static void asm_gcstep(ASMState *as, IRIns *ir) | |||
1071 | as->gcsteps = 0x80000000; /* Prevent implicit GC check further up. */ | 1071 | as->gcsteps = 0x80000000; /* Prevent implicit GC check further up. */ |
1072 | } | 1072 | } |
1073 | 1073 | ||
1074 | /* -- Buffer handling ----------------------------------------------------- */ | ||
1075 | |||
1076 | static void asm_bufhdr(ASMState *as, IRIns *ir) | ||
1077 | { | ||
1078 | if (ra_used(ir)) { | ||
1079 | Reg sb = ra_dest(as, ir, RSET_GPR); | ||
1080 | if (!(ir->op2 & IRBUFHDR_APPEND)) { | ||
1081 | Reg tmp = ra_scratch(as, rset_exclude(RSET_GPR, sb)); | ||
1082 | /* Passing ir isn't strictly correct, but it's an IRT_P32, too. */ | ||
1083 | emit_storeofs(as, ir, tmp, sb, offsetof(SBuf, p)); | ||
1084 | emit_loadofs(as, ir, tmp, sb, offsetof(SBuf, b)); | ||
1085 | } | ||
1086 | #if LJ_TARGET_X86ORX64 | ||
1087 | ra_left(as, sb, ir->op1); | ||
1088 | #else | ||
1089 | ra_leftov(as, sb, ir->op1); | ||
1090 | #endif | ||
1091 | } | ||
1092 | } | ||
1093 | |||
1094 | #if !LJ_TARGET_X86ORX64 | ||
1095 | static void asm_tvptr(ASMState *as, Reg dest, IRRef ref); | ||
1096 | #endif | ||
1097 | |||
1098 | static void asm_bufput(ASMState *as, IRIns *ir) | ||
1099 | { | ||
1100 | const CCallInfo *ci; | ||
1101 | IRRef args[2]; | ||
1102 | IRIns *ir2; | ||
1103 | if (!ra_used(ir)) return; | ||
1104 | args[0] = ir->op1; /* SBuf * */ | ||
1105 | args[1] = ir->op2; /* int, double, GCstr * */ | ||
1106 | ir2 = IR(ir->op2); | ||
1107 | if (irt_isstr(ir2->t)) { | ||
1108 | ci = &lj_ir_callinfo[IRCALL_lj_buf_putstr]; | ||
1109 | } else if (LJ_SOFTFP ? irt_type((ir2+1)->t)==IRT_SOFTFP : irt_isnum(ir2->t)) { | ||
1110 | ci = &lj_ir_callinfo[IRCALL_lj_buf_putnum]; | ||
1111 | args[1] = ASMREF_TMP1; | ||
1112 | } else { | ||
1113 | lua_assert(irt_isinteger(ir2->t)); | ||
1114 | ci = &lj_ir_callinfo[IRCALL_lj_buf_putint]; | ||
1115 | } | ||
1116 | asm_setupresult(as, ir, ci); /* SBuf * */ | ||
1117 | asm_gencall(as, ci, args); | ||
1118 | if (args[1] == ASMREF_TMP1) { | ||
1119 | #if LJ_TARGET_X86ORX64 | ||
1120 | emit_rmro(as, XO_LEA, ra_releasetmp(as, ASMREF_TMP1)|REX_64, | ||
1121 | RID_ESP, ra_spill(as, IR(ir->op2))); | ||
1122 | #else | ||
1123 | asm_tvptr(as, ra_releasetmp(as, ASMREF_TMP1), ir->op2); | ||
1124 | #endif | ||
1125 | } | ||
1126 | } | ||
1127 | |||
1128 | static void asm_bufstr(ASMState *as, IRIns *ir) | ||
1129 | { | ||
1130 | const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_buf_tostr]; | ||
1131 | IRRef args[1]; | ||
1132 | args[0] = ir->op2; /* SBuf *sb */ | ||
1133 | as->gcsteps++; | ||
1134 | asm_setupresult(as, ir, ci); /* GCstr * */ | ||
1135 | asm_gencall(as, ci, args); | ||
1136 | } | ||
1137 | |||
1074 | /* -- PHI and loop handling ----------------------------------------------- */ | 1138 | /* -- PHI and loop handling ----------------------------------------------- */ |
1075 | 1139 | ||
1076 | /* Break a PHI cycle by renaming to a free register (evict if needed). */ | 1140 | /* Break a PHI cycle by renaming to a free register (evict if needed). */ |
@@ -1724,6 +1788,7 @@ static void asm_setup_regsp(ASMState *as) | |||
1724 | if (REGARG_NUMGPR < 3 && as->evenspill < 3) | 1788 | if (REGARG_NUMGPR < 3 && as->evenspill < 3) |
1725 | as->evenspill = 3; /* lj_str_new and lj_tab_newkey need 3 args. */ | 1789 | as->evenspill = 3; /* lj_str_new and lj_tab_newkey need 3 args. */ |
1726 | case IR_TNEW: case IR_TDUP: case IR_CNEW: case IR_CNEWI: case IR_TOSTR: | 1790 | case IR_TNEW: case IR_TDUP: case IR_CNEW: case IR_CNEWI: case IR_TOSTR: |
1791 | case IR_BUFPUT: case IR_BUFSTR: | ||
1727 | ir->prev = REGSP_HINT(RID_RET); | 1792 | ir->prev = REGSP_HINT(RID_RET); |
1728 | if (inloop) | 1793 | if (inloop) |
1729 | as->modset = RSET_SCRATCH; | 1794 | as->modset = RSET_SCRATCH; |