diff options
Diffstat (limited to '')
-rw-r--r-- | src/lj_emit_mips.h | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/src/lj_emit_mips.h b/src/lj_emit_mips.h index 0dea78ce..fdebe94b 100644 --- a/src/lj_emit_mips.h +++ b/src/lj_emit_mips.h | |||
@@ -152,16 +152,18 @@ static void emit_jmp(ASMState *as, MCode *target) | |||
152 | emit_branch(as, MIPSI_B, RID_ZERO, RID_ZERO, (target)); | 152 | emit_branch(as, MIPSI_B, RID_ZERO, RID_ZERO, (target)); |
153 | } | 153 | } |
154 | 154 | ||
155 | static void emit_call(ASMState *as, void *target) | 155 | static void emit_call(ASMState *as, void *target, int needcfa) |
156 | { | 156 | { |
157 | MCode *p = as->mcp; | 157 | MCode *p = as->mcp; |
158 | *--p = MIPSI_NOP; | 158 | *--p = MIPSI_NOP; |
159 | if ((((uintptr_t)target ^ (uintptr_t)p) >> 28) == 0) | 159 | if ((((uintptr_t)target ^ (uintptr_t)p) >> 28) == 0) { |
160 | *--p = MIPSI_JAL | (((uintptr_t)target >>2) & 0x03ffffffu); | 160 | *--p = MIPSI_JAL | (((uintptr_t)target >>2) & 0x03ffffffu); |
161 | else /* Target out of range: need indirect call. */ | 161 | } else { /* Target out of range: need indirect call. */ |
162 | *--p = MIPSI_JALR | MIPSF_S(RID_CFUNCADDR); | 162 | *--p = MIPSI_JALR | MIPSF_S(RID_CFUNCADDR); |
163 | needcfa = 1; | ||
164 | } | ||
163 | as->mcp = p; | 165 | as->mcp = p; |
164 | ra_allockreg(as, i32ptr(target), RID_CFUNCADDR); | 166 | if (needcfa) ra_allockreg(as, i32ptr(target), RID_CFUNCADDR); |
165 | } | 167 | } |
166 | 168 | ||
167 | /* -- Emit generic operations --------------------------------------------- */ | 169 | /* -- Emit generic operations --------------------------------------------- */ |
@@ -178,24 +180,24 @@ static void emit_movrr(ASMState *as, IRIns *ir, Reg dst, Reg src) | |||
178 | emit_fg(as, irt_isnum(ir->t) ? MIPSI_MOV_D : MIPSI_MOV_S, dst, src); | 180 | emit_fg(as, irt_isnum(ir->t) ? MIPSI_MOV_D : MIPSI_MOV_S, dst, src); |
179 | } | 181 | } |
180 | 182 | ||
181 | /* Generic load of register from stack slot. */ | 183 | /* Generic load of register with base and (small) offset address. */ |
182 | static void emit_spload(ASMState *as, IRIns *ir, Reg r, int32_t ofs) | 184 | static void emit_loadofs(ASMState *as, IRIns *ir, Reg r, Reg base, int32_t ofs) |
183 | { | 185 | { |
184 | if (r < RID_MAX_GPR) | 186 | if (r < RID_MAX_GPR) |
185 | emit_tsi(as, MIPSI_LW, r, RID_SP, ofs); | 187 | emit_tsi(as, MIPSI_LW, r, base, ofs); |
186 | else | 188 | else |
187 | emit_tsi(as, irt_isnum(ir->t) ? MIPSI_LDC1 : MIPSI_LWC1, | 189 | emit_tsi(as, irt_isnum(ir->t) ? MIPSI_LDC1 : MIPSI_LWC1, |
188 | (r & 31), RID_SP, ofs); | 190 | (r & 31), base, ofs); |
189 | } | 191 | } |
190 | 192 | ||
191 | /* Generic store of register to stack slot. */ | 193 | /* Generic store of register with base and (small) offset address. */ |
192 | static void emit_spstore(ASMState *as, IRIns *ir, Reg r, int32_t ofs) | 194 | static void emit_storeofs(ASMState *as, IRIns *ir, Reg r, Reg base, int32_t ofs) |
193 | { | 195 | { |
194 | if (r < RID_MAX_GPR) | 196 | if (r < RID_MAX_GPR) |
195 | emit_tsi(as, MIPSI_SW, r, RID_SP, ofs); | 197 | emit_tsi(as, MIPSI_SW, r, base, ofs); |
196 | else | 198 | else |
197 | emit_tsi(as, irt_isnum(ir->t) ? MIPSI_SDC1 : MIPSI_SWC1, | 199 | emit_tsi(as, irt_isnum(ir->t) ? MIPSI_SDC1 : MIPSI_SWC1, |
198 | (r&31), RID_SP, ofs); | 200 | (r&31), base, ofs); |
199 | } | 201 | } |
200 | 202 | ||
201 | /* Add offset to pointer. */ | 203 | /* Add offset to pointer. */ |