• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Keine Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Revisiond8ae530ec00368d4adfb996b5ef6c74cb4460504 (tree)
Zeit2021-08-26 05:09:48
AutorPeter Maydell <peter.maydell@lina...>
CommiterPeter Maydell

Log Message

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
-----BEGIN PGP SIGNATURE-----

iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmEmI78ACgkQ4+MsLN6t
wN4RLw/+PIBVfaDvASnFa2f9b4SGQ2WiM0LuLh/sN6ieMiFccqJZPq2Dz5GCQsR7
7v2+MZ9gcAoWH/NCft+vbXGwiP9exoChb8c65Gm0GdpQ3sKPYXJJAi/D0vjuPMGe
Yk8DrfERavu4bcpXPaC+B3p8krii88W+vEYvmvWfirD+gWxjF/HviLzHQK/62YMK
N695BYVav5Fd3fjqn3p7Kw/WdP++NS757G53dSF/r5l1wFEGFZAuYW7R2rWDQsz+
yWvPUkIFoJ9OXitKw01FVaDNXF3a1efMhZjFvCr0EU0eF4qsxAywXomC4CDpAo+Y
s15aNZoxWM4D0eEoNLm874QAgNu9txPJPg5kuZVpBDwdTKWMrShj5+m/QlWqVRcA
mj7Ff2/B50mmB8aGfkQm82DpnqNXk9Vr1Y4hGzKrSOc1NGZItnpX2XJfqymEF7M9
9SW73jF6X2871FyiRvd5cO9TGlBieMNMlkenuxiyQNvIgocw1FX606EDji/aFp2e
KehjWw/2JCmBC1uUhaYqks4db7B8MSeVl8G3Dwx3lxnuz4xson/yscAxengZBR2r
clubyAoEa7+6sc2DhflLGlWfQpiOBDW4FFCW37H7KhVnJXFTomuiMBSSBc+njLMi
NDT7wAMCyMXtmZtx3zeWZpppqdc3doaGm3Bq6HDWEkiYaOe6TxA=
=ceCP
-----END PGP SIGNATURE-----

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)

target/mips: Replace TARGET_WORDS_BIGENDIAN by cpu_is_bigendian()
target/mips: Store CP0_Config0 in DisasContext
target/mips: Replace GET_LMASK64() macro by get_lmask(64) function
target/mips: Replace GET_LMASK() macro by get_lmask(32) function
target/mips: Call cpu_is_bigendian & inline GET_OFFSET in ld/st helpers
target/mips: Define gen_helper() macros in translate.h
target/mips: Use tcg_constant_i32() in generate_exception_err()
target/mips: Inline gen_helper_0e0i()
target/mips: Inline gen_helper_1e1i() call in op_ld_INSN() macros
target/mips: Simplify gen_helper() macros by using tcg_constant_i32()
target/mips: Use tcg_constant_i32() in gen_helper_0e2i()
target/mips: Remove gen_helper_1e2i()
target/mips: Remove gen_helper_0e3i()
target/mips: Remove duplicated check_cp1_enabled() calls in Loongson EXT
target/mips: Allow Loongson 3A1000 to use up to 48-bit VAddr
target/mips: Document Loongson-3A CPU definitions
target/mips: Convert Vr54xx MSA* opcodes to decodetree
target/mips: Convert Vr54xx MUL* opcodes to decodetree
target/mips: Convert Vr54xx MACC* opcodes to decodetree
target/mips: Introduce decodetree structure for NEC Vr54xx extension
...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Ändern Zusammenfassung

Diff

--- a/target/mips/cpu-defs.c.inc
+++ b/target/mips/cpu-defs.c.inc
@@ -805,7 +805,7 @@ const mips_def_t mips_defs[] =
805805 .mmu_type = MMU_TYPE_R4000,
806806 },
807807 {
808- .name = "Loongson-3A1000",
808+ .name = "Loongson-3A1000", /* Loongson-3A R1, GS464-based */
809809 .CP0_PRid = 0x6305,
810810 /* 64KB I-cache and d-cache. 4 way with 32 bit cache line size. */
811811 .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | (0x2 << CP0C0_AT) |
@@ -828,14 +828,14 @@ const mips_def_t mips_defs[] =
828828 (0x1 << FCR0_D) | (0x1 << FCR0_S),
829829 .CP1_fcr31 = 0,
830830 .CP1_fcr31_rw_bitmask = 0xFF83FFFF,
831- .SEGBITS = 42,
831+ .SEGBITS = 48,
832832 .PABITS = 48,
833833 .insn_flags = CPU_MIPS64R2 | INSN_LOONGSON3A |
834834 ASE_LMMI | ASE_LEXT,
835835 .mmu_type = MMU_TYPE_R4000,
836836 },
837837 {
838- .name = "Loongson-3A4000", /* GS464V-based */
838+ .name = "Loongson-3A4000", /* Loongson-3A R4, GS464V-based */
839839 .CP0_PRid = 0x14C000,
840840 /* 64KB I-cache and d-cache. 4 way with 32 bit cache line size. */
841841 .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | (0x2 << CP0C0_AT) |
--- a/target/mips/helper.h
+++ b/target/mips/helper.h
@@ -16,21 +16,6 @@ DEF_HELPER_3(lld, tl, env, tl, int)
1616 #endif
1717 #endif
1818
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-
3419 DEF_HELPER_FLAGS_1(bitswap, TCG_CALL_NO_RWG_SE, tl, tl)
3520 #ifdef TARGET_MIPS64
3621 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)
609594 #endif /* !CONFIG_USER_ONLY */
610595
611596 #include "tcg/msa_helper.h.inc"
597+
598+/* Vendor extensions */
599+#include "tcg/vr54xx_helper.h.inc"
--- a/target/mips/tcg/ldst_helper.c
+++ b/target/mips/tcg/ldst_helper.c
@@ -52,31 +52,45 @@ HELPER_LD_ATOMIC(lld, ldq, 0x7, (target_ulong))
5252
5353 #endif /* !CONFIG_USER_ONLY */
5454
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+}
6273
6374 void helper_swl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
6475 int mem_idx)
6576 {
77+ target_ulong lmask = get_lmask(env, arg2, 32);
78+ int dir = cpu_is_bigendian(env) ? 1 : -1;
79+
6680 cpu_stb_mmuidx_ra(env, arg2, (uint8_t)(arg1 >> 24), mem_idx, GETPC());
6781
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),
7084 mem_idx, GETPC());
7185 }
7286
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),
7589 mem_idx, GETPC());
7690 }
7791
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,
8094 mem_idx, GETPC());
8195 }
8296 }
@@ -84,20 +98,23 @@ void helper_swl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
8498 void helper_swr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
8599 int mem_idx)
86100 {
101+ target_ulong lmask = get_lmask(env, arg2, 32);
102+ int dir = cpu_is_bigendian(env) ? 1 : -1;
103+
87104 cpu_stb_mmuidx_ra(env, arg2, (uint8_t)arg1, mem_idx, GETPC());
88105
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),
91108 mem_idx, GETPC());
92109 }
93110
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),
96113 mem_idx, GETPC());
97114 }
98115
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),
101118 mem_idx, GETPC());
102119 }
103120 }
@@ -107,49 +124,47 @@ void helper_swr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
107124 * "half" load and stores. We must do the memory access inline,
108125 * or fault handling won't work.
109126 */
110-#ifdef TARGET_WORDS_BIGENDIAN
111-#define GET_LMASK64(v) ((v) & 7)
112-#else
113-#define GET_LMASK64(v) (((v) & 7) ^ 7)
114-#endif
115127
116128 void helper_sdl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
117129 int mem_idx)
118130 {
131+ target_ulong lmask = get_lmask(env, arg2, 64);
132+ int dir = cpu_is_bigendian(env) ? 1 : -1;
133+
119134 cpu_stb_mmuidx_ra(env, arg2, (uint8_t)(arg1 >> 56), mem_idx, GETPC());
120135
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),
123138 mem_idx, GETPC());
124139 }
125140
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),
128143 mem_idx, GETPC());
129144 }
130145
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),
133148 mem_idx, GETPC());
134149 }
135150
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),
138153 mem_idx, GETPC());
139154 }
140155
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),
143158 mem_idx, GETPC());
144159 }
145160
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),
148163 mem_idx, GETPC());
149164 }
150165
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,
153168 mem_idx, GETPC());
154169 }
155170 }
@@ -157,40 +172,43 @@ void helper_sdl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
157172 void helper_sdr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
158173 int mem_idx)
159174 {
175+ target_ulong lmask = get_lmask(env, arg2, 64);
176+ int dir = cpu_is_bigendian(env) ? 1 : -1;
177+
160178 cpu_stb_mmuidx_ra(env, arg2, (uint8_t)arg1, mem_idx, GETPC());
161179
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),
164182 mem_idx, GETPC());
165183 }
166184
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),
169187 mem_idx, GETPC());
170188 }
171189
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),
174192 mem_idx, GETPC());
175193 }
176194
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),
179197 mem_idx, GETPC());
180198 }
181199
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),
184202 mem_idx, GETPC());
185203 }
186204
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),
189207 mem_idx, GETPC());
190208 }
191209
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),
194212 mem_idx, GETPC());
195213 }
196214 }
--- a/target/mips/tcg/meson.build
+++ b/target/mips/tcg/meson.build
@@ -1,8 +1,8 @@
11 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']),
43 decodetree.process('msa.decode', extra_args: '--decode=decode_ase_msa'),
54 decodetree.process('tx79.decode', extra_args: '--static-decode=decode_tx79'),
5+ decodetree.process('vr54xx.decode', extra_args: '--decode=decode_ext_vr54xx'),
66 ]
77
88 mips_ss.add(gen)
@@ -19,6 +19,8 @@ mips_ss.add(files(
1919 'translate.c',
2020 'translate_addr_const.c',
2121 'txx9_translate.c',
22+ 'vr54xx_helper.c',
23+ 'vr54xx_translate.c',
2224 ))
2325 mips_ss.add(when: 'TARGET_MIPS64', if_true: files(
2426 'tx79_translate.c',
--- a/target/mips/tcg/mips64r6.decode
+++ /dev/null
@@ -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
--- a/target/mips/tcg/msa.decode
+++ b/target/mips/tcg/msa.decode
@@ -11,11 +11,11 @@
1111 # - The MIPS64 SIMD Architecture Module, Revision 1.12
1212 # (Document Number: MD00868-1D-MSA64-AFP-01.12)
1313
14-&rtype rs rt rd sa
14+&r rs rt rd sa
1515
1616 &msa_bz df wt s16
1717
18-@lsa ...... rs:5 rt:5 rd:5 ... sa:2 ...... &rtype
18+@lsa ...... rs:5 rt:5 rd:5 ... sa:2 ...... &r
1919 @bz ...... ... .. wt:5 s16:16 &msa_bz df=3
2020 @bz_df ...... ... df:2 wt:5 s16:16 &msa_bz
2121
--- a/target/mips/tcg/msa_translate.c
+++ b/target/mips/tcg/msa_translate.c
@@ -2261,12 +2261,12 @@ static bool trans_MSA(DisasContext *ctx, arg_MSA *a)
22612261 return true;
22622262 }
22632263
2264-static bool trans_LSA(DisasContext *ctx, arg_rtype *a)
2264+static bool trans_LSA(DisasContext *ctx, arg_r *a)
22652265 {
22662266 return gen_lsa(ctx, a->rd, a->rt, a->rs, a->sa);
22672267 }
22682268
2269-static bool trans_DLSA(DisasContext *ctx, arg_rtype *a)
2269+static bool trans_DLSA(DisasContext *ctx, arg_r *a)
22702270 {
22712271 if (TARGET_LONG_BITS != 64) {
22722272 return false;
--- a/target/mips/tcg/nanomips_translate.c.inc
+++ b/target/mips/tcg/nanomips_translate.c.inc
@@ -999,11 +999,11 @@ static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
999999
10001000 gen_base_offset_addr(ctx, taddr, base, offset);
10011001 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+ }
10071007 gen_store_gpr(tmp1, reg1);
10081008 tcg_temp_free(tmp1);
10091009 gen_store_gpr(tmp2, reg2);
@@ -1035,11 +1035,11 @@ static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
10351035 gen_load_gpr(tmp1, reg1);
10361036 gen_load_gpr(tmp2, reg2);
10371037
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+ }
10431043
10441044 tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
10451045 tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
--- a/target/mips/tcg/op_helper.c
+++ b/target/mips/tcg/op_helper.c
@@ -26,124 +26,6 @@
2626 #include "exec/memop.h"
2727 #include "fpu_helper.h"
2828
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-
14729 static inline target_ulong bitswap(target_ulong v)
14830 {
14931 v = ((v >> 1) & (target_ulong)0x5555555555555555ULL) |
--- a/target/mips/tcg/mips32r6.decode
+++ b/target/mips/tcg/rel6.decode
@@ -5,21 +5,29 @@
55 # SPDX-License-Identifier: LGPL-2.1-or-later
66 #
77 # Reference:
8+#
89 # MIPS Architecture for Programmers Volume II-A
910 # The MIPS32 Instruction Set Reference Manual, Revision 6.06
1011 # (Document Number: MD00086-2B-MIPS32BIS-AFP-06.06)
1112 #
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)
1216
13-&rtype rs rt rd sa
17+&r rs rt rd sa
1418
15-@lsa ...... rs:5 rt:5 rd:5 ... sa:2 ...... &rtype
19+@lsa ...... rs:5 rt:5 rd:5 ... sa:2 ...... &r
1620
1721 LSA 000000 ..... ..... ..... 000 .. 000101 @lsa
22+DLSA 000000 ..... ..... ..... 000 .. 010101 @lsa
1823
1924 REMOVED 010011 ----- ----- ----- ----- ------ # COP1X (COP3)
2025
2126 REMOVED 011100 ----- ----- ----- ----- ------ # SPECIAL2
2227
28+REMOVED 011010 ----- ----- ---------------- # LDL
29+REMOVED 011011 ----- ----- ---------------- # LDR
30+
2331 REMOVED 011111 ----- ----- ---------- 011001 # LWLE
2432 REMOVED 011111 ----- ----- ---------- 011010 # LWRE
2533 REMOVED 011111 ----- ----- ---------- 100001 # SWLE
@@ -28,9 +36,14 @@ REMOVED 011111 ----- ----- ---------- 100010 # SWRE
2836 REMOVED 100010 ----- ----- ---------------- # LWL
2937 REMOVED 100110 ----- ----- ---------------- # LWR
3038 REMOVED 101010 ----- ----- ---------------- # SWL
39+REMOVED 101100 ----- ----- ---------------- # SDL
40+REMOVED 101101 ----- ----- ---------------- # SDR
3141 REMOVED 101110 ----- ----- ---------------- # SWR
3242
3343 REMOVED 101111 ----- ----- ---------------- # CACHE
44+
3445 REMOVED 110000 ----- ----- ---------------- # LL
3546 REMOVED 110011 ----- ----- ---------------- # PREF
47+REMOVED 110100 ----- ----- ---------------- # LLD
3648 REMOVED 111000 ----- ----- ---------------- # SC
49+REMOVED 111100 ----- ----- ---------------- # SCD
--- a/target/mips/tcg/rel6_translate.c
+++ b/target/mips/tcg/rel6_translate.c
@@ -13,9 +13,8 @@
1313 #include "exec/helper-gen.h"
1414 #include "translate.h"
1515
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"
1918
2019 bool trans_REMOVED(DisasContext *ctx, arg_REMOVED *a)
2120 {
@@ -24,20 +23,15 @@ bool trans_REMOVED(DisasContext *ctx, arg_REMOVED *a)
2423 return true;
2524 }
2625
27-static bool trans_LSA(DisasContext *ctx, arg_rtype *a)
26+static bool trans_LSA(DisasContext *ctx, arg_r *a)
2827 {
2928 return gen_lsa(ctx, a->rd, a->rt, a->rs, a->sa);
3029 }
3130
32-static bool trans_DLSA(DisasContext *ctx, arg_rtype *a)
31+static bool trans_DLSA(DisasContext *ctx, arg_r *a)
3332 {
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;
4135 }
42- return decode_mips32r6(ctx, insn);
36+ return gen_dlsa(ctx, a->rd, a->rt, a->rs, a->sa);
4337 }
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -294,26 +294,6 @@ enum {
294294 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
295295 };
296296
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-
317297 /* REGIMM (rt field) opcodes */
318298 #define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16)))
319299
@@ -1233,48 +1213,6 @@ TCGv_i64 fpu_f64[32];
12331213
12341214 #include "exec/gen-icount.h"
12351215
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-
12781216 #define DISAS_STOP DISAS_TARGET_0
12791217 #define DISAS_EXIT DISAS_TARGET_1
12801218
@@ -1413,18 +1351,15 @@ static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
14131351
14141352 void generate_exception_err(DisasContext *ctx, int excp, int err)
14151353 {
1416- TCGv_i32 texcp = tcg_const_i32(excp);
1417- TCGv_i32 terr = tcg_const_i32(err);
14181354 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));
14221357 ctx->base.is_jmp = DISAS_NORETURN;
14231358 }
14241359
14251360 void generate_exception(DisasContext *ctx, int excp)
14261361 {
1427- gen_helper_0e0i(raise_exception, excp);
1362+ gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
14281363 }
14291364
14301365 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, \
20331968 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
20341969 DisasContext *ctx) \
20351970 { \
2036- gen_helper_1e1i(insn, ret, arg1, mem_idx); \
1971+ gen_helper_##insn(ret, cpu_env, arg1, tcg_constant_i32(mem_idx)); \
20371972 }
20381973 #endif
20391974 OP_LD_ATOMIC(ll, ld32s);
@@ -2113,9 +2048,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
21132048 */
21142049 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
21152050 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+ }
21192054 tcg_gen_shli_tl(t1, t1, 3);
21202055 tcg_gen_andi_tl(t0, t0, ~7);
21212056 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
@@ -2137,9 +2072,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
21372072 */
21382073 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
21392074 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+ }
21432078 tcg_gen_shli_tl(t1, t1, 3);
21442079 tcg_gen_andi_tl(t0, t0, ~7);
21452080 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
@@ -2218,9 +2153,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
22182153 */
22192154 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
22202155 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+ }
22242159 tcg_gen_shli_tl(t1, t1, 3);
22252160 tcg_gen_andi_tl(t0, t0, ~3);
22262161 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
@@ -2246,9 +2181,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
22462181 */
22472182 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
22482183 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+ }
22522187 tcg_gen_shli_tl(t1, t1, 3);
22532188 tcg_gen_andi_tl(t0, t0, ~3);
22542189 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,
37643699 tcg_temp_free(t1);
37653700 }
37663701
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-
38313702 static void gen_cl(DisasContext *ctx, uint32_t opc,
38323703 int rd, int rs)
38333704 {
@@ -4529,9 +4400,9 @@ static void gen_loongson_lswc2(DisasContext *ctx, int rt,
45294400 t1 = tcg_temp_new();
45304401 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
45314402 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+ }
45354406 tcg_gen_shli_tl(t1, t1, 3);
45364407 tcg_gen_andi_tl(t0, t0, ~3);
45374408 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,
45594430 t1 = tcg_temp_new();
45604431 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
45614432 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+ }
45654436 tcg_gen_shli_tl(t1, t1, 3);
45664437 tcg_gen_andi_tl(t0, t0, ~3);
45674438 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,
45914462 t1 = tcg_temp_new();
45924463 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
45934464 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+ }
45974468 tcg_gen_shli_tl(t1, t1, 3);
45984469 tcg_gen_andi_tl(t0, t0, ~7);
45994470 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,
46134484 t1 = tcg_temp_new();
46144485 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
46154486 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+ }
46194490 tcg_gen_shli_tl(t1, t1, 3);
46204491 tcg_gen_andi_tl(t0, t0, ~7);
46214492 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,
47774648 break;
47784649 #endif
47794650 case OPC_GSLWXC1:
4780- check_cp1_enabled(ctx);
47814651 gen_base_offset_addr(ctx, t0, rs, offset);
47824652 if (rd) {
47834653 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
@@ -4790,7 +4660,6 @@ static void gen_loongson_lsdc2(DisasContext *ctx, int rt,
47904660 break;
47914661 #if defined(TARGET_MIPS64)
47924662 case OPC_GSLDXC1:
4793- check_cp1_enabled(ctx);
47944663 gen_base_offset_addr(ctx, t0, rs, offset);
47954664 if (rd) {
47964665 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,
91709039 break;
91719040 case 3:
91729041 /* 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);
91799043 /* Stop translation as we may have changed hflags */
91809044 ctx->base.is_jmp = DISAS_STOP;
91819045 break;
@@ -9792,12 +9656,7 @@ static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs)
97929656 case OPC_CTC1:
97939657 gen_load_gpr(t0, rt);
97949658 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);
98019660 /* Stop translation as we may have changed hflags */
98029661 ctx->base.is_jmp = DISAS_STOP;
98039662 break;
@@ -11550,17 +11409,17 @@ static void gen_flt3_arith(DisasContext *ctx, uint32_t opc,
1155011409 gen_set_label(l1);
1155111410 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
1155211411 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+ }
1156411423 gen_set_label(l2);
1156511424 tcg_temp_free_i32(fp);
1156611425 tcg_temp_free_i32(fph);
@@ -14144,13 +14003,12 @@ static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
1414414003
1414514004 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
1414614005 {
14147- int rs, rt, rd, sa;
14006+ int rs, rt, rd;
1414814007 uint32_t op1;
1414914008
1415014009 rs = (ctx->opcode >> 21) & 0x1f;
1415114010 rt = (ctx->opcode >> 16) & 0x1f;
1415214011 rd = (ctx->opcode >> 11) & 0x1f;
14153- sa = (ctx->opcode >> 6) & 0x1f;
1415414012
1415514013 op1 = MASK_SPECIAL(ctx->opcode);
1415614014 switch (op1) {
@@ -14180,13 +14038,7 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
1418014038 break;
1418114039 case OPC_MULT:
1418214040 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);
1419014042 break;
1419114043 case OPC_DIV:
1419214044 case OPC_DIVU:
@@ -14203,7 +14055,7 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
1420314055 break;
1420414056 #endif
1420514057 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);
1420714059 break;
1420814060 case OPC_SPIM:
1420914061 #ifdef MIPS_STRICT_STANDARD
@@ -14317,7 +14169,7 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
1431714169 MIPS_INVAL("PMON / selsl");
1431814170 gen_reserved_instruction(ctx);
1431914171 #else
14320- gen_helper_0e0i(pmon, sa);
14172+ gen_helper_pmon(cpu_env, tcg_constant_i32(sa));
1432114173 #endif
1432214174 break;
1432314175 case OPC_SYSCALL:
@@ -15739,12 +15591,8 @@ static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
1573915591 /* Treat as NOP. */
1574015592 break;
1574115593 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. */
1574815596 break;
1574915597
1575015598 /* Floating point (COP1). */
@@ -16098,6 +15946,14 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
1609815946
1609915947 /* Transition to the auto-generated decoder. */
1610015948
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+
1610115957 /* ISA extensions */
1610215958 if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) {
1610315959 return;
@@ -16107,9 +15963,6 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
1610715963 if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) {
1610815964 return;
1610915965 }
16110- if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) {
16111- return;
16112- }
1611315966
1611415967 if (decode_opc_legacy(env, ctx)) {
1611515968 return;
@@ -16126,6 +15979,7 @@ static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
1612615979 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
1612715980 ctx->saved_pc = -1;
1612815981 ctx->insn_flags = env->insn_flags;
15982+ ctx->CP0_Config0 = env->CP0_Config0;
1612915983 ctx->CP0_Config1 = env->CP0_Config1;
1613015984 ctx->CP0_Config2 = env->CP0_Config2;
1613115985 ctx->CP0_Config3 = env->CP0_Config3;
--- a/target/mips/tcg/translate.h
+++ b/target/mips/tcg/translate.h
@@ -18,6 +18,7 @@ typedef struct DisasContext {
1818 target_ulong page_start;
1919 uint32_t opcode;
2020 uint64_t insn_flags;
21+ int32_t CP0_Config0;
2122 int32_t CP0_Config1;
2223 int32_t CP0_Config2;
2324 int32_t CP0_Config3;
@@ -113,6 +114,18 @@ enum {
113114 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
114115 };
115116
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+
116129 void generate_exception(DisasContext *ctx, int excp);
117130 void generate_exception_err(DisasContext *ctx, int excp, int err);
118131 void generate_exception_end(DisasContext *ctx, int excp);
@@ -201,5 +214,19 @@ bool decode_ext_txx9(DisasContext *ctx, uint32_t insn);
201214 #if defined(TARGET_MIPS64)
202215 bool decode_ext_tx79(DisasContext *ctx, uint32_t insn);
203216 #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+}
204231
205232 #endif
--- a/target/mips/tcg/tx79.decode
+++ b/target/mips/tcg/tx79.decode
@@ -11,20 +11,20 @@
1111 # when creating helpers common to those for the individual
1212 # instruction patterns.
1313
14-&rtype rs rt rd sa
14+&r rs rt rd sa
1515
16-&itype base rt offset
16+&i base rt offset
1717
1818 ###########################################################################
1919 # Named instruction formats. These are generally used to
2020 # reduce the amount of duplication between instruction patterns.
2121
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
2626
27-@ldst ...... base:5 rt:5 offset:16 &itype
27+@ldst ...... base:5 rt:5 offset:16 &i
2828
2929 ###########################################################################
3030
--- a/target/mips/tcg/tx79_translate.c
+++ b/target/mips/tcg/tx79_translate.c
@@ -64,28 +64,28 @@ bool decode_ext_tx79(DisasContext *ctx, uint32_t insn)
6464 * MTLO1 rs Move To LO1 Register
6565 */
6666
67-static bool trans_MFHI1(DisasContext *ctx, arg_rtype *a)
67+static bool trans_MFHI1(DisasContext *ctx, arg_r *a)
6868 {
6969 gen_store_gpr(cpu_HI[1], a->rd);
7070
7171 return true;
7272 }
7373
74-static bool trans_MFLO1(DisasContext *ctx, arg_rtype *a)
74+static bool trans_MFLO1(DisasContext *ctx, arg_r *a)
7575 {
7676 gen_store_gpr(cpu_LO[1], a->rd);
7777
7878 return true;
7979 }
8080
81-static bool trans_MTHI1(DisasContext *ctx, arg_rtype *a)
81+static bool trans_MTHI1(DisasContext *ctx, arg_r *a)
8282 {
8383 gen_load_gpr(cpu_HI[1], a->rs);
8484
8585 return true;
8686 }
8787
88-static bool trans_MTLO1(DisasContext *ctx, arg_rtype *a)
88+static bool trans_MTLO1(DisasContext *ctx, arg_r *a)
8989 {
9090 gen_load_gpr(cpu_LO[1], a->rs);
9191
@@ -116,7 +116,7 @@ static bool trans_MTLO1(DisasContext *ctx, arg_rtype *a)
116116 * PSUBUW rd, rs, rt Parallel Subtract with Unsigned saturation Word
117117 */
118118
119-static bool trans_parallel_arith(DisasContext *ctx, arg_rtype *a,
119+static bool trans_parallel_arith(DisasContext *ctx, arg_r *a,
120120 void (*gen_logic_i64)(TCGv_i64, TCGv_i64, TCGv_i64))
121121 {
122122 TCGv_i64 ax, bx;
@@ -146,19 +146,19 @@ static bool trans_parallel_arith(DisasContext *ctx, arg_rtype *a,
146146 }
147147
148148 /* Parallel Subtract Byte */
149-static bool trans_PSUBB(DisasContext *ctx, arg_rtype *a)
149+static bool trans_PSUBB(DisasContext *ctx, arg_r *a)
150150 {
151151 return trans_parallel_arith(ctx, a, tcg_gen_vec_sub8_i64);
152152 }
153153
154154 /* Parallel Subtract Halfword */
155-static bool trans_PSUBH(DisasContext *ctx, arg_rtype *a)
155+static bool trans_PSUBH(DisasContext *ctx, arg_r *a)
156156 {
157157 return trans_parallel_arith(ctx, a, tcg_gen_vec_sub16_i64);
158158 }
159159
160160 /* Parallel Subtract Word */
161-static bool trans_PSUBW(DisasContext *ctx, arg_rtype *a)
161+static bool trans_PSUBW(DisasContext *ctx, arg_r *a)
162162 {
163163 return trans_parallel_arith(ctx, a, tcg_gen_vec_sub32_i64);
164164 }
@@ -189,25 +189,25 @@ static bool trans_PSUBW(DisasContext *ctx, arg_rtype *a)
189189 */
190190
191191 /* Parallel And */
192-static bool trans_PAND(DisasContext *ctx, arg_rtype *a)
192+static bool trans_PAND(DisasContext *ctx, arg_r *a)
193193 {
194194 return trans_parallel_arith(ctx, a, tcg_gen_and_i64);
195195 }
196196
197197 /* Parallel Or */
198-static bool trans_POR(DisasContext *ctx, arg_rtype *a)
198+static bool trans_POR(DisasContext *ctx, arg_r *a)
199199 {
200200 return trans_parallel_arith(ctx, a, tcg_gen_or_i64);
201201 }
202202
203203 /* Parallel Exclusive Or */
204-static bool trans_PXOR(DisasContext *ctx, arg_rtype *a)
204+static bool trans_PXOR(DisasContext *ctx, arg_r *a)
205205 {
206206 return trans_parallel_arith(ctx, a, tcg_gen_xor_i64);
207207 }
208208
209209 /* Parallel Not Or */
210-static bool trans_PNOR(DisasContext *ctx, arg_rtype *a)
210+static bool trans_PNOR(DisasContext *ctx, arg_r *a)
211211 {
212212 return trans_parallel_arith(ctx, a, tcg_gen_nor_i64);
213213 }
@@ -237,7 +237,7 @@ static bool trans_PNOR(DisasContext *ctx, arg_rtype *a)
237237 * PCEQW rd, rs, rt Parallel Compare for Equal Word
238238 */
239239
240-static bool trans_parallel_compare(DisasContext *ctx, arg_rtype *a,
240+static bool trans_parallel_compare(DisasContext *ctx, arg_r *a,
241241 TCGCond cond, unsigned wlen)
242242 {
243243 TCGv_i64 c0, c1, ax, bx, t0, t1, t2;
@@ -286,37 +286,37 @@ static bool trans_parallel_compare(DisasContext *ctx, arg_rtype *a,
286286 }
287287
288288 /* 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)
290290 {
291291 return trans_parallel_compare(ctx, a, TCG_COND_GE, 8);
292292 }
293293
294294 /* 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)
296296 {
297297 return trans_parallel_compare(ctx, a, TCG_COND_EQ, 8);
298298 }
299299
300300 /* 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)
302302 {
303303 return trans_parallel_compare(ctx, a, TCG_COND_GE, 16);
304304 }
305305
306306 /* 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)
308308 {
309309 return trans_parallel_compare(ctx, a, TCG_COND_EQ, 16);
310310 }
311311
312312 /* 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)
314314 {
315315 return trans_parallel_compare(ctx, a, TCG_COND_GE, 32);
316316 }
317317
318318 /* 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)
320320 {
321321 return trans_parallel_compare(ctx, a, TCG_COND_EQ, 32);
322322 }
@@ -334,7 +334,7 @@ static bool trans_PCEQW(DisasContext *ctx, arg_rtype *a)
334334 * SQ rt, offset(base) Store Quadword
335335 */
336336
337-static bool trans_LQ(DisasContext *ctx, arg_itype *a)
337+static bool trans_LQ(DisasContext *ctx, arg_i *a)
338338 {
339339 TCGv_i64 t0;
340340 TCGv addr;
@@ -369,7 +369,7 @@ static bool trans_LQ(DisasContext *ctx, arg_itype *a)
369369 return true;
370370 }
371371
372-static bool trans_SQ(DisasContext *ctx, arg_itype *a)
372+static bool trans_SQ(DisasContext *ctx, arg_i *a)
373373 {
374374 TCGv_i64 t0 = tcg_temp_new_i64();
375375 TCGv addr = tcg_temp_new();
@@ -437,7 +437,7 @@ static bool trans_SQ(DisasContext *ctx, arg_itype *a)
437437 */
438438
439439 /* Parallel Pack to Word */
440-static bool trans_PPACW(DisasContext *ctx, arg_rtype *a)
440+static bool trans_PPACW(DisasContext *ctx, arg_r *a)
441441 {
442442 TCGv_i64 a0, b0, t0;
443443
@@ -473,7 +473,7 @@ static void gen_pextw(TCGv_i64 dl, TCGv_i64 dh, TCGv_i64 a, TCGv_i64 b)
473473 tcg_gen_deposit_i64(dh, a, b, 0, 32);
474474 }
475475
476-static bool trans_PEXTLx(DisasContext *ctx, arg_rtype *a, unsigned wlen)
476+static bool trans_PEXTLx(DisasContext *ctx, arg_r *a, unsigned wlen)
477477 {
478478 TCGv_i64 ax, bx;
479479
@@ -514,19 +514,19 @@ static bool trans_PEXTLx(DisasContext *ctx, arg_rtype *a, unsigned wlen)
514514 }
515515
516516 /* 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)
518518 {
519519 return trans_PEXTLx(ctx, a, 8);
520520 }
521521
522522 /* 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)
524524 {
525525 return trans_PEXTLx(ctx, a, 16);
526526 }
527527
528528 /* 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)
530530 {
531531 TCGv_i64 ax, bx;
532532
@@ -549,7 +549,7 @@ static bool trans_PEXTLW(DisasContext *ctx, arg_rtype *a)
549549 }
550550
551551 /* 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)
553553 {
554554 TCGv_i64 ax, bx;
555555
@@ -593,7 +593,7 @@ static bool trans_PEXTUW(DisasContext *ctx, arg_rtype *a)
593593 */
594594
595595 /* Parallel Copy Halfword */
596-static bool trans_PCPYH(DisasContext *s, arg_rtype *a)
596+static bool trans_PCPYH(DisasContext *s, arg_r *a)
597597 {
598598 if (a->rd == 0) {
599599 /* nop */
@@ -615,7 +615,7 @@ static bool trans_PCPYH(DisasContext *s, arg_rtype *a)
615615 }
616616
617617 /* Parallel Copy Lower Doubleword */
618-static bool trans_PCPYLD(DisasContext *s, arg_rtype *a)
618+static bool trans_PCPYLD(DisasContext *s, arg_r *a)
619619 {
620620 if (a->rd == 0) {
621621 /* nop */
@@ -638,7 +638,7 @@ static bool trans_PCPYLD(DisasContext *s, arg_rtype *a)
638638 }
639639
640640 /* Parallel Copy Upper Doubleword */
641-static bool trans_PCPYUD(DisasContext *s, arg_rtype *a)
641+static bool trans_PCPYUD(DisasContext *s, arg_r *a)
642642 {
643643 if (a->rd == 0) {
644644 /* nop */
@@ -657,7 +657,7 @@ static bool trans_PCPYUD(DisasContext *s, arg_rtype *a)
657657 }
658658
659659 /* 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)
661661 {
662662 TCGv_i64 ax;
663663
--- /dev/null
+++ b/target/mips/tcg/vr54xx.decode
@@ -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
--- /dev/null
+++ b/target/mips/tcg/vr54xx_helper.c
@@ -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+}
--- /dev/null
+++ b/target/mips/tcg/vr54xx_helper.h.inc
@@ -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)
--- /dev/null
+++ b/target/mips/tcg/vr54xx_translate.c
@@ -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);