diff options
Diffstat (limited to '')
-rw-r--r-- | src/lj_asm_arm64.h | 42 |
1 files changed, 28 insertions, 14 deletions
diff --git a/src/lj_asm_arm64.h b/src/lj_asm_arm64.h index b58ab3a1..8fd92e76 100644 --- a/src/lj_asm_arm64.h +++ b/src/lj_asm_arm64.h | |||
@@ -56,11 +56,11 @@ static void asm_exitstub_setup(ASMState *as, ExitNo nexits) | |||
56 | asm_mclimit(as); | 56 | asm_mclimit(as); |
57 | /* 1: str lr,[sp]; bl ->vm_exit_handler; movz w0,traceno; bl <1; bl <1; ... */ | 57 | /* 1: str lr,[sp]; bl ->vm_exit_handler; movz w0,traceno; bl <1; bl <1; ... */ |
58 | for (i = nexits-1; (int32_t)i >= 0; i--) | 58 | for (i = nexits-1; (int32_t)i >= 0; i--) |
59 | *--mxp = A64I_BL|((-3-i)&0x03ffffffu); | 59 | *--mxp = A64I_LE(A64I_BL|((-3-i)&0x03ffffffu)); |
60 | *--mxp = A64I_MOVZw|A64F_U16(as->T->traceno); | 60 | *--mxp = A64I_LE(A64I_MOVZw|A64F_U16(as->T->traceno)); |
61 | mxp--; | 61 | mxp--; |
62 | *mxp = A64I_BL|(((MCode *)(void *)lj_vm_exit_handler-mxp)&0x03ffffffu); | 62 | *mxp = A64I_LE(A64I_BL|(((MCode *)(void *)lj_vm_exit_handler-mxp)&0x03ffffffu)); |
63 | *--mxp = A64I_STRx|A64F_D(RID_LR)|A64F_N(RID_SP); | 63 | *--mxp = A64I_LE(A64I_STRx|A64F_D(RID_LR)|A64F_N(RID_SP)); |
64 | as->mctop = mxp; | 64 | as->mctop = mxp; |
65 | } | 65 | } |
66 | 66 | ||
@@ -431,7 +431,7 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args) | |||
431 | fpr++; | 431 | fpr++; |
432 | } else { | 432 | } else { |
433 | Reg r = ra_alloc1(as, ref, RSET_FPR); | 433 | Reg r = ra_alloc1(as, ref, RSET_FPR); |
434 | emit_spstore(as, ir, r, ofs); | 434 | emit_spstore(as, ir, r, ofs + ((LJ_BE && !irt_isnum(ir->t)) ? 4 : 0)); |
435 | ofs += 8; | 435 | ofs += 8; |
436 | } | 436 | } |
437 | } else { | 437 | } else { |
@@ -441,7 +441,7 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args) | |||
441 | gpr++; | 441 | gpr++; |
442 | } else { | 442 | } else { |
443 | Reg r = ra_alloc1(as, ref, RSET_GPR); | 443 | Reg r = ra_alloc1(as, ref, RSET_GPR); |
444 | emit_spstore(as, ir, r, ofs); | 444 | emit_spstore(as, ir, r, ofs + ((LJ_BE && !irt_is64(ir->t)) ? 4 : 0)); |
445 | ofs += 8; | 445 | ofs += 8; |
446 | } | 446 | } |
447 | } | 447 | } |
@@ -1082,7 +1082,7 @@ static void asm_ahustore(ASMState *as, IRIns *ir) | |||
1082 | src = ra_alloc1(as, ir->op2, allow); | 1082 | src = ra_alloc1(as, ir->op2, allow); |
1083 | rset_clear(allow, src); | 1083 | rset_clear(allow, src); |
1084 | if (irt_isinteger(ir->t)) | 1084 | if (irt_isinteger(ir->t)) |
1085 | type = ra_allock(as, (int64_t)LJ_TISNUM << 47, allow); | 1085 | type = ra_allock(as, (uint64_t)(int32_t)LJ_TISNUM << 47, allow); |
1086 | else | 1086 | else |
1087 | type = ra_allock(as, irt_toitype(ir->t), allow); | 1087 | type = ra_allock(as, irt_toitype(ir->t), allow); |
1088 | } else { | 1088 | } else { |
@@ -1179,7 +1179,8 @@ dotypecheck: | |||
1179 | } | 1179 | } |
1180 | if (ra_hasreg(dest)) { | 1180 | if (ra_hasreg(dest)) { |
1181 | emit_lso(as, irt_isnum(t) ? A64I_LDRd : | 1181 | emit_lso(as, irt_isnum(t) ? A64I_LDRd : |
1182 | (irt_isint(t) ? A64I_LDRw : A64I_LDRx), (dest & 31), base, ofs); | 1182 | (irt_isint(t) ? A64I_LDRw : A64I_LDRx), (dest & 31), base, |
1183 | ofs ^ ((LJ_BE && irt_isint(t) ? 4 : 0))); | ||
1183 | } | 1184 | } |
1184 | } | 1185 | } |
1185 | 1186 | ||
@@ -1909,7 +1910,7 @@ static void asm_tail_fixup(ASMState *as, TraceNo lnk) | |||
1909 | /* Undo the sp adjustment in BC_JLOOP when exiting to the interpreter. */ | 1910 | /* Undo the sp adjustment in BC_JLOOP when exiting to the interpreter. */ |
1910 | int32_t spadj = as->T->spadjust + (lnk ? 0 : sps_scale(SPS_FIXED)); | 1911 | int32_t spadj = as->T->spadjust + (lnk ? 0 : sps_scale(SPS_FIXED)); |
1911 | if (spadj == 0) { | 1912 | if (spadj == 0) { |
1912 | *--p = A64I_NOP; | 1913 | *--p = A64I_LE(A64I_NOP); |
1913 | as->mctop = p; | 1914 | as->mctop = p; |
1914 | } else { | 1915 | } else { |
1915 | /* Patch stack adjustment. */ | 1916 | /* Patch stack adjustment. */ |
@@ -1962,6 +1963,19 @@ static void asm_setup_target(ASMState *as) | |||
1962 | asm_exitstub_setup(as, as->T->nsnap + (as->parent ? 1 : 0)); | 1963 | asm_exitstub_setup(as, as->T->nsnap + (as->parent ? 1 : 0)); |
1963 | } | 1964 | } |
1964 | 1965 | ||
1966 | #if LJ_BE | ||
1967 | /* ARM64 instructions are always little-endian. Swap for ARM64BE. */ | ||
1968 | static void asm_mcode_fixup(MCode *mcode, MSize size) | ||
1969 | { | ||
1970 | MCode *pe = (MCode *)((char *)mcode + size); | ||
1971 | while (mcode < pe) { | ||
1972 | MCode ins = *mcode; | ||
1973 | *mcode++ = lj_bswap(ins); | ||
1974 | } | ||
1975 | } | ||
1976 | #define LJ_TARGET_MCODE_FIXUP 1 | ||
1977 | #endif | ||
1978 | |||
1965 | /* -- Trace patching ------------------------------------------------------ */ | 1979 | /* -- Trace patching ------------------------------------------------------ */ |
1966 | 1980 | ||
1967 | /* Patch exit jumps of existing machine code to a new target. */ | 1981 | /* Patch exit jumps of existing machine code to a new target. */ |
@@ -1974,29 +1988,29 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target) | |||
1974 | MCode *px = exitstub_trace_addr(T, exitno); | 1988 | MCode *px = exitstub_trace_addr(T, exitno); |
1975 | for (; p < pe; p++) { | 1989 | for (; p < pe; p++) { |
1976 | /* Look for exitstub branch, replace with branch to target. */ | 1990 | /* Look for exitstub branch, replace with branch to target. */ |
1977 | uint32_t ins = *p; | 1991 | MCode ins = A64I_LE(*p); |
1978 | if ((ins & 0xff000000u) == 0x54000000u && | 1992 | if ((ins & 0xff000000u) == 0x54000000u && |
1979 | ((ins ^ ((px-p)<<5)) & 0x00ffffe0u) == 0) { | 1993 | ((ins ^ ((px-p)<<5)) & 0x00ffffe0u) == 0) { |
1980 | /* Patch bcc exitstub. */ | 1994 | /* Patch bcc exitstub. */ |
1981 | *p = (ins & 0xff00001fu) | (((target-p)<<5) & 0x00ffffe0u); | 1995 | *p = A64I_LE((ins & 0xff00001fu) | (((target-p)<<5) & 0x00ffffe0u)); |
1982 | cend = p+1; | 1996 | cend = p+1; |
1983 | if (!cstart) cstart = p; | 1997 | if (!cstart) cstart = p; |
1984 | } else if ((ins & 0xfc000000u) == 0x14000000u && | 1998 | } else if ((ins & 0xfc000000u) == 0x14000000u && |
1985 | ((ins ^ (px-p)) & 0x03ffffffu) == 0) { | 1999 | ((ins ^ (px-p)) & 0x03ffffffu) == 0) { |
1986 | /* Patch b exitstub. */ | 2000 | /* Patch b exitstub. */ |
1987 | *p = (ins & 0xfc000000u) | ((target-p) & 0x03ffffffu); | 2001 | *p = A64I_LE((ins & 0xfc000000u) | ((target-p) & 0x03ffffffu)); |
1988 | cend = p+1; | 2002 | cend = p+1; |
1989 | if (!cstart) cstart = p; | 2003 | if (!cstart) cstart = p; |
1990 | } else if ((ins & 0x7e000000u) == 0x34000000u && | 2004 | } else if ((ins & 0x7e000000u) == 0x34000000u && |
1991 | ((ins ^ ((px-p)<<5)) & 0x00ffffe0u) == 0) { | 2005 | ((ins ^ ((px-p)<<5)) & 0x00ffffe0u) == 0) { |
1992 | /* Patch cbz/cbnz exitstub. */ | 2006 | /* Patch cbz/cbnz exitstub. */ |
1993 | *p = (ins & 0xff00001f) | (((target-p)<<5) & 0x00ffffe0u); | 2007 | *p = A64I_LE((ins & 0xff00001f) | (((target-p)<<5) & 0x00ffffe0u)); |
1994 | cend = p+1; | 2008 | cend = p+1; |
1995 | if (!cstart) cstart = p; | 2009 | if (!cstart) cstart = p; |
1996 | } else if ((ins & 0x7e000000u) == 0x36000000u && | 2010 | } else if ((ins & 0x7e000000u) == 0x36000000u && |
1997 | ((ins ^ ((px-p)<<5)) & 0x0007ffe0u) == 0) { | 2011 | ((ins ^ ((px-p)<<5)) & 0x0007ffe0u) == 0) { |
1998 | /* Patch tbz/tbnz exitstub. */ | 2012 | /* Patch tbz/tbnz exitstub. */ |
1999 | *p = (ins & 0xfff8001fu) | (((target-p)<<5) & 0x0007ffe0u); | 2013 | *p = A64I_LE((ins & 0xfff8001fu) | (((target-p)<<5) & 0x0007ffe0u)); |
2000 | cend = p+1; | 2014 | cend = p+1; |
2001 | if (!cstart) cstart = p; | 2015 | if (!cstart) cstart = p; |
2002 | } | 2016 | } |