aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2017-11-08 12:54:03 +0100
committerMike Pall <mike>2017-11-08 12:54:03 +0100
commit99cdfbf6a1e8856f64908072ef10443a7eab14f2 (patch)
treed24c0394915d9a40a6c799796c7b5731cd92bd36
parent06cd9fce7df440323647174f1ca4a01281ec8acd (diff)
downloadluajit-99cdfbf6a1e8856f64908072ef10443a7eab14f2.tar.gz
luajit-99cdfbf6a1e8856f64908072ef10443a7eab14f2.tar.bz2
luajit-99cdfbf6a1e8856f64908072ef10443a7eab14f2.zip
MIPS64: Fix register allocation in assembly of HREF.
Contributed by James Cowgill.
-rw-r--r--src/lj_asm_mips.h42
1 files changed, 25 insertions, 17 deletions
diff --git a/src/lj_asm_mips.h b/src/lj_asm_mips.h
index 1406a873..3a4679b8 100644
--- a/src/lj_asm_mips.h
+++ b/src/lj_asm_mips.h
@@ -859,6 +859,9 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
859 Reg dest = ra_dest(as, ir, allow); 859 Reg dest = ra_dest(as, ir, allow);
860 Reg tab = ra_alloc1(as, ir->op1, rset_clear(allow, dest)); 860 Reg tab = ra_alloc1(as, ir->op1, rset_clear(allow, dest));
861 Reg key = RID_NONE, type = RID_NONE, tmpnum = RID_NONE, tmp1 = RID_TMP, tmp2; 861 Reg key = RID_NONE, type = RID_NONE, tmpnum = RID_NONE, tmp1 = RID_TMP, tmp2;
862#if LJ_64
863 Reg cmp64 = RID_NONE;
864#endif
862 IRRef refkey = ir->op2; 865 IRRef refkey = ir->op2;
863 IRIns *irkey = IR(refkey); 866 IRIns *irkey = IR(refkey);
864 int isk = irref_isk(refkey); 867 int isk = irref_isk(refkey);
@@ -901,6 +904,26 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
901#endif 904#endif
902 tmp2 = ra_scratch(as, allow); 905 tmp2 = ra_scratch(as, allow);
903 rset_clear(allow, tmp2); 906 rset_clear(allow, tmp2);
907#if LJ_64
908 if (LJ_SOFTFP || !irt_isnum(kt)) {
909 /* Allocate cmp64 register used for 64-bit comparisons */
910 if (LJ_SOFTFP && irt_isnum(kt)) {
911 cmp64 = key;
912 } else if (!isk && irt_isaddr(kt)) {
913 cmp64 = tmp2;
914 } else {
915 int64_t k;
916 if (isk && irt_isaddr(kt)) {
917 k = ((int64_t)irt_toitype(irkey->t) << 47) | irkey[1].tv.u64;
918 } else {
919 lua_assert(irt_ispri(kt) && !irt_isnil(kt));
920 k = ~((int64_t)~irt_toitype(ir->t) << 47);
921 }
922 cmp64 = ra_allock(as, k, allow);
923 rset_clear(allow, cmp64);
924 }
925 }
926#endif
904 927
905 /* Key not found in chain: jump to exit (if merged) or load niltv. */ 928 /* Key not found in chain: jump to exit (if merged) or load niltv. */
906 l_end = emit_label(as); 929 l_end = emit_label(as);
@@ -943,24 +966,9 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
943 emit_dta(as, MIPSI_DSRA32, tmp1, tmp1, 15); 966 emit_dta(as, MIPSI_DSRA32, tmp1, tmp1, 15);
944 emit_tg(as, MIPSI_DMTC1, tmp1, tmpnum); 967 emit_tg(as, MIPSI_DMTC1, tmp1, tmpnum);
945 emit_tsi(as, MIPSI_LD, tmp1, dest, (int32_t)offsetof(Node, key.u64)); 968 emit_tsi(as, MIPSI_LD, tmp1, dest, (int32_t)offsetof(Node, key.u64));
946 } else if (LJ_SOFTFP && irt_isnum(kt)) {
947 emit_branch(as, MIPSI_BEQ, tmp1, key, l_end);
948 emit_tsi(as, MIPSI_LD, tmp1, dest, (int32_t)offsetof(Node, key.u64));
949 } else if (irt_isaddr(kt)) {
950 Reg refk = tmp2;
951 if (isk) {
952 int64_t k = ((int64_t)irt_toitype(irkey->t) << 47) | irkey[1].tv.u64;
953 refk = ra_allock(as, k, allow);
954 rset_clear(allow, refk);
955 }
956 emit_branch(as, MIPSI_BEQ, tmp1, refk, l_end);
957 emit_tsi(as, MIPSI_LD, tmp1, dest, offsetof(Node, key));
958 } else { 969 } else {
959 Reg pri = ra_allock(as, ~((int64_t)~irt_toitype(ir->t) << 47), allow); 970 emit_branch(as, MIPSI_BEQ, tmp1, cmp64, l_end);
960 rset_clear(allow, pri); 971 emit_tsi(as, MIPSI_LD, tmp1, dest, (int32_t)offsetof(Node, key.u64));
961 lua_assert(irt_ispri(kt) && !irt_isnil(kt));
962 emit_branch(as, MIPSI_BEQ, tmp1, pri, l_end);
963 emit_tsi(as, MIPSI_LD, tmp1, dest, offsetof(Node, key));
964 } 972 }
965 *l_loop = MIPSI_BNE | MIPSF_S(tmp1) | ((as->mcp-l_loop-1) & 0xffffu); 973 *l_loop = MIPSI_BNE | MIPSF_S(tmp1) | ((as->mcp-l_loop-1) & 0xffffu);
966 if (!isk && irt_isaddr(kt)) { 974 if (!isk && irt_isaddr(kt)) {