diff options
author | Mike Pall <mike> | 2017-11-08 12:54:03 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2017-11-08 12:54:03 +0100 |
commit | 99cdfbf6a1e8856f64908072ef10443a7eab14f2 (patch) | |
tree | d24c0394915d9a40a6c799796c7b5731cd92bd36 | |
parent | 06cd9fce7df440323647174f1ca4a01281ec8acd (diff) | |
download | luajit-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.h | 42 |
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)) { |