aboutsummaryrefslogtreecommitdiff
path: root/src/lj_emit_arm.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_emit_arm.h')
-rw-r--r--src/lj_emit_arm.h55
1 files changed, 53 insertions, 2 deletions
diff --git a/src/lj_emit_arm.h b/src/lj_emit_arm.h
index 27de6852..79ca2db7 100644
--- a/src/lj_emit_arm.h
+++ b/src/lj_emit_arm.h
@@ -103,6 +103,15 @@ static void emit_lso(ASMState *as, ARMIns ai, Reg rd, Reg rn, int32_t ofs)
103 *--as->mcp = ai | ARMI_LS_P | ARMF_D(rd) | ARMF_N(rn) | ofs; 103 *--as->mcp = ai | ARMI_LS_P | ARMF_D(rd) | ARMF_N(rn) | ofs;
104} 104}
105 105
106#if !LJ_SOFTFP
107static void emit_vlso(ASMState *as, ARMIns ai, Reg rd, Reg rn, int32_t ofs)
108{
109 lua_assert(ofs >= -1020 && ofs <= 1020 && (ofs&3) == 0);
110 if (ofs < 0) ofs = -ofs; else ai |= ARMI_LS_U;
111 *--as->mcp = ai | ARMI_LS_P | ARMF_D(rd & 15) | ARMF_N(rn) | (ofs >> 2);
112}
113#endif
114
106/* -- Emit loads/stores --------------------------------------------------- */ 115/* -- Emit loads/stores --------------------------------------------------- */
107 116
108/* Prefer spills of BASE/L. */ 117/* Prefer spills of BASE/L. */
@@ -208,6 +217,28 @@ static void emit_lsptr(ASMState *as, ARMIns ai, Reg r, void *p)
208 (i & 4095)); 217 (i & 4095));
209} 218}
210 219
220#if !LJ_SOFTFP
221/* Load a number constant into an FPR. */
222static void emit_loadn(ASMState *as, Reg r, cTValue *tv)
223{
224 int32_t i;
225 if ((as->flags & JIT_F_VFPV3) && !tv->u32.lo) {
226 uint32_t hi = tv->u32.hi;
227 uint32_t b = ((hi >> 22) & 0x1ff);
228 if (!(hi & 0xffff) && (b == 0x100 || b == 0x0ff)) {
229 *--as->mcp = ARMI_VMOVI_D | ARMF_D(r & 15) |
230 ((tv->u32.hi >> 12) & 0x00080000) |
231 ((tv->u32.hi >> 4) & 0x00070000) |
232 ((tv->u32.hi >> 16) & 0x0000000f);
233 return;
234 }
235 }
236 i = i32ptr(tv);
237 emit_vlso(as, ARMI_VLDR_D, r,
238 ra_allock(as, (i & ~1020), RSET_GPR), (i & 1020));
239}
240#endif
241
211/* Get/set global_State fields. */ 242/* Get/set global_State fields. */
212#define emit_getgl(as, r, field) \ 243#define emit_getgl(as, r, field) \
213 emit_lsptr(as, ARMI_LDR, (r), (void *)&J2G(as->J)->field) 244 emit_lsptr(as, ARMI_LDR, (r), (void *)&J2G(as->J)->field)
@@ -256,7 +287,15 @@ static void emit_call(ASMState *as, void *target)
256/* Generic move between two regs. */ 287/* Generic move between two regs. */
257static void emit_movrr(ASMState *as, IRIns *ir, Reg dst, Reg src) 288static void emit_movrr(ASMState *as, IRIns *ir, Reg dst, Reg src)
258{ 289{
290#if LJ_SOFTFP
259 lua_assert(!irt_isnum(ir->t)); UNUSED(ir); 291 lua_assert(!irt_isnum(ir->t)); UNUSED(ir);
292#else
293 if (dst >= RID_MAX_GPR) {
294 emit_dm(as, irt_isnum(ir->t) ? ARMI_VMOV_D : ARMI_VMOV_S,
295 (dst & 15), (src & 15));
296 return;
297 }
298#endif
260 if (as->mcp != as->mcloop) { /* Swap early registers for loads/stores. */ 299 if (as->mcp != as->mcloop) { /* Swap early registers for loads/stores. */
261 MCode ins = *as->mcp, swp = (src^dst); 300 MCode ins = *as->mcp, swp = (src^dst);
262 if ((ins & 0x0c000000) == 0x04000000 && (ins & 0x02000010) != 0x02000010) { 301 if ((ins & 0x0c000000) == 0x04000000 && (ins & 0x02000010) != 0x02000010) {
@@ -272,15 +311,27 @@ static void emit_movrr(ASMState *as, IRIns *ir, Reg dst, Reg src)
272/* Generic load of register from stack slot. */ 311/* Generic load of register from stack slot. */
273static void emit_spload(ASMState *as, IRIns *ir, Reg r, int32_t ofs) 312static void emit_spload(ASMState *as, IRIns *ir, Reg r, int32_t ofs)
274{ 313{
314#if LJ_SOFTFP
275 lua_assert(!irt_isnum(ir->t)); UNUSED(ir); 315 lua_assert(!irt_isnum(ir->t)); UNUSED(ir);
276 emit_lso(as, ARMI_LDR, r, RID_SP, ofs); 316#else
317 if (r >= RID_MAX_GPR)
318 emit_vlso(as, irt_isnum(ir->t) ? ARMI_VLDR_D : ARMI_VLDR_S, r, RID_SP, ofs);
319 else
320#endif
321 emit_lso(as, ARMI_LDR, r, RID_SP, ofs);
277} 322}
278 323
279/* Generic store of register to stack slot. */ 324/* Generic store of register to stack slot. */
280static void emit_spstore(ASMState *as, IRIns *ir, Reg r, int32_t ofs) 325static void emit_spstore(ASMState *as, IRIns *ir, Reg r, int32_t ofs)
281{ 326{
327#if LJ_SOFTFP
282 lua_assert(!irt_isnum(ir->t)); UNUSED(ir); 328 lua_assert(!irt_isnum(ir->t)); UNUSED(ir);
283 emit_lso(as, ARMI_STR, r, RID_SP, ofs); 329#else
330 if (r >= RID_MAX_GPR)
331 emit_vlso(as, irt_isnum(ir->t) ? ARMI_VSTR_D : ARMI_VSTR_S, r, RID_SP, ofs);
332 else
333#endif
334 emit_lso(as, ARMI_STR, r, RID_SP, ofs);
284} 335}
285 336
286/* Emit an arithmetic/logic operation with a constant operand. */ 337/* Emit an arithmetic/logic operation with a constant operand. */