Revision | d8ae530ec00368d4adfb996b5ef6c74cb4460504 (tree) |
---|---|
Zeit | 2021-08-26 05:09:48 |
Autor | Peter Maydell <peter.maydell@lina...> |
Commiter | Peter Maydell |
Merge remote-tracking branch 'remotes/philmd/tags/mips-20210825' into staging
MIPS patches queue
- minor simplifications in PREF / JR opcodes
- merge 32-bit/64-bit Release6 decodetree definitions
- converted NEC Vr54xx extension opcodes to decodetree
- housekeeping in gen_helper() macros
- replace TARGET_WORDS_BIGENDIAN #ifdef'ry by cpu_is_bigendian()
- allow Loongson 3A1000 to use up to 48-bit VAddr
# gpg: Signature made Wed 25 Aug 2021 12:04:31 BST
# gpg: using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE
# gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [full]
# Primary key fingerprint: FAAB E75E 1291 7221 DCFD 6BB2 E3E3 2C2C DEAD C0DE
* remotes/philmd/tags/mips-20210825: (28 commits)
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
@@ -805,7 +805,7 @@ const mips_def_t mips_defs[] = | ||
805 | 805 | .mmu_type = MMU_TYPE_R4000, |
806 | 806 | }, |
807 | 807 | { |
808 | - .name = "Loongson-3A1000", | |
808 | + .name = "Loongson-3A1000", /* Loongson-3A R1, GS464-based */ | |
809 | 809 | .CP0_PRid = 0x6305, |
810 | 810 | /* 64KB I-cache and d-cache. 4 way with 32 bit cache line size. */ |
811 | 811 | .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | (0x2 << CP0C0_AT) | |
@@ -828,14 +828,14 @@ const mips_def_t mips_defs[] = | ||
828 | 828 | (0x1 << FCR0_D) | (0x1 << FCR0_S), |
829 | 829 | .CP1_fcr31 = 0, |
830 | 830 | .CP1_fcr31_rw_bitmask = 0xFF83FFFF, |
831 | - .SEGBITS = 42, | |
831 | + .SEGBITS = 48, | |
832 | 832 | .PABITS = 48, |
833 | 833 | .insn_flags = CPU_MIPS64R2 | INSN_LOONGSON3A | |
834 | 834 | ASE_LMMI | ASE_LEXT, |
835 | 835 | .mmu_type = MMU_TYPE_R4000, |
836 | 836 | }, |
837 | 837 | { |
838 | - .name = "Loongson-3A4000", /* GS464V-based */ | |
838 | + .name = "Loongson-3A4000", /* Loongson-3A R4, GS464V-based */ | |
839 | 839 | .CP0_PRid = 0x14C000, |
840 | 840 | /* 64KB I-cache and d-cache. 4 way with 32 bit cache line size. */ |
841 | 841 | .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | (0x2 << CP0C0_AT) | |
@@ -16,21 +16,6 @@ DEF_HELPER_3(lld, tl, env, tl, int) | ||
16 | 16 | #endif |
17 | 17 | #endif |
18 | 18 | |
19 | -DEF_HELPER_3(muls, tl, env, tl, tl) | |
20 | -DEF_HELPER_3(mulsu, tl, env, tl, tl) | |
21 | -DEF_HELPER_3(macc, tl, env, tl, tl) | |
22 | -DEF_HELPER_3(maccu, tl, env, tl, tl) | |
23 | -DEF_HELPER_3(msac, tl, env, tl, tl) | |
24 | -DEF_HELPER_3(msacu, tl, env, tl, tl) | |
25 | -DEF_HELPER_3(mulhi, tl, env, tl, tl) | |
26 | -DEF_HELPER_3(mulhiu, tl, env, tl, tl) | |
27 | -DEF_HELPER_3(mulshi, tl, env, tl, tl) | |
28 | -DEF_HELPER_3(mulshiu, tl, env, tl, tl) | |
29 | -DEF_HELPER_3(macchi, tl, env, tl, tl) | |
30 | -DEF_HELPER_3(macchiu, tl, env, tl, tl) | |
31 | -DEF_HELPER_3(msachi, tl, env, tl, tl) | |
32 | -DEF_HELPER_3(msachiu, tl, env, tl, tl) | |
33 | - | |
34 | 19 | DEF_HELPER_FLAGS_1(bitswap, TCG_CALL_NO_RWG_SE, tl, tl) |
35 | 20 | #ifdef TARGET_MIPS64 |
36 | 21 | DEF_HELPER_FLAGS_1(dbitswap, TCG_CALL_NO_RWG_SE, tl, tl) |
@@ -609,3 +594,6 @@ DEF_HELPER_FLAGS_2(rddsp, 0, tl, tl, env) | ||
609 | 594 | #endif /* !CONFIG_USER_ONLY */ |
610 | 595 | |
611 | 596 | #include "tcg/msa_helper.h.inc" |
597 | + | |
598 | +/* Vendor extensions */ | |
599 | +#include "tcg/vr54xx_helper.h.inc" |
@@ -52,31 +52,45 @@ HELPER_LD_ATOMIC(lld, ldq, 0x7, (target_ulong)) | ||
52 | 52 | |
53 | 53 | #endif /* !CONFIG_USER_ONLY */ |
54 | 54 | |
55 | -#ifdef TARGET_WORDS_BIGENDIAN | |
56 | -#define GET_LMASK(v) ((v) & 3) | |
57 | -#define GET_OFFSET(addr, offset) (addr + (offset)) | |
58 | -#else | |
59 | -#define GET_LMASK(v) (((v) & 3) ^ 3) | |
60 | -#define GET_OFFSET(addr, offset) (addr - (offset)) | |
61 | -#endif | |
55 | +static inline bool cpu_is_bigendian(CPUMIPSState *env) | |
56 | +{ | |
57 | + return extract32(env->CP0_Config0, CP0C0_BE, 1); | |
58 | +} | |
59 | + | |
60 | +static inline target_ulong get_lmask(CPUMIPSState *env, | |
61 | + target_ulong value, unsigned bits) | |
62 | +{ | |
63 | + unsigned mask = (bits / BITS_PER_BYTE) - 1; | |
64 | + | |
65 | + value &= mask; | |
66 | + | |
67 | + if (!cpu_is_bigendian(env)) { | |
68 | + value ^= mask; | |
69 | + } | |
70 | + | |
71 | + return value; | |
72 | +} | |
62 | 73 | |
63 | 74 | void helper_swl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2, |
64 | 75 | int mem_idx) |
65 | 76 | { |
77 | + target_ulong lmask = get_lmask(env, arg2, 32); | |
78 | + int dir = cpu_is_bigendian(env) ? 1 : -1; | |
79 | + | |
66 | 80 | cpu_stb_mmuidx_ra(env, arg2, (uint8_t)(arg1 >> 24), mem_idx, GETPC()); |
67 | 81 | |
68 | - if (GET_LMASK(arg2) <= 2) { | |
69 | - cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 1), (uint8_t)(arg1 >> 16), | |
82 | + if (lmask <= 2) { | |
83 | + cpu_stb_mmuidx_ra(env, arg2 + 1 * dir, (uint8_t)(arg1 >> 16), | |
70 | 84 | mem_idx, GETPC()); |
71 | 85 | } |
72 | 86 | |
73 | - if (GET_LMASK(arg2) <= 1) { | |
74 | - cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 2), (uint8_t)(arg1 >> 8), | |
87 | + if (lmask <= 1) { | |
88 | + cpu_stb_mmuidx_ra(env, arg2 + 2 * dir, (uint8_t)(arg1 >> 8), | |
75 | 89 | mem_idx, GETPC()); |
76 | 90 | } |
77 | 91 | |
78 | - if (GET_LMASK(arg2) == 0) { | |
79 | - cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 3), (uint8_t)arg1, | |
92 | + if (lmask == 0) { | |
93 | + cpu_stb_mmuidx_ra(env, arg2 + 3 * dir, (uint8_t)arg1, | |
80 | 94 | mem_idx, GETPC()); |
81 | 95 | } |
82 | 96 | } |
@@ -84,20 +98,23 @@ void helper_swl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2, | ||
84 | 98 | void helper_swr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2, |
85 | 99 | int mem_idx) |
86 | 100 | { |
101 | + target_ulong lmask = get_lmask(env, arg2, 32); | |
102 | + int dir = cpu_is_bigendian(env) ? 1 : -1; | |
103 | + | |
87 | 104 | cpu_stb_mmuidx_ra(env, arg2, (uint8_t)arg1, mem_idx, GETPC()); |
88 | 105 | |
89 | - if (GET_LMASK(arg2) >= 1) { | |
90 | - cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, -1), (uint8_t)(arg1 >> 8), | |
106 | + if (lmask >= 1) { | |
107 | + cpu_stb_mmuidx_ra(env, arg2 - 1 * dir, (uint8_t)(arg1 >> 8), | |
91 | 108 | mem_idx, GETPC()); |
92 | 109 | } |
93 | 110 | |
94 | - if (GET_LMASK(arg2) >= 2) { | |
95 | - cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, -2), (uint8_t)(arg1 >> 16), | |
111 | + if (lmask >= 2) { | |
112 | + cpu_stb_mmuidx_ra(env, arg2 - 2 * dir, (uint8_t)(arg1 >> 16), | |
96 | 113 | mem_idx, GETPC()); |
97 | 114 | } |
98 | 115 | |
99 | - if (GET_LMASK(arg2) == 3) { | |
100 | - cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, -3), (uint8_t)(arg1 >> 24), | |
116 | + if (lmask == 3) { | |
117 | + cpu_stb_mmuidx_ra(env, arg2 - 3 * dir, (uint8_t)(arg1 >> 24), | |
101 | 118 | mem_idx, GETPC()); |
102 | 119 | } |
103 | 120 | } |
@@ -107,49 +124,47 @@ void helper_swr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2, | ||
107 | 124 | * "half" load and stores. We must do the memory access inline, |
108 | 125 | * or fault handling won't work. |
109 | 126 | */ |
110 | -#ifdef TARGET_WORDS_BIGENDIAN | |
111 | -#define GET_LMASK64(v) ((v) & 7) | |
112 | -#else | |
113 | -#define GET_LMASK64(v) (((v) & 7) ^ 7) | |
114 | -#endif | |
115 | 127 | |
116 | 128 | void helper_sdl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2, |
117 | 129 | int mem_idx) |
118 | 130 | { |
131 | + target_ulong lmask = get_lmask(env, arg2, 64); | |
132 | + int dir = cpu_is_bigendian(env) ? 1 : -1; | |
133 | + | |
119 | 134 | cpu_stb_mmuidx_ra(env, arg2, (uint8_t)(arg1 >> 56), mem_idx, GETPC()); |
120 | 135 | |
121 | - if (GET_LMASK64(arg2) <= 6) { | |
122 | - cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 1), (uint8_t)(arg1 >> 48), | |
136 | + if (lmask <= 6) { | |
137 | + cpu_stb_mmuidx_ra(env, arg2 + 1 * dir, (uint8_t)(arg1 >> 48), | |
123 | 138 | mem_idx, GETPC()); |
124 | 139 | } |
125 | 140 | |
126 | - if (GET_LMASK64(arg2) <= 5) { | |
127 | - cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 2), (uint8_t)(arg1 >> 40), | |
141 | + if (lmask <= 5) { | |
142 | + cpu_stb_mmuidx_ra(env, arg2 + 2 * dir, (uint8_t)(arg1 >> 40), | |
128 | 143 | mem_idx, GETPC()); |
129 | 144 | } |
130 | 145 | |
131 | - if (GET_LMASK64(arg2) <= 4) { | |
132 | - cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 3), (uint8_t)(arg1 >> 32), | |
146 | + if (lmask <= 4) { | |
147 | + cpu_stb_mmuidx_ra(env, arg2 + 3 * dir, (uint8_t)(arg1 >> 32), | |
133 | 148 | mem_idx, GETPC()); |
134 | 149 | } |
135 | 150 | |
136 | - if (GET_LMASK64(arg2) <= 3) { | |
137 | - cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 4), (uint8_t)(arg1 >> 24), | |
151 | + if (lmask <= 3) { | |
152 | + cpu_stb_mmuidx_ra(env, arg2 + 4 * dir, (uint8_t)(arg1 >> 24), | |
138 | 153 | mem_idx, GETPC()); |
139 | 154 | } |
140 | 155 | |
141 | - if (GET_LMASK64(arg2) <= 2) { | |
142 | - cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 5), (uint8_t)(arg1 >> 16), | |
156 | + if (lmask <= 2) { | |
157 | + cpu_stb_mmuidx_ra(env, arg2 + 5 * dir, (uint8_t)(arg1 >> 16), | |
143 | 158 | mem_idx, GETPC()); |
144 | 159 | } |
145 | 160 | |
146 | - if (GET_LMASK64(arg2) <= 1) { | |
147 | - cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 6), (uint8_t)(arg1 >> 8), | |
161 | + if (lmask <= 1) { | |
162 | + cpu_stb_mmuidx_ra(env, arg2 + 6 * dir, (uint8_t)(arg1 >> 8), | |
148 | 163 | mem_idx, GETPC()); |
149 | 164 | } |
150 | 165 | |
151 | - if (GET_LMASK64(arg2) <= 0) { | |
152 | - cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 7), (uint8_t)arg1, | |
166 | + if (lmask <= 0) { | |
167 | + cpu_stb_mmuidx_ra(env, arg2 + 7 * dir, (uint8_t)arg1, | |
153 | 168 | mem_idx, GETPC()); |
154 | 169 | } |
155 | 170 | } |
@@ -157,40 +172,43 @@ void helper_sdl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2, | ||
157 | 172 | void helper_sdr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2, |
158 | 173 | int mem_idx) |
159 | 174 | { |
175 | + target_ulong lmask = get_lmask(env, arg2, 64); | |
176 | + int dir = cpu_is_bigendian(env) ? 1 : -1; | |
177 | + | |
160 | 178 | cpu_stb_mmuidx_ra(env, arg2, (uint8_t)arg1, mem_idx, GETPC()); |
161 | 179 | |
162 | - if (GET_LMASK64(arg2) >= 1) { | |
163 | - cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, -1), (uint8_t)(arg1 >> 8), | |
180 | + if (lmask >= 1) { | |
181 | + cpu_stb_mmuidx_ra(env, arg2 - 1 * dir, (uint8_t)(arg1 >> 8), | |
164 | 182 | mem_idx, GETPC()); |
165 | 183 | } |
166 | 184 | |
167 | - if (GET_LMASK64(arg2) >= 2) { | |
168 | - cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, -2), (uint8_t)(arg1 >> 16), | |
185 | + if (lmask >= 2) { | |
186 | + cpu_stb_mmuidx_ra(env, arg2 - 2 * dir, (uint8_t)(arg1 >> 16), | |
169 | 187 | mem_idx, GETPC()); |
170 | 188 | } |
171 | 189 | |
172 | - if (GET_LMASK64(arg2) >= 3) { | |
173 | - cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, -3), (uint8_t)(arg1 >> 24), | |
190 | + if (lmask >= 3) { | |
191 | + cpu_stb_mmuidx_ra(env, arg2 - 3 * dir, (uint8_t)(arg1 >> 24), | |
174 | 192 | mem_idx, GETPC()); |
175 | 193 | } |
176 | 194 | |
177 | - if (GET_LMASK64(arg2) >= 4) { | |
178 | - cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, -4), (uint8_t)(arg1 >> 32), | |
195 | + if (lmask >= 4) { | |
196 | + cpu_stb_mmuidx_ra(env, arg2 - 4 * dir, (uint8_t)(arg1 >> 32), | |
179 | 197 | mem_idx, GETPC()); |
180 | 198 | } |
181 | 199 | |
182 | - if (GET_LMASK64(arg2) >= 5) { | |
183 | - cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, -5), (uint8_t)(arg1 >> 40), | |
200 | + if (lmask >= 5) { | |
201 | + cpu_stb_mmuidx_ra(env, arg2 - 5 * dir, (uint8_t)(arg1 >> 40), | |
184 | 202 | mem_idx, GETPC()); |
185 | 203 | } |
186 | 204 | |
187 | - if (GET_LMASK64(arg2) >= 6) { | |
188 | - cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, -6), (uint8_t)(arg1 >> 48), | |
205 | + if (lmask >= 6) { | |
206 | + cpu_stb_mmuidx_ra(env, arg2 - 6 * dir, (uint8_t)(arg1 >> 48), | |
189 | 207 | mem_idx, GETPC()); |
190 | 208 | } |
191 | 209 | |
192 | - if (GET_LMASK64(arg2) == 7) { | |
193 | - cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, -7), (uint8_t)(arg1 >> 56), | |
210 | + if (lmask == 7) { | |
211 | + cpu_stb_mmuidx_ra(env, arg2 - 7 * dir, (uint8_t)(arg1 >> 56), | |
194 | 212 | mem_idx, GETPC()); |
195 | 213 | } |
196 | 214 | } |
@@ -1,8 +1,8 @@ | ||
1 | 1 | gen = [ |
2 | - decodetree.process('mips32r6.decode', extra_args: '--static-decode=decode_mips32r6'), | |
3 | - decodetree.process('mips64r6.decode', extra_args: '--static-decode=decode_mips64r6'), | |
2 | + decodetree.process('rel6.decode', extra_args: ['--decode=decode_isa_rel6']), | |
4 | 3 | decodetree.process('msa.decode', extra_args: '--decode=decode_ase_msa'), |
5 | 4 | decodetree.process('tx79.decode', extra_args: '--static-decode=decode_tx79'), |
5 | + decodetree.process('vr54xx.decode', extra_args: '--decode=decode_ext_vr54xx'), | |
6 | 6 | ] |
7 | 7 | |
8 | 8 | mips_ss.add(gen) |
@@ -19,6 +19,8 @@ mips_ss.add(files( | ||
19 | 19 | 'translate.c', |
20 | 20 | 'translate_addr_const.c', |
21 | 21 | 'txx9_translate.c', |
22 | + 'vr54xx_helper.c', | |
23 | + 'vr54xx_translate.c', | |
22 | 24 | )) |
23 | 25 | mips_ss.add(when: 'TARGET_MIPS64', if_true: files( |
24 | 26 | 'tx79_translate.c', |
@@ -1,27 +0,0 @@ | ||
1 | -# MIPS64 Release 6 instruction set | |
2 | -# | |
3 | -# Copyright (C) 2020 Philippe Mathieu-Daudé | |
4 | -# | |
5 | -# SPDX-License-Identifier: LGPL-2.1-or-later | |
6 | -# | |
7 | -# Reference: | |
8 | -# MIPS Architecture for Programmers Volume II-A | |
9 | -# The MIPS64 Instruction Set Reference Manual, Revision 6.06 | |
10 | -# (Document Number: MD00087-2B-MIPS64BIS-AFP-6.06) | |
11 | -# | |
12 | - | |
13 | -&rtype rs rt rd sa !extern | |
14 | - | |
15 | -&REMOVED !extern | |
16 | - | |
17 | -@lsa ...... rs:5 rt:5 rd:5 ... sa:2 ...... &rtype | |
18 | - | |
19 | -DLSA 000000 ..... ..... ..... 000 .. 010101 @lsa | |
20 | - | |
21 | -REMOVED 011010 ----- ----- ---------------- # LDL | |
22 | -REMOVED 011011 ----- ----- ---------------- # LDR | |
23 | -REMOVED 101100 ----- ----- ---------------- # SDL | |
24 | -REMOVED 101101 ----- ----- ---------------- # SDR | |
25 | - | |
26 | -REMOVED 110100 ----- ----- ---------------- # LLD | |
27 | -REMOVED 111100 ----- ----- ---------------- # SCD |
@@ -11,11 +11,11 @@ | ||
11 | 11 | # - The MIPS64 SIMD Architecture Module, Revision 1.12 |
12 | 12 | # (Document Number: MD00868-1D-MSA64-AFP-01.12) |
13 | 13 | |
14 | -&rtype rs rt rd sa | |
14 | +&r rs rt rd sa | |
15 | 15 | |
16 | 16 | &msa_bz df wt s16 |
17 | 17 | |
18 | -@lsa ...... rs:5 rt:5 rd:5 ... sa:2 ...... &rtype | |
18 | +@lsa ...... rs:5 rt:5 rd:5 ... sa:2 ...... &r | |
19 | 19 | @bz ...... ... .. wt:5 s16:16 &msa_bz df=3 |
20 | 20 | @bz_df ...... ... df:2 wt:5 s16:16 &msa_bz |
21 | 21 |
@@ -2261,12 +2261,12 @@ static bool trans_MSA(DisasContext *ctx, arg_MSA *a) | ||
2261 | 2261 | return true; |
2262 | 2262 | } |
2263 | 2263 | |
2264 | -static bool trans_LSA(DisasContext *ctx, arg_rtype *a) | |
2264 | +static bool trans_LSA(DisasContext *ctx, arg_r *a) | |
2265 | 2265 | { |
2266 | 2266 | return gen_lsa(ctx, a->rd, a->rt, a->rs, a->sa); |
2267 | 2267 | } |
2268 | 2268 | |
2269 | -static bool trans_DLSA(DisasContext *ctx, arg_rtype *a) | |
2269 | +static bool trans_DLSA(DisasContext *ctx, arg_r *a) | |
2270 | 2270 | { |
2271 | 2271 | if (TARGET_LONG_BITS != 64) { |
2272 | 2272 | return false; |
@@ -999,11 +999,11 @@ static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset, | ||
999 | 999 | |
1000 | 1000 | gen_base_offset_addr(ctx, taddr, base, offset); |
1001 | 1001 | tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx); |
1002 | -#ifdef TARGET_WORDS_BIGENDIAN | |
1003 | - tcg_gen_extr_i64_tl(tmp2, tmp1, tval); | |
1004 | -#else | |
1005 | - tcg_gen_extr_i64_tl(tmp1, tmp2, tval); | |
1006 | -#endif | |
1002 | + if (cpu_is_bigendian(ctx)) { | |
1003 | + tcg_gen_extr_i64_tl(tmp2, tmp1, tval); | |
1004 | + } else { | |
1005 | + tcg_gen_extr_i64_tl(tmp1, tmp2, tval); | |
1006 | + } | |
1007 | 1007 | gen_store_gpr(tmp1, reg1); |
1008 | 1008 | tcg_temp_free(tmp1); |
1009 | 1009 | gen_store_gpr(tmp2, reg2); |
@@ -1035,11 +1035,11 @@ static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset, | ||
1035 | 1035 | gen_load_gpr(tmp1, reg1); |
1036 | 1036 | gen_load_gpr(tmp2, reg2); |
1037 | 1037 | |
1038 | -#ifdef TARGET_WORDS_BIGENDIAN | |
1039 | - tcg_gen_concat_tl_i64(tval, tmp2, tmp1); | |
1040 | -#else | |
1041 | - tcg_gen_concat_tl_i64(tval, tmp1, tmp2); | |
1042 | -#endif | |
1038 | + if (cpu_is_bigendian(ctx)) { | |
1039 | + tcg_gen_concat_tl_i64(tval, tmp2, tmp1); | |
1040 | + } else { | |
1041 | + tcg_gen_concat_tl_i64(tval, tmp1, tmp2); | |
1042 | + } | |
1043 | 1043 | |
1044 | 1044 | tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp)); |
1045 | 1045 | tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval, |
@@ -26,124 +26,6 @@ | ||
26 | 26 | #include "exec/memop.h" |
27 | 27 | #include "fpu_helper.h" |
28 | 28 | |
29 | -/* 64 bits arithmetic for 32 bits hosts */ | |
30 | -static inline uint64_t get_HILO(CPUMIPSState *env) | |
31 | -{ | |
32 | - return ((uint64_t)(env->active_tc.HI[0]) << 32) | | |
33 | - (uint32_t)env->active_tc.LO[0]; | |
34 | -} | |
35 | - | |
36 | -static inline target_ulong set_HIT0_LO(CPUMIPSState *env, uint64_t HILO) | |
37 | -{ | |
38 | - env->active_tc.LO[0] = (int32_t)(HILO & 0xFFFFFFFF); | |
39 | - return env->active_tc.HI[0] = (int32_t)(HILO >> 32); | |
40 | -} | |
41 | - | |
42 | -static inline target_ulong set_HI_LOT0(CPUMIPSState *env, uint64_t HILO) | |
43 | -{ | |
44 | - target_ulong tmp = env->active_tc.LO[0] = (int32_t)(HILO & 0xFFFFFFFF); | |
45 | - env->active_tc.HI[0] = (int32_t)(HILO >> 32); | |
46 | - return tmp; | |
47 | -} | |
48 | - | |
49 | -/* Multiplication variants of the vr54xx. */ | |
50 | -target_ulong helper_muls(CPUMIPSState *env, target_ulong arg1, | |
51 | - target_ulong arg2) | |
52 | -{ | |
53 | - return set_HI_LOT0(env, 0 - ((int64_t)(int32_t)arg1 * | |
54 | - (int64_t)(int32_t)arg2)); | |
55 | -} | |
56 | - | |
57 | -target_ulong helper_mulsu(CPUMIPSState *env, target_ulong arg1, | |
58 | - target_ulong arg2) | |
59 | -{ | |
60 | - return set_HI_LOT0(env, 0 - (uint64_t)(uint32_t)arg1 * | |
61 | - (uint64_t)(uint32_t)arg2); | |
62 | -} | |
63 | - | |
64 | -target_ulong helper_macc(CPUMIPSState *env, target_ulong arg1, | |
65 | - target_ulong arg2) | |
66 | -{ | |
67 | - return set_HI_LOT0(env, (int64_t)get_HILO(env) + (int64_t)(int32_t)arg1 * | |
68 | - (int64_t)(int32_t)arg2); | |
69 | -} | |
70 | - | |
71 | -target_ulong helper_macchi(CPUMIPSState *env, target_ulong arg1, | |
72 | - target_ulong arg2) | |
73 | -{ | |
74 | - return set_HIT0_LO(env, (int64_t)get_HILO(env) + (int64_t)(int32_t)arg1 * | |
75 | - (int64_t)(int32_t)arg2); | |
76 | -} | |
77 | - | |
78 | -target_ulong helper_maccu(CPUMIPSState *env, target_ulong arg1, | |
79 | - target_ulong arg2) | |
80 | -{ | |
81 | - return set_HI_LOT0(env, (uint64_t)get_HILO(env) + | |
82 | - (uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2); | |
83 | -} | |
84 | - | |
85 | -target_ulong helper_macchiu(CPUMIPSState *env, target_ulong arg1, | |
86 | - target_ulong arg2) | |
87 | -{ | |
88 | - return set_HIT0_LO(env, (uint64_t)get_HILO(env) + | |
89 | - (uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2); | |
90 | -} | |
91 | - | |
92 | -target_ulong helper_msac(CPUMIPSState *env, target_ulong arg1, | |
93 | - target_ulong arg2) | |
94 | -{ | |
95 | - return set_HI_LOT0(env, (int64_t)get_HILO(env) - (int64_t)(int32_t)arg1 * | |
96 | - (int64_t)(int32_t)arg2); | |
97 | -} | |
98 | - | |
99 | -target_ulong helper_msachi(CPUMIPSState *env, target_ulong arg1, | |
100 | - target_ulong arg2) | |
101 | -{ | |
102 | - return set_HIT0_LO(env, (int64_t)get_HILO(env) - (int64_t)(int32_t)arg1 * | |
103 | - (int64_t)(int32_t)arg2); | |
104 | -} | |
105 | - | |
106 | -target_ulong helper_msacu(CPUMIPSState *env, target_ulong arg1, | |
107 | - target_ulong arg2) | |
108 | -{ | |
109 | - return set_HI_LOT0(env, (uint64_t)get_HILO(env) - | |
110 | - (uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2); | |
111 | -} | |
112 | - | |
113 | -target_ulong helper_msachiu(CPUMIPSState *env, target_ulong arg1, | |
114 | - target_ulong arg2) | |
115 | -{ | |
116 | - return set_HIT0_LO(env, (uint64_t)get_HILO(env) - | |
117 | - (uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2); | |
118 | -} | |
119 | - | |
120 | -target_ulong helper_mulhi(CPUMIPSState *env, target_ulong arg1, | |
121 | - target_ulong arg2) | |
122 | -{ | |
123 | - return set_HIT0_LO(env, (int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2); | |
124 | -} | |
125 | - | |
126 | -target_ulong helper_mulhiu(CPUMIPSState *env, target_ulong arg1, | |
127 | - target_ulong arg2) | |
128 | -{ | |
129 | - return set_HIT0_LO(env, (uint64_t)(uint32_t)arg1 * | |
130 | - (uint64_t)(uint32_t)arg2); | |
131 | -} | |
132 | - | |
133 | -target_ulong helper_mulshi(CPUMIPSState *env, target_ulong arg1, | |
134 | - target_ulong arg2) | |
135 | -{ | |
136 | - return set_HIT0_LO(env, 0 - (int64_t)(int32_t)arg1 * | |
137 | - (int64_t)(int32_t)arg2); | |
138 | -} | |
139 | - | |
140 | -target_ulong helper_mulshiu(CPUMIPSState *env, target_ulong arg1, | |
141 | - target_ulong arg2) | |
142 | -{ | |
143 | - return set_HIT0_LO(env, 0 - (uint64_t)(uint32_t)arg1 * | |
144 | - (uint64_t)(uint32_t)arg2); | |
145 | -} | |
146 | - | |
147 | 29 | static inline target_ulong bitswap(target_ulong v) |
148 | 30 | { |
149 | 31 | v = ((v >> 1) & (target_ulong)0x5555555555555555ULL) | |
@@ -5,21 +5,29 @@ | ||
5 | 5 | # SPDX-License-Identifier: LGPL-2.1-or-later |
6 | 6 | # |
7 | 7 | # Reference: |
8 | +# | |
8 | 9 | # MIPS Architecture for Programmers Volume II-A |
9 | 10 | # The MIPS32 Instruction Set Reference Manual, Revision 6.06 |
10 | 11 | # (Document Number: MD00086-2B-MIPS32BIS-AFP-06.06) |
11 | 12 | # |
13 | +# MIPS Architecture for Programmers Volume II-A | |
14 | +# The MIPS64 Instruction Set Reference Manual, Revision 6.06 | |
15 | +# (Document Number: MD00087-2B-MIPS64BIS-AFP-6.06) | |
12 | 16 | |
13 | -&rtype rs rt rd sa | |
17 | +&r rs rt rd sa | |
14 | 18 | |
15 | -@lsa ...... rs:5 rt:5 rd:5 ... sa:2 ...... &rtype | |
19 | +@lsa ...... rs:5 rt:5 rd:5 ... sa:2 ...... &r | |
16 | 20 | |
17 | 21 | LSA 000000 ..... ..... ..... 000 .. 000101 @lsa |
22 | +DLSA 000000 ..... ..... ..... 000 .. 010101 @lsa | |
18 | 23 | |
19 | 24 | REMOVED 010011 ----- ----- ----- ----- ------ # COP1X (COP3) |
20 | 25 | |
21 | 26 | REMOVED 011100 ----- ----- ----- ----- ------ # SPECIAL2 |
22 | 27 | |
28 | +REMOVED 011010 ----- ----- ---------------- # LDL | |
29 | +REMOVED 011011 ----- ----- ---------------- # LDR | |
30 | + | |
23 | 31 | REMOVED 011111 ----- ----- ---------- 011001 # LWLE |
24 | 32 | REMOVED 011111 ----- ----- ---------- 011010 # LWRE |
25 | 33 | REMOVED 011111 ----- ----- ---------- 100001 # SWLE |
@@ -28,9 +36,14 @@ REMOVED 011111 ----- ----- ---------- 100010 # SWRE | ||
28 | 36 | REMOVED 100010 ----- ----- ---------------- # LWL |
29 | 37 | REMOVED 100110 ----- ----- ---------------- # LWR |
30 | 38 | REMOVED 101010 ----- ----- ---------------- # SWL |
39 | +REMOVED 101100 ----- ----- ---------------- # SDL | |
40 | +REMOVED 101101 ----- ----- ---------------- # SDR | |
31 | 41 | REMOVED 101110 ----- ----- ---------------- # SWR |
32 | 42 | |
33 | 43 | REMOVED 101111 ----- ----- ---------------- # CACHE |
44 | + | |
34 | 45 | REMOVED 110000 ----- ----- ---------------- # LL |
35 | 46 | REMOVED 110011 ----- ----- ---------------- # PREF |
47 | +REMOVED 110100 ----- ----- ---------------- # LLD | |
36 | 48 | REMOVED 111000 ----- ----- ---------------- # SC |
49 | +REMOVED 111100 ----- ----- ---------------- # SCD |
@@ -13,9 +13,8 @@ | ||
13 | 13 | #include "exec/helper-gen.h" |
14 | 14 | #include "translate.h" |
15 | 15 | |
16 | -/* Include the auto-generated decoder. */ | |
17 | -#include "decode-mips32r6.c.inc" | |
18 | -#include "decode-mips64r6.c.inc" | |
16 | +/* Include the auto-generated decoders. */ | |
17 | +#include "decode-rel6.c.inc" | |
19 | 18 | |
20 | 19 | bool trans_REMOVED(DisasContext *ctx, arg_REMOVED *a) |
21 | 20 | { |
@@ -24,20 +23,15 @@ bool trans_REMOVED(DisasContext *ctx, arg_REMOVED *a) | ||
24 | 23 | return true; |
25 | 24 | } |
26 | 25 | |
27 | -static bool trans_LSA(DisasContext *ctx, arg_rtype *a) | |
26 | +static bool trans_LSA(DisasContext *ctx, arg_r *a) | |
28 | 27 | { |
29 | 28 | return gen_lsa(ctx, a->rd, a->rt, a->rs, a->sa); |
30 | 29 | } |
31 | 30 | |
32 | -static bool trans_DLSA(DisasContext *ctx, arg_rtype *a) | |
31 | +static bool trans_DLSA(DisasContext *ctx, arg_r *a) | |
33 | 32 | { |
34 | - return gen_dlsa(ctx, a->rd, a->rt, a->rs, a->sa); | |
35 | -} | |
36 | - | |
37 | -bool decode_isa_rel6(DisasContext *ctx, uint32_t insn) | |
38 | -{ | |
39 | - if (TARGET_LONG_BITS == 64 && decode_mips64r6(ctx, insn)) { | |
40 | - return true; | |
33 | + if (TARGET_LONG_BITS != 64) { | |
34 | + return false; | |
41 | 35 | } |
42 | - return decode_mips32r6(ctx, insn); | |
36 | + return gen_dlsa(ctx, a->rd, a->rt, a->rs, a->sa); | |
43 | 37 | } |
@@ -294,26 +294,6 @@ enum { | ||
294 | 294 | R6_OPC_SDBBP = 0x0e | OPC_SPECIAL, |
295 | 295 | }; |
296 | 296 | |
297 | -/* Multiplication variants of the vr54xx. */ | |
298 | -#define MASK_MUL_VR54XX(op) (MASK_SPECIAL(op) | (op & (0x1F << 6))) | |
299 | - | |
300 | -enum { | |
301 | - OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT, | |
302 | - OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU, | |
303 | - OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT, | |
304 | - OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU, | |
305 | - OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT, | |
306 | - OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU, | |
307 | - OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT, | |
308 | - OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU, | |
309 | - OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT, | |
310 | - OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU, | |
311 | - OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT, | |
312 | - OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU, | |
313 | - OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT, | |
314 | - OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU, | |
315 | -}; | |
316 | - | |
317 | 297 | /* REGIMM (rt field) opcodes */ |
318 | 298 | #define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16))) |
319 | 299 |
@@ -1233,48 +1213,6 @@ TCGv_i64 fpu_f64[32]; | ||
1233 | 1213 | |
1234 | 1214 | #include "exec/gen-icount.h" |
1235 | 1215 | |
1236 | -#define gen_helper_0e0i(name, arg) do { \ | |
1237 | - TCGv_i32 helper_tmp = tcg_const_i32(arg); \ | |
1238 | - gen_helper_##name(cpu_env, helper_tmp); \ | |
1239 | - tcg_temp_free_i32(helper_tmp); \ | |
1240 | - } while (0) | |
1241 | - | |
1242 | -#define gen_helper_0e1i(name, arg1, arg2) do { \ | |
1243 | - TCGv_i32 helper_tmp = tcg_const_i32(arg2); \ | |
1244 | - gen_helper_##name(cpu_env, arg1, helper_tmp); \ | |
1245 | - tcg_temp_free_i32(helper_tmp); \ | |
1246 | - } while (0) | |
1247 | - | |
1248 | -#define gen_helper_1e0i(name, ret, arg1) do { \ | |
1249 | - TCGv_i32 helper_tmp = tcg_const_i32(arg1); \ | |
1250 | - gen_helper_##name(ret, cpu_env, helper_tmp); \ | |
1251 | - tcg_temp_free_i32(helper_tmp); \ | |
1252 | - } while (0) | |
1253 | - | |
1254 | -#define gen_helper_1e1i(name, ret, arg1, arg2) do { \ | |
1255 | - TCGv_i32 helper_tmp = tcg_const_i32(arg2); \ | |
1256 | - gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \ | |
1257 | - tcg_temp_free_i32(helper_tmp); \ | |
1258 | - } while (0) | |
1259 | - | |
1260 | -#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \ | |
1261 | - TCGv_i32 helper_tmp = tcg_const_i32(arg3); \ | |
1262 | - gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \ | |
1263 | - tcg_temp_free_i32(helper_tmp); \ | |
1264 | - } while (0) | |
1265 | - | |
1266 | -#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \ | |
1267 | - TCGv_i32 helper_tmp = tcg_const_i32(arg3); \ | |
1268 | - gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \ | |
1269 | - tcg_temp_free_i32(helper_tmp); \ | |
1270 | - } while (0) | |
1271 | - | |
1272 | -#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \ | |
1273 | - TCGv_i32 helper_tmp = tcg_const_i32(arg4); \ | |
1274 | - gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \ | |
1275 | - tcg_temp_free_i32(helper_tmp); \ | |
1276 | - } while (0) | |
1277 | - | |
1278 | 1216 | #define DISAS_STOP DISAS_TARGET_0 |
1279 | 1217 | #define DISAS_EXIT DISAS_TARGET_1 |
1280 | 1218 |
@@ -1413,18 +1351,15 @@ static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx) | ||
1413 | 1351 | |
1414 | 1352 | void generate_exception_err(DisasContext *ctx, int excp, int err) |
1415 | 1353 | { |
1416 | - TCGv_i32 texcp = tcg_const_i32(excp); | |
1417 | - TCGv_i32 terr = tcg_const_i32(err); | |
1418 | 1354 | save_cpu_state(ctx, 1); |
1419 | - gen_helper_raise_exception_err(cpu_env, texcp, terr); | |
1420 | - tcg_temp_free_i32(terr); | |
1421 | - tcg_temp_free_i32(texcp); | |
1355 | + gen_helper_raise_exception_err(cpu_env, tcg_constant_i32(excp), | |
1356 | + tcg_constant_i32(err)); | |
1422 | 1357 | ctx->base.is_jmp = DISAS_NORETURN; |
1423 | 1358 | } |
1424 | 1359 | |
1425 | 1360 | void generate_exception(DisasContext *ctx, int excp) |
1426 | 1361 | { |
1427 | - gen_helper_0e0i(raise_exception, excp); | |
1362 | + gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp)); | |
1428 | 1363 | } |
1429 | 1364 | |
1430 | 1365 | void generate_exception_end(DisasContext *ctx, int excp) |
@@ -2033,7 +1968,7 @@ static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ | ||
2033 | 1968 | static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ |
2034 | 1969 | DisasContext *ctx) \ |
2035 | 1970 | { \ |
2036 | - gen_helper_1e1i(insn, ret, arg1, mem_idx); \ | |
1971 | + gen_helper_##insn(ret, cpu_env, arg1, tcg_constant_i32(mem_idx)); \ | |
2037 | 1972 | } |
2038 | 1973 | #endif |
2039 | 1974 | OP_LD_ATOMIC(ll, ld32s); |
@@ -2113,9 +2048,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, | ||
2113 | 2048 | */ |
2114 | 2049 | tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); |
2115 | 2050 | tcg_gen_andi_tl(t1, t0, 7); |
2116 | -#ifndef TARGET_WORDS_BIGENDIAN | |
2117 | - tcg_gen_xori_tl(t1, t1, 7); | |
2118 | -#endif | |
2051 | + if (!cpu_is_bigendian(ctx)) { | |
2052 | + tcg_gen_xori_tl(t1, t1, 7); | |
2053 | + } | |
2119 | 2054 | tcg_gen_shli_tl(t1, t1, 3); |
2120 | 2055 | tcg_gen_andi_tl(t0, t0, ~7); |
2121 | 2056 | tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ); |
@@ -2137,9 +2072,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, | ||
2137 | 2072 | */ |
2138 | 2073 | tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); |
2139 | 2074 | tcg_gen_andi_tl(t1, t0, 7); |
2140 | -#ifdef TARGET_WORDS_BIGENDIAN | |
2141 | - tcg_gen_xori_tl(t1, t1, 7); | |
2142 | -#endif | |
2075 | + if (cpu_is_bigendian(ctx)) { | |
2076 | + tcg_gen_xori_tl(t1, t1, 7); | |
2077 | + } | |
2143 | 2078 | tcg_gen_shli_tl(t1, t1, 3); |
2144 | 2079 | tcg_gen_andi_tl(t0, t0, ~7); |
2145 | 2080 | tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ); |
@@ -2218,9 +2153,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, | ||
2218 | 2153 | */ |
2219 | 2154 | tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); |
2220 | 2155 | tcg_gen_andi_tl(t1, t0, 3); |
2221 | -#ifndef TARGET_WORDS_BIGENDIAN | |
2222 | - tcg_gen_xori_tl(t1, t1, 3); | |
2223 | -#endif | |
2156 | + if (!cpu_is_bigendian(ctx)) { | |
2157 | + tcg_gen_xori_tl(t1, t1, 3); | |
2158 | + } | |
2224 | 2159 | tcg_gen_shli_tl(t1, t1, 3); |
2225 | 2160 | tcg_gen_andi_tl(t0, t0, ~3); |
2226 | 2161 | tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL); |
@@ -2246,9 +2181,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, | ||
2246 | 2181 | */ |
2247 | 2182 | tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); |
2248 | 2183 | tcg_gen_andi_tl(t1, t0, 3); |
2249 | -#ifdef TARGET_WORDS_BIGENDIAN | |
2250 | - tcg_gen_xori_tl(t1, t1, 3); | |
2251 | -#endif | |
2184 | + if (cpu_is_bigendian(ctx)) { | |
2185 | + tcg_gen_xori_tl(t1, t1, 3); | |
2186 | + } | |
2252 | 2187 | tcg_gen_shli_tl(t1, t1, 3); |
2253 | 2188 | tcg_gen_andi_tl(t0, t0, ~3); |
2254 | 2189 | tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL); |
@@ -3764,70 +3699,6 @@ static void gen_mul_txx9(DisasContext *ctx, uint32_t opc, | ||
3764 | 3699 | tcg_temp_free(t1); |
3765 | 3700 | } |
3766 | 3701 | |
3767 | -static void gen_mul_vr54xx(DisasContext *ctx, uint32_t opc, | |
3768 | - int rd, int rs, int rt) | |
3769 | -{ | |
3770 | - TCGv t0 = tcg_temp_new(); | |
3771 | - TCGv t1 = tcg_temp_new(); | |
3772 | - | |
3773 | - gen_load_gpr(t0, rs); | |
3774 | - gen_load_gpr(t1, rt); | |
3775 | - | |
3776 | - switch (opc) { | |
3777 | - case OPC_VR54XX_MULS: | |
3778 | - gen_helper_muls(t0, cpu_env, t0, t1); | |
3779 | - break; | |
3780 | - case OPC_VR54XX_MULSU: | |
3781 | - gen_helper_mulsu(t0, cpu_env, t0, t1); | |
3782 | - break; | |
3783 | - case OPC_VR54XX_MACC: | |
3784 | - gen_helper_macc(t0, cpu_env, t0, t1); | |
3785 | - break; | |
3786 | - case OPC_VR54XX_MACCU: | |
3787 | - gen_helper_maccu(t0, cpu_env, t0, t1); | |
3788 | - break; | |
3789 | - case OPC_VR54XX_MSAC: | |
3790 | - gen_helper_msac(t0, cpu_env, t0, t1); | |
3791 | - break; | |
3792 | - case OPC_VR54XX_MSACU: | |
3793 | - gen_helper_msacu(t0, cpu_env, t0, t1); | |
3794 | - break; | |
3795 | - case OPC_VR54XX_MULHI: | |
3796 | - gen_helper_mulhi(t0, cpu_env, t0, t1); | |
3797 | - break; | |
3798 | - case OPC_VR54XX_MULHIU: | |
3799 | - gen_helper_mulhiu(t0, cpu_env, t0, t1); | |
3800 | - break; | |
3801 | - case OPC_VR54XX_MULSHI: | |
3802 | - gen_helper_mulshi(t0, cpu_env, t0, t1); | |
3803 | - break; | |
3804 | - case OPC_VR54XX_MULSHIU: | |
3805 | - gen_helper_mulshiu(t0, cpu_env, t0, t1); | |
3806 | - break; | |
3807 | - case OPC_VR54XX_MACCHI: | |
3808 | - gen_helper_macchi(t0, cpu_env, t0, t1); | |
3809 | - break; | |
3810 | - case OPC_VR54XX_MACCHIU: | |
3811 | - gen_helper_macchiu(t0, cpu_env, t0, t1); | |
3812 | - break; | |
3813 | - case OPC_VR54XX_MSACHI: | |
3814 | - gen_helper_msachi(t0, cpu_env, t0, t1); | |
3815 | - break; | |
3816 | - case OPC_VR54XX_MSACHIU: | |
3817 | - gen_helper_msachiu(t0, cpu_env, t0, t1); | |
3818 | - break; | |
3819 | - default: | |
3820 | - MIPS_INVAL("mul vr54xx"); | |
3821 | - gen_reserved_instruction(ctx); | |
3822 | - goto out; | |
3823 | - } | |
3824 | - gen_store_gpr(t0, rd); | |
3825 | - | |
3826 | - out: | |
3827 | - tcg_temp_free(t0); | |
3828 | - tcg_temp_free(t1); | |
3829 | -} | |
3830 | - | |
3831 | 3702 | static void gen_cl(DisasContext *ctx, uint32_t opc, |
3832 | 3703 | int rd, int rs) |
3833 | 3704 | { |
@@ -4529,9 +4400,9 @@ static void gen_loongson_lswc2(DisasContext *ctx, int rt, | ||
4529 | 4400 | t1 = tcg_temp_new(); |
4530 | 4401 | tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); |
4531 | 4402 | tcg_gen_andi_tl(t1, t0, 3); |
4532 | -#ifndef TARGET_WORDS_BIGENDIAN | |
4533 | - tcg_gen_xori_tl(t1, t1, 3); | |
4534 | -#endif | |
4403 | + if (!cpu_is_bigendian(ctx)) { | |
4404 | + tcg_gen_xori_tl(t1, t1, 3); | |
4405 | + } | |
4535 | 4406 | tcg_gen_shli_tl(t1, t1, 3); |
4536 | 4407 | tcg_gen_andi_tl(t0, t0, ~3); |
4537 | 4408 | tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL); |
@@ -4559,9 +4430,9 @@ static void gen_loongson_lswc2(DisasContext *ctx, int rt, | ||
4559 | 4430 | t1 = tcg_temp_new(); |
4560 | 4431 | tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); |
4561 | 4432 | tcg_gen_andi_tl(t1, t0, 3); |
4562 | -#ifdef TARGET_WORDS_BIGENDIAN | |
4563 | - tcg_gen_xori_tl(t1, t1, 3); | |
4564 | -#endif | |
4433 | + if (cpu_is_bigendian(ctx)) { | |
4434 | + tcg_gen_xori_tl(t1, t1, 3); | |
4435 | + } | |
4565 | 4436 | tcg_gen_shli_tl(t1, t1, 3); |
4566 | 4437 | tcg_gen_andi_tl(t0, t0, ~3); |
4567 | 4438 | tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL); |
@@ -4591,9 +4462,9 @@ static void gen_loongson_lswc2(DisasContext *ctx, int rt, | ||
4591 | 4462 | t1 = tcg_temp_new(); |
4592 | 4463 | tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); |
4593 | 4464 | tcg_gen_andi_tl(t1, t0, 7); |
4594 | -#ifndef TARGET_WORDS_BIGENDIAN | |
4595 | - tcg_gen_xori_tl(t1, t1, 7); | |
4596 | -#endif | |
4465 | + if (!cpu_is_bigendian(ctx)) { | |
4466 | + tcg_gen_xori_tl(t1, t1, 7); | |
4467 | + } | |
4597 | 4468 | tcg_gen_shli_tl(t1, t1, 3); |
4598 | 4469 | tcg_gen_andi_tl(t0, t0, ~7); |
4599 | 4470 | tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ); |
@@ -4613,9 +4484,9 @@ static void gen_loongson_lswc2(DisasContext *ctx, int rt, | ||
4613 | 4484 | t1 = tcg_temp_new(); |
4614 | 4485 | tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); |
4615 | 4486 | tcg_gen_andi_tl(t1, t0, 7); |
4616 | -#ifdef TARGET_WORDS_BIGENDIAN | |
4617 | - tcg_gen_xori_tl(t1, t1, 7); | |
4618 | -#endif | |
4487 | + if (cpu_is_bigendian(ctx)) { | |
4488 | + tcg_gen_xori_tl(t1, t1, 7); | |
4489 | + } | |
4619 | 4490 | tcg_gen_shli_tl(t1, t1, 3); |
4620 | 4491 | tcg_gen_andi_tl(t0, t0, ~7); |
4621 | 4492 | tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ); |
@@ -4777,7 +4648,6 @@ static void gen_loongson_lsdc2(DisasContext *ctx, int rt, | ||
4777 | 4648 | break; |
4778 | 4649 | #endif |
4779 | 4650 | case OPC_GSLWXC1: |
4780 | - check_cp1_enabled(ctx); | |
4781 | 4651 | gen_base_offset_addr(ctx, t0, rs, offset); |
4782 | 4652 | if (rd) { |
4783 | 4653 | gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); |
@@ -4790,7 +4660,6 @@ static void gen_loongson_lsdc2(DisasContext *ctx, int rt, | ||
4790 | 4660 | break; |
4791 | 4661 | #if defined(TARGET_MIPS64) |
4792 | 4662 | case OPC_GSLDXC1: |
4793 | - check_cp1_enabled(ctx); | |
4794 | 4663 | gen_base_offset_addr(ctx, t0, rs, offset); |
4795 | 4664 | if (rd) { |
4796 | 4665 | gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0); |
@@ -9170,12 +9039,7 @@ static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt, | ||
9170 | 9039 | break; |
9171 | 9040 | case 3: |
9172 | 9041 | /* XXX: For now we support only a single FPU context. */ |
9173 | - { | |
9174 | - TCGv_i32 fs_tmp = tcg_const_i32(rd); | |
9175 | - | |
9176 | - gen_helper_0e2i(ctc1, t0, fs_tmp, rt); | |
9177 | - tcg_temp_free_i32(fs_tmp); | |
9178 | - } | |
9042 | + gen_helper_0e2i(ctc1, t0, tcg_constant_i32(rd), rt); | |
9179 | 9043 | /* Stop translation as we may have changed hflags */ |
9180 | 9044 | ctx->base.is_jmp = DISAS_STOP; |
9181 | 9045 | break; |
@@ -9792,12 +9656,7 @@ static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs) | ||
9792 | 9656 | case OPC_CTC1: |
9793 | 9657 | gen_load_gpr(t0, rt); |
9794 | 9658 | save_cpu_state(ctx, 0); |
9795 | - { | |
9796 | - TCGv_i32 fs_tmp = tcg_const_i32(fs); | |
9797 | - | |
9798 | - gen_helper_0e2i(ctc1, t0, fs_tmp, rt); | |
9799 | - tcg_temp_free_i32(fs_tmp); | |
9800 | - } | |
9659 | + gen_helper_0e2i(ctc1, t0, tcg_constant_i32(fs), rt); | |
9801 | 9660 | /* Stop translation as we may have changed hflags */ |
9802 | 9661 | ctx->base.is_jmp = DISAS_STOP; |
9803 | 9662 | break; |
@@ -11550,17 +11409,17 @@ static void gen_flt3_arith(DisasContext *ctx, uint32_t opc, | ||
11550 | 11409 | gen_set_label(l1); |
11551 | 11410 | tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2); |
11552 | 11411 | tcg_temp_free(t0); |
11553 | -#ifdef TARGET_WORDS_BIGENDIAN | |
11554 | - gen_load_fpr32(ctx, fp, fs); | |
11555 | - gen_load_fpr32h(ctx, fph, ft); | |
11556 | - gen_store_fpr32h(ctx, fp, fd); | |
11557 | - gen_store_fpr32(ctx, fph, fd); | |
11558 | -#else | |
11559 | - gen_load_fpr32h(ctx, fph, fs); | |
11560 | - gen_load_fpr32(ctx, fp, ft); | |
11561 | - gen_store_fpr32(ctx, fph, fd); | |
11562 | - gen_store_fpr32h(ctx, fp, fd); | |
11563 | -#endif | |
11412 | + if (cpu_is_bigendian(ctx)) { | |
11413 | + gen_load_fpr32(ctx, fp, fs); | |
11414 | + gen_load_fpr32h(ctx, fph, ft); | |
11415 | + gen_store_fpr32h(ctx, fp, fd); | |
11416 | + gen_store_fpr32(ctx, fph, fd); | |
11417 | + } else { | |
11418 | + gen_load_fpr32h(ctx, fph, fs); | |
11419 | + gen_load_fpr32(ctx, fp, ft); | |
11420 | + gen_store_fpr32(ctx, fph, fd); | |
11421 | + gen_store_fpr32h(ctx, fp, fd); | |
11422 | + } | |
11564 | 11423 | gen_set_label(l2); |
11565 | 11424 | tcg_temp_free_i32(fp); |
11566 | 11425 | tcg_temp_free_i32(fph); |
@@ -14144,13 +14003,12 @@ static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx) | ||
14144 | 14003 | |
14145 | 14004 | static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) |
14146 | 14005 | { |
14147 | - int rs, rt, rd, sa; | |
14006 | + int rs, rt, rd; | |
14148 | 14007 | uint32_t op1; |
14149 | 14008 | |
14150 | 14009 | rs = (ctx->opcode >> 21) & 0x1f; |
14151 | 14010 | rt = (ctx->opcode >> 16) & 0x1f; |
14152 | 14011 | rd = (ctx->opcode >> 11) & 0x1f; |
14153 | - sa = (ctx->opcode >> 6) & 0x1f; | |
14154 | 14012 | |
14155 | 14013 | op1 = MASK_SPECIAL(ctx->opcode); |
14156 | 14014 | switch (op1) { |
@@ -14180,13 +14038,7 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) | ||
14180 | 14038 | break; |
14181 | 14039 | case OPC_MULT: |
14182 | 14040 | case OPC_MULTU: |
14183 | - if (sa) { | |
14184 | - check_insn(ctx, INSN_VR54XX); | |
14185 | - op1 = MASK_MUL_VR54XX(ctx->opcode); | |
14186 | - gen_mul_vr54xx(ctx, op1, rd, rs, rt); | |
14187 | - } else { | |
14188 | - gen_muldiv(ctx, op1, rd & 3, rs, rt); | |
14189 | - } | |
14041 | + gen_muldiv(ctx, op1, rd & 3, rs, rt); | |
14190 | 14042 | break; |
14191 | 14043 | case OPC_DIV: |
14192 | 14044 | case OPC_DIVU: |
@@ -14203,7 +14055,7 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) | ||
14203 | 14055 | break; |
14204 | 14056 | #endif |
14205 | 14057 | case OPC_JR: |
14206 | - gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4); | |
14058 | + gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4); | |
14207 | 14059 | break; |
14208 | 14060 | case OPC_SPIM: |
14209 | 14061 | #ifdef MIPS_STRICT_STANDARD |
@@ -14317,7 +14169,7 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) | ||
14317 | 14169 | MIPS_INVAL("PMON / selsl"); |
14318 | 14170 | gen_reserved_instruction(ctx); |
14319 | 14171 | #else |
14320 | - gen_helper_0e0i(pmon, sa); | |
14172 | + gen_helper_pmon(cpu_env, tcg_constant_i32(sa)); | |
14321 | 14173 | #endif |
14322 | 14174 | break; |
14323 | 14175 | case OPC_SYSCALL: |
@@ -15739,12 +15591,8 @@ static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx) | ||
15739 | 15591 | /* Treat as NOP. */ |
15740 | 15592 | break; |
15741 | 15593 | case OPC_PREF: |
15742 | - if (ctx->insn_flags & INSN_R5900) { | |
15743 | - /* Treat as NOP. */ | |
15744 | - } else { | |
15745 | - check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1); | |
15746 | - /* Treat as NOP. */ | |
15747 | - } | |
15594 | + check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | INSN_R5900); | |
15595 | + /* Treat as NOP. */ | |
15748 | 15596 | break; |
15749 | 15597 | |
15750 | 15598 | /* Floating point (COP1). */ |
@@ -16098,6 +15946,14 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) | ||
16098 | 15946 | |
16099 | 15947 | /* Transition to the auto-generated decoder. */ |
16100 | 15948 | |
15949 | + /* Vendor specific extensions */ | |
15950 | + if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) { | |
15951 | + return; | |
15952 | + } | |
15953 | + if (cpu_supports_isa(env, INSN_VR54XX) && decode_ext_vr54xx(ctx, ctx->opcode)) { | |
15954 | + return; | |
15955 | + } | |
15956 | + | |
16101 | 15957 | /* ISA extensions */ |
16102 | 15958 | if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) { |
16103 | 15959 | return; |
@@ -16107,9 +15963,6 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) | ||
16107 | 15963 | if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) { |
16108 | 15964 | return; |
16109 | 15965 | } |
16110 | - if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) { | |
16111 | - return; | |
16112 | - } | |
16113 | 15966 | |
16114 | 15967 | if (decode_opc_legacy(env, ctx)) { |
16115 | 15968 | return; |
@@ -16126,6 +15979,7 @@ static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) | ||
16126 | 15979 | ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK; |
16127 | 15980 | ctx->saved_pc = -1; |
16128 | 15981 | ctx->insn_flags = env->insn_flags; |
15982 | + ctx->CP0_Config0 = env->CP0_Config0; | |
16129 | 15983 | ctx->CP0_Config1 = env->CP0_Config1; |
16130 | 15984 | ctx->CP0_Config2 = env->CP0_Config2; |
16131 | 15985 | ctx->CP0_Config3 = env->CP0_Config3; |
@@ -18,6 +18,7 @@ typedef struct DisasContext { | ||
18 | 18 | target_ulong page_start; |
19 | 19 | uint32_t opcode; |
20 | 20 | uint64_t insn_flags; |
21 | + int32_t CP0_Config0; | |
21 | 22 | int32_t CP0_Config1; |
22 | 23 | int32_t CP0_Config2; |
23 | 24 | int32_t CP0_Config3; |
@@ -113,6 +114,18 @@ enum { | ||
113 | 114 | OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4, |
114 | 115 | }; |
115 | 116 | |
117 | +#define gen_helper_0e1i(name, arg1, arg2) do { \ | |
118 | + gen_helper_##name(cpu_env, arg1, tcg_constant_i32(arg2)); \ | |
119 | + } while (0) | |
120 | + | |
121 | +#define gen_helper_1e0i(name, ret, arg1) do { \ | |
122 | + gen_helper_##name(ret, cpu_env, tcg_constant_i32(arg1)); \ | |
123 | + } while (0) | |
124 | + | |
125 | +#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \ | |
126 | + gen_helper_##name(cpu_env, arg1, arg2, tcg_constant_i32(arg3));\ | |
127 | + } while (0) | |
128 | + | |
116 | 129 | void generate_exception(DisasContext *ctx, int excp); |
117 | 130 | void generate_exception_err(DisasContext *ctx, int excp, int err); |
118 | 131 | void generate_exception_end(DisasContext *ctx, int excp); |
@@ -201,5 +214,19 @@ bool decode_ext_txx9(DisasContext *ctx, uint32_t insn); | ||
201 | 214 | #if defined(TARGET_MIPS64) |
202 | 215 | bool decode_ext_tx79(DisasContext *ctx, uint32_t insn); |
203 | 216 | #endif |
217 | +bool decode_ext_vr54xx(DisasContext *ctx, uint32_t insn); | |
218 | + | |
219 | +/* | |
220 | + * Helpers for implementing sets of trans_* functions. | |
221 | + * Defer the implementation of NAME to FUNC, with optional extra arguments. | |
222 | + */ | |
223 | +#define TRANS(NAME, FUNC, ...) \ | |
224 | + static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a) \ | |
225 | + { return FUNC(ctx, a, __VA_ARGS__); } | |
226 | + | |
227 | +static inline bool cpu_is_bigendian(DisasContext *ctx) | |
228 | +{ | |
229 | + return extract32(ctx->CP0_Config0, CP0C0_BE, 1); | |
230 | +} | |
204 | 231 | |
205 | 232 | #endif |
@@ -11,20 +11,20 @@ | ||
11 | 11 | # when creating helpers common to those for the individual |
12 | 12 | # instruction patterns. |
13 | 13 | |
14 | -&rtype rs rt rd sa | |
14 | +&r rs rt rd sa | |
15 | 15 | |
16 | -&itype base rt offset | |
16 | +&i base rt offset | |
17 | 17 | |
18 | 18 | ########################################################################### |
19 | 19 | # Named instruction formats. These are generally used to |
20 | 20 | # reduce the amount of duplication between instruction patterns. |
21 | 21 | |
22 | -@rs_rt_rd ...... rs:5 rt:5 rd:5 ..... ...... &rtype sa=0 | |
23 | -@rt_rd ...... ..... rt:5 rd:5 ..... ...... &rtype rs=0 sa=0 | |
24 | -@rs ...... rs:5 ..... .......... ...... &rtype rt=0 rd=0 sa=0 | |
25 | -@rd ...... .......... rd:5 ..... ...... &rtype rs=0 rt=0 sa=0 | |
22 | +@rs_rt_rd ...... rs:5 rt:5 rd:5 ..... ...... &r sa=0 | |
23 | +@rt_rd ...... ..... rt:5 rd:5 ..... ...... &r sa=0 rs=0 | |
24 | +@rs ...... rs:5 ..... .......... ...... &r sa=0 rt=0 rd=0 | |
25 | +@rd ...... .......... rd:5 ..... ...... &r sa=0 rs=0 rt=0 | |
26 | 26 | |
27 | -@ldst ...... base:5 rt:5 offset:16 &itype | |
27 | +@ldst ...... base:5 rt:5 offset:16 &i | |
28 | 28 | |
29 | 29 | ########################################################################### |
30 | 30 |
@@ -64,28 +64,28 @@ bool decode_ext_tx79(DisasContext *ctx, uint32_t insn) | ||
64 | 64 | * MTLO1 rs Move To LO1 Register |
65 | 65 | */ |
66 | 66 | |
67 | -static bool trans_MFHI1(DisasContext *ctx, arg_rtype *a) | |
67 | +static bool trans_MFHI1(DisasContext *ctx, arg_r *a) | |
68 | 68 | { |
69 | 69 | gen_store_gpr(cpu_HI[1], a->rd); |
70 | 70 | |
71 | 71 | return true; |
72 | 72 | } |
73 | 73 | |
74 | -static bool trans_MFLO1(DisasContext *ctx, arg_rtype *a) | |
74 | +static bool trans_MFLO1(DisasContext *ctx, arg_r *a) | |
75 | 75 | { |
76 | 76 | gen_store_gpr(cpu_LO[1], a->rd); |
77 | 77 | |
78 | 78 | return true; |
79 | 79 | } |
80 | 80 | |
81 | -static bool trans_MTHI1(DisasContext *ctx, arg_rtype *a) | |
81 | +static bool trans_MTHI1(DisasContext *ctx, arg_r *a) | |
82 | 82 | { |
83 | 83 | gen_load_gpr(cpu_HI[1], a->rs); |
84 | 84 | |
85 | 85 | return true; |
86 | 86 | } |
87 | 87 | |
88 | -static bool trans_MTLO1(DisasContext *ctx, arg_rtype *a) | |
88 | +static bool trans_MTLO1(DisasContext *ctx, arg_r *a) | |
89 | 89 | { |
90 | 90 | gen_load_gpr(cpu_LO[1], a->rs); |
91 | 91 |
@@ -116,7 +116,7 @@ static bool trans_MTLO1(DisasContext *ctx, arg_rtype *a) | ||
116 | 116 | * PSUBUW rd, rs, rt Parallel Subtract with Unsigned saturation Word |
117 | 117 | */ |
118 | 118 | |
119 | -static bool trans_parallel_arith(DisasContext *ctx, arg_rtype *a, | |
119 | +static bool trans_parallel_arith(DisasContext *ctx, arg_r *a, | |
120 | 120 | void (*gen_logic_i64)(TCGv_i64, TCGv_i64, TCGv_i64)) |
121 | 121 | { |
122 | 122 | TCGv_i64 ax, bx; |
@@ -146,19 +146,19 @@ static bool trans_parallel_arith(DisasContext *ctx, arg_rtype *a, | ||
146 | 146 | } |
147 | 147 | |
148 | 148 | /* Parallel Subtract Byte */ |
149 | -static bool trans_PSUBB(DisasContext *ctx, arg_rtype *a) | |
149 | +static bool trans_PSUBB(DisasContext *ctx, arg_r *a) | |
150 | 150 | { |
151 | 151 | return trans_parallel_arith(ctx, a, tcg_gen_vec_sub8_i64); |
152 | 152 | } |
153 | 153 | |
154 | 154 | /* Parallel Subtract Halfword */ |
155 | -static bool trans_PSUBH(DisasContext *ctx, arg_rtype *a) | |
155 | +static bool trans_PSUBH(DisasContext *ctx, arg_r *a) | |
156 | 156 | { |
157 | 157 | return trans_parallel_arith(ctx, a, tcg_gen_vec_sub16_i64); |
158 | 158 | } |
159 | 159 | |
160 | 160 | /* Parallel Subtract Word */ |
161 | -static bool trans_PSUBW(DisasContext *ctx, arg_rtype *a) | |
161 | +static bool trans_PSUBW(DisasContext *ctx, arg_r *a) | |
162 | 162 | { |
163 | 163 | return trans_parallel_arith(ctx, a, tcg_gen_vec_sub32_i64); |
164 | 164 | } |
@@ -189,25 +189,25 @@ static bool trans_PSUBW(DisasContext *ctx, arg_rtype *a) | ||
189 | 189 | */ |
190 | 190 | |
191 | 191 | /* Parallel And */ |
192 | -static bool trans_PAND(DisasContext *ctx, arg_rtype *a) | |
192 | +static bool trans_PAND(DisasContext *ctx, arg_r *a) | |
193 | 193 | { |
194 | 194 | return trans_parallel_arith(ctx, a, tcg_gen_and_i64); |
195 | 195 | } |
196 | 196 | |
197 | 197 | /* Parallel Or */ |
198 | -static bool trans_POR(DisasContext *ctx, arg_rtype *a) | |
198 | +static bool trans_POR(DisasContext *ctx, arg_r *a) | |
199 | 199 | { |
200 | 200 | return trans_parallel_arith(ctx, a, tcg_gen_or_i64); |
201 | 201 | } |
202 | 202 | |
203 | 203 | /* Parallel Exclusive Or */ |
204 | -static bool trans_PXOR(DisasContext *ctx, arg_rtype *a) | |
204 | +static bool trans_PXOR(DisasContext *ctx, arg_r *a) | |
205 | 205 | { |
206 | 206 | return trans_parallel_arith(ctx, a, tcg_gen_xor_i64); |
207 | 207 | } |
208 | 208 | |
209 | 209 | /* Parallel Not Or */ |
210 | -static bool trans_PNOR(DisasContext *ctx, arg_rtype *a) | |
210 | +static bool trans_PNOR(DisasContext *ctx, arg_r *a) | |
211 | 211 | { |
212 | 212 | return trans_parallel_arith(ctx, a, tcg_gen_nor_i64); |
213 | 213 | } |
@@ -237,7 +237,7 @@ static bool trans_PNOR(DisasContext *ctx, arg_rtype *a) | ||
237 | 237 | * PCEQW rd, rs, rt Parallel Compare for Equal Word |
238 | 238 | */ |
239 | 239 | |
240 | -static bool trans_parallel_compare(DisasContext *ctx, arg_rtype *a, | |
240 | +static bool trans_parallel_compare(DisasContext *ctx, arg_r *a, | |
241 | 241 | TCGCond cond, unsigned wlen) |
242 | 242 | { |
243 | 243 | TCGv_i64 c0, c1, ax, bx, t0, t1, t2; |
@@ -286,37 +286,37 @@ static bool trans_parallel_compare(DisasContext *ctx, arg_rtype *a, | ||
286 | 286 | } |
287 | 287 | |
288 | 288 | /* Parallel Compare for Greater Than Byte */ |
289 | -static bool trans_PCGTB(DisasContext *ctx, arg_rtype *a) | |
289 | +static bool trans_PCGTB(DisasContext *ctx, arg_r *a) | |
290 | 290 | { |
291 | 291 | return trans_parallel_compare(ctx, a, TCG_COND_GE, 8); |
292 | 292 | } |
293 | 293 | |
294 | 294 | /* Parallel Compare for Equal Byte */ |
295 | -static bool trans_PCEQB(DisasContext *ctx, arg_rtype *a) | |
295 | +static bool trans_PCEQB(DisasContext *ctx, arg_r *a) | |
296 | 296 | { |
297 | 297 | return trans_parallel_compare(ctx, a, TCG_COND_EQ, 8); |
298 | 298 | } |
299 | 299 | |
300 | 300 | /* Parallel Compare for Greater Than Halfword */ |
301 | -static bool trans_PCGTH(DisasContext *ctx, arg_rtype *a) | |
301 | +static bool trans_PCGTH(DisasContext *ctx, arg_r *a) | |
302 | 302 | { |
303 | 303 | return trans_parallel_compare(ctx, a, TCG_COND_GE, 16); |
304 | 304 | } |
305 | 305 | |
306 | 306 | /* Parallel Compare for Equal Halfword */ |
307 | -static bool trans_PCEQH(DisasContext *ctx, arg_rtype *a) | |
307 | +static bool trans_PCEQH(DisasContext *ctx, arg_r *a) | |
308 | 308 | { |
309 | 309 | return trans_parallel_compare(ctx, a, TCG_COND_EQ, 16); |
310 | 310 | } |
311 | 311 | |
312 | 312 | /* Parallel Compare for Greater Than Word */ |
313 | -static bool trans_PCGTW(DisasContext *ctx, arg_rtype *a) | |
313 | +static bool trans_PCGTW(DisasContext *ctx, arg_r *a) | |
314 | 314 | { |
315 | 315 | return trans_parallel_compare(ctx, a, TCG_COND_GE, 32); |
316 | 316 | } |
317 | 317 | |
318 | 318 | /* Parallel Compare for Equal Word */ |
319 | -static bool trans_PCEQW(DisasContext *ctx, arg_rtype *a) | |
319 | +static bool trans_PCEQW(DisasContext *ctx, arg_r *a) | |
320 | 320 | { |
321 | 321 | return trans_parallel_compare(ctx, a, TCG_COND_EQ, 32); |
322 | 322 | } |
@@ -334,7 +334,7 @@ static bool trans_PCEQW(DisasContext *ctx, arg_rtype *a) | ||
334 | 334 | * SQ rt, offset(base) Store Quadword |
335 | 335 | */ |
336 | 336 | |
337 | -static bool trans_LQ(DisasContext *ctx, arg_itype *a) | |
337 | +static bool trans_LQ(DisasContext *ctx, arg_i *a) | |
338 | 338 | { |
339 | 339 | TCGv_i64 t0; |
340 | 340 | TCGv addr; |
@@ -369,7 +369,7 @@ static bool trans_LQ(DisasContext *ctx, arg_itype *a) | ||
369 | 369 | return true; |
370 | 370 | } |
371 | 371 | |
372 | -static bool trans_SQ(DisasContext *ctx, arg_itype *a) | |
372 | +static bool trans_SQ(DisasContext *ctx, arg_i *a) | |
373 | 373 | { |
374 | 374 | TCGv_i64 t0 = tcg_temp_new_i64(); |
375 | 375 | TCGv addr = tcg_temp_new(); |
@@ -437,7 +437,7 @@ static bool trans_SQ(DisasContext *ctx, arg_itype *a) | ||
437 | 437 | */ |
438 | 438 | |
439 | 439 | /* Parallel Pack to Word */ |
440 | -static bool trans_PPACW(DisasContext *ctx, arg_rtype *a) | |
440 | +static bool trans_PPACW(DisasContext *ctx, arg_r *a) | |
441 | 441 | { |
442 | 442 | TCGv_i64 a0, b0, t0; |
443 | 443 |
@@ -473,7 +473,7 @@ static void gen_pextw(TCGv_i64 dl, TCGv_i64 dh, TCGv_i64 a, TCGv_i64 b) | ||
473 | 473 | tcg_gen_deposit_i64(dh, a, b, 0, 32); |
474 | 474 | } |
475 | 475 | |
476 | -static bool trans_PEXTLx(DisasContext *ctx, arg_rtype *a, unsigned wlen) | |
476 | +static bool trans_PEXTLx(DisasContext *ctx, arg_r *a, unsigned wlen) | |
477 | 477 | { |
478 | 478 | TCGv_i64 ax, bx; |
479 | 479 |
@@ -514,19 +514,19 @@ static bool trans_PEXTLx(DisasContext *ctx, arg_rtype *a, unsigned wlen) | ||
514 | 514 | } |
515 | 515 | |
516 | 516 | /* Parallel Extend Lower from Byte */ |
517 | -static bool trans_PEXTLB(DisasContext *ctx, arg_rtype *a) | |
517 | +static bool trans_PEXTLB(DisasContext *ctx, arg_r *a) | |
518 | 518 | { |
519 | 519 | return trans_PEXTLx(ctx, a, 8); |
520 | 520 | } |
521 | 521 | |
522 | 522 | /* Parallel Extend Lower from Halfword */ |
523 | -static bool trans_PEXTLH(DisasContext *ctx, arg_rtype *a) | |
523 | +static bool trans_PEXTLH(DisasContext *ctx, arg_r *a) | |
524 | 524 | { |
525 | 525 | return trans_PEXTLx(ctx, a, 16); |
526 | 526 | } |
527 | 527 | |
528 | 528 | /* Parallel Extend Lower from Word */ |
529 | -static bool trans_PEXTLW(DisasContext *ctx, arg_rtype *a) | |
529 | +static bool trans_PEXTLW(DisasContext *ctx, arg_r *a) | |
530 | 530 | { |
531 | 531 | TCGv_i64 ax, bx; |
532 | 532 |
@@ -549,7 +549,7 @@ static bool trans_PEXTLW(DisasContext *ctx, arg_rtype *a) | ||
549 | 549 | } |
550 | 550 | |
551 | 551 | /* Parallel Extend Upper from Word */ |
552 | -static bool trans_PEXTUW(DisasContext *ctx, arg_rtype *a) | |
552 | +static bool trans_PEXTUW(DisasContext *ctx, arg_r *a) | |
553 | 553 | { |
554 | 554 | TCGv_i64 ax, bx; |
555 | 555 |
@@ -593,7 +593,7 @@ static bool trans_PEXTUW(DisasContext *ctx, arg_rtype *a) | ||
593 | 593 | */ |
594 | 594 | |
595 | 595 | /* Parallel Copy Halfword */ |
596 | -static bool trans_PCPYH(DisasContext *s, arg_rtype *a) | |
596 | +static bool trans_PCPYH(DisasContext *s, arg_r *a) | |
597 | 597 | { |
598 | 598 | if (a->rd == 0) { |
599 | 599 | /* nop */ |
@@ -615,7 +615,7 @@ static bool trans_PCPYH(DisasContext *s, arg_rtype *a) | ||
615 | 615 | } |
616 | 616 | |
617 | 617 | /* Parallel Copy Lower Doubleword */ |
618 | -static bool trans_PCPYLD(DisasContext *s, arg_rtype *a) | |
618 | +static bool trans_PCPYLD(DisasContext *s, arg_r *a) | |
619 | 619 | { |
620 | 620 | if (a->rd == 0) { |
621 | 621 | /* nop */ |
@@ -638,7 +638,7 @@ static bool trans_PCPYLD(DisasContext *s, arg_rtype *a) | ||
638 | 638 | } |
639 | 639 | |
640 | 640 | /* Parallel Copy Upper Doubleword */ |
641 | -static bool trans_PCPYUD(DisasContext *s, arg_rtype *a) | |
641 | +static bool trans_PCPYUD(DisasContext *s, arg_r *a) | |
642 | 642 | { |
643 | 643 | if (a->rd == 0) { |
644 | 644 | /* nop */ |
@@ -657,7 +657,7 @@ static bool trans_PCPYUD(DisasContext *s, arg_rtype *a) | ||
657 | 657 | } |
658 | 658 | |
659 | 659 | /* Parallel Rotate 3 Words Left */ |
660 | -static bool trans_PROT3W(DisasContext *ctx, arg_rtype *a) | |
660 | +static bool trans_PROT3W(DisasContext *ctx, arg_r *a) | |
661 | 661 | { |
662 | 662 | TCGv_i64 ax; |
663 | 663 |
@@ -0,0 +1,27 @@ | ||
1 | +# MIPS VR5432 instruction set extensions | |
2 | +# | |
3 | +# Copyright (C) 2021 Philippe Mathieu-Daudé | |
4 | +# | |
5 | +# SPDX-License-Identifier: LGPL-2.1-or-later | |
6 | +# | |
7 | +# Reference: VR5432 Microprocessor User’s Manual | |
8 | +# (Document Number U13751EU5V0UM00) | |
9 | + | |
10 | +&r rs rt rd | |
11 | + | |
12 | +@rs_rt_rd ...... rs:5 rt:5 rd:5 ..... ...... &r | |
13 | + | |
14 | +MULS 000000 ..... ..... ..... 00011011000 @rs_rt_rd | |
15 | +MULSU 000000 ..... ..... ..... 00011011001 @rs_rt_rd | |
16 | +MACC 000000 ..... ..... ..... 00101011000 @rs_rt_rd | |
17 | +MACCU 000000 ..... ..... ..... 00101011001 @rs_rt_rd | |
18 | +MSAC 000000 ..... ..... ..... 00111011000 @rs_rt_rd | |
19 | +MSACU 000000 ..... ..... ..... 00111011001 @rs_rt_rd | |
20 | +MULHI 000000 ..... ..... ..... 01001011000 @rs_rt_rd | |
21 | +MULHIU 000000 ..... ..... ..... 01001011001 @rs_rt_rd | |
22 | +MULSHI 000000 ..... ..... ..... 01011011000 @rs_rt_rd | |
23 | +MULSHIU 000000 ..... ..... ..... 01011011001 @rs_rt_rd | |
24 | +MACCHI 000000 ..... ..... ..... 01101011000 @rs_rt_rd | |
25 | +MACCHIU 000000 ..... ..... ..... 01101011001 @rs_rt_rd | |
26 | +MSACHI 000000 ..... ..... ..... 01111011000 @rs_rt_rd | |
27 | +MSACHIU 000000 ..... ..... ..... 01111011001 @rs_rt_rd |
@@ -0,0 +1,142 @@ | ||
1 | +/* | |
2 | + * MIPS VR5432 emulation helpers | |
3 | + * | |
4 | + * Copyright (c) 2004-2005 Jocelyn Mayer | |
5 | + * | |
6 | + * This library is free software; you can redistribute it and/or | |
7 | + * modify it under the terms of the GNU Lesser General Public | |
8 | + * License as published by the Free Software Foundation; either | |
9 | + * version 2.1 of the License, or (at your option) any later version. | |
10 | + * | |
11 | + * This library is distributed in the hope that it will be useful, | |
12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | + * Lesser General Public License for more details. | |
15 | + * | |
16 | + * You should have received a copy of the GNU Lesser General Public | |
17 | + * License along with this library; if not, see <http://www.gnu.org/licenses/>. | |
18 | + * | |
19 | + * SPDX-License-Identifier: LGPL-2.1-or-later | |
20 | + */ | |
21 | + | |
22 | +#include "qemu/osdep.h" | |
23 | +#include "cpu.h" | |
24 | +#include "exec/helper-proto.h" | |
25 | + | |
26 | +/* 64 bits arithmetic for 32 bits hosts */ | |
27 | +static inline uint64_t get_HILO(CPUMIPSState *env) | |
28 | +{ | |
29 | + return ((uint64_t)(env->active_tc.HI[0]) << 32) | | |
30 | + (uint32_t)env->active_tc.LO[0]; | |
31 | +} | |
32 | + | |
33 | +static inline target_ulong set_HIT0_LO(CPUMIPSState *env, uint64_t HILO) | |
34 | +{ | |
35 | + env->active_tc.LO[0] = (int32_t)(HILO & 0xFFFFFFFF); | |
36 | + return env->active_tc.HI[0] = (int32_t)(HILO >> 32); | |
37 | +} | |
38 | + | |
39 | +static inline target_ulong set_HI_LOT0(CPUMIPSState *env, uint64_t HILO) | |
40 | +{ | |
41 | + target_ulong tmp = env->active_tc.LO[0] = (int32_t)(HILO & 0xFFFFFFFF); | |
42 | + env->active_tc.HI[0] = (int32_t)(HILO >> 32); | |
43 | + return tmp; | |
44 | +} | |
45 | + | |
46 | +/* Multiplication variants of the vr54xx. */ | |
47 | +target_ulong helper_muls(CPUMIPSState *env, target_ulong arg1, | |
48 | + target_ulong arg2) | |
49 | +{ | |
50 | + return set_HI_LOT0(env, 0 - ((int64_t)(int32_t)arg1 * | |
51 | + (int64_t)(int32_t)arg2)); | |
52 | +} | |
53 | + | |
54 | +target_ulong helper_mulsu(CPUMIPSState *env, target_ulong arg1, | |
55 | + target_ulong arg2) | |
56 | +{ | |
57 | + return set_HI_LOT0(env, 0 - (uint64_t)(uint32_t)arg1 * | |
58 | + (uint64_t)(uint32_t)arg2); | |
59 | +} | |
60 | + | |
61 | +target_ulong helper_macc(CPUMIPSState *env, target_ulong arg1, | |
62 | + target_ulong arg2) | |
63 | +{ | |
64 | + return set_HI_LOT0(env, (int64_t)get_HILO(env) + (int64_t)(int32_t)arg1 * | |
65 | + (int64_t)(int32_t)arg2); | |
66 | +} | |
67 | + | |
68 | +target_ulong helper_macchi(CPUMIPSState *env, target_ulong arg1, | |
69 | + target_ulong arg2) | |
70 | +{ | |
71 | + return set_HIT0_LO(env, (int64_t)get_HILO(env) + (int64_t)(int32_t)arg1 * | |
72 | + (int64_t)(int32_t)arg2); | |
73 | +} | |
74 | + | |
75 | +target_ulong helper_maccu(CPUMIPSState *env, target_ulong arg1, | |
76 | + target_ulong arg2) | |
77 | +{ | |
78 | + return set_HI_LOT0(env, (uint64_t)get_HILO(env) + (uint64_t)(uint32_t)arg1 * | |
79 | + (uint64_t)(uint32_t)arg2); | |
80 | +} | |
81 | + | |
82 | +target_ulong helper_macchiu(CPUMIPSState *env, target_ulong arg1, | |
83 | + target_ulong arg2) | |
84 | +{ | |
85 | + return set_HIT0_LO(env, (uint64_t)get_HILO(env) + (uint64_t)(uint32_t)arg1 * | |
86 | + (uint64_t)(uint32_t)arg2); | |
87 | +} | |
88 | + | |
89 | +target_ulong helper_msac(CPUMIPSState *env, target_ulong arg1, | |
90 | + target_ulong arg2) | |
91 | +{ | |
92 | + return set_HI_LOT0(env, (int64_t)get_HILO(env) - (int64_t)(int32_t)arg1 * | |
93 | + (int64_t)(int32_t)arg2); | |
94 | +} | |
95 | + | |
96 | +target_ulong helper_msachi(CPUMIPSState *env, target_ulong arg1, | |
97 | + target_ulong arg2) | |
98 | +{ | |
99 | + return set_HIT0_LO(env, (int64_t)get_HILO(env) - (int64_t)(int32_t)arg1 * | |
100 | + (int64_t)(int32_t)arg2); | |
101 | +} | |
102 | + | |
103 | +target_ulong helper_msacu(CPUMIPSState *env, target_ulong arg1, | |
104 | + target_ulong arg2) | |
105 | +{ | |
106 | + return set_HI_LOT0(env, (uint64_t)get_HILO(env) - (uint64_t)(uint32_t)arg1 * | |
107 | + (uint64_t)(uint32_t)arg2); | |
108 | +} | |
109 | + | |
110 | +target_ulong helper_msachiu(CPUMIPSState *env, target_ulong arg1, | |
111 | + target_ulong arg2) | |
112 | +{ | |
113 | + return set_HIT0_LO(env, (uint64_t)get_HILO(env) - (uint64_t)(uint32_t)arg1 * | |
114 | + (uint64_t)(uint32_t)arg2); | |
115 | +} | |
116 | + | |
117 | +target_ulong helper_mulhi(CPUMIPSState *env, target_ulong arg1, | |
118 | + target_ulong arg2) | |
119 | +{ | |
120 | + return set_HIT0_LO(env, (int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2); | |
121 | +} | |
122 | + | |
123 | +target_ulong helper_mulhiu(CPUMIPSState *env, target_ulong arg1, | |
124 | + target_ulong arg2) | |
125 | +{ | |
126 | + return set_HIT0_LO(env, (uint64_t)(uint32_t)arg1 * | |
127 | + (uint64_t)(uint32_t)arg2); | |
128 | +} | |
129 | + | |
130 | +target_ulong helper_mulshi(CPUMIPSState *env, target_ulong arg1, | |
131 | + target_ulong arg2) | |
132 | +{ | |
133 | + return set_HIT0_LO(env, 0 - (int64_t)(int32_t)arg1 * | |
134 | + (int64_t)(int32_t)arg2); | |
135 | +} | |
136 | + | |
137 | +target_ulong helper_mulshiu(CPUMIPSState *env, target_ulong arg1, | |
138 | + target_ulong arg2) | |
139 | +{ | |
140 | + return set_HIT0_LO(env, 0 - (uint64_t)(uint32_t)arg1 * | |
141 | + (uint64_t)(uint32_t)arg2); | |
142 | +} |
@@ -0,0 +1,24 @@ | ||
1 | +/* | |
2 | + * MIPS NEC Vr54xx instruction emulation helpers for QEMU. | |
3 | + * | |
4 | + * Copyright (c) 2004-2005 Jocelyn Mayer | |
5 | + * Copyright (c) 2006 Marius Groeger (FPU operations) | |
6 | + * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support) | |
7 | + * | |
8 | + * SPDX-License-Identifier: LGPL-2.1-or-later | |
9 | + */ | |
10 | + | |
11 | +DEF_HELPER_3(muls, tl, env, tl, tl) | |
12 | +DEF_HELPER_3(mulsu, tl, env, tl, tl) | |
13 | +DEF_HELPER_3(macc, tl, env, tl, tl) | |
14 | +DEF_HELPER_3(maccu, tl, env, tl, tl) | |
15 | +DEF_HELPER_3(msac, tl, env, tl, tl) | |
16 | +DEF_HELPER_3(msacu, tl, env, tl, tl) | |
17 | +DEF_HELPER_3(mulhi, tl, env, tl, tl) | |
18 | +DEF_HELPER_3(mulhiu, tl, env, tl, tl) | |
19 | +DEF_HELPER_3(mulshi, tl, env, tl, tl) | |
20 | +DEF_HELPER_3(mulshiu, tl, env, tl, tl) | |
21 | +DEF_HELPER_3(macchi, tl, env, tl, tl) | |
22 | +DEF_HELPER_3(macchiu, tl, env, tl, tl) | |
23 | +DEF_HELPER_3(msachi, tl, env, tl, tl) | |
24 | +DEF_HELPER_3(msachiu, tl, env, tl, tl) |
@@ -0,0 +1,72 @@ | ||
1 | +/* | |
2 | + * VR5432 extensions translation routines | |
3 | + * | |
4 | + * Reference: VR5432 Microprocessor User’s Manual | |
5 | + * (Document Number U13751EU5V0UM00) | |
6 | + * | |
7 | + * Copyright (c) 2021 Philippe Mathieu-Daudé | |
8 | + * | |
9 | + * SPDX-License-Identifier: GPL-2.0-or-later | |
10 | + */ | |
11 | + | |
12 | +#include "qemu/osdep.h" | |
13 | +#include "tcg/tcg-op.h" | |
14 | +#include "exec/helper-gen.h" | |
15 | +#include "translate.h" | |
16 | +#include "internal.h" | |
17 | + | |
18 | +/* Include the auto-generated decoder. */ | |
19 | +#include "decode-vr54xx.c.inc" | |
20 | + | |
21 | +/* | |
22 | + * Integer Multiply-Accumulate Instructions | |
23 | + * | |
24 | + * MACC Multiply, accumulate, and move LO | |
25 | + * MACCHI Multiply, accumulate, and move HI | |
26 | + * MACCHIU Unsigned multiply, accumulate, and move HI | |
27 | + * MACCU Unsigned multiply, accumulate, and move LO | |
28 | + * MSAC Multiply, negate, accumulate, and move LO | |
29 | + * MSACHI Multiply, negate, accumulate, and move HI | |
30 | + * MSACHIU Unsigned multiply, negate, accumulate, and move HI | |
31 | + * MSACU Unsigned multiply, negate, accumulate, and move LO | |
32 | + * MULHI Multiply and move HI | |
33 | + * MULHIU Unsigned multiply and move HI | |
34 | + * MULS Multiply, negate, and move LO | |
35 | + * MULSHI Multiply, negate, and move HI | |
36 | + * MULSHIU Unsigned multiply, negate, and move HI | |
37 | + * MULSU Unsigned multiply, negate, and move LO | |
38 | + */ | |
39 | + | |
40 | +static bool trans_mult_acc(DisasContext *ctx, arg_r *a, | |
41 | + void (*gen_helper_mult_acc)(TCGv, TCGv_ptr, TCGv, TCGv)) | |
42 | +{ | |
43 | + TCGv t0 = tcg_temp_new(); | |
44 | + TCGv t1 = tcg_temp_new(); | |
45 | + | |
46 | + gen_load_gpr(t0, a->rs); | |
47 | + gen_load_gpr(t1, a->rt); | |
48 | + | |
49 | + gen_helper_mult_acc(t0, cpu_env, t0, t1); | |
50 | + | |
51 | + gen_store_gpr(t0, a->rd); | |
52 | + | |
53 | + tcg_temp_free(t0); | |
54 | + tcg_temp_free(t1); | |
55 | + | |
56 | + return false; | |
57 | +} | |
58 | + | |
59 | +TRANS(MACC, trans_mult_acc, gen_helper_macc); | |
60 | +TRANS(MACCHI, trans_mult_acc, gen_helper_macchi); | |
61 | +TRANS(MACCHIU, trans_mult_acc, gen_helper_macchiu); | |
62 | +TRANS(MACCU, trans_mult_acc, gen_helper_maccu); | |
63 | +TRANS(MSAC, trans_mult_acc, gen_helper_msac); | |
64 | +TRANS(MSACHI, trans_mult_acc, gen_helper_msachi); | |
65 | +TRANS(MSACHIU, trans_mult_acc, gen_helper_msachiu); | |
66 | +TRANS(MSACU, trans_mult_acc, gen_helper_msacu); | |
67 | +TRANS(MULHI, trans_mult_acc, gen_helper_mulhi); | |
68 | +TRANS(MULHIU, trans_mult_acc, gen_helper_mulhiu); | |
69 | +TRANS(MULS, trans_mult_acc, gen_helper_muls); | |
70 | +TRANS(MULSHI, trans_mult_acc, gen_helper_mulshi); | |
71 | +TRANS(MULSHIU, trans_mult_acc, gen_helper_mulshiu); | |
72 | +TRANS(MULSU, trans_mult_acc, gen_helper_mulsu); |