diff options
| author | Mike Pall <mike> | 2023-09-09 18:01:37 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2023-09-09 18:01:37 +0200 |
| commit | b8c6ccd50c61b7a2df5123ddc5a85ac7d089542b (patch) | |
| tree | 32767fb37df6e3a9aed971fc75de32226b78a7a7 /src | |
| parent | 0705ef6ce41320b097cfb4f3c9a2a876c1949e86 (diff) | |
| download | luajit-b8c6ccd50c61b7a2df5123ddc5a85ac7d089542b.tar.gz luajit-b8c6ccd50c61b7a2df5123ddc5a85ac7d089542b.tar.bz2 luajit-b8c6ccd50c61b7a2df5123ddc5a85ac7d089542b.zip | |
ARM64: Fix LDP/STP fusion (again).
Reported and analyzed by Zhongwei Yao. Fix by Peter Cawley. #1075
Diffstat (limited to 'src')
| -rw-r--r-- | src/lj_emit_arm64.h | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/src/lj_emit_arm64.h b/src/lj_emit_arm64.h index d4c54255..9161c958 100644 --- a/src/lj_emit_arm64.h +++ b/src/lj_emit_arm64.h | |||
| @@ -113,6 +113,17 @@ static int emit_checkofs(A64Ins ai, int64_t ofs) | |||
| 113 | } | 113 | } |
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | static LJ_AINLINE uint32_t emit_lso_pair_candidate(A64Ins ai, int ofs, int sc) | ||
| 117 | { | ||
| 118 | if (ofs >= 0) { | ||
| 119 | return ai | A64F_U12(ofs>>sc); /* Subsequent lj_ror checks ofs. */ | ||
| 120 | } else if (ofs >= -256) { | ||
| 121 | return (ai^A64I_LS_U) | A64F_S9(ofs & 0x1ff); | ||
| 122 | } else { | ||
| 123 | return A64F_D(31); /* Will mismatch prev. */ | ||
| 124 | } | ||
| 125 | } | ||
| 126 | |||
| 116 | static void emit_lso(ASMState *as, A64Ins ai, Reg rd, Reg rn, int64_t ofs) | 127 | static void emit_lso(ASMState *as, A64Ins ai, Reg rd, Reg rn, int64_t ofs) |
| 117 | { | 128 | { |
| 118 | int ot = emit_checkofs(ai, ofs), sc = (ai >> 30) & 3; | 129 | int ot = emit_checkofs(ai, ofs), sc = (ai >> 30) & 3; |
| @@ -124,11 +135,9 @@ static void emit_lso(ASMState *as, A64Ins ai, Reg rd, Reg rn, int64_t ofs) | |||
| 124 | uint32_t prev = *as->mcp & ~A64F_D(31); | 135 | uint32_t prev = *as->mcp & ~A64F_D(31); |
| 125 | int ofsm = ofs - (1<<sc), ofsp = ofs + (1<<sc); | 136 | int ofsm = ofs - (1<<sc), ofsp = ofs + (1<<sc); |
| 126 | A64Ins aip; | 137 | A64Ins aip; |
| 127 | if (prev == (ai | A64F_N(rn) | A64F_U12(ofsm>>sc)) || | 138 | if (prev == emit_lso_pair_candidate(ai | A64F_N(rn), ofsm, sc)) { |
| 128 | prev == ((ai^A64I_LS_U) | A64F_N(rn) | A64F_S9(ofsm&0x1ff))) { | ||
| 129 | aip = (A64F_A(rd) | A64F_D(*as->mcp & 31)); | 139 | aip = (A64F_A(rd) | A64F_D(*as->mcp & 31)); |
| 130 | } else if (prev == (ai | A64F_N(rn) | A64F_U12(ofsp>>sc)) || | 140 | } else if (prev == emit_lso_pair_candidate(ai | A64F_N(rn), ofsp, sc)) { |
| 131 | prev == ((ai^A64I_LS_U) | A64F_N(rn) | A64F_S9(ofsp&0x1ff))) { | ||
| 132 | aip = (A64F_D(rd) | A64F_A(*as->mcp & 31)); | 141 | aip = (A64F_D(rd) | A64F_A(*as->mcp & 31)); |
| 133 | ofsm = ofs; | 142 | ofsm = ofs; |
| 134 | } else { | 143 | } else { |
