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)) { |
