]> Git Repo - qemu.git/blame - target/xtensa/translate.c
target/xtensa: check zero overhead loop alignment
[qemu.git] / target / xtensa / translate.c
CommitLineData
2328826b
MF
1/*
2 * Xtensa ISA:
3 * http://www.tensilica.com/products/literature-docs/documentation/xtensa-isa-databook.htm
4 *
5 * Copyright (c) 2011, Max Filippov, Open Source and Linux Lab.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of the Open Source and Linux Lab nor the
16 * names of its contributors may be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
09aae23d 31#include "qemu/osdep.h"
2328826b
MF
32
33#include "cpu.h"
022c62cb 34#include "exec/exec-all.h"
76cad711 35#include "disas/disas.h"
2328826b 36#include "tcg-op.h"
1de7afc9 37#include "qemu/log.h"
9c17d615 38#include "sysemu/sysemu.h"
f08b6170 39#include "exec/cpu_ldst.h"
cfe67cef 40#include "exec/semihost.h"
77fc6f5e 41#include "exec/translator.h"
2328826b 42
2ef6175a
RH
43#include "exec/helper-proto.h"
44#include "exec/helper-gen.h"
dedc5eae 45
a7e30d84 46#include "trace-tcg.h"
508127e2 47#include "exec/log.h"
a7e30d84
LV
48
49
77fc6f5e
LV
50/* is_jmp field values */
51#define DISAS_UPDATE DISAS_TARGET_0 /* cpu state was modified dynamically */
52
a3380cf6 53struct DisasContext {
dedc5eae
MF
54 const XtensaConfig *config;
55 TranslationBlock *tb;
56 uint32_t pc;
57 uint32_t next_pc;
f0a548b9
MF
58 int cring;
59 int ring;
797d780b
MF
60 uint32_t lbeg;
61 uint32_t lend;
dedc5eae
MF
62 int is_jmp;
63 int singlestep_enabled;
3580ecad
MF
64
65 bool sar_5bit;
66 bool sar_m32_5bit;
67 bool sar_m32_allocated;
68 TCGv_i32 sar_m32;
b994e91b 69
2db59a76 70 unsigned window;
e61dc8f7
MF
71
72 bool debug;
35b5c044
MF
73 bool icount;
74 TCGv_i32 next_icount;
ef04a846
MF
75
76 unsigned cpenable;
168c12b0
MF
77
78 uint32_t *raw_arg;
33071f68
MF
79 xtensa_insnbuf insnbuf;
80 xtensa_insnbuf slotbuf;
a3380cf6 81};
dedc5eae 82
dedc5eae
MF
83static TCGv_i32 cpu_pc;
84static TCGv_i32 cpu_R[16];
dd519cbe 85static TCGv_i32 cpu_FR[16];
2af3da91
MF
86static TCGv_i32 cpu_SR[256];
87static TCGv_i32 cpu_UR[256];
dedc5eae 88
022c62cb 89#include "exec/gen-icount.h"
2328826b 90
fe0bd475
MF
91typedef struct XtensaReg {
92 const char *name;
93 uint64_t opt_bits;
53593e90
MF
94 enum {
95 SR_R = 1,
96 SR_W = 2,
97 SR_X = 4,
98 SR_RW = 3,
99 SR_RWX = 7,
100 } access;
fe0bd475
MF
101} XtensaReg;
102
53593e90 103#define XTENSA_REG_ACCESS(regname, opt, acc) { \
fe0bd475
MF
104 .name = (regname), \
105 .opt_bits = XTENSA_OPTION_BIT(opt), \
53593e90 106 .access = (acc), \
fe0bd475
MF
107 }
108
53593e90
MF
109#define XTENSA_REG(regname, opt) XTENSA_REG_ACCESS(regname, opt, SR_RWX)
110
604e1f9c 111#define XTENSA_REG_BITS_ACCESS(regname, opt, acc) { \
fe0bd475
MF
112 .name = (regname), \
113 .opt_bits = (opt), \
604e1f9c 114 .access = (acc), \
fe0bd475
MF
115 }
116
604e1f9c
MF
117#define XTENSA_REG_BITS(regname, opt) \
118 XTENSA_REG_BITS_ACCESS(regname, opt, SR_RWX)
119
fe0bd475
MF
120static const XtensaReg sregnames[256] = {
121 [LBEG] = XTENSA_REG("LBEG", XTENSA_OPTION_LOOP),
122 [LEND] = XTENSA_REG("LEND", XTENSA_OPTION_LOOP),
123 [LCOUNT] = XTENSA_REG("LCOUNT", XTENSA_OPTION_LOOP),
124 [SAR] = XTENSA_REG_BITS("SAR", XTENSA_OPTION_ALL),
125 [BR] = XTENSA_REG("BR", XTENSA_OPTION_BOOLEAN),
126 [LITBASE] = XTENSA_REG("LITBASE", XTENSA_OPTION_EXTENDED_L32R),
127 [SCOMPARE1] = XTENSA_REG("SCOMPARE1", XTENSA_OPTION_CONDITIONAL_STORE),
128 [ACCLO] = XTENSA_REG("ACCLO", XTENSA_OPTION_MAC16),
129 [ACCHI] = XTENSA_REG("ACCHI", XTENSA_OPTION_MAC16),
130 [MR] = XTENSA_REG("MR0", XTENSA_OPTION_MAC16),
131 [MR + 1] = XTENSA_REG("MR1", XTENSA_OPTION_MAC16),
132 [MR + 2] = XTENSA_REG("MR2", XTENSA_OPTION_MAC16),
133 [MR + 3] = XTENSA_REG("MR3", XTENSA_OPTION_MAC16),
134 [WINDOW_BASE] = XTENSA_REG("WINDOW_BASE", XTENSA_OPTION_WINDOWED_REGISTER),
135 [WINDOW_START] = XTENSA_REG("WINDOW_START",
136 XTENSA_OPTION_WINDOWED_REGISTER),
137 [PTEVADDR] = XTENSA_REG("PTEVADDR", XTENSA_OPTION_MMU),
13f6a7cd 138 [MMID] = XTENSA_REG_BITS("MMID", XTENSA_OPTION_ALL),
fe0bd475
MF
139 [RASID] = XTENSA_REG("RASID", XTENSA_OPTION_MMU),
140 [ITLBCFG] = XTENSA_REG("ITLBCFG", XTENSA_OPTION_MMU),
141 [DTLBCFG] = XTENSA_REG("DTLBCFG", XTENSA_OPTION_MMU),
142 [IBREAKENABLE] = XTENSA_REG("IBREAKENABLE", XTENSA_OPTION_DEBUG),
9e03ade4 143 [MEMCTL] = XTENSA_REG_BITS("MEMCTL", XTENSA_OPTION_ALL),
fe0bd475
MF
144 [CACHEATTR] = XTENSA_REG("CACHEATTR", XTENSA_OPTION_CACHEATTR),
145 [ATOMCTL] = XTENSA_REG("ATOMCTL", XTENSA_OPTION_ATOMCTL),
13f6a7cd 146 [DDR] = XTENSA_REG("DDR", XTENSA_OPTION_DEBUG),
fe0bd475
MF
147 [IBREAKA] = XTENSA_REG("IBREAKA0", XTENSA_OPTION_DEBUG),
148 [IBREAKA + 1] = XTENSA_REG("IBREAKA1", XTENSA_OPTION_DEBUG),
149 [DBREAKA] = XTENSA_REG("DBREAKA0", XTENSA_OPTION_DEBUG),
150 [DBREAKA + 1] = XTENSA_REG("DBREAKA1", XTENSA_OPTION_DEBUG),
151 [DBREAKC] = XTENSA_REG("DBREAKC0", XTENSA_OPTION_DEBUG),
152 [DBREAKC + 1] = XTENSA_REG("DBREAKC1", XTENSA_OPTION_DEBUG),
604e1f9c 153 [CONFIGID0] = XTENSA_REG_BITS_ACCESS("CONFIGID0", XTENSA_OPTION_ALL, SR_R),
fe0bd475
MF
154 [EPC1] = XTENSA_REG("EPC1", XTENSA_OPTION_EXCEPTION),
155 [EPC1 + 1] = XTENSA_REG("EPC2", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
156 [EPC1 + 2] = XTENSA_REG("EPC3", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
157 [EPC1 + 3] = XTENSA_REG("EPC4", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
158 [EPC1 + 4] = XTENSA_REG("EPC5", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
159 [EPC1 + 5] = XTENSA_REG("EPC6", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
160 [EPC1 + 6] = XTENSA_REG("EPC7", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
161 [DEPC] = XTENSA_REG("DEPC", XTENSA_OPTION_EXCEPTION),
162 [EPS2] = XTENSA_REG("EPS2", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
163 [EPS2 + 1] = XTENSA_REG("EPS3", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
164 [EPS2 + 2] = XTENSA_REG("EPS4", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
165 [EPS2 + 3] = XTENSA_REG("EPS5", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
166 [EPS2 + 4] = XTENSA_REG("EPS6", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
167 [EPS2 + 5] = XTENSA_REG("EPS7", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
604e1f9c 168 [CONFIGID1] = XTENSA_REG_BITS_ACCESS("CONFIGID1", XTENSA_OPTION_ALL, SR_R),
fe0bd475
MF
169 [EXCSAVE1] = XTENSA_REG("EXCSAVE1", XTENSA_OPTION_EXCEPTION),
170 [EXCSAVE1 + 1] = XTENSA_REG("EXCSAVE2",
171 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
172 [EXCSAVE1 + 2] = XTENSA_REG("EXCSAVE3",
173 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
174 [EXCSAVE1 + 3] = XTENSA_REG("EXCSAVE4",
175 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
176 [EXCSAVE1 + 4] = XTENSA_REG("EXCSAVE5",
177 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
178 [EXCSAVE1 + 5] = XTENSA_REG("EXCSAVE6",
179 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
180 [EXCSAVE1 + 6] = XTENSA_REG("EXCSAVE7",
181 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
182 [CPENABLE] = XTENSA_REG("CPENABLE", XTENSA_OPTION_COPROCESSOR),
53593e90
MF
183 [INTSET] = XTENSA_REG_ACCESS("INTSET", XTENSA_OPTION_INTERRUPT, SR_RW),
184 [INTCLEAR] = XTENSA_REG_ACCESS("INTCLEAR", XTENSA_OPTION_INTERRUPT, SR_W),
fe0bd475
MF
185 [INTENABLE] = XTENSA_REG("INTENABLE", XTENSA_OPTION_INTERRUPT),
186 [PS] = XTENSA_REG_BITS("PS", XTENSA_OPTION_ALL),
187 [VECBASE] = XTENSA_REG("VECBASE", XTENSA_OPTION_RELOCATABLE_VECTOR),
188 [EXCCAUSE] = XTENSA_REG("EXCCAUSE", XTENSA_OPTION_EXCEPTION),
53593e90 189 [DEBUGCAUSE] = XTENSA_REG_ACCESS("DEBUGCAUSE", XTENSA_OPTION_DEBUG, SR_R),
fe0bd475 190 [CCOUNT] = XTENSA_REG("CCOUNT", XTENSA_OPTION_TIMER_INTERRUPT),
53593e90 191 [PRID] = XTENSA_REG_ACCESS("PRID", XTENSA_OPTION_PROCESSOR_ID, SR_R),
fe0bd475
MF
192 [ICOUNT] = XTENSA_REG("ICOUNT", XTENSA_OPTION_DEBUG),
193 [ICOUNTLEVEL] = XTENSA_REG("ICOUNTLEVEL", XTENSA_OPTION_DEBUG),
194 [EXCVADDR] = XTENSA_REG("EXCVADDR", XTENSA_OPTION_EXCEPTION),
195 [CCOMPARE] = XTENSA_REG("CCOMPARE0", XTENSA_OPTION_TIMER_INTERRUPT),
196 [CCOMPARE + 1] = XTENSA_REG("CCOMPARE1",
197 XTENSA_OPTION_TIMER_INTERRUPT),
198 [CCOMPARE + 2] = XTENSA_REG("CCOMPARE2",
199 XTENSA_OPTION_TIMER_INTERRUPT),
b7909d81
MF
200 [MISC] = XTENSA_REG("MISC0", XTENSA_OPTION_MISC_SR),
201 [MISC + 1] = XTENSA_REG("MISC1", XTENSA_OPTION_MISC_SR),
202 [MISC + 2] = XTENSA_REG("MISC2", XTENSA_OPTION_MISC_SR),
203 [MISC + 3] = XTENSA_REG("MISC3", XTENSA_OPTION_MISC_SR),
2af3da91
MF
204};
205
fe0bd475 206static const XtensaReg uregnames[256] = {
e9872741 207 [EXPSTATE] = XTENSA_REG_BITS("EXPSTATE", XTENSA_OPTION_ALL),
fe0bd475
MF
208 [THREADPTR] = XTENSA_REG("THREADPTR", XTENSA_OPTION_THREAD_POINTER),
209 [FCR] = XTENSA_REG("FCR", XTENSA_OPTION_FP_COPROCESSOR),
210 [FSR] = XTENSA_REG("FSR", XTENSA_OPTION_FP_COPROCESSOR),
2af3da91
MF
211};
212
2328826b
MF
213void xtensa_translate_init(void)
214{
dedc5eae
MF
215 static const char * const regnames[] = {
216 "ar0", "ar1", "ar2", "ar3",
217 "ar4", "ar5", "ar6", "ar7",
218 "ar8", "ar9", "ar10", "ar11",
219 "ar12", "ar13", "ar14", "ar15",
220 };
dd519cbe
MF
221 static const char * const fregnames[] = {
222 "f0", "f1", "f2", "f3",
223 "f4", "f5", "f6", "f7",
224 "f8", "f9", "f10", "f11",
225 "f12", "f13", "f14", "f15",
226 };
dedc5eae
MF
227 int i;
228
e1ccc054 229 cpu_pc = tcg_global_mem_new_i32(cpu_env,
97129ac8 230 offsetof(CPUXtensaState, pc), "pc");
dedc5eae
MF
231
232 for (i = 0; i < 16; i++) {
e1ccc054 233 cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
97129ac8 234 offsetof(CPUXtensaState, regs[i]),
dedc5eae
MF
235 regnames[i]);
236 }
2af3da91 237
dd519cbe 238 for (i = 0; i < 16; i++) {
e1ccc054 239 cpu_FR[i] = tcg_global_mem_new_i32(cpu_env,
ddd44279 240 offsetof(CPUXtensaState, fregs[i].f32[FP_F32_LOW]),
dd519cbe
MF
241 fregnames[i]);
242 }
243
2af3da91 244 for (i = 0; i < 256; ++i) {
fe0bd475 245 if (sregnames[i].name) {
e1ccc054 246 cpu_SR[i] = tcg_global_mem_new_i32(cpu_env,
97129ac8 247 offsetof(CPUXtensaState, sregs[i]),
fe0bd475 248 sregnames[i].name);
2af3da91
MF
249 }
250 }
251
252 for (i = 0; i < 256; ++i) {
fe0bd475 253 if (uregnames[i].name) {
e1ccc054 254 cpu_UR[i] = tcg_global_mem_new_i32(cpu_env,
97129ac8 255 offsetof(CPUXtensaState, uregs[i]),
fe0bd475 256 uregnames[i].name);
2af3da91
MF
257 }
258 }
dedc5eae
MF
259}
260
261static inline bool option_enabled(DisasContext *dc, int opt)
262{
263 return xtensa_option_enabled(dc->config, opt);
264}
265
3580ecad
MF
266static void init_sar_tracker(DisasContext *dc)
267{
268 dc->sar_5bit = false;
269 dc->sar_m32_5bit = false;
270 dc->sar_m32_allocated = false;
271}
272
273static void reset_sar_tracker(DisasContext *dc)
274{
275 if (dc->sar_m32_allocated) {
276 tcg_temp_free(dc->sar_m32);
277 }
278}
279
280static void gen_right_shift_sar(DisasContext *dc, TCGv_i32 sa)
281{
282 tcg_gen_andi_i32(cpu_SR[SAR], sa, 0x1f);
283 if (dc->sar_m32_5bit) {
284 tcg_gen_discard_i32(dc->sar_m32);
285 }
286 dc->sar_5bit = true;
287 dc->sar_m32_5bit = false;
288}
289
290static void gen_left_shift_sar(DisasContext *dc, TCGv_i32 sa)
291{
292 TCGv_i32 tmp = tcg_const_i32(32);
293 if (!dc->sar_m32_allocated) {
294 dc->sar_m32 = tcg_temp_local_new_i32();
295 dc->sar_m32_allocated = true;
296 }
297 tcg_gen_andi_i32(dc->sar_m32, sa, 0x1f);
298 tcg_gen_sub_i32(cpu_SR[SAR], tmp, dc->sar_m32);
299 dc->sar_5bit = false;
300 dc->sar_m32_5bit = true;
301 tcg_temp_free(tmp);
302}
303
b994e91b 304static void gen_exception(DisasContext *dc, int excp)
dedc5eae
MF
305{
306 TCGv_i32 tmp = tcg_const_i32(excp);
f492b82d 307 gen_helper_exception(cpu_env, tmp);
dedc5eae
MF
308 tcg_temp_free(tmp);
309}
310
40643d7c
MF
311static void gen_exception_cause(DisasContext *dc, uint32_t cause)
312{
313 TCGv_i32 tpc = tcg_const_i32(dc->pc);
314 TCGv_i32 tcause = tcg_const_i32(cause);
f492b82d 315 gen_helper_exception_cause(cpu_env, tpc, tcause);
40643d7c
MF
316 tcg_temp_free(tpc);
317 tcg_temp_free(tcause);
6b814719
MF
318 if (cause == ILLEGAL_INSTRUCTION_CAUSE ||
319 cause == SYSCALL_CAUSE) {
320 dc->is_jmp = DISAS_UPDATE;
321 }
40643d7c
MF
322}
323
5b4e481b
MF
324static void gen_exception_cause_vaddr(DisasContext *dc, uint32_t cause,
325 TCGv_i32 vaddr)
326{
327 TCGv_i32 tpc = tcg_const_i32(dc->pc);
328 TCGv_i32 tcause = tcg_const_i32(cause);
f492b82d 329 gen_helper_exception_cause_vaddr(cpu_env, tpc, tcause, vaddr);
5b4e481b
MF
330 tcg_temp_free(tpc);
331 tcg_temp_free(tcause);
332}
333
e61dc8f7
MF
334static void gen_debug_exception(DisasContext *dc, uint32_t cause)
335{
336 TCGv_i32 tpc = tcg_const_i32(dc->pc);
337 TCGv_i32 tcause = tcg_const_i32(cause);
f492b82d 338 gen_helper_debug_exception(cpu_env, tpc, tcause);
e61dc8f7
MF
339 tcg_temp_free(tpc);
340 tcg_temp_free(tcause);
341 if (cause & (DEBUGCAUSE_IB | DEBUGCAUSE_BI | DEBUGCAUSE_BN)) {
342 dc->is_jmp = DISAS_UPDATE;
343 }
344}
345
97e89ee9 346static bool gen_check_privilege(DisasContext *dc)
40643d7c 347{
ba7651fb
MF
348#ifndef CONFIG_USER_ONLY
349 if (!dc->cring) {
350 return true;
40643d7c 351 }
ba7651fb
MF
352#endif
353 gen_exception_cause(dc, PRIVILEGED_CAUSE);
354 dc->is_jmp = DISAS_UPDATE;
355 return false;
40643d7c
MF
356}
357
97e89ee9 358static bool gen_check_cpenable(DisasContext *dc, unsigned cp)
ef04a846
MF
359{
360 if (option_enabled(dc, XTENSA_OPTION_COPROCESSOR) &&
361 !(dc->cpenable & (1 << cp))) {
362 gen_exception_cause(dc, COPROCESSOR0_DISABLED + cp);
363 dc->is_jmp = DISAS_UPDATE;
97e89ee9 364 return false;
ef04a846 365 }
97e89ee9 366 return true;
ef04a846
MF
367}
368
dedc5eae
MF
369static void gen_jump_slot(DisasContext *dc, TCGv dest, int slot)
370{
371 tcg_gen_mov_i32(cpu_pc, dest);
35b5c044
MF
372 if (dc->icount) {
373 tcg_gen_mov_i32(cpu_SR[ICOUNT], dc->next_icount);
374 }
dedc5eae 375 if (dc->singlestep_enabled) {
b994e91b 376 gen_exception(dc, EXCP_DEBUG);
dedc5eae
MF
377 } else {
378 if (slot >= 0) {
379 tcg_gen_goto_tb(slot);
07ea28b4 380 tcg_gen_exit_tb(dc->tb, slot);
dedc5eae 381 } else {
07ea28b4 382 tcg_gen_exit_tb(NULL, 0);
dedc5eae
MF
383 }
384 }
385 dc->is_jmp = DISAS_UPDATE;
386}
387
67882fd1
MF
388static void gen_jump(DisasContext *dc, TCGv dest)
389{
390 gen_jump_slot(dc, dest, -1);
391}
392
dedc5eae
MF
393static void gen_jumpi(DisasContext *dc, uint32_t dest, int slot)
394{
395 TCGv_i32 tmp = tcg_const_i32(dest);
90aa39a1 396#ifndef CONFIG_USER_ONLY
433d33c5 397 if (((dc->tb->pc ^ dest) & TARGET_PAGE_MASK) != 0) {
dedc5eae
MF
398 slot = -1;
399 }
90aa39a1 400#endif
dedc5eae
MF
401 gen_jump_slot(dc, tmp, slot);
402 tcg_temp_free(tmp);
403}
404
553e44f9
MF
405static void gen_callw_slot(DisasContext *dc, int callinc, TCGv_i32 dest,
406 int slot)
407{
408 TCGv_i32 tcallinc = tcg_const_i32(callinc);
409
410 tcg_gen_deposit_i32(cpu_SR[PS], cpu_SR[PS],
411 tcallinc, PS_CALLINC_SHIFT, PS_CALLINC_LEN);
412 tcg_temp_free(tcallinc);
413 tcg_gen_movi_i32(cpu_R[callinc << 2],
414 (callinc << 30) | (dc->next_pc & 0x3fffffff));
415 gen_jump_slot(dc, dest, slot);
416}
417
418static void gen_callw(DisasContext *dc, int callinc, TCGv_i32 dest)
419{
420 gen_callw_slot(dc, callinc, dest, -1);
421}
422
423static void gen_callwi(DisasContext *dc, int callinc, uint32_t dest, int slot)
424{
425 TCGv_i32 tmp = tcg_const_i32(dest);
90aa39a1 426#ifndef CONFIG_USER_ONLY
433d33c5 427 if (((dc->tb->pc ^ dest) & TARGET_PAGE_MASK) != 0) {
553e44f9
MF
428 slot = -1;
429 }
90aa39a1 430#endif
553e44f9
MF
431 gen_callw_slot(dc, callinc, tmp, slot);
432 tcg_temp_free(tmp);
433}
434
797d780b
MF
435static bool gen_check_loop_end(DisasContext *dc, int slot)
436{
437 if (option_enabled(dc, XTENSA_OPTION_LOOP) &&
438 !(dc->tb->flags & XTENSA_TBFLAG_EXCM) &&
439 dc->next_pc == dc->lend) {
42a268c2 440 TCGLabel *label = gen_new_label();
797d780b
MF
441
442 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_SR[LCOUNT], 0, label);
443 tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_SR[LCOUNT], 1);
444 gen_jumpi(dc, dc->lbeg, slot);
445 gen_set_label(label);
446 gen_jumpi(dc, dc->next_pc, -1);
447 return true;
448 }
449 return false;
450}
451
452static void gen_jumpi_check_loop_end(DisasContext *dc, int slot)
453{
454 if (!gen_check_loop_end(dc, slot)) {
455 gen_jumpi(dc, dc->next_pc, slot);
456 }
457}
458
bd57fb91 459static void gen_brcond(DisasContext *dc, TCGCond cond,
33071f68 460 TCGv_i32 t0, TCGv_i32 t1, uint32_t addr)
bd57fb91 461{
42a268c2 462 TCGLabel *label = gen_new_label();
bd57fb91
MF
463
464 tcg_gen_brcond_i32(cond, t0, t1, label);
797d780b 465 gen_jumpi_check_loop_end(dc, 0);
bd57fb91 466 gen_set_label(label);
33071f68 467 gen_jumpi(dc, addr, 1);
bd57fb91
MF
468}
469
470static void gen_brcondi(DisasContext *dc, TCGCond cond,
33071f68 471 TCGv_i32 t0, uint32_t t1, uint32_t addr)
bd57fb91
MF
472{
473 TCGv_i32 tmp = tcg_const_i32(t1);
33071f68 474 gen_brcond(dc, cond, t0, tmp, addr);
bd57fb91
MF
475 tcg_temp_free(tmp);
476}
477
0857a06e 478static bool gen_check_sr(DisasContext *dc, uint32_t sr, unsigned access)
fe0bd475
MF
479{
480 if (!xtensa_option_bits_enabled(dc->config, sregnames[sr].opt_bits)) {
481 if (sregnames[sr].name) {
c30f0d18 482 qemu_log_mask(LOG_GUEST_ERROR, "SR %s is not configured\n", sregnames[sr].name);
fe0bd475 483 } else {
c30f0d18 484 qemu_log_mask(LOG_UNIMP, "SR %d is not implemented\n", sr);
fe0bd475
MF
485 }
486 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
0857a06e 487 return false;
53593e90
MF
488 } else if (!(sregnames[sr].access & access)) {
489 static const char * const access_text[] = {
490 [SR_R] = "rsr",
491 [SR_W] = "wsr",
492 [SR_X] = "xsr",
493 };
494 assert(access < ARRAY_SIZE(access_text) && access_text[access]);
c30f0d18
PB
495 qemu_log_mask(LOG_GUEST_ERROR, "SR %s is not available for %s\n", sregnames[sr].name,
496 access_text[access]);
53593e90 497 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
0857a06e 498 return false;
fe0bd475 499 }
0857a06e 500 return true;
fe0bd475
MF
501}
502
ba7651fb 503#ifndef CONFIG_USER_ONLY
d2132510 504static bool gen_rsr_ccount(DisasContext *dc, TCGv_i32 d, uint32_t sr)
b994e91b 505{
c5a49c63 506 if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
d2132510
MF
507 gen_io_start();
508 }
59a71f75 509 gen_helper_update_ccount(cpu_env);
b994e91b 510 tcg_gen_mov_i32(d, cpu_SR[sr]);
c5a49c63 511 if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
d2132510
MF
512 gen_io_end();
513 return true;
514 }
515 return false;
b994e91b
MF
516}
517
d2132510 518static bool gen_rsr_ptevaddr(DisasContext *dc, TCGv_i32 d, uint32_t sr)
b67ea0cd
MF
519{
520 tcg_gen_shri_i32(d, cpu_SR[EXCVADDR], 10);
521 tcg_gen_or_i32(d, d, cpu_SR[sr]);
522 tcg_gen_andi_i32(d, d, 0xfffffffc);
d2132510 523 return false;
b67ea0cd 524}
ba7651fb 525#endif
b67ea0cd 526
d2132510 527static bool gen_rsr(DisasContext *dc, TCGv_i32 d, uint32_t sr)
b8132eff 528{
d2132510 529 static bool (* const rsr_handler[256])(DisasContext *dc,
b8132eff 530 TCGv_i32 d, uint32_t sr) = {
ba7651fb 531#ifndef CONFIG_USER_ONLY
b994e91b 532 [CCOUNT] = gen_rsr_ccount,
59a71f75 533 [INTSET] = gen_rsr_ccount,
b67ea0cd 534 [PTEVADDR] = gen_rsr_ptevaddr,
ba7651fb 535#endif
b8132eff
MF
536 };
537
fe0bd475 538 if (rsr_handler[sr]) {
d2132510 539 return rsr_handler[sr](dc, d, sr);
b8132eff 540 } else {
fe0bd475 541 tcg_gen_mov_i32(d, cpu_SR[sr]);
d2132510 542 return false;
b8132eff
MF
543 }
544}
545
d2132510 546static bool gen_wsr_lbeg(DisasContext *dc, uint32_t sr, TCGv_i32 s)
797d780b 547{
f492b82d 548 gen_helper_wsr_lbeg(cpu_env, s);
3d0be8a5 549 gen_jumpi_check_loop_end(dc, 0);
d2132510 550 return false;
797d780b
MF
551}
552
d2132510 553static bool gen_wsr_lend(DisasContext *dc, uint32_t sr, TCGv_i32 s)
797d780b 554{
f492b82d 555 gen_helper_wsr_lend(cpu_env, s);
3d0be8a5 556 gen_jumpi_check_loop_end(dc, 0);
d2132510 557 return false;
797d780b
MF
558}
559
d2132510 560static bool gen_wsr_sar(DisasContext *dc, uint32_t sr, TCGv_i32 s)
3580ecad
MF
561{
562 tcg_gen_andi_i32(cpu_SR[sr], s, 0x3f);
563 if (dc->sar_m32_5bit) {
564 tcg_gen_discard_i32(dc->sar_m32);
565 }
566 dc->sar_5bit = false;
567 dc->sar_m32_5bit = false;
d2132510 568 return false;
3580ecad
MF
569}
570
d2132510 571static bool gen_wsr_br(DisasContext *dc, uint32_t sr, TCGv_i32 s)
4dd85b6b
MF
572{
573 tcg_gen_andi_i32(cpu_SR[sr], s, 0xffff);
d2132510 574 return false;
4dd85b6b
MF
575}
576
d2132510 577static bool gen_wsr_litbase(DisasContext *dc, uint32_t sr, TCGv_i32 s)
6ad6dbf7
MF
578{
579 tcg_gen_andi_i32(cpu_SR[sr], s, 0xfffff001);
580 /* This can change tb->flags, so exit tb */
581 gen_jumpi_check_loop_end(dc, -1);
d2132510 582 return true;
6ad6dbf7
MF
583}
584
d2132510 585static bool gen_wsr_acchi(DisasContext *dc, uint32_t sr, TCGv_i32 s)
6825b6c3
MF
586{
587 tcg_gen_ext8s_i32(cpu_SR[sr], s);
d2132510 588 return false;
6825b6c3
MF
589}
590
ba7651fb 591#ifndef CONFIG_USER_ONLY
d2132510 592static bool gen_wsr_windowbase(DisasContext *dc, uint32_t sr, TCGv_i32 v)
553e44f9 593{
f492b82d 594 gen_helper_wsr_windowbase(cpu_env, v);
2db59a76
MF
595 /* This can change tb->flags, so exit tb */
596 gen_jumpi_check_loop_end(dc, -1);
d2132510 597 return true;
772177c1
MF
598}
599
d2132510 600static bool gen_wsr_windowstart(DisasContext *dc, uint32_t sr, TCGv_i32 v)
772177c1 601{
53a72dfd 602 tcg_gen_andi_i32(cpu_SR[sr], v, (1 << dc->config->nareg / 4) - 1);
2db59a76
MF
603 /* This can change tb->flags, so exit tb */
604 gen_jumpi_check_loop_end(dc, -1);
d2132510 605 return true;
553e44f9
MF
606}
607
d2132510 608static bool gen_wsr_ptevaddr(DisasContext *dc, uint32_t sr, TCGv_i32 v)
b67ea0cd
MF
609{
610 tcg_gen_andi_i32(cpu_SR[sr], v, 0xffc00000);
d2132510 611 return false;
b67ea0cd
MF
612}
613
d2132510 614static bool gen_wsr_rasid(DisasContext *dc, uint32_t sr, TCGv_i32 v)
b67ea0cd 615{
f492b82d 616 gen_helper_wsr_rasid(cpu_env, v);
b67ea0cd
MF
617 /* This can change tb->flags, so exit tb */
618 gen_jumpi_check_loop_end(dc, -1);
d2132510 619 return true;
b67ea0cd
MF
620}
621
d2132510 622static bool gen_wsr_tlbcfg(DisasContext *dc, uint32_t sr, TCGv_i32 v)
b67ea0cd
MF
623{
624 tcg_gen_andi_i32(cpu_SR[sr], v, 0x01130000);
d2132510 625 return false;
b67ea0cd
MF
626}
627
d2132510 628static bool gen_wsr_ibreakenable(DisasContext *dc, uint32_t sr, TCGv_i32 v)
e61dc8f7 629{
f492b82d 630 gen_helper_wsr_ibreakenable(cpu_env, v);
e61dc8f7 631 gen_jumpi_check_loop_end(dc, 0);
d2132510 632 return true;
e61dc8f7
MF
633}
634
9e03ade4
MF
635static bool gen_wsr_memctl(DisasContext *dc, uint32_t sr, TCGv_i32 v)
636{
637 gen_helper_wsr_memctl(cpu_env, v);
638 return false;
e61dc8f7
MF
639}
640
d2132510 641static bool gen_wsr_atomctl(DisasContext *dc, uint32_t sr, TCGv_i32 v)
fcc803d1
MF
642{
643 tcg_gen_andi_i32(cpu_SR[sr], v, 0x3f);
d2132510 644 return false;
fcc803d1
MF
645}
646
d2132510 647static bool gen_wsr_ibreaka(DisasContext *dc, uint32_t sr, TCGv_i32 v)
e61dc8f7
MF
648{
649 unsigned id = sr - IBREAKA;
650
651 if (id < dc->config->nibreak) {
652 TCGv_i32 tmp = tcg_const_i32(id);
f492b82d 653 gen_helper_wsr_ibreaka(cpu_env, tmp, v);
e61dc8f7
MF
654 tcg_temp_free(tmp);
655 gen_jumpi_check_loop_end(dc, 0);
d2132510 656 return true;
e61dc8f7 657 }
d2132510 658 return false;
e61dc8f7
MF
659}
660
d2132510 661static bool gen_wsr_dbreaka(DisasContext *dc, uint32_t sr, TCGv_i32 v)
f14c4b5f
MF
662{
663 unsigned id = sr - DBREAKA;
664
665 if (id < dc->config->ndbreak) {
666 TCGv_i32 tmp = tcg_const_i32(id);
f492b82d 667 gen_helper_wsr_dbreaka(cpu_env, tmp, v);
f14c4b5f
MF
668 tcg_temp_free(tmp);
669 }
d2132510 670 return false;
f14c4b5f
MF
671}
672
d2132510 673static bool gen_wsr_dbreakc(DisasContext *dc, uint32_t sr, TCGv_i32 v)
f14c4b5f
MF
674{
675 unsigned id = sr - DBREAKC;
676
677 if (id < dc->config->ndbreak) {
678 TCGv_i32 tmp = tcg_const_i32(id);
f492b82d 679 gen_helper_wsr_dbreakc(cpu_env, tmp, v);
f14c4b5f
MF
680 tcg_temp_free(tmp);
681 }
d2132510 682 return false;
f14c4b5f
MF
683}
684
d2132510 685static bool gen_wsr_cpenable(DisasContext *dc, uint32_t sr, TCGv_i32 v)
ef04a846
MF
686{
687 tcg_gen_andi_i32(cpu_SR[sr], v, 0xff);
688 /* This can change tb->flags, so exit tb */
689 gen_jumpi_check_loop_end(dc, -1);
d2132510 690 return true;
ef04a846
MF
691}
692
d2132510
MF
693static void gen_check_interrupts(DisasContext *dc)
694{
c5a49c63 695 if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
d2132510
MF
696 gen_io_start();
697 }
698 gen_helper_check_interrupts(cpu_env);
c5a49c63 699 if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
d2132510
MF
700 gen_io_end();
701 }
702}
703
704static bool gen_wsr_intset(DisasContext *dc, uint32_t sr, TCGv_i32 v)
b994e91b
MF
705{
706 tcg_gen_andi_i32(cpu_SR[sr], v,
707 dc->config->inttype_mask[INTTYPE_SOFTWARE]);
d2132510 708 gen_check_interrupts(dc);
b994e91b 709 gen_jumpi_check_loop_end(dc, 0);
d2132510 710 return true;
b994e91b
MF
711}
712
d2132510 713static bool gen_wsr_intclear(DisasContext *dc, uint32_t sr, TCGv_i32 v)
b994e91b
MF
714{
715 TCGv_i32 tmp = tcg_temp_new_i32();
716
717 tcg_gen_andi_i32(tmp, v,
718 dc->config->inttype_mask[INTTYPE_EDGE] |
719 dc->config->inttype_mask[INTTYPE_NMI] |
720 dc->config->inttype_mask[INTTYPE_SOFTWARE]);
721 tcg_gen_andc_i32(cpu_SR[INTSET], cpu_SR[INTSET], tmp);
722 tcg_temp_free(tmp);
d2132510
MF
723 gen_check_interrupts(dc);
724 gen_jumpi_check_loop_end(dc, 0);
725 return true;
b994e91b
MF
726}
727
d2132510 728static bool gen_wsr_intenable(DisasContext *dc, uint32_t sr, TCGv_i32 v)
b994e91b
MF
729{
730 tcg_gen_mov_i32(cpu_SR[sr], v);
d2132510 731 gen_check_interrupts(dc);
b994e91b 732 gen_jumpi_check_loop_end(dc, 0);
d2132510 733 return true;
b994e91b
MF
734}
735
d2132510 736static bool gen_wsr_ps(DisasContext *dc, uint32_t sr, TCGv_i32 v)
f0a548b9
MF
737{
738 uint32_t mask = PS_WOE | PS_CALLINC | PS_OWB |
739 PS_UM | PS_EXCM | PS_INTLEVEL;
740
741 if (option_enabled(dc, XTENSA_OPTION_MMU)) {
742 mask |= PS_RING;
743 }
744 tcg_gen_andi_i32(cpu_SR[sr], v, mask);
d2132510 745 gen_check_interrupts(dc);
b994e91b 746 /* This can change mmu index and tb->flags, so exit tb */
797d780b 747 gen_jumpi_check_loop_end(dc, -1);
d2132510 748 return true;
f0a548b9
MF
749}
750
d2132510 751static bool gen_wsr_ccount(DisasContext *dc, uint32_t sr, TCGv_i32 v)
59a71f75 752{
c5a49c63 753 if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
d2132510
MF
754 gen_io_start();
755 }
59a71f75 756 gen_helper_wsr_ccount(cpu_env, v);
c5a49c63 757 if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
d2132510
MF
758 gen_io_end();
759 gen_jumpi_check_loop_end(dc, 0);
760 return true;
761 }
762 return false;
f0a548b9
MF
763}
764
d2132510 765static bool gen_wsr_icount(DisasContext *dc, uint32_t sr, TCGv_i32 v)
35b5c044
MF
766{
767 if (dc->icount) {
768 tcg_gen_mov_i32(dc->next_icount, v);
769 } else {
770 tcg_gen_mov_i32(cpu_SR[sr], v);
771 }
d2132510 772 return false;
35b5c044
MF
773}
774
d2132510 775static bool gen_wsr_icountlevel(DisasContext *dc, uint32_t sr, TCGv_i32 v)
35b5c044
MF
776{
777 tcg_gen_andi_i32(cpu_SR[sr], v, 0xf);
778 /* This can change tb->flags, so exit tb */
779 gen_jumpi_check_loop_end(dc, -1);
d2132510 780 return true;
35b5c044
MF
781}
782
d2132510 783static bool gen_wsr_ccompare(DisasContext *dc, uint32_t sr, TCGv_i32 v)
b994e91b
MF
784{
785 uint32_t id = sr - CCOMPARE;
d2132510
MF
786 bool ret = false;
787
b994e91b
MF
788 if (id < dc->config->nccompare) {
789 uint32_t int_bit = 1 << dc->config->timerint[id];
59a71f75
MF
790 TCGv_i32 tmp = tcg_const_i32(id);
791
b994e91b
MF
792 tcg_gen_mov_i32(cpu_SR[sr], v);
793 tcg_gen_andi_i32(cpu_SR[INTSET], cpu_SR[INTSET], ~int_bit);
c5a49c63 794 if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
d2132510
MF
795 gen_io_start();
796 }
59a71f75 797 gen_helper_update_ccompare(cpu_env, tmp);
c5a49c63 798 if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
d2132510
MF
799 gen_io_end();
800 gen_jumpi_check_loop_end(dc, 0);
801 ret = true;
802 }
59a71f75 803 tcg_temp_free(tmp);
b994e91b 804 }
d2132510 805 return ret;
b994e91b 806}
ba7651fb
MF
807#else
808static void gen_check_interrupts(DisasContext *dc)
809{
810}
811#endif
b994e91b 812
d2132510 813static bool gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s)
b8132eff 814{
d2132510 815 static bool (* const wsr_handler[256])(DisasContext *dc,
b8132eff 816 uint32_t sr, TCGv_i32 v) = {
797d780b
MF
817 [LBEG] = gen_wsr_lbeg,
818 [LEND] = gen_wsr_lend,
3580ecad 819 [SAR] = gen_wsr_sar,
4dd85b6b 820 [BR] = gen_wsr_br,
6ad6dbf7 821 [LITBASE] = gen_wsr_litbase,
6825b6c3 822 [ACCHI] = gen_wsr_acchi,
ba7651fb 823#ifndef CONFIG_USER_ONLY
553e44f9 824 [WINDOW_BASE] = gen_wsr_windowbase,
772177c1 825 [WINDOW_START] = gen_wsr_windowstart,
b67ea0cd
MF
826 [PTEVADDR] = gen_wsr_ptevaddr,
827 [RASID] = gen_wsr_rasid,
828 [ITLBCFG] = gen_wsr_tlbcfg,
829 [DTLBCFG] = gen_wsr_tlbcfg,
e61dc8f7 830 [IBREAKENABLE] = gen_wsr_ibreakenable,
9e03ade4 831 [MEMCTL] = gen_wsr_memctl,
fcc803d1 832 [ATOMCTL] = gen_wsr_atomctl,
e61dc8f7
MF
833 [IBREAKA] = gen_wsr_ibreaka,
834 [IBREAKA + 1] = gen_wsr_ibreaka,
f14c4b5f
MF
835 [DBREAKA] = gen_wsr_dbreaka,
836 [DBREAKA + 1] = gen_wsr_dbreaka,
837 [DBREAKC] = gen_wsr_dbreakc,
838 [DBREAKC + 1] = gen_wsr_dbreakc,
ef04a846 839 [CPENABLE] = gen_wsr_cpenable,
b994e91b
MF
840 [INTSET] = gen_wsr_intset,
841 [INTCLEAR] = gen_wsr_intclear,
842 [INTENABLE] = gen_wsr_intenable,
f0a548b9 843 [PS] = gen_wsr_ps,
59a71f75 844 [CCOUNT] = gen_wsr_ccount,
35b5c044
MF
845 [ICOUNT] = gen_wsr_icount,
846 [ICOUNTLEVEL] = gen_wsr_icountlevel,
b994e91b
MF
847 [CCOMPARE] = gen_wsr_ccompare,
848 [CCOMPARE + 1] = gen_wsr_ccompare,
849 [CCOMPARE + 2] = gen_wsr_ccompare,
ba7651fb 850#endif
b8132eff
MF
851 };
852
fe0bd475 853 if (wsr_handler[sr]) {
d2132510 854 return wsr_handler[sr](dc, sr, s);
b8132eff 855 } else {
fe0bd475 856 tcg_gen_mov_i32(cpu_SR[sr], s);
d2132510 857 return false;
b8132eff
MF
858 }
859}
860
dd519cbe
MF
861static void gen_wur(uint32_t ur, TCGv_i32 s)
862{
863 switch (ur) {
864 case FCR:
865 gen_helper_wur_fcr(cpu_env, s);
866 break;
867
868 case FSR:
869 tcg_gen_andi_i32(cpu_UR[ur], s, 0xffffff80);
870 break;
871
872 default:
873 tcg_gen_mov_i32(cpu_UR[ur], s);
874 break;
875 }
876}
877
5b4e481b
MF
878static void gen_load_store_alignment(DisasContext *dc, int shift,
879 TCGv_i32 addr, bool no_hw_alignment)
880{
881 if (!option_enabled(dc, XTENSA_OPTION_UNALIGNED_EXCEPTION)) {
882 tcg_gen_andi_i32(addr, addr, ~0 << shift);
883 } else if (option_enabled(dc, XTENSA_OPTION_HW_ALIGNMENT) &&
884 no_hw_alignment) {
42a268c2 885 TCGLabel *label = gen_new_label();
5b4e481b
MF
886 TCGv_i32 tmp = tcg_temp_new_i32();
887 tcg_gen_andi_i32(tmp, addr, ~(~0 << shift));
888 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
889 gen_exception_cause_vaddr(dc, LOAD_STORE_ALIGNMENT_CAUSE, addr);
890 gen_set_label(label);
891 tcg_temp_free(tmp);
892 }
893}
894
ba7651fb 895#ifndef CONFIG_USER_ONLY
b994e91b
MF
896static void gen_waiti(DisasContext *dc, uint32_t imm4)
897{
898 TCGv_i32 pc = tcg_const_i32(dc->next_pc);
899 TCGv_i32 intlevel = tcg_const_i32(imm4);
d2132510 900
c5a49c63 901 if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
d2132510
MF
902 gen_io_start();
903 }
f492b82d 904 gen_helper_waiti(cpu_env, pc, intlevel);
c5a49c63 905 if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
d2132510
MF
906 gen_io_end();
907 }
b994e91b
MF
908 tcg_temp_free(pc);
909 tcg_temp_free(intlevel);
d2132510 910 gen_jumpi_check_loop_end(dc, 0);
b994e91b 911}
ba7651fb 912#endif
b994e91b 913
97e89ee9 914static bool gen_window_check1(DisasContext *dc, unsigned r1)
772177c1 915{
2db59a76
MF
916 if (r1 / 4 > dc->window) {
917 TCGv_i32 pc = tcg_const_i32(dc->pc);
918 TCGv_i32 w = tcg_const_i32(r1 / 4);
908c67fc 919
2db59a76
MF
920 gen_helper_window_check(cpu_env, pc, w);
921 dc->is_jmp = DISAS_UPDATE;
97e89ee9 922 return false;
772177c1 923 }
97e89ee9 924 return true;
772177c1
MF
925}
926
97e89ee9 927static bool gen_window_check2(DisasContext *dc, unsigned r1, unsigned r2)
772177c1 928{
97e89ee9 929 return gen_window_check1(dc, r1 > r2 ? r1 : r2);
772177c1
MF
930}
931
97e89ee9 932static bool gen_window_check3(DisasContext *dc, unsigned r1, unsigned r2,
772177c1
MF
933 unsigned r3)
934{
97e89ee9 935 return gen_window_check2(dc, r1, r2 > r3 ? r2 : r3);
772177c1
MF
936}
937
6825b6c3
MF
938static TCGv_i32 gen_mac16_m(TCGv_i32 v, bool hi, bool is_unsigned)
939{
940 TCGv_i32 m = tcg_temp_new_i32();
941
942 if (hi) {
943 (is_unsigned ? tcg_gen_shri_i32 : tcg_gen_sari_i32)(m, v, 16);
944 } else {
945 (is_unsigned ? tcg_gen_ext16u_i32 : tcg_gen_ext16s_i32)(m, v);
946 }
947 return m;
948}
949
33071f68 950static inline unsigned xtensa_op0_insn_len(DisasContext *dc, uint8_t op0)
01673a34 951{
33071f68 952 return xtensa_isa_length_from_chars(dc->config->isa, &op0);
01673a34
MF
953}
954
0c4fabea 955static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
dedc5eae 956{
33071f68
MF
957 xtensa_isa isa = dc->config->isa;
958 unsigned char b[MAX_INSN_LENGTH] = {cpu_ldub_code(env, dc->pc)};
959 unsigned len = xtensa_op0_insn_len(dc, b[0]);
960 xtensa_format fmt;
847a6473 961 int slot, slots;
33071f68 962 unsigned i;
01673a34 963
33071f68
MF
964 if (len == XTENSA_UNDEFINED) {
965 qemu_log_mask(LOG_GUEST_ERROR,
966 "unknown instruction length (pc = %08x)\n",
967 dc->pc);
968 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
969 return;
dedc5eae 970 }
dedc5eae 971
33071f68 972 dc->next_pc = dc->pc + len;
f40385c9
MF
973 if (xtensa_option_enabled(dc->config, XTENSA_OPTION_LOOP) &&
974 dc->lbeg == dc->pc &&
975 ((dc->pc ^ (dc->next_pc - 1)) & -dc->config->inst_fetch_width)) {
976 qemu_log_mask(LOG_GUEST_ERROR,
977 "unaligned first instruction of a loop (pc = %08x)\n",
978 dc->pc);
979 }
33071f68
MF
980 for (i = 1; i < len; ++i) {
981 b[i] = cpu_ldub_code(env, dc->pc + i);
982 }
983 xtensa_insnbuf_from_chars(isa, dc->insnbuf, b, len);
984 fmt = xtensa_format_decode(isa, dc->insnbuf);
985 if (fmt == XTENSA_UNDEFINED) {
986 qemu_log_mask(LOG_GUEST_ERROR,
987 "unrecognized instruction format (pc = %08x)\n",
988 dc->pc);
989 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
990 return;
991 }
992 slots = xtensa_format_num_slots(isa, fmt);
993 for (slot = 0; slot < slots; ++slot) {
994 xtensa_opcode opc;
847a6473 995 int opnd, vopnd, opnds;
33071f68
MF
996 uint32_t raw_arg[MAX_OPCODE_ARGS];
997 uint32_t arg[MAX_OPCODE_ARGS];
998 XtensaOpcodeOps *ops;
999
1000 dc->raw_arg = raw_arg;
1001
1002 xtensa_format_get_slot(isa, fmt, slot, dc->insnbuf, dc->slotbuf);
1003 opc = xtensa_opcode_decode(isa, fmt, slot, dc->slotbuf);
1004 if (opc == XTENSA_UNDEFINED) {
1005 qemu_log_mask(LOG_GUEST_ERROR,
1006 "unrecognized opcode in slot %d (pc = %08x)\n",
1007 slot, dc->pc);
1008 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
1009 return;
dedc5eae 1010 }
33071f68 1011 opnds = xtensa_opcode_num_operands(isa, opc);
bd57fb91 1012
33071f68
MF
1013 for (opnd = vopnd = 0; opnd < opnds; ++opnd) {
1014 if (xtensa_operand_is_visible(isa, opc, opnd)) {
1015 uint32_t v;
dedc5eae 1016
33071f68
MF
1017 xtensa_operand_get_field(isa, opc, opnd, fmt, slot,
1018 dc->slotbuf, &v);
1019 xtensa_operand_decode(isa, opc, opnd, &v);
1020 raw_arg[vopnd] = v;
1021 if (xtensa_operand_is_PCrelative(isa, opc, opnd)) {
1022 xtensa_operand_undo_reloc(isa, opc, opnd, &v, dc->pc);
bd57fb91 1023 }
33071f68
MF
1024 arg[vopnd] = v;
1025 ++vopnd;
bd57fb91
MF
1026 }
1027 }
33071f68
MF
1028 ops = dc->config->opcode_ops[opc];
1029 if (ops) {
1030 ops->translate(dc, arg, ops->par);
1031 } else {
1032 qemu_log_mask(LOG_GUEST_ERROR,
1033 "unimplemented opcode '%s' in slot %d (pc = %08x)\n",
1034 xtensa_opcode_name(isa, opc), slot, dc->pc);
1035 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
1036 return;
67882fd1 1037 }
dedc5eae 1038 }
c26032b2
MF
1039 if (dc->is_jmp == DISAS_NEXT) {
1040 gen_check_loop_end(dc, 0);
1041 }
dedc5eae 1042 dc->pc = dc->next_pc;
dedc5eae
MF
1043}
1044
01673a34
MF
1045static inline unsigned xtensa_insn_len(CPUXtensaState *env, DisasContext *dc)
1046{
1047 uint8_t b0 = cpu_ldub_code(env, dc->pc);
33071f68 1048 return xtensa_op0_insn_len(dc, b0);
01673a34
MF
1049}
1050
97129ac8 1051static void gen_ibreak_check(CPUXtensaState *env, DisasContext *dc)
e61dc8f7
MF
1052{
1053 unsigned i;
1054
1055 for (i = 0; i < dc->config->nibreak; ++i) {
1056 if ((env->sregs[IBREAKENABLE] & (1 << i)) &&
1057 env->sregs[IBREAKA + i] == dc->pc) {
1058 gen_debug_exception(dc, DEBUGCAUSE_IB);
1059 break;
1060 }
1061 }
1062}
1063
9c489ea6 1064void gen_intermediate_code(CPUState *cs, TranslationBlock *tb)
dedc5eae 1065{
9c489ea6 1066 CPUXtensaState *env = cs->env_ptr;
dedc5eae
MF
1067 DisasContext dc;
1068 int insn_count = 0;
c5a49c63 1069 int max_insns = tb_cflags(tb) & CF_COUNT_MASK;
dedc5eae 1070 uint32_t pc_start = tb->pc;
4e8b44b6 1071 uint32_t page_start = pc_start & TARGET_PAGE_MASK;
dedc5eae
MF
1072
1073 if (max_insns == 0) {
1074 max_insns = CF_COUNT_MASK;
1075 }
190ce7fb
RH
1076 if (max_insns > TCG_MAX_INSNS) {
1077 max_insns = TCG_MAX_INSNS;
1078 }
dedc5eae
MF
1079
1080 dc.config = env->config;
ed2803da 1081 dc.singlestep_enabled = cs->singlestep_enabled;
dedc5eae
MF
1082 dc.tb = tb;
1083 dc.pc = pc_start;
f0a548b9
MF
1084 dc.ring = tb->flags & XTENSA_TBFLAG_RING_MASK;
1085 dc.cring = (tb->flags & XTENSA_TBFLAG_EXCM) ? 0 : dc.ring;
797d780b
MF
1086 dc.lbeg = env->sregs[LBEG];
1087 dc.lend = env->sregs[LEND];
dedc5eae 1088 dc.is_jmp = DISAS_NEXT;
e61dc8f7 1089 dc.debug = tb->flags & XTENSA_TBFLAG_DEBUG;
35b5c044 1090 dc.icount = tb->flags & XTENSA_TBFLAG_ICOUNT;
ef04a846
MF
1091 dc.cpenable = (tb->flags & XTENSA_TBFLAG_CPENABLE_MASK) >>
1092 XTENSA_TBFLAG_CPENABLE_SHIFT;
2db59a76
MF
1093 dc.window = ((tb->flags & XTENSA_TBFLAG_WINDOW_MASK) >>
1094 XTENSA_TBFLAG_WINDOW_SHIFT);
dedc5eae 1095
33071f68
MF
1096 if (dc.config->isa) {
1097 dc.insnbuf = xtensa_insnbuf_alloc(dc.config->isa);
1098 dc.slotbuf = xtensa_insnbuf_alloc(dc.config->isa);
1099 }
1100
3580ecad 1101 init_sar_tracker(&dc);
35b5c044
MF
1102 if (dc.icount) {
1103 dc.next_icount = tcg_temp_local_new_i32();
1104 }
3580ecad 1105
cd42d5b2 1106 gen_tb_start(tb);
dedc5eae 1107
c5a49c63 1108 if ((tb_cflags(tb) & CF_USE_ICOUNT) &&
d2132510
MF
1109 (tb->flags & XTENSA_TBFLAG_YIELD)) {
1110 tcg_gen_insn_start(dc.pc);
1111 ++insn_count;
1112 gen_exception(&dc, EXCP_YIELD);
1113 dc.is_jmp = DISAS_UPDATE;
1114 goto done;
1115 }
a00817cc 1116 if (tb->flags & XTENSA_TBFLAG_EXCEPTION) {
787eaa49
MF
1117 tcg_gen_insn_start(dc.pc);
1118 ++insn_count;
b994e91b 1119 gen_exception(&dc, EXCP_DEBUG);
787eaa49
MF
1120 dc.is_jmp = DISAS_UPDATE;
1121 goto done;
40643d7c
MF
1122 }
1123
dedc5eae 1124 do {
667b8e29 1125 tcg_gen_insn_start(dc.pc);
959082fc 1126 ++insn_count;
dedc5eae 1127
b933066a
RH
1128 if (unlikely(cpu_breakpoint_test(cs, dc.pc, BP_ANY))) {
1129 tcg_gen_movi_i32(cpu_pc, dc.pc);
1130 gen_exception(&dc, EXCP_DEBUG);
1131 dc.is_jmp = DISAS_UPDATE;
522a0d4e
RH
1132 /* The address covered by the breakpoint must be included in
1133 [tb->pc, tb->pc + tb->size) in order to for it to be
1134 properly cleared -- thus we increment the PC here so that
1135 the logic setting tb->size below does the right thing. */
1136 dc.pc += 2;
b933066a
RH
1137 break;
1138 }
1139
c5a49c63 1140 if (insn_count == max_insns && (tb_cflags(tb) & CF_LAST_IO)) {
b994e91b
MF
1141 gen_io_start();
1142 }
1143
35b5c044 1144 if (dc.icount) {
42a268c2 1145 TCGLabel *label = gen_new_label();
35b5c044
MF
1146
1147 tcg_gen_addi_i32(dc.next_icount, cpu_SR[ICOUNT], 1);
1148 tcg_gen_brcondi_i32(TCG_COND_NE, dc.next_icount, 0, label);
1149 tcg_gen_mov_i32(dc.next_icount, cpu_SR[ICOUNT]);
1150 if (dc.debug) {
1151 gen_debug_exception(&dc, DEBUGCAUSE_IC);
1152 }
1153 gen_set_label(label);
1154 }
1155
e61dc8f7
MF
1156 if (dc.debug) {
1157 gen_ibreak_check(env, &dc);
1158 }
1159
0c4fabea 1160 disas_xtensa_insn(env, &dc);
35b5c044
MF
1161 if (dc.icount) {
1162 tcg_gen_mov_i32(cpu_SR[ICOUNT], dc.next_icount);
1163 }
ed2803da 1164 if (cs->singlestep_enabled) {
dedc5eae 1165 tcg_gen_movi_i32(cpu_pc, dc.pc);
b994e91b 1166 gen_exception(&dc, EXCP_DEBUG);
dedc5eae
MF
1167 break;
1168 }
1169 } while (dc.is_jmp == DISAS_NEXT &&
1170 insn_count < max_insns &&
4e8b44b6
EC
1171 dc.pc - page_start < TARGET_PAGE_SIZE &&
1172 dc.pc - page_start + xtensa_insn_len(env, &dc) <= TARGET_PAGE_SIZE
1173 && !tcg_op_buf_full());
d2132510 1174done:
3580ecad 1175 reset_sar_tracker(&dc);
35b5c044
MF
1176 if (dc.icount) {
1177 tcg_temp_free(dc.next_icount);
1178 }
33071f68
MF
1179 if (dc.config->isa) {
1180 xtensa_insnbuf_free(dc.config->isa, dc.insnbuf);
1181 xtensa_insnbuf_free(dc.config->isa, dc.slotbuf);
1182 }
3580ecad 1183
c5a49c63 1184 if (tb_cflags(tb) & CF_LAST_IO) {
b994e91b
MF
1185 gen_io_end();
1186 }
1187
dedc5eae
MF
1188 if (dc.is_jmp == DISAS_NEXT) {
1189 gen_jumpi(&dc, dc.pc, 0);
1190 }
806f352d 1191 gen_tb_end(tb, insn_count);
dedc5eae 1192
ca529f8e 1193#ifdef DEBUG_DISAS
4910e6e4
RH
1194 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
1195 && qemu_log_in_addr_range(pc_start)) {
1ee73216 1196 qemu_log_lock();
ca529f8e
MF
1197 qemu_log("----------------\n");
1198 qemu_log("IN: %s\n", lookup_symbol(pc_start));
1d48474d 1199 log_target_disas(cs, pc_start, dc.pc - pc_start);
ca529f8e 1200 qemu_log("\n");
1ee73216 1201 qemu_log_unlock();
ca529f8e
MF
1202 }
1203#endif
4e5e1215
RH
1204 tb->size = dc.pc - pc_start;
1205 tb->icount = insn_count;
2328826b
MF
1206}
1207
878096ee
AF
1208void xtensa_cpu_dump_state(CPUState *cs, FILE *f,
1209 fprintf_function cpu_fprintf, int flags)
2328826b 1210{
878096ee
AF
1211 XtensaCPU *cpu = XTENSA_CPU(cs);
1212 CPUXtensaState *env = &cpu->env;
2af3da91
MF
1213 int i, j;
1214
1215 cpu_fprintf(f, "PC=%08x\n\n", env->pc);
1216
1217 for (i = j = 0; i < 256; ++i) {
fe0bd475
MF
1218 if (xtensa_option_bits_enabled(env->config, sregnames[i].opt_bits)) {
1219 cpu_fprintf(f, "%12s=%08x%c", sregnames[i].name, env->sregs[i],
2af3da91
MF
1220 (j++ % 4) == 3 ? '\n' : ' ');
1221 }
1222 }
1223
1224 cpu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n");
1225
1226 for (i = j = 0; i < 256; ++i) {
fe0bd475
MF
1227 if (xtensa_option_bits_enabled(env->config, uregnames[i].opt_bits)) {
1228 cpu_fprintf(f, "%s=%08x%c", uregnames[i].name, env->uregs[i],
2af3da91
MF
1229 (j++ % 4) == 3 ? '\n' : ' ');
1230 }
1231 }
2328826b 1232
2af3da91 1233 cpu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n");
2328826b
MF
1234
1235 for (i = 0; i < 16; ++i) {
fe0bd475 1236 cpu_fprintf(f, " A%02d=%08x%c", i, env->regs[i],
2328826b
MF
1237 (i % 4) == 3 ? '\n' : ' ');
1238 }
553e44f9 1239
b55b1afd 1240 xtensa_sync_phys_from_window(env);
553e44f9
MF
1241 cpu_fprintf(f, "\n");
1242
1243 for (i = 0; i < env->config->nareg; ++i) {
b9317a2a
MF
1244 cpu_fprintf(f, "AR%02d=%08x ", i, env->phys_regs[i]);
1245 if (i % 4 == 3) {
1246 bool ws = (env->sregs[WINDOW_START] & (1 << (i / 4))) != 0;
1247 bool cw = env->sregs[WINDOW_BASE] == i / 4;
1248
1249 cpu_fprintf(f, "%c%c\n", ws ? '<' : ' ', cw ? '=' : ' ');
1250 }
553e44f9 1251 }
dd519cbe 1252
f29c0b17
RH
1253 if ((flags & CPU_DUMP_FPU) &&
1254 xtensa_option_enabled(env->config, XTENSA_OPTION_FP_COPROCESSOR)) {
dd519cbe
MF
1255 cpu_fprintf(f, "\n");
1256
1257 for (i = 0; i < 16; ++i) {
1258 cpu_fprintf(f, "F%02d=%08x (%+10.8e)%c", i,
ddd44279
MF
1259 float32_val(env->fregs[i].f32[FP_F32_LOW]),
1260 *(float *)(env->fregs[i].f32 + FP_F32_LOW),
1261 (i % 2) == 1 ? '\n' : ' ');
dd519cbe
MF
1262 }
1263 }
2328826b
MF
1264}
1265
bad729e2
RH
1266void restore_state_to_opc(CPUXtensaState *env, TranslationBlock *tb,
1267 target_ulong *data)
2328826b 1268{
bad729e2 1269 env->pc = data[0];
2328826b 1270}
168c12b0
MF
1271
1272static int compare_opcode_ops(const void *a, const void *b)
1273{
1274 return strcmp((const char *)a,
1275 ((const XtensaOpcodeOps *)b)->name);
1276}
1277
1278XtensaOpcodeOps *
1279xtensa_find_opcode_ops(const XtensaOpcodeTranslators *t,
1280 const char *name)
1281{
4a4ff4c5
LV
1282 return bsearch(name, t->opcode, t->num_opcodes,
1283 sizeof(XtensaOpcodeOps), compare_opcode_ops);
168c12b0
MF
1284}
1285
1286static void translate_abs(DisasContext *dc, const uint32_t arg[],
1287 const uint32_t par[])
1288{
1289 if (gen_window_check2(dc, arg[0], arg[1])) {
1290 TCGv_i32 zero = tcg_const_i32(0);
1291 TCGv_i32 neg = tcg_temp_new_i32();
1292
1293 tcg_gen_neg_i32(neg, cpu_R[arg[1]]);
1294 tcg_gen_movcond_i32(TCG_COND_GE, cpu_R[arg[0]],
1295 cpu_R[arg[1]], zero, cpu_R[arg[1]], neg);
1296 tcg_temp_free(neg);
1297 tcg_temp_free(zero);
1298 }
1299}
1300
1301static void translate_add(DisasContext *dc, const uint32_t arg[],
1302 const uint32_t par[])
1303{
1304 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
1305 tcg_gen_add_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
1306 }
1307}
1308
1309static void translate_addi(DisasContext *dc, const uint32_t arg[],
1310 const uint32_t par[])
1311{
1312 if (gen_window_check2(dc, arg[0], arg[1])) {
1313 tcg_gen_addi_i32(cpu_R[arg[0]], cpu_R[arg[1]], arg[2]);
1314 }
1315}
1316
1317static void translate_addx(DisasContext *dc, const uint32_t arg[],
1318 const uint32_t par[])
1319{
1320 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
1321 TCGv_i32 tmp = tcg_temp_new_i32();
1322 tcg_gen_shli_i32(tmp, cpu_R[arg[1]], par[0]);
1323 tcg_gen_add_i32(cpu_R[arg[0]], tmp, cpu_R[arg[2]]);
1324 tcg_temp_free(tmp);
1325 }
1326}
1327
1328static void translate_all(DisasContext *dc, const uint32_t arg[],
1329 const uint32_t par[])
1330{
1331 uint32_t shift = par[1];
1332 TCGv_i32 mask = tcg_const_i32(((1 << shift) - 1) << arg[1]);
1333 TCGv_i32 tmp = tcg_temp_new_i32();
1334
1335 tcg_gen_and_i32(tmp, cpu_SR[BR], mask);
1336 if (par[0]) {
1337 tcg_gen_addi_i32(tmp, tmp, 1 << arg[1]);
1338 } else {
1339 tcg_gen_add_i32(tmp, tmp, mask);
1340 }
1341 tcg_gen_shri_i32(tmp, tmp, arg[1] + shift);
1342 tcg_gen_deposit_i32(cpu_SR[BR], cpu_SR[BR],
1343 tmp, arg[0], 1);
1344 tcg_temp_free(mask);
1345 tcg_temp_free(tmp);
1346}
1347
1348static void translate_and(DisasContext *dc, const uint32_t arg[],
1349 const uint32_t par[])
1350{
1351 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
1352 tcg_gen_and_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
1353 }
1354}
1355
1356static void translate_ball(DisasContext *dc, const uint32_t arg[],
1357 const uint32_t par[])
1358{
1359 if (gen_window_check2(dc, arg[0], arg[1])) {
1360 TCGv_i32 tmp = tcg_temp_new_i32();
1361 tcg_gen_and_i32(tmp, cpu_R[arg[0]], cpu_R[arg[1]]);
1362 gen_brcond(dc, par[0], tmp, cpu_R[arg[1]], arg[2]);
1363 tcg_temp_free(tmp);
1364 }
1365}
1366
1367static void translate_bany(DisasContext *dc, const uint32_t arg[],
1368 const uint32_t par[])
1369{
1370 if (gen_window_check2(dc, arg[0], arg[1])) {
1371 TCGv_i32 tmp = tcg_temp_new_i32();
1372 tcg_gen_and_i32(tmp, cpu_R[arg[0]], cpu_R[arg[1]]);
1373 gen_brcondi(dc, par[0], tmp, 0, arg[2]);
1374 tcg_temp_free(tmp);
1375 }
1376}
1377
1378static void translate_b(DisasContext *dc, const uint32_t arg[],
1379 const uint32_t par[])
1380{
1381 if (gen_window_check2(dc, arg[0], arg[1])) {
1382 gen_brcond(dc, par[0], cpu_R[arg[0]], cpu_R[arg[1]], arg[2]);
1383 }
1384}
1385
1386static void translate_bb(DisasContext *dc, const uint32_t arg[],
1387 const uint32_t par[])
1388{
1389 if (gen_window_check2(dc, arg[0], arg[1])) {
1390#ifdef TARGET_WORDS_BIGENDIAN
1391 TCGv_i32 bit = tcg_const_i32(0x80000000u);
1392#else
1393 TCGv_i32 bit = tcg_const_i32(0x00000001u);
1394#endif
1395 TCGv_i32 tmp = tcg_temp_new_i32();
1396 tcg_gen_andi_i32(tmp, cpu_R[arg[1]], 0x1f);
1397#ifdef TARGET_WORDS_BIGENDIAN
1398 tcg_gen_shr_i32(bit, bit, tmp);
1399#else
1400 tcg_gen_shl_i32(bit, bit, tmp);
1401#endif
1402 tcg_gen_and_i32(tmp, cpu_R[arg[0]], bit);
1403 gen_brcondi(dc, par[0], tmp, 0, arg[2]);
1404 tcg_temp_free(tmp);
1405 tcg_temp_free(bit);
1406 }
1407}
1408
1409static void translate_bbi(DisasContext *dc, const uint32_t arg[],
1410 const uint32_t par[])
1411{
1412 if (gen_window_check1(dc, arg[0])) {
1413 TCGv_i32 tmp = tcg_temp_new_i32();
1414#ifdef TARGET_WORDS_BIGENDIAN
1415 tcg_gen_andi_i32(tmp, cpu_R[arg[0]], 0x80000000u >> arg[1]);
1416#else
1417 tcg_gen_andi_i32(tmp, cpu_R[arg[0]], 0x00000001u << arg[1]);
1418#endif
1419 gen_brcondi(dc, par[0], tmp, 0, arg[2]);
1420 tcg_temp_free(tmp);
1421 }
1422}
1423
1424static void translate_bi(DisasContext *dc, const uint32_t arg[],
1425 const uint32_t par[])
1426{
1427 if (gen_window_check1(dc, arg[0])) {
1428 gen_brcondi(dc, par[0], cpu_R[arg[0]], arg[1], arg[2]);
1429 }
1430}
1431
1432static void translate_bz(DisasContext *dc, const uint32_t arg[],
1433 const uint32_t par[])
1434{
1435 if (gen_window_check1(dc, arg[0])) {
1436 gen_brcondi(dc, par[0], cpu_R[arg[0]], 0, arg[1]);
1437 }
1438}
1439
1440enum {
1441 BOOLEAN_AND,
1442 BOOLEAN_ANDC,
1443 BOOLEAN_OR,
1444 BOOLEAN_ORC,
1445 BOOLEAN_XOR,
1446};
1447
1448static void translate_boolean(DisasContext *dc, const uint32_t arg[],
1449 const uint32_t par[])
1450{
1451 static void (* const op[])(TCGv_i32, TCGv_i32, TCGv_i32) = {
1452 [BOOLEAN_AND] = tcg_gen_and_i32,
1453 [BOOLEAN_ANDC] = tcg_gen_andc_i32,
1454 [BOOLEAN_OR] = tcg_gen_or_i32,
1455 [BOOLEAN_ORC] = tcg_gen_orc_i32,
1456 [BOOLEAN_XOR] = tcg_gen_xor_i32,
1457 };
1458
1459 TCGv_i32 tmp1 = tcg_temp_new_i32();
1460 TCGv_i32 tmp2 = tcg_temp_new_i32();
1461
1462 tcg_gen_shri_i32(tmp1, cpu_SR[BR], arg[1]);
1463 tcg_gen_shri_i32(tmp2, cpu_SR[BR], arg[2]);
1464 op[par[0]](tmp1, tmp1, tmp2);
1465 tcg_gen_deposit_i32(cpu_SR[BR], cpu_SR[BR], tmp1, arg[0], 1);
1466 tcg_temp_free(tmp1);
1467 tcg_temp_free(tmp2);
1468}
1469
1470static void translate_bp(DisasContext *dc, const uint32_t arg[],
1471 const uint32_t par[])
1472{
1473 TCGv_i32 tmp = tcg_temp_new_i32();
1474
1475 tcg_gen_andi_i32(tmp, cpu_SR[BR], 1 << arg[0]);
1476 gen_brcondi(dc, par[0], tmp, 0, arg[1]);
1477 tcg_temp_free(tmp);
1478}
1479
1480static void translate_break(DisasContext *dc, const uint32_t arg[],
1481 const uint32_t par[])
1482{
1483 if (dc->debug) {
1484 gen_debug_exception(dc, par[0]);
1485 }
1486}
1487
1488static void translate_call0(DisasContext *dc, const uint32_t arg[],
1489 const uint32_t par[])
1490{
1491 tcg_gen_movi_i32(cpu_R[0], dc->next_pc);
1492 gen_jumpi(dc, arg[0], 0);
1493}
1494
1495static void translate_callw(DisasContext *dc, const uint32_t arg[],
1496 const uint32_t par[])
1497{
1498 if (gen_window_check1(dc, par[0] << 2)) {
1499 gen_callwi(dc, par[0], arg[0], 0);
1500 }
1501}
1502
1503static void translate_callx0(DisasContext *dc, const uint32_t arg[],
1504 const uint32_t par[])
1505{
1506 if (gen_window_check1(dc, arg[0])) {
1507 TCGv_i32 tmp = tcg_temp_new_i32();
1508 tcg_gen_mov_i32(tmp, cpu_R[arg[0]]);
1509 tcg_gen_movi_i32(cpu_R[0], dc->next_pc);
1510 gen_jump(dc, tmp);
1511 tcg_temp_free(tmp);
1512 }
1513}
1514
1515static void translate_callxw(DisasContext *dc, const uint32_t arg[],
1516 const uint32_t par[])
1517{
1518 if (gen_window_check2(dc, arg[0], par[0] << 2)) {
1519 TCGv_i32 tmp = tcg_temp_new_i32();
1520
1521 tcg_gen_mov_i32(tmp, cpu_R[arg[0]]);
1522 gen_callw(dc, par[0], tmp);
1523 tcg_temp_free(tmp);
1524 }
1525}
1526
1527static void translate_clamps(DisasContext *dc, const uint32_t arg[],
1528 const uint32_t par[])
1529{
1530 if (gen_window_check2(dc, arg[0], arg[1])) {
1531 TCGv_i32 tmp1 = tcg_const_i32(-1u << arg[2]);
1532 TCGv_i32 tmp2 = tcg_const_i32((1 << arg[2]) - 1);
1533
426afc3b
RH
1534 tcg_gen_smax_i32(tmp1, tmp1, cpu_R[arg[1]]);
1535 tcg_gen_smin_i32(cpu_R[arg[0]], tmp1, tmp2);
168c12b0
MF
1536 tcg_temp_free(tmp1);
1537 tcg_temp_free(tmp2);
1538 }
1539}
1540
e9872741
MF
1541static void translate_clrb_expstate(DisasContext *dc, const uint32_t arg[],
1542 const uint32_t par[])
1543{
1544 /* TODO: GPIO32 may be a part of coprocessor */
1545 tcg_gen_andi_i32(cpu_UR[EXPSTATE], cpu_UR[EXPSTATE], ~(1u << arg[0]));
1546}
1547
c5ac936e
MF
1548static void translate_const16(DisasContext *dc, const uint32_t arg[],
1549 const uint32_t par[])
1550{
1551 if (gen_window_check1(dc, arg[0])) {
1552 TCGv_i32 c = tcg_const_i32(arg[1]);
1553
1554 tcg_gen_deposit_i32(cpu_R[arg[0]], c, cpu_R[arg[0]], 16, 16);
1555 tcg_temp_free(c);
1556 }
1557}
1558
168c12b0
MF
1559/* par[0]: privileged, par[1]: check memory access */
1560static void translate_dcache(DisasContext *dc, const uint32_t arg[],
1561 const uint32_t par[])
1562{
1563 if ((!par[0] || gen_check_privilege(dc)) &&
1564 gen_window_check1(dc, arg[0]) && par[1]) {
1565 TCGv_i32 addr = tcg_temp_new_i32();
1566 TCGv_i32 res = tcg_temp_new_i32();
1567
1568 tcg_gen_addi_i32(addr, cpu_R[arg[0]], arg[1]);
1569 tcg_gen_qemu_ld8u(res, addr, dc->cring);
1570 tcg_temp_free(addr);
1571 tcg_temp_free(res);
1572 }
1573}
1574
1575static void translate_depbits(DisasContext *dc, const uint32_t arg[],
1576 const uint32_t par[])
1577{
1578 if (gen_window_check2(dc, arg[0], arg[1])) {
1579 tcg_gen_deposit_i32(cpu_R[arg[1]], cpu_R[arg[1]], cpu_R[arg[0]],
1580 arg[2], arg[3]);
1581 }
1582}
1583
1584static void translate_entry(DisasContext *dc, const uint32_t arg[],
1585 const uint32_t par[])
1586{
1587 TCGv_i32 pc = tcg_const_i32(dc->pc);
1588 TCGv_i32 s = tcg_const_i32(arg[0]);
1589 TCGv_i32 imm = tcg_const_i32(arg[1]);
1590 gen_helper_entry(cpu_env, pc, s, imm);
1591 tcg_temp_free(imm);
1592 tcg_temp_free(s);
1593 tcg_temp_free(pc);
1594 /* This can change tb->flags, so exit tb */
1595 gen_jumpi_check_loop_end(dc, -1);
1596}
1597
1598static void translate_extui(DisasContext *dc, const uint32_t arg[],
1599 const uint32_t par[])
1600{
1601 if (gen_window_check2(dc, arg[0], arg[1])) {
1602 int maskimm = (1 << arg[3]) - 1;
1603
1604 TCGv_i32 tmp = tcg_temp_new_i32();
1605 tcg_gen_shri_i32(tmp, cpu_R[arg[1]], arg[2]);
1606 tcg_gen_andi_i32(cpu_R[arg[0]], tmp, maskimm);
1607 tcg_temp_free(tmp);
1608 }
1609}
1610
1611/* par[0]: privileged, par[1]: check memory access */
1612static void translate_icache(DisasContext *dc, const uint32_t arg[],
1613 const uint32_t par[])
1614{
1615 if ((!par[0] || gen_check_privilege(dc)) &&
1616 gen_window_check1(dc, arg[0]) && par[1]) {
ba7651fb 1617#ifndef CONFIG_USER_ONLY
168c12b0
MF
1618 TCGv_i32 addr = tcg_temp_new_i32();
1619
1620 tcg_gen_movi_i32(cpu_pc, dc->pc);
1621 tcg_gen_addi_i32(addr, cpu_R[arg[0]], arg[1]);
1622 gen_helper_itlb_hit_test(cpu_env, addr);
1623 tcg_temp_free(addr);
ba7651fb 1624#endif
168c12b0
MF
1625 }
1626}
1627
1628static void translate_itlb(DisasContext *dc, const uint32_t arg[],
1629 const uint32_t par[])
1630{
1631 if (gen_check_privilege(dc) &&
1632 gen_window_check1(dc, arg[0])) {
ba7651fb 1633#ifndef CONFIG_USER_ONLY
168c12b0
MF
1634 TCGv_i32 dtlb = tcg_const_i32(par[0]);
1635
1636 gen_helper_itlb(cpu_env, cpu_R[arg[0]], dtlb);
1637 /* This could change memory mapping, so exit tb */
1638 gen_jumpi_check_loop_end(dc, -1);
1639 tcg_temp_free(dtlb);
ba7651fb 1640#endif
168c12b0
MF
1641 }
1642}
1643
1644static void translate_ill(DisasContext *dc, const uint32_t arg[],
1645 const uint32_t par[])
1646{
1647 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
1648}
1649
1650static void translate_j(DisasContext *dc, const uint32_t arg[],
1651 const uint32_t par[])
1652{
1653 gen_jumpi(dc, arg[0], 0);
1654}
1655
1656static void translate_jx(DisasContext *dc, const uint32_t arg[],
1657 const uint32_t par[])
1658{
1659 if (gen_window_check1(dc, arg[0])) {
1660 gen_jump(dc, cpu_R[arg[0]]);
1661 }
1662}
1663
1664static void translate_l32e(DisasContext *dc, const uint32_t arg[],
1665 const uint32_t par[])
1666{
1667 if (gen_check_privilege(dc) &&
1668 gen_window_check2(dc, arg[0], arg[1])) {
1669 TCGv_i32 addr = tcg_temp_new_i32();
1670
1671 tcg_gen_addi_i32(addr, cpu_R[arg[1]], arg[2]);
1672 gen_load_store_alignment(dc, 2, addr, false);
1673 tcg_gen_qemu_ld_tl(cpu_R[arg[0]], addr, dc->ring, MO_TEUL);
1674 tcg_temp_free(addr);
1675 }
1676}
1677
1678static void translate_ldst(DisasContext *dc, const uint32_t arg[],
1679 const uint32_t par[])
1680{
1681 if (gen_window_check2(dc, arg[0], arg[1])) {
1682 TCGv_i32 addr = tcg_temp_new_i32();
1683
1684 tcg_gen_addi_i32(addr, cpu_R[arg[1]], arg[2]);
1685 if (par[0] & MO_SIZE) {
1686 gen_load_store_alignment(dc, par[0] & MO_SIZE, addr, par[1]);
1687 }
1688 if (par[2]) {
9fb40342
MF
1689 if (par[1]) {
1690 tcg_gen_mb(TCG_BAR_STRL | TCG_MO_ALL);
1691 }
168c12b0
MF
1692 tcg_gen_qemu_st_tl(cpu_R[arg[0]], addr, dc->cring, par[0]);
1693 } else {
1694 tcg_gen_qemu_ld_tl(cpu_R[arg[0]], addr, dc->cring, par[0]);
9fb40342
MF
1695 if (par[1]) {
1696 tcg_gen_mb(TCG_BAR_LDAQ | TCG_MO_ALL);
1697 }
168c12b0
MF
1698 }
1699 tcg_temp_free(addr);
1700 }
1701}
1702
1703static void translate_l32r(DisasContext *dc, const uint32_t arg[],
1704 const uint32_t par[])
1705{
1706 if (gen_window_check1(dc, arg[0])) {
5b9b2763 1707 TCGv_i32 tmp;
168c12b0
MF
1708
1709 if (dc->tb->flags & XTENSA_TBFLAG_LITBASE) {
5b9b2763
MF
1710 tmp = tcg_const_i32(dc->raw_arg[1] - 1);
1711 tcg_gen_add_i32(tmp, cpu_SR[LITBASE], tmp);
1712 } else {
1713 tmp = tcg_const_i32(arg[1]);
168c12b0
MF
1714 }
1715 tcg_gen_qemu_ld32u(cpu_R[arg[0]], tmp, dc->cring);
1716 tcg_temp_free(tmp);
1717 }
1718}
1719
1720static void translate_loop(DisasContext *dc, const uint32_t arg[],
1721 const uint32_t par[])
1722{
1723 if (gen_window_check1(dc, arg[0])) {
1724 uint32_t lend = arg[1];
1725 TCGv_i32 tmp = tcg_const_i32(lend);
1726
1727 tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_R[arg[0]], 1);
1728 tcg_gen_movi_i32(cpu_SR[LBEG], dc->next_pc);
1729 gen_helper_wsr_lend(cpu_env, tmp);
1730 tcg_temp_free(tmp);
1731
1732 if (par[0] != TCG_COND_NEVER) {
1733 TCGLabel *label = gen_new_label();
1734 tcg_gen_brcondi_i32(par[0], cpu_R[arg[0]], 0, label);
1735 gen_jumpi(dc, lend, 1);
1736 gen_set_label(label);
1737 }
1738
1739 gen_jumpi(dc, dc->next_pc, 0);
1740 }
1741}
1742
1743enum {
1744 MAC16_UMUL,
1745 MAC16_MUL,
1746 MAC16_MULA,
1747 MAC16_MULS,
1748 MAC16_NONE,
1749};
1750
1751enum {
1752 MAC16_LL,
1753 MAC16_HL,
1754 MAC16_LH,
1755 MAC16_HH,
1756
1757 MAC16_HX = 0x1,
1758 MAC16_XH = 0x2,
1759};
1760
1761enum {
1762 MAC16_AA,
1763 MAC16_AD,
1764 MAC16_DA,
1765 MAC16_DD,
1766
1767 MAC16_XD = 0x1,
1768 MAC16_DX = 0x2,
1769};
1770
1771static void translate_mac16(DisasContext *dc, const uint32_t arg[],
1772 const uint32_t par[])
1773{
1774 int op = par[0];
1775 bool is_m1_sr = par[1] & MAC16_DX;
1776 bool is_m2_sr = par[1] & MAC16_XD;
1777 unsigned half = par[2];
1778 uint32_t ld_offset = par[3];
1779 unsigned off = ld_offset ? 2 : 0;
1780 uint32_t ar[3] = {0};
1781 unsigned n_ar = 0;
1782
1783 if (op != MAC16_NONE) {
1784 if (!is_m1_sr) {
1785 ar[n_ar++] = arg[off];
1786 }
1787 if (!is_m2_sr) {
1788 ar[n_ar++] = arg[off + 1];
1789 }
1790 }
1791
1792 if (ld_offset) {
1793 ar[n_ar++] = arg[1];
1794 }
1795
1796 if (gen_window_check3(dc, ar[0], ar[1], ar[2])) {
1797 TCGv_i32 vaddr = tcg_temp_new_i32();
1798 TCGv_i32 mem32 = tcg_temp_new_i32();
1799
1800 if (ld_offset) {
1801 tcg_gen_addi_i32(vaddr, cpu_R[arg[1]], ld_offset);
1802 gen_load_store_alignment(dc, 2, vaddr, false);
1803 tcg_gen_qemu_ld32u(mem32, vaddr, dc->cring);
1804 }
1805 if (op != MAC16_NONE) {
1806 TCGv_i32 m1 = gen_mac16_m(is_m1_sr ?
1807 cpu_SR[MR + arg[off]] :
1808 cpu_R[arg[off]],
1809 half & MAC16_HX, op == MAC16_UMUL);
1810 TCGv_i32 m2 = gen_mac16_m(is_m2_sr ?
1811 cpu_SR[MR + arg[off + 1]] :
1812 cpu_R[arg[off + 1]],
1813 half & MAC16_XH, op == MAC16_UMUL);
1814
1815 if (op == MAC16_MUL || op == MAC16_UMUL) {
1816 tcg_gen_mul_i32(cpu_SR[ACCLO], m1, m2);
1817 if (op == MAC16_UMUL) {
1818 tcg_gen_movi_i32(cpu_SR[ACCHI], 0);
1819 } else {
1820 tcg_gen_sari_i32(cpu_SR[ACCHI], cpu_SR[ACCLO], 31);
1821 }
1822 } else {
1823 TCGv_i32 lo = tcg_temp_new_i32();
1824 TCGv_i32 hi = tcg_temp_new_i32();
1825
1826 tcg_gen_mul_i32(lo, m1, m2);
1827 tcg_gen_sari_i32(hi, lo, 31);
1828 if (op == MAC16_MULA) {
1829 tcg_gen_add2_i32(cpu_SR[ACCLO], cpu_SR[ACCHI],
1830 cpu_SR[ACCLO], cpu_SR[ACCHI],
1831 lo, hi);
1832 } else {
1833 tcg_gen_sub2_i32(cpu_SR[ACCLO], cpu_SR[ACCHI],
1834 cpu_SR[ACCLO], cpu_SR[ACCHI],
1835 lo, hi);
1836 }
1837 tcg_gen_ext8s_i32(cpu_SR[ACCHI], cpu_SR[ACCHI]);
1838
1839 tcg_temp_free_i32(lo);
1840 tcg_temp_free_i32(hi);
1841 }
1842 tcg_temp_free(m1);
1843 tcg_temp_free(m2);
1844 }
1845 if (ld_offset) {
1846 tcg_gen_mov_i32(cpu_R[arg[1]], vaddr);
1847 tcg_gen_mov_i32(cpu_SR[MR + arg[0]], mem32);
1848 }
1849 tcg_temp_free(vaddr);
1850 tcg_temp_free(mem32);
1851 }
1852}
1853
9fb40342
MF
1854static void translate_memw(DisasContext *dc, const uint32_t arg[],
1855 const uint32_t par[])
1856{
1857 tcg_gen_mb(TCG_BAR_SC | TCG_MO_ALL);
1858}
1859
426afc3b
RH
1860static void translate_smin(DisasContext *dc, const uint32_t arg[],
1861 const uint32_t par[])
168c12b0
MF
1862{
1863 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
426afc3b
RH
1864 tcg_gen_smin_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
1865 }
1866}
1867
1868static void translate_umin(DisasContext *dc, const uint32_t arg[],
1869 const uint32_t par[])
1870{
1871 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
1872 tcg_gen_umin_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
1873 }
1874}
1875
1876static void translate_smax(DisasContext *dc, const uint32_t arg[],
1877 const uint32_t par[])
1878{
1879 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
1880 tcg_gen_smax_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
1881 }
1882}
1883
1884static void translate_umax(DisasContext *dc, const uint32_t arg[],
1885 const uint32_t par[])
1886{
1887 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
1888 tcg_gen_umax_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
168c12b0
MF
1889 }
1890}
1891
1892static void translate_mov(DisasContext *dc, const uint32_t arg[],
1893 const uint32_t par[])
1894{
1895 if (gen_window_check2(dc, arg[0], arg[1])) {
1896 tcg_gen_mov_i32(cpu_R[arg[0]], cpu_R[arg[1]]);
1897 }
1898}
1899
1900static void translate_movcond(DisasContext *dc, const uint32_t arg[],
1901 const uint32_t par[])
1902{
1903 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
1904 TCGv_i32 zero = tcg_const_i32(0);
1905
1906 tcg_gen_movcond_i32(par[0], cpu_R[arg[0]],
1907 cpu_R[arg[2]], zero, cpu_R[arg[1]], cpu_R[arg[0]]);
1908 tcg_temp_free(zero);
1909 }
1910}
1911
1912static void translate_movi(DisasContext *dc, const uint32_t arg[],
1913 const uint32_t par[])
1914{
1915 if (gen_window_check1(dc, arg[0])) {
1916 tcg_gen_movi_i32(cpu_R[arg[0]], arg[1]);
1917 }
1918}
1919
1920static void translate_movp(DisasContext *dc, const uint32_t arg[],
1921 const uint32_t par[])
1922{
1923 if (gen_window_check2(dc, arg[0], arg[1])) {
1924 TCGv_i32 zero = tcg_const_i32(0);
1925 TCGv_i32 tmp = tcg_temp_new_i32();
1926
1927 tcg_gen_andi_i32(tmp, cpu_SR[BR], 1 << arg[2]);
1928 tcg_gen_movcond_i32(par[0],
1929 cpu_R[arg[0]], tmp, zero,
1930 cpu_R[arg[1]], cpu_R[arg[0]]);
1931 tcg_temp_free(tmp);
1932 tcg_temp_free(zero);
1933 }
1934}
1935
1936static void translate_movsp(DisasContext *dc, const uint32_t arg[],
1937 const uint32_t par[])
1938{
1939 if (gen_window_check2(dc, arg[0], arg[1])) {
1940 TCGv_i32 pc = tcg_const_i32(dc->pc);
1941 gen_helper_movsp(cpu_env, pc);
1942 tcg_gen_mov_i32(cpu_R[arg[0]], cpu_R[arg[1]]);
1943 tcg_temp_free(pc);
1944 }
1945}
1946
1947static void translate_mul16(DisasContext *dc, const uint32_t arg[],
1948 const uint32_t par[])
1949{
1950 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
1951 TCGv_i32 v1 = tcg_temp_new_i32();
1952 TCGv_i32 v2 = tcg_temp_new_i32();
1953
1954 if (par[0]) {
1955 tcg_gen_ext16s_i32(v1, cpu_R[arg[1]]);
1956 tcg_gen_ext16s_i32(v2, cpu_R[arg[2]]);
1957 } else {
1958 tcg_gen_ext16u_i32(v1, cpu_R[arg[1]]);
1959 tcg_gen_ext16u_i32(v2, cpu_R[arg[2]]);
1960 }
1961 tcg_gen_mul_i32(cpu_R[arg[0]], v1, v2);
1962 tcg_temp_free(v2);
1963 tcg_temp_free(v1);
1964 }
1965}
1966
1967static void translate_mull(DisasContext *dc, const uint32_t arg[],
1968 const uint32_t par[])
1969{
1970 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
1971 tcg_gen_mul_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
1972 }
1973}
1974
1975static void translate_mulh(DisasContext *dc, const uint32_t arg[],
1976 const uint32_t par[])
1977{
1978 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
1979 TCGv_i32 lo = tcg_temp_new();
1980
1981 if (par[0]) {
1982 tcg_gen_muls2_i32(lo, cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
1983 } else {
1984 tcg_gen_mulu2_i32(lo, cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
1985 }
1986 tcg_temp_free(lo);
1987 }
1988}
1989
1990static void translate_neg(DisasContext *dc, const uint32_t arg[],
1991 const uint32_t par[])
1992{
1993 if (gen_window_check2(dc, arg[0], arg[1])) {
1994 tcg_gen_neg_i32(cpu_R[arg[0]], cpu_R[arg[1]]);
1995 }
1996}
1997
1998static void translate_nop(DisasContext *dc, const uint32_t arg[],
1999 const uint32_t par[])
2000{
2001}
2002
2003static void translate_nsa(DisasContext *dc, const uint32_t arg[],
2004 const uint32_t par[])
2005{
2006 if (gen_window_check2(dc, arg[0], arg[1])) {
2007 tcg_gen_clrsb_i32(cpu_R[arg[0]], cpu_R[arg[1]]);
2008 }
2009}
2010
2011static void translate_nsau(DisasContext *dc, const uint32_t arg[],
2012 const uint32_t par[])
2013{
2014 if (gen_window_check2(dc, arg[0], arg[1])) {
2015 tcg_gen_clzi_i32(cpu_R[arg[0]], cpu_R[arg[1]], 32);
2016 }
2017}
2018
2019static void translate_or(DisasContext *dc, const uint32_t arg[],
2020 const uint32_t par[])
2021{
2022 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
2023 tcg_gen_or_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
2024 }
2025}
2026
2027static void translate_ptlb(DisasContext *dc, const uint32_t arg[],
2028 const uint32_t par[])
2029{
2030 if (gen_check_privilege(dc) &&
2031 gen_window_check2(dc, arg[0], arg[1])) {
ba7651fb 2032#ifndef CONFIG_USER_ONLY
168c12b0
MF
2033 TCGv_i32 dtlb = tcg_const_i32(par[0]);
2034
2035 tcg_gen_movi_i32(cpu_pc, dc->pc);
2036 gen_helper_ptlb(cpu_R[arg[0]], cpu_env, cpu_R[arg[1]], dtlb);
2037 tcg_temp_free(dtlb);
ba7651fb 2038#endif
168c12b0
MF
2039 }
2040}
2041
2042static void gen_zero_check(DisasContext *dc, const uint32_t arg[])
2043{
2044 TCGLabel *label = gen_new_label();
2045
2046 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[arg[2]], 0, label);
2047 gen_exception_cause(dc, INTEGER_DIVIDE_BY_ZERO_CAUSE);
2048 gen_set_label(label);
2049}
2050
2051static void translate_quos(DisasContext *dc, const uint32_t arg[],
2052 const uint32_t par[])
2053{
2054 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
2055 TCGLabel *label1 = gen_new_label();
2056 TCGLabel *label2 = gen_new_label();
2057
2058 gen_zero_check(dc, arg);
2059
2060 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[arg[1]], 0x80000000,
2061 label1);
2062 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[arg[2]], 0xffffffff,
2063 label1);
2064 tcg_gen_movi_i32(cpu_R[arg[0]],
2065 par[0] ? 0x80000000 : 0);
2066 tcg_gen_br(label2);
2067 gen_set_label(label1);
2068 if (par[0]) {
2069 tcg_gen_div_i32(cpu_R[arg[0]],
2070 cpu_R[arg[1]], cpu_R[arg[2]]);
2071 } else {
2072 tcg_gen_rem_i32(cpu_R[arg[0]],
2073 cpu_R[arg[1]], cpu_R[arg[2]]);
2074 }
2075 gen_set_label(label2);
2076 }
2077}
2078
2079static void translate_quou(DisasContext *dc, const uint32_t arg[],
2080 const uint32_t par[])
2081{
2082 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
2083 gen_zero_check(dc, arg);
2084 if (par[0]) {
2085 tcg_gen_divu_i32(cpu_R[arg[0]],
2086 cpu_R[arg[1]], cpu_R[arg[2]]);
2087 } else {
2088 tcg_gen_remu_i32(cpu_R[arg[0]],
2089 cpu_R[arg[1]], cpu_R[arg[2]]);
2090 }
2091 }
2092}
2093
e9872741
MF
2094static void translate_read_impwire(DisasContext *dc, const uint32_t arg[],
2095 const uint32_t par[])
2096{
2097 if (gen_window_check1(dc, arg[0])) {
2098 /* TODO: GPIO32 may be a part of coprocessor */
2099 tcg_gen_movi_i32(cpu_R[arg[0]], 0);
2100 }
2101}
2102
168c12b0
MF
2103static void translate_rer(DisasContext *dc, const uint32_t arg[],
2104 const uint32_t par[])
2105{
2106 if (gen_check_privilege(dc) &&
2107 gen_window_check2(dc, arg[0], arg[1])) {
2108 gen_helper_rer(cpu_R[arg[0]], cpu_env, cpu_R[arg[1]]);
2109 }
2110}
2111
2112static void translate_ret(DisasContext *dc, const uint32_t arg[],
2113 const uint32_t par[])
2114{
2115 gen_jump(dc, cpu_R[0]);
2116}
2117
2118static void translate_retw(DisasContext *dc, const uint32_t arg[],
2119 const uint32_t par[])
2120{
2121 TCGv_i32 tmp = tcg_const_i32(dc->pc);
2122 gen_helper_retw(tmp, cpu_env, tmp);
2123 gen_jump(dc, tmp);
2124 tcg_temp_free(tmp);
2125}
2126
2127static void translate_rfde(DisasContext *dc, const uint32_t arg[],
2128 const uint32_t par[])
2129{
2130 if (gen_check_privilege(dc)) {
2131 gen_jump(dc, cpu_SR[dc->config->ndepc ? DEPC : EPC1]);
2132 }
2133}
2134
2135static void translate_rfe(DisasContext *dc, const uint32_t arg[],
2136 const uint32_t par[])
2137{
2138 if (gen_check_privilege(dc)) {
2139 tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_EXCM);
2140 gen_check_interrupts(dc);
2141 gen_jump(dc, cpu_SR[EPC1]);
2142 }
2143}
2144
2145static void translate_rfi(DisasContext *dc, const uint32_t arg[],
2146 const uint32_t par[])
2147{
2148 if (gen_check_privilege(dc)) {
2149 tcg_gen_mov_i32(cpu_SR[PS], cpu_SR[EPS2 + arg[0] - 2]);
2150 gen_check_interrupts(dc);
2151 gen_jump(dc, cpu_SR[EPC1 + arg[0] - 1]);
2152 }
2153}
2154
2155static void translate_rfw(DisasContext *dc, const uint32_t arg[],
2156 const uint32_t par[])
2157{
2158 if (gen_check_privilege(dc)) {
2159 TCGv_i32 tmp = tcg_const_i32(1);
2160
2161 tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_EXCM);
2162 tcg_gen_shl_i32(tmp, tmp, cpu_SR[WINDOW_BASE]);
2163
2164 if (par[0]) {
2165 tcg_gen_andc_i32(cpu_SR[WINDOW_START],
2166 cpu_SR[WINDOW_START], tmp);
2167 } else {
2168 tcg_gen_or_i32(cpu_SR[WINDOW_START],
2169 cpu_SR[WINDOW_START], tmp);
2170 }
2171
2172 gen_helper_restore_owb(cpu_env);
2173 gen_check_interrupts(dc);
2174 gen_jump(dc, cpu_SR[EPC1]);
2175
2176 tcg_temp_free(tmp);
2177 }
2178}
2179
2180static void translate_rotw(DisasContext *dc, const uint32_t arg[],
2181 const uint32_t par[])
2182{
2183 if (gen_check_privilege(dc)) {
2184 TCGv_i32 tmp = tcg_const_i32(arg[0]);
2185 gen_helper_rotw(cpu_env, tmp);
2186 tcg_temp_free(tmp);
2187 /* This can change tb->flags, so exit tb */
2188 gen_jumpi_check_loop_end(dc, -1);
2189 }
2190}
2191
2192static void translate_rsil(DisasContext *dc, const uint32_t arg[],
2193 const uint32_t par[])
2194{
2195 if (gen_check_privilege(dc) &&
2196 gen_window_check1(dc, arg[0])) {
2197 tcg_gen_mov_i32(cpu_R[arg[0]], cpu_SR[PS]);
2198 tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_INTLEVEL);
2199 tcg_gen_ori_i32(cpu_SR[PS], cpu_SR[PS], arg[1]);
2200 gen_check_interrupts(dc);
2201 gen_jumpi_check_loop_end(dc, 0);
2202 }
2203}
2204
2205static void translate_rsr(DisasContext *dc, const uint32_t arg[],
2206 const uint32_t par[])
2207{
2208 if (gen_check_sr(dc, par[0], SR_R) &&
2209 (par[0] < 64 || gen_check_privilege(dc)) &&
2210 gen_window_check1(dc, arg[0])) {
2211 if (gen_rsr(dc, cpu_R[arg[0]], par[0])) {
2212 gen_jumpi_check_loop_end(dc, 0);
2213 }
2214 }
2215}
2216
2217static void translate_rtlb(DisasContext *dc, const uint32_t arg[],
2218 const uint32_t par[])
2219{
2220 static void (* const helper[])(TCGv_i32 r, TCGv_env env, TCGv_i32 a1,
2221 TCGv_i32 a2) = {
ba7651fb 2222#ifndef CONFIG_USER_ONLY
168c12b0
MF
2223 gen_helper_rtlb0,
2224 gen_helper_rtlb1,
ba7651fb 2225#endif
168c12b0
MF
2226 };
2227
2228 if (gen_check_privilege(dc) &&
2229 gen_window_check2(dc, arg[0], arg[1])) {
2230 TCGv_i32 dtlb = tcg_const_i32(par[0]);
2231
2232 helper[par[1]](cpu_R[arg[0]], cpu_env, cpu_R[arg[1]], dtlb);
2233 tcg_temp_free(dtlb);
2234 }
2235}
2236
2237static void translate_rur(DisasContext *dc, const uint32_t arg[],
2238 const uint32_t par[])
2239{
2240 if (gen_window_check1(dc, arg[0])) {
2241 if (uregnames[par[0]].name) {
2242 tcg_gen_mov_i32(cpu_R[arg[0]], cpu_UR[par[0]]);
2243 } else {
8e96f594 2244 qemu_log_mask(LOG_UNIMP, "RUR %d not implemented\n", par[0]);
168c12b0
MF
2245 }
2246 }
2247}
2248
e9872741
MF
2249static void translate_setb_expstate(DisasContext *dc, const uint32_t arg[],
2250 const uint32_t par[])
2251{
2252 /* TODO: GPIO32 may be a part of coprocessor */
2253 tcg_gen_ori_i32(cpu_UR[EXPSTATE], cpu_UR[EXPSTATE], 1u << arg[0]);
2254}
2255
9fb40342
MF
2256#ifdef CONFIG_USER_ONLY
2257static void gen_check_atomctl(DisasContext *dc, TCGv_i32 addr)
2258{
2259}
2260#else
2261static void gen_check_atomctl(DisasContext *dc, TCGv_i32 addr)
2262{
2263 TCGv_i32 tpc = tcg_const_i32(dc->pc);
2264
2265 gen_helper_check_atomctl(cpu_env, tpc, addr);
2266 tcg_temp_free(tpc);
2267}
2268#endif
2269
168c12b0
MF
2270static void translate_s32c1i(DisasContext *dc, const uint32_t arg[],
2271 const uint32_t par[])
2272{
2273 if (gen_window_check2(dc, arg[0], arg[1])) {
168c12b0
MF
2274 TCGv_i32 tmp = tcg_temp_local_new_i32();
2275 TCGv_i32 addr = tcg_temp_local_new_i32();
168c12b0
MF
2276
2277 tcg_gen_mov_i32(tmp, cpu_R[arg[0]]);
2278 tcg_gen_addi_i32(addr, cpu_R[arg[1]], arg[2]);
2279 gen_load_store_alignment(dc, 2, addr, true);
9fb40342
MF
2280 gen_check_atomctl(dc, addr);
2281 tcg_gen_atomic_cmpxchg_i32(cpu_R[arg[0]], addr, cpu_SR[SCOMPARE1],
2282 tmp, dc->cring, MO_32);
168c12b0
MF
2283 tcg_temp_free(addr);
2284 tcg_temp_free(tmp);
2285 }
2286}
2287
2288static void translate_s32e(DisasContext *dc, const uint32_t arg[],
2289 const uint32_t par[])
2290{
2291 if (gen_check_privilege(dc) &&
2292 gen_window_check2(dc, arg[0], arg[1])) {
2293 TCGv_i32 addr = tcg_temp_new_i32();
2294
2295 tcg_gen_addi_i32(addr, cpu_R[arg[1]], arg[2]);
2296 gen_load_store_alignment(dc, 2, addr, false);
2297 tcg_gen_qemu_st_tl(cpu_R[arg[0]], addr, dc->ring, MO_TEUL);
2298 tcg_temp_free(addr);
2299 }
2300}
2301
d1e9b006
MF
2302static void translate_salt(DisasContext *dc, const uint32_t arg[],
2303 const uint32_t par[])
2304{
2305 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
2306 tcg_gen_setcond_i32(par[0],
2307 cpu_R[arg[0]],
2308 cpu_R[arg[1]], cpu_R[arg[2]]);
2309 }
2310}
2311
168c12b0
MF
2312static void translate_sext(DisasContext *dc, const uint32_t arg[],
2313 const uint32_t par[])
2314{
2315 if (gen_window_check2(dc, arg[0], arg[1])) {
2316 int shift = 31 - arg[2];
2317
2318 if (shift == 24) {
2319 tcg_gen_ext8s_i32(cpu_R[arg[0]], cpu_R[arg[1]]);
2320 } else if (shift == 16) {
2321 tcg_gen_ext16s_i32(cpu_R[arg[0]], cpu_R[arg[1]]);
2322 } else {
2323 TCGv_i32 tmp = tcg_temp_new_i32();
2324 tcg_gen_shli_i32(tmp, cpu_R[arg[1]], shift);
2325 tcg_gen_sari_i32(cpu_R[arg[0]], tmp, shift);
2326 tcg_temp_free(tmp);
2327 }
2328 }
2329}
2330
2331static void translate_simcall(DisasContext *dc, const uint32_t arg[],
2332 const uint32_t par[])
2333{
ba7651fb 2334#ifndef CONFIG_USER_ONLY
168c12b0
MF
2335 if (semihosting_enabled()) {
2336 if (gen_check_privilege(dc)) {
2337 gen_helper_simcall(cpu_env);
2338 }
ba7651fb
MF
2339 } else
2340#endif
2341 {
168c12b0
MF
2342 qemu_log_mask(LOG_GUEST_ERROR, "SIMCALL but semihosting is disabled\n");
2343 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
2344 }
2345}
2346
2347/*
2348 * Note: 64 bit ops are used here solely because SAR values
2349 * have range 0..63
2350 */
2351#define gen_shift_reg(cmd, reg) do { \
2352 TCGv_i64 tmp = tcg_temp_new_i64(); \
2353 tcg_gen_extu_i32_i64(tmp, reg); \
2354 tcg_gen_##cmd##_i64(v, v, tmp); \
2355 tcg_gen_extrl_i64_i32(cpu_R[arg[0]], v); \
2356 tcg_temp_free_i64(v); \
2357 tcg_temp_free_i64(tmp); \
2358 } while (0)
2359
2360#define gen_shift(cmd) gen_shift_reg(cmd, cpu_SR[SAR])
2361
2362static void translate_sll(DisasContext *dc, const uint32_t arg[],
2363 const uint32_t par[])
2364{
2365 if (gen_window_check2(dc, arg[0], arg[1])) {
2366 if (dc->sar_m32_5bit) {
2367 tcg_gen_shl_i32(cpu_R[arg[0]], cpu_R[arg[1]], dc->sar_m32);
2368 } else {
2369 TCGv_i64 v = tcg_temp_new_i64();
2370 TCGv_i32 s = tcg_const_i32(32);
2371 tcg_gen_sub_i32(s, s, cpu_SR[SAR]);
2372 tcg_gen_andi_i32(s, s, 0x3f);
2373 tcg_gen_extu_i32_i64(v, cpu_R[arg[1]]);
2374 gen_shift_reg(shl, s);
2375 tcg_temp_free(s);
2376 }
2377 }
2378}
2379
2380static void translate_slli(DisasContext *dc, const uint32_t arg[],
2381 const uint32_t par[])
2382{
2383 if (gen_window_check2(dc, arg[0], arg[1])) {
2384 if (arg[2] == 32) {
8e96f594 2385 qemu_log_mask(LOG_GUEST_ERROR, "slli a%d, a%d, 32 is undefined\n",
168c12b0
MF
2386 arg[0], arg[1]);
2387 }
2388 tcg_gen_shli_i32(cpu_R[arg[0]], cpu_R[arg[1]], arg[2] & 0x1f);
2389 }
2390}
2391
2392static void translate_sra(DisasContext *dc, const uint32_t arg[],
2393 const uint32_t par[])
2394{
2395 if (gen_window_check2(dc, arg[0], arg[1])) {
2396 if (dc->sar_m32_5bit) {
2397 tcg_gen_sar_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_SR[SAR]);
2398 } else {
2399 TCGv_i64 v = tcg_temp_new_i64();
2400 tcg_gen_ext_i32_i64(v, cpu_R[arg[1]]);
2401 gen_shift(sar);
2402 }
2403 }
2404}
2405
2406static void translate_srai(DisasContext *dc, const uint32_t arg[],
2407 const uint32_t par[])
2408{
2409 if (gen_window_check2(dc, arg[0], arg[1])) {
2410 tcg_gen_sari_i32(cpu_R[arg[0]], cpu_R[arg[1]], arg[2]);
2411 }
2412}
2413
2414static void translate_src(DisasContext *dc, const uint32_t arg[],
2415 const uint32_t par[])
2416{
2417 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
2418 TCGv_i64 v = tcg_temp_new_i64();
2419 tcg_gen_concat_i32_i64(v, cpu_R[arg[2]], cpu_R[arg[1]]);
2420 gen_shift(shr);
2421 }
2422}
2423
2424static void translate_srl(DisasContext *dc, const uint32_t arg[],
2425 const uint32_t par[])
2426{
2427 if (gen_window_check2(dc, arg[0], arg[1])) {
2428 if (dc->sar_m32_5bit) {
2429 tcg_gen_shr_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_SR[SAR]);
2430 } else {
2431 TCGv_i64 v = tcg_temp_new_i64();
2432 tcg_gen_extu_i32_i64(v, cpu_R[arg[1]]);
2433 gen_shift(shr);
2434 }
2435 }
2436}
2437
2438#undef gen_shift
2439#undef gen_shift_reg
2440
2441static void translate_srli(DisasContext *dc, const uint32_t arg[],
2442 const uint32_t par[])
2443{
2444 if (gen_window_check2(dc, arg[0], arg[1])) {
2445 tcg_gen_shri_i32(cpu_R[arg[0]], cpu_R[arg[1]], arg[2]);
2446 }
2447}
2448
2449static void translate_ssa8b(DisasContext *dc, const uint32_t arg[],
2450 const uint32_t par[])
2451{
2452 if (gen_window_check1(dc, arg[0])) {
2453 TCGv_i32 tmp = tcg_temp_new_i32();
2454 tcg_gen_shli_i32(tmp, cpu_R[arg[0]], 3);
2455 gen_left_shift_sar(dc, tmp);
2456 tcg_temp_free(tmp);
2457 }
2458}
2459
2460static void translate_ssa8l(DisasContext *dc, const uint32_t arg[],
2461 const uint32_t par[])
2462{
2463 if (gen_window_check1(dc, arg[0])) {
2464 TCGv_i32 tmp = tcg_temp_new_i32();
2465 tcg_gen_shli_i32(tmp, cpu_R[arg[0]], 3);
2466 gen_right_shift_sar(dc, tmp);
2467 tcg_temp_free(tmp);
2468 }
2469}
2470
2471static void translate_ssai(DisasContext *dc, const uint32_t arg[],
2472 const uint32_t par[])
2473{
2474 TCGv_i32 tmp = tcg_const_i32(arg[0]);
2475 gen_right_shift_sar(dc, tmp);
2476 tcg_temp_free(tmp);
2477}
2478
2479static void translate_ssl(DisasContext *dc, const uint32_t arg[],
2480 const uint32_t par[])
2481{
2482 if (gen_window_check1(dc, arg[0])) {
2483 gen_left_shift_sar(dc, cpu_R[arg[0]]);
2484 }
2485}
2486
2487static void translate_ssr(DisasContext *dc, const uint32_t arg[],
2488 const uint32_t par[])
2489{
2490 if (gen_window_check1(dc, arg[0])) {
2491 gen_right_shift_sar(dc, cpu_R[arg[0]]);
2492 }
2493}
2494
2495static void translate_sub(DisasContext *dc, const uint32_t arg[],
2496 const uint32_t par[])
2497{
2498 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
2499 tcg_gen_sub_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
2500 }
2501}
2502
2503static void translate_subx(DisasContext *dc, const uint32_t arg[],
2504 const uint32_t par[])
2505{
2506 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
2507 TCGv_i32 tmp = tcg_temp_new_i32();
2508 tcg_gen_shli_i32(tmp, cpu_R[arg[1]], par[0]);
2509 tcg_gen_sub_i32(cpu_R[arg[0]], tmp, cpu_R[arg[2]]);
2510 tcg_temp_free(tmp);
2511 }
2512}
2513
2514static void translate_syscall(DisasContext *dc, const uint32_t arg[],
2515 const uint32_t par[])
2516{
2517 gen_exception_cause(dc, SYSCALL_CAUSE);
2518}
2519
2520static void translate_waiti(DisasContext *dc, const uint32_t arg[],
2521 const uint32_t par[])
2522{
2523 if (gen_check_privilege(dc)) {
ba7651fb 2524#ifndef CONFIG_USER_ONLY
168c12b0 2525 gen_waiti(dc, arg[0]);
ba7651fb 2526#endif
168c12b0
MF
2527 }
2528}
2529
2530static void translate_wtlb(DisasContext *dc, const uint32_t arg[],
2531 const uint32_t par[])
2532{
2533 if (gen_check_privilege(dc) &&
2534 gen_window_check2(dc, arg[0], arg[1])) {
ba7651fb 2535#ifndef CONFIG_USER_ONLY
168c12b0
MF
2536 TCGv_i32 dtlb = tcg_const_i32(par[0]);
2537
2538 gen_helper_wtlb(cpu_env, cpu_R[arg[0]], cpu_R[arg[1]], dtlb);
2539 /* This could change memory mapping, so exit tb */
2540 gen_jumpi_check_loop_end(dc, -1);
2541 tcg_temp_free(dtlb);
ba7651fb 2542#endif
168c12b0
MF
2543 }
2544}
2545
2546static void translate_wer(DisasContext *dc, const uint32_t arg[],
2547 const uint32_t par[])
2548{
2549 if (gen_check_privilege(dc) &&
2550 gen_window_check2(dc, arg[0], arg[1])) {
2551 gen_helper_wer(cpu_env, cpu_R[arg[0]], cpu_R[arg[1]]);
2552 }
2553}
2554
e9872741
MF
2555static void translate_wrmsk_expstate(DisasContext *dc, const uint32_t arg[],
2556 const uint32_t par[])
2557{
2558 if (gen_window_check2(dc, arg[0], arg[1])) {
2559 /* TODO: GPIO32 may be a part of coprocessor */
2560 tcg_gen_and_i32(cpu_UR[EXPSTATE], cpu_R[arg[0]], cpu_R[arg[1]]);
2561 }
2562}
2563
168c12b0
MF
2564static void translate_wsr(DisasContext *dc, const uint32_t arg[],
2565 const uint32_t par[])
2566{
2567 if (gen_check_sr(dc, par[0], SR_W) &&
2568 (par[0] < 64 || gen_check_privilege(dc)) &&
2569 gen_window_check1(dc, arg[0])) {
2570 gen_wsr(dc, par[0], cpu_R[arg[0]]);
2571 }
2572}
2573
2574static void translate_wur(DisasContext *dc, const uint32_t arg[],
2575 const uint32_t par[])
2576{
2577 if (gen_window_check1(dc, arg[0])) {
2578 if (uregnames[par[0]].name) {
2579 gen_wur(par[0], cpu_R[arg[0]]);
2580 } else {
8e96f594 2581 qemu_log_mask(LOG_UNIMP, "WUR %d not implemented\n", par[0]);
168c12b0
MF
2582 }
2583 }
2584}
2585
2586static void translate_xor(DisasContext *dc, const uint32_t arg[],
2587 const uint32_t par[])
2588{
2589 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
2590 tcg_gen_xor_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
2591 }
2592}
2593
2594static void translate_xsr(DisasContext *dc, const uint32_t arg[],
2595 const uint32_t par[])
2596{
2597 if (gen_check_sr(dc, par[0], SR_X) &&
2598 (par[0] < 64 || gen_check_privilege(dc)) &&
2599 gen_window_check1(dc, arg[0])) {
2600 TCGv_i32 tmp = tcg_temp_new_i32();
2601 bool rsr_end, wsr_end;
2602
2603 tcg_gen_mov_i32(tmp, cpu_R[arg[0]]);
2604 rsr_end = gen_rsr(dc, cpu_R[arg[0]], par[0]);
2605 wsr_end = gen_wsr(dc, par[0], tmp);
2606 tcg_temp_free(tmp);
2607 if (rsr_end && !wsr_end) {
2608 gen_jumpi_check_loop_end(dc, 0);
2609 }
2610 }
2611}
2612
2613static const XtensaOpcodeOps core_ops[] = {
2614 {
2615 .name = "abs",
2616 .translate = translate_abs,
2617 }, {
2618 .name = "add",
2619 .translate = translate_add,
2620 }, {
2621 .name = "add.n",
2622 .translate = translate_add,
2623 }, {
2624 .name = "addi",
2625 .translate = translate_addi,
2626 }, {
2627 .name = "addi.n",
2628 .translate = translate_addi,
2629 }, {
2630 .name = "addmi",
2631 .translate = translate_addi,
2632 }, {
2633 .name = "addx2",
2634 .translate = translate_addx,
2635 .par = (const uint32_t[]){1},
2636 }, {
2637 .name = "addx4",
2638 .translate = translate_addx,
2639 .par = (const uint32_t[]){2},
2640 }, {
2641 .name = "addx8",
2642 .translate = translate_addx,
2643 .par = (const uint32_t[]){3},
2644 }, {
2645 .name = "all4",
2646 .translate = translate_all,
2647 .par = (const uint32_t[]){true, 4},
2648 }, {
2649 .name = "all8",
2650 .translate = translate_all,
2651 .par = (const uint32_t[]){true, 8},
2652 }, {
2653 .name = "and",
2654 .translate = translate_and,
2655 }, {
2656 .name = "andb",
2657 .translate = translate_boolean,
2658 .par = (const uint32_t[]){BOOLEAN_AND},
2659 }, {
2660 .name = "andbc",
2661 .translate = translate_boolean,
2662 .par = (const uint32_t[]){BOOLEAN_ANDC},
2663 }, {
2664 .name = "any4",
2665 .translate = translate_all,
2666 .par = (const uint32_t[]){false, 4},
2667 }, {
2668 .name = "any8",
2669 .translate = translate_all,
2670 .par = (const uint32_t[]){false, 8},
2671 }, {
2672 .name = "ball",
2673 .translate = translate_ball,
2674 .par = (const uint32_t[]){TCG_COND_EQ},
2675 }, {
2676 .name = "bany",
2677 .translate = translate_bany,
2678 .par = (const uint32_t[]){TCG_COND_NE},
2679 }, {
2680 .name = "bbc",
2681 .translate = translate_bb,
2682 .par = (const uint32_t[]){TCG_COND_EQ},
2683 }, {
2684 .name = "bbci",
2685 .translate = translate_bbi,
2686 .par = (const uint32_t[]){TCG_COND_EQ},
2687 }, {
2688 .name = "bbs",
2689 .translate = translate_bb,
2690 .par = (const uint32_t[]){TCG_COND_NE},
2691 }, {
2692 .name = "bbsi",
2693 .translate = translate_bbi,
2694 .par = (const uint32_t[]){TCG_COND_NE},
2695 }, {
2696 .name = "beq",
2697 .translate = translate_b,
2698 .par = (const uint32_t[]){TCG_COND_EQ},
2699 }, {
2700 .name = "beqi",
2701 .translate = translate_bi,
2702 .par = (const uint32_t[]){TCG_COND_EQ},
2703 }, {
2704 .name = "beqz",
2705 .translate = translate_bz,
2706 .par = (const uint32_t[]){TCG_COND_EQ},
2707 }, {
2708 .name = "beqz.n",
2709 .translate = translate_bz,
2710 .par = (const uint32_t[]){TCG_COND_EQ},
2711 }, {
2712 .name = "bf",
2713 .translate = translate_bp,
2714 .par = (const uint32_t[]){TCG_COND_EQ},
2715 }, {
2716 .name = "bge",
2717 .translate = translate_b,
2718 .par = (const uint32_t[]){TCG_COND_GE},
2719 }, {
2720 .name = "bgei",
2721 .translate = translate_bi,
2722 .par = (const uint32_t[]){TCG_COND_GE},
2723 }, {
2724 .name = "bgeu",
2725 .translate = translate_b,
2726 .par = (const uint32_t[]){TCG_COND_GEU},
2727 }, {
2728 .name = "bgeui",
2729 .translate = translate_bi,
2730 .par = (const uint32_t[]){TCG_COND_GEU},
2731 }, {
2732 .name = "bgez",
2733 .translate = translate_bz,
2734 .par = (const uint32_t[]){TCG_COND_GE},
2735 }, {
2736 .name = "blt",
2737 .translate = translate_b,
2738 .par = (const uint32_t[]){TCG_COND_LT},
2739 }, {
2740 .name = "blti",
2741 .translate = translate_bi,
2742 .par = (const uint32_t[]){TCG_COND_LT},
2743 }, {
2744 .name = "bltu",
2745 .translate = translate_b,
2746 .par = (const uint32_t[]){TCG_COND_LTU},
2747 }, {
2748 .name = "bltui",
2749 .translate = translate_bi,
2750 .par = (const uint32_t[]){TCG_COND_LTU},
2751 }, {
2752 .name = "bltz",
2753 .translate = translate_bz,
2754 .par = (const uint32_t[]){TCG_COND_LT},
2755 }, {
2756 .name = "bnall",
2757 .translate = translate_ball,
2758 .par = (const uint32_t[]){TCG_COND_NE},
2759 }, {
2760 .name = "bne",
2761 .translate = translate_b,
2762 .par = (const uint32_t[]){TCG_COND_NE},
2763 }, {
2764 .name = "bnei",
2765 .translate = translate_bi,
2766 .par = (const uint32_t[]){TCG_COND_NE},
2767 }, {
2768 .name = "bnez",
2769 .translate = translate_bz,
2770 .par = (const uint32_t[]){TCG_COND_NE},
2771 }, {
2772 .name = "bnez.n",
2773 .translate = translate_bz,
2774 .par = (const uint32_t[]){TCG_COND_NE},
2775 }, {
2776 .name = "bnone",
2777 .translate = translate_bany,
2778 .par = (const uint32_t[]){TCG_COND_EQ},
2779 }, {
2780 .name = "break",
2781 .translate = translate_break,
2782 .par = (const uint32_t[]){DEBUGCAUSE_BI},
2783 }, {
2784 .name = "break.n",
2785 .translate = translate_break,
2786 .par = (const uint32_t[]){DEBUGCAUSE_BN},
2787 }, {
2788 .name = "bt",
2789 .translate = translate_bp,
2790 .par = (const uint32_t[]){TCG_COND_NE},
2791 }, {
2792 .name = "call0",
2793 .translate = translate_call0,
2794 }, {
2795 .name = "call12",
2796 .translate = translate_callw,
2797 .par = (const uint32_t[]){3},
2798 }, {
2799 .name = "call4",
2800 .translate = translate_callw,
2801 .par = (const uint32_t[]){1},
2802 }, {
2803 .name = "call8",
2804 .translate = translate_callw,
2805 .par = (const uint32_t[]){2},
2806 }, {
2807 .name = "callx0",
2808 .translate = translate_callx0,
2809 }, {
2810 .name = "callx12",
2811 .translate = translate_callxw,
2812 .par = (const uint32_t[]){3},
2813 }, {
2814 .name = "callx4",
2815 .translate = translate_callxw,
2816 .par = (const uint32_t[]){1},
2817 }, {
2818 .name = "callx8",
2819 .translate = translate_callxw,
2820 .par = (const uint32_t[]){2},
2821 }, {
2822 .name = "clamps",
2823 .translate = translate_clamps,
e9872741
MF
2824 }, {
2825 .name = "clrb_expstate",
2826 .translate = translate_clrb_expstate,
c5ac936e
MF
2827 }, {
2828 .name = "const16",
2829 .translate = translate_const16,
168c12b0
MF
2830 }, {
2831 .name = "depbits",
2832 .translate = translate_depbits,
2833 }, {
2834 .name = "dhi",
2835 .translate = translate_dcache,
2836 .par = (const uint32_t[]){true, true},
2837 }, {
2838 .name = "dhu",
2839 .translate = translate_dcache,
2840 .par = (const uint32_t[]){true, true},
2841 }, {
2842 .name = "dhwb",
2843 .translate = translate_dcache,
2844 .par = (const uint32_t[]){false, true},
2845 }, {
2846 .name = "dhwbi",
2847 .translate = translate_dcache,
2848 .par = (const uint32_t[]){false, true},
2849 }, {
2850 .name = "dii",
2851 .translate = translate_dcache,
2852 .par = (const uint32_t[]){true, false},
2853 }, {
2854 .name = "diu",
2855 .translate = translate_dcache,
2856 .par = (const uint32_t[]){true, false},
2857 }, {
2858 .name = "diwb",
2859 .translate = translate_dcache,
2860 .par = (const uint32_t[]){true, false},
2861 }, {
2862 .name = "diwbi",
2863 .translate = translate_dcache,
2864 .par = (const uint32_t[]){true, false},
2865 }, {
2866 .name = "dpfl",
2867 .translate = translate_dcache,
2868 .par = (const uint32_t[]){true, true},
2869 }, {
2870 .name = "dpfr",
2871 .translate = translate_dcache,
2872 .par = (const uint32_t[]){false, false},
2873 }, {
2874 .name = "dpfro",
2875 .translate = translate_dcache,
2876 .par = (const uint32_t[]){false, false},
2877 }, {
2878 .name = "dpfw",
2879 .translate = translate_dcache,
2880 .par = (const uint32_t[]){false, false},
2881 }, {
2882 .name = "dpfwo",
2883 .translate = translate_dcache,
2884 .par = (const uint32_t[]){false, false},
2885 }, {
2886 .name = "dsync",
2887 .translate = translate_nop,
2888 }, {
2889 .name = "entry",
2890 .translate = translate_entry,
2891 }, {
2892 .name = "esync",
2893 .translate = translate_nop,
2894 }, {
2895 .name = "excw",
2896 .translate = translate_nop,
2897 }, {
2898 .name = "extui",
2899 .translate = translate_extui,
2900 }, {
2901 .name = "extw",
9fb40342 2902 .translate = translate_memw,
13f6a7cd
MF
2903 }, {
2904 .name = "hwwdtlba",
2905 .translate = translate_ill,
2906 }, {
2907 .name = "hwwitlba",
2908 .translate = translate_ill,
168c12b0
MF
2909 }, {
2910 .name = "idtlb",
2911 .translate = translate_itlb,
2912 .par = (const uint32_t[]){true},
2913 }, {
2914 .name = "ihi",
2915 .translate = translate_icache,
2916 .par = (const uint32_t[]){false, true},
2917 }, {
2918 .name = "ihu",
2919 .translate = translate_icache,
2920 .par = (const uint32_t[]){true, true},
2921 }, {
2922 .name = "iii",
2923 .translate = translate_icache,
2924 .par = (const uint32_t[]){true, false},
2925 }, {
2926 .name = "iitlb",
2927 .translate = translate_itlb,
2928 .par = (const uint32_t[]){false},
2929 }, {
2930 .name = "iiu",
2931 .translate = translate_icache,
2932 .par = (const uint32_t[]){true, false},
2933 }, {
2934 .name = "ill",
2935 .translate = translate_ill,
2936 }, {
2937 .name = "ill.n",
2938 .translate = translate_ill,
2939 }, {
2940 .name = "ipf",
2941 .translate = translate_icache,
2942 .par = (const uint32_t[]){false, false},
2943 }, {
2944 .name = "ipfl",
2945 .translate = translate_icache,
2946 .par = (const uint32_t[]){true, true},
2947 }, {
2948 .name = "isync",
2949 .translate = translate_nop,
2950 }, {
2951 .name = "j",
2952 .translate = translate_j,
2953 }, {
2954 .name = "jx",
2955 .translate = translate_jx,
2956 }, {
2957 .name = "l16si",
2958 .translate = translate_ldst,
2959 .par = (const uint32_t[]){MO_TESW, false, false},
2960 }, {
2961 .name = "l16ui",
2962 .translate = translate_ldst,
2963 .par = (const uint32_t[]){MO_TEUW, false, false},
2964 }, {
2965 .name = "l32ai",
2966 .translate = translate_ldst,
2967 .par = (const uint32_t[]){MO_TEUL, true, false},
2968 }, {
2969 .name = "l32e",
2970 .translate = translate_l32e,
2971 }, {
2972 .name = "l32i",
2973 .translate = translate_ldst,
2974 .par = (const uint32_t[]){MO_TEUL, false, false},
2975 }, {
2976 .name = "l32i.n",
2977 .translate = translate_ldst,
2978 .par = (const uint32_t[]){MO_TEUL, false, false},
2979 }, {
2980 .name = "l32r",
2981 .translate = translate_l32r,
2982 }, {
2983 .name = "l8ui",
2984 .translate = translate_ldst,
2985 .par = (const uint32_t[]){MO_UB, false, false},
2986 }, {
2987 .name = "lddec",
2988 .translate = translate_mac16,
2989 .par = (const uint32_t[]){MAC16_NONE, 0, 0, -4},
2990 }, {
2991 .name = "ldinc",
2992 .translate = translate_mac16,
2993 .par = (const uint32_t[]){MAC16_NONE, 0, 0, 4},
13f6a7cd
MF
2994 }, {
2995 .name = "ldpte",
2996 .translate = translate_ill,
168c12b0
MF
2997 }, {
2998 .name = "loop",
2999 .translate = translate_loop,
3000 .par = (const uint32_t[]){TCG_COND_NEVER},
3001 }, {
3002 .name = "loopgtz",
3003 .translate = translate_loop,
3004 .par = (const uint32_t[]){TCG_COND_GT},
3005 }, {
3006 .name = "loopnez",
3007 .translate = translate_loop,
3008 .par = (const uint32_t[]){TCG_COND_NE},
3009 }, {
3010 .name = "max",
426afc3b 3011 .translate = translate_smax,
168c12b0
MF
3012 }, {
3013 .name = "maxu",
426afc3b 3014 .translate = translate_umax,
168c12b0
MF
3015 }, {
3016 .name = "memw",
9fb40342 3017 .translate = translate_memw,
168c12b0
MF
3018 }, {
3019 .name = "min",
426afc3b 3020 .translate = translate_smin,
168c12b0
MF
3021 }, {
3022 .name = "minu",
426afc3b 3023 .translate = translate_umin,
168c12b0
MF
3024 }, {
3025 .name = "mov",
3026 .translate = translate_mov,
3027 }, {
3028 .name = "mov.n",
3029 .translate = translate_mov,
3030 }, {
3031 .name = "moveqz",
3032 .translate = translate_movcond,
3033 .par = (const uint32_t[]){TCG_COND_EQ},
3034 }, {
3035 .name = "movf",
3036 .translate = translate_movp,
3037 .par = (const uint32_t[]){TCG_COND_EQ},
3038 }, {
3039 .name = "movgez",
3040 .translate = translate_movcond,
3041 .par = (const uint32_t[]){TCG_COND_GE},
3042 }, {
3043 .name = "movi",
3044 .translate = translate_movi,
3045 }, {
3046 .name = "movi.n",
3047 .translate = translate_movi,
3048 }, {
3049 .name = "movltz",
3050 .translate = translate_movcond,
3051 .par = (const uint32_t[]){TCG_COND_LT},
3052 }, {
3053 .name = "movnez",
3054 .translate = translate_movcond,
3055 .par = (const uint32_t[]){TCG_COND_NE},
3056 }, {
3057 .name = "movsp",
3058 .translate = translate_movsp,
3059 }, {
3060 .name = "movt",
3061 .translate = translate_movp,
3062 .par = (const uint32_t[]){TCG_COND_NE},
3063 }, {
3064 .name = "mul.aa.hh",
3065 .translate = translate_mac16,
3066 .par = (const uint32_t[]){MAC16_MUL, MAC16_AA, MAC16_HH, 0},
3067 }, {
3068 .name = "mul.aa.hl",
3069 .translate = translate_mac16,
3070 .par = (const uint32_t[]){MAC16_MUL, MAC16_AA, MAC16_HL, 0},
3071 }, {
3072 .name = "mul.aa.lh",
3073 .translate = translate_mac16,
3074 .par = (const uint32_t[]){MAC16_MUL, MAC16_AA, MAC16_LH, 0},
3075 }, {
3076 .name = "mul.aa.ll",
3077 .translate = translate_mac16,
3078 .par = (const uint32_t[]){MAC16_MUL, MAC16_AA, MAC16_LL, 0},
3079 }, {
3080 .name = "mul.ad.hh",
3081 .translate = translate_mac16,
3082 .par = (const uint32_t[]){MAC16_MUL, MAC16_AD, MAC16_HH, 0},
3083 }, {
3084 .name = "mul.ad.hl",
3085 .translate = translate_mac16,
3086 .par = (const uint32_t[]){MAC16_MUL, MAC16_AD, MAC16_HL, 0},
3087 }, {
3088 .name = "mul.ad.lh",
3089 .translate = translate_mac16,
3090 .par = (const uint32_t[]){MAC16_MUL, MAC16_AD, MAC16_LH, 0},
3091 }, {
3092 .name = "mul.ad.ll",
3093 .translate = translate_mac16,
3094 .par = (const uint32_t[]){MAC16_MUL, MAC16_AD, MAC16_LL, 0},
3095 }, {
3096 .name = "mul.da.hh",
3097 .translate = translate_mac16,
3098 .par = (const uint32_t[]){MAC16_MUL, MAC16_DA, MAC16_HH, 0},
3099 }, {
3100 .name = "mul.da.hl",
3101 .translate = translate_mac16,
3102 .par = (const uint32_t[]){MAC16_MUL, MAC16_DA, MAC16_HL, 0},
3103 }, {
3104 .name = "mul.da.lh",
3105 .translate = translate_mac16,
3106 .par = (const uint32_t[]){MAC16_MUL, MAC16_DA, MAC16_LH, 0},
3107 }, {
3108 .name = "mul.da.ll",
3109 .translate = translate_mac16,
3110 .par = (const uint32_t[]){MAC16_MUL, MAC16_DA, MAC16_LL, 0},
3111 }, {
3112 .name = "mul.dd.hh",
3113 .translate = translate_mac16,
3114 .par = (const uint32_t[]){MAC16_MUL, MAC16_DD, MAC16_HH, 0},
3115 }, {
3116 .name = "mul.dd.hl",
3117 .translate = translate_mac16,
3118 .par = (const uint32_t[]){MAC16_MUL, MAC16_DD, MAC16_HL, 0},
3119 }, {
3120 .name = "mul.dd.lh",
3121 .translate = translate_mac16,
3122 .par = (const uint32_t[]){MAC16_MUL, MAC16_DD, MAC16_LH, 0},
3123 }, {
3124 .name = "mul.dd.ll",
3125 .translate = translate_mac16,
3126 .par = (const uint32_t[]){MAC16_MUL, MAC16_DD, MAC16_LL, 0},
3127 }, {
3128 .name = "mul16s",
3129 .translate = translate_mul16,
3130 .par = (const uint32_t[]){true},
3131 }, {
3132 .name = "mul16u",
3133 .translate = translate_mul16,
3134 .par = (const uint32_t[]){false},
3135 }, {
3136 .name = "mula.aa.hh",
3137 .translate = translate_mac16,
3138 .par = (const uint32_t[]){MAC16_MULA, MAC16_AA, MAC16_HH, 0},
3139 }, {
3140 .name = "mula.aa.hl",
3141 .translate = translate_mac16,
3142 .par = (const uint32_t[]){MAC16_MULA, MAC16_AA, MAC16_HL, 0},
3143 }, {
3144 .name = "mula.aa.lh",
3145 .translate = translate_mac16,
3146 .par = (const uint32_t[]){MAC16_MULA, MAC16_AA, MAC16_LH, 0},
3147 }, {
3148 .name = "mula.aa.ll",
3149 .translate = translate_mac16,
3150 .par = (const uint32_t[]){MAC16_MULA, MAC16_AA, MAC16_LL, 0},
3151 }, {
3152 .name = "mula.ad.hh",
3153 .translate = translate_mac16,
3154 .par = (const uint32_t[]){MAC16_MULA, MAC16_AD, MAC16_HH, 0},
3155 }, {
3156 .name = "mula.ad.hl",
3157 .translate = translate_mac16,
3158 .par = (const uint32_t[]){MAC16_MULA, MAC16_AD, MAC16_HL, 0},
3159 }, {
3160 .name = "mula.ad.lh",
3161 .translate = translate_mac16,
3162 .par = (const uint32_t[]){MAC16_MULA, MAC16_AD, MAC16_LH, 0},
3163 }, {
3164 .name = "mula.ad.ll",
3165 .translate = translate_mac16,
3166 .par = (const uint32_t[]){MAC16_MULA, MAC16_AD, MAC16_LL, 0},
3167 }, {
3168 .name = "mula.da.hh",
3169 .translate = translate_mac16,
3170 .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_HH, 0},
3171 }, {
3172 .name = "mula.da.hh.lddec",
3173 .translate = translate_mac16,
3174 .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_HH, -4},
3175 }, {
3176 .name = "mula.da.hh.ldinc",
3177 .translate = translate_mac16,
3178 .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_HH, 4},
3179 }, {
3180 .name = "mula.da.hl",
3181 .translate = translate_mac16,
3182 .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_HL, 0},
3183 }, {
3184 .name = "mula.da.hl.lddec",
3185 .translate = translate_mac16,
3186 .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_HL, -4},
3187 }, {
3188 .name = "mula.da.hl.ldinc",
3189 .translate = translate_mac16,
3190 .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_HL, 4},
3191 }, {
3192 .name = "mula.da.lh",
3193 .translate = translate_mac16,
3194 .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_LH, 0},
3195 }, {
3196 .name = "mula.da.lh.lddec",
3197 .translate = translate_mac16,
3198 .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_LH, -4},
3199 }, {
3200 .name = "mula.da.lh.ldinc",
3201 .translate = translate_mac16,
3202 .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_LH, 4},
3203 }, {
3204 .name = "mula.da.ll",
3205 .translate = translate_mac16,
3206 .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_LL, 0},
3207 }, {
3208 .name = "mula.da.ll.lddec",
3209 .translate = translate_mac16,
3210 .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_LL, -4},
3211 }, {
3212 .name = "mula.da.ll.ldinc",
3213 .translate = translate_mac16,
3214 .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_LL, 4},
3215 }, {
3216 .name = "mula.dd.hh",
3217 .translate = translate_mac16,
3218 .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_HH, 0},
3219 }, {
3220 .name = "mula.dd.hh.lddec",
3221 .translate = translate_mac16,
3222 .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_HH, -4},
3223 }, {
3224 .name = "mula.dd.hh.ldinc",
3225 .translate = translate_mac16,
3226 .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_HH, 4},
3227 }, {
3228 .name = "mula.dd.hl",
3229 .translate = translate_mac16,
3230 .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_HL, 0},
3231 }, {
3232 .name = "mula.dd.hl.lddec",
3233 .translate = translate_mac16,
3234 .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_HL, -4},
3235 }, {
3236 .name = "mula.dd.hl.ldinc",
3237 .translate = translate_mac16,
3238 .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_HL, 4},
3239 }, {
3240 .name = "mula.dd.lh",
3241 .translate = translate_mac16,
3242 .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_LH, 0},
3243 }, {
3244 .name = "mula.dd.lh.lddec",
3245 .translate = translate_mac16,
3246 .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_LH, -4},
3247 }, {
3248 .name = "mula.dd.lh.ldinc",
3249 .translate = translate_mac16,
3250 .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_LH, 4},
3251 }, {
3252 .name = "mula.dd.ll",
3253 .translate = translate_mac16,
3254 .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_LL, 0},
3255 }, {
3256 .name = "mula.dd.ll.lddec",
3257 .translate = translate_mac16,
3258 .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_LL, -4},
3259 }, {
3260 .name = "mula.dd.ll.ldinc",
3261 .translate = translate_mac16,
3262 .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_LL, 4},
3263 }, {
3264 .name = "mull",
3265 .translate = translate_mull,
3266 }, {
3267 .name = "muls.aa.hh",
3268 .translate = translate_mac16,
3269 .par = (const uint32_t[]){MAC16_MULS, MAC16_AA, MAC16_HH, 0},
3270 }, {
3271 .name = "muls.aa.hl",
3272 .translate = translate_mac16,
3273 .par = (const uint32_t[]){MAC16_MULS, MAC16_AA, MAC16_HL, 0},
3274 }, {
3275 .name = "muls.aa.lh",
3276 .translate = translate_mac16,
3277 .par = (const uint32_t[]){MAC16_MULS, MAC16_AA, MAC16_LH, 0},
3278 }, {
3279 .name = "muls.aa.ll",
3280 .translate = translate_mac16,
3281 .par = (const uint32_t[]){MAC16_MULS, MAC16_AA, MAC16_LL, 0},
3282 }, {
3283 .name = "muls.ad.hh",
3284 .translate = translate_mac16,
3285 .par = (const uint32_t[]){MAC16_MULS, MAC16_AD, MAC16_HH, 0},
3286 }, {
3287 .name = "muls.ad.hl",
3288 .translate = translate_mac16,
3289 .par = (const uint32_t[]){MAC16_MULS, MAC16_AD, MAC16_HL, 0},
3290 }, {
3291 .name = "muls.ad.lh",
3292 .translate = translate_mac16,
3293 .par = (const uint32_t[]){MAC16_MULS, MAC16_AD, MAC16_LH, 0},
3294 }, {
3295 .name = "muls.ad.ll",
3296 .translate = translate_mac16,
3297 .par = (const uint32_t[]){MAC16_MULS, MAC16_AD, MAC16_LL, 0},
3298 }, {
3299 .name = "muls.da.hh",
3300 .translate = translate_mac16,
3301 .par = (const uint32_t[]){MAC16_MULS, MAC16_DA, MAC16_HH, 0},
3302 }, {
3303 .name = "muls.da.hl",
3304 .translate = translate_mac16,
3305 .par = (const uint32_t[]){MAC16_MULS, MAC16_DA, MAC16_HL, 0},
3306 }, {
3307 .name = "muls.da.lh",
3308 .translate = translate_mac16,
3309 .par = (const uint32_t[]){MAC16_MULS, MAC16_DA, MAC16_LH, 0},
3310 }, {
3311 .name = "muls.da.ll",
3312 .translate = translate_mac16,
3313 .par = (const uint32_t[]){MAC16_MULS, MAC16_DA, MAC16_LL, 0},
3314 }, {
3315 .name = "muls.dd.hh",
3316 .translate = translate_mac16,
3317 .par = (const uint32_t[]){MAC16_MULS, MAC16_DD, MAC16_HH, 0},
3318 }, {
3319 .name = "muls.dd.hl",
3320 .translate = translate_mac16,
3321 .par = (const uint32_t[]){MAC16_MULS, MAC16_DD, MAC16_HL, 0},
3322 }, {
3323 .name = "muls.dd.lh",
3324 .translate = translate_mac16,
3325 .par = (const uint32_t[]){MAC16_MULS, MAC16_DD, MAC16_LH, 0},
3326 }, {
3327 .name = "muls.dd.ll",
3328 .translate = translate_mac16,
3329 .par = (const uint32_t[]){MAC16_MULS, MAC16_DD, MAC16_LL, 0},
3330 }, {
3331 .name = "mulsh",
3332 .translate = translate_mulh,
3333 .par = (const uint32_t[]){true},
3334 }, {
3335 .name = "muluh",
3336 .translate = translate_mulh,
3337 .par = (const uint32_t[]){false},
3338 }, {
3339 .name = "neg",
3340 .translate = translate_neg,
3341 }, {
3342 .name = "nop",
3343 .translate = translate_nop,
3344 }, {
3345 .name = "nop.n",
3346 .translate = translate_nop,
3347 }, {
3348 .name = "nsa",
3349 .translate = translate_nsa,
3350 }, {
3351 .name = "nsau",
3352 .translate = translate_nsau,
3353 }, {
3354 .name = "or",
3355 .translate = translate_or,
3356 }, {
3357 .name = "orb",
3358 .translate = translate_boolean,
3359 .par = (const uint32_t[]){BOOLEAN_OR},
3360 }, {
3361 .name = "orbc",
3362 .translate = translate_boolean,
3363 .par = (const uint32_t[]){BOOLEAN_ORC},
3364 }, {
3365 .name = "pdtlb",
3366 .translate = translate_ptlb,
3367 .par = (const uint32_t[]){true},
3368 }, {
3369 .name = "pitlb",
3370 .translate = translate_ptlb,
3371 .par = (const uint32_t[]){false},
3372 }, {
3373 .name = "quos",
3374 .translate = translate_quos,
3375 .par = (const uint32_t[]){true},
3376 }, {
3377 .name = "quou",
3378 .translate = translate_quou,
3379 .par = (const uint32_t[]){true},
3380 }, {
3381 .name = "rdtlb0",
3382 .translate = translate_rtlb,
3383 .par = (const uint32_t[]){true, 0},
3384 }, {
3385 .name = "rdtlb1",
3386 .translate = translate_rtlb,
3387 .par = (const uint32_t[]){true, 1},
e9872741
MF
3388 }, {
3389 .name = "read_impwire",
3390 .translate = translate_read_impwire,
168c12b0
MF
3391 }, {
3392 .name = "rems",
3393 .translate = translate_quos,
3394 .par = (const uint32_t[]){false},
3395 }, {
3396 .name = "remu",
3397 .translate = translate_quou,
3398 .par = (const uint32_t[]){false},
3399 }, {
3400 .name = "rer",
3401 .translate = translate_rer,
3402 }, {
3403 .name = "ret",
3404 .translate = translate_ret,
3405 }, {
3406 .name = "ret.n",
3407 .translate = translate_ret,
3408 }, {
3409 .name = "retw",
3410 .translate = translate_retw,
3411 }, {
3412 .name = "retw.n",
3413 .translate = translate_retw,
13f6a7cd
MF
3414 }, {
3415 .name = "rfdd",
3416 .translate = translate_ill,
168c12b0
MF
3417 }, {
3418 .name = "rfde",
3419 .translate = translate_rfde,
13f6a7cd
MF
3420 }, {
3421 .name = "rfdo",
3422 .translate = translate_ill,
168c12b0
MF
3423 }, {
3424 .name = "rfe",
3425 .translate = translate_rfe,
3426 }, {
3427 .name = "rfi",
3428 .translate = translate_rfi,
3429 }, {
3430 .name = "rfwo",
3431 .translate = translate_rfw,
3432 .par = (const uint32_t[]){true},
3433 }, {
3434 .name = "rfwu",
3435 .translate = translate_rfw,
3436 .par = (const uint32_t[]){false},
3437 }, {
3438 .name = "ritlb0",
3439 .translate = translate_rtlb,
3440 .par = (const uint32_t[]){false, 0},
3441 }, {
3442 .name = "ritlb1",
3443 .translate = translate_rtlb,
3444 .par = (const uint32_t[]){false, 1},
3445 }, {
3446 .name = "rotw",
3447 .translate = translate_rotw,
3448 }, {
3449 .name = "rsil",
3450 .translate = translate_rsil,
3451 }, {
3452 .name = "rsr.176",
3453 .translate = translate_rsr,
3454 .par = (const uint32_t[]){176},
3455 }, {
3456 .name = "rsr.208",
3457 .translate = translate_rsr,
3458 .par = (const uint32_t[]){208},
3459 }, {
3460 .name = "rsr.acchi",
3461 .translate = translate_rsr,
3462 .par = (const uint32_t[]){ACCHI},
3463 }, {
3464 .name = "rsr.acclo",
3465 .translate = translate_rsr,
3466 .par = (const uint32_t[]){ACCLO},
3467 }, {
3468 .name = "rsr.atomctl",
3469 .translate = translate_rsr,
3470 .par = (const uint32_t[]){ATOMCTL},
3471 }, {
3472 .name = "rsr.br",
3473 .translate = translate_rsr,
3474 .par = (const uint32_t[]){BR},
3475 }, {
3476 .name = "rsr.cacheattr",
3477 .translate = translate_rsr,
3478 .par = (const uint32_t[]){CACHEATTR},
3479 }, {
3480 .name = "rsr.ccompare0",
3481 .translate = translate_rsr,
3482 .par = (const uint32_t[]){CCOMPARE},
3483 }, {
3484 .name = "rsr.ccompare1",
3485 .translate = translate_rsr,
3486 .par = (const uint32_t[]){CCOMPARE + 1},
3487 }, {
3488 .name = "rsr.ccompare2",
3489 .translate = translate_rsr,
3490 .par = (const uint32_t[]){CCOMPARE + 2},
3491 }, {
3492 .name = "rsr.ccount",
3493 .translate = translate_rsr,
3494 .par = (const uint32_t[]){CCOUNT},
3495 }, {
3496 .name = "rsr.configid0",
3497 .translate = translate_rsr,
3498 .par = (const uint32_t[]){CONFIGID0},
3499 }, {
3500 .name = "rsr.configid1",
3501 .translate = translate_rsr,
3502 .par = (const uint32_t[]){CONFIGID1},
3503 }, {
3504 .name = "rsr.cpenable",
3505 .translate = translate_rsr,
3506 .par = (const uint32_t[]){CPENABLE},
3507 }, {
3508 .name = "rsr.dbreaka0",
3509 .translate = translate_rsr,
3510 .par = (const uint32_t[]){DBREAKA},
3511 }, {
3512 .name = "rsr.dbreaka1",
3513 .translate = translate_rsr,
3514 .par = (const uint32_t[]){DBREAKA + 1},
3515 }, {
3516 .name = "rsr.dbreakc0",
3517 .translate = translate_rsr,
3518 .par = (const uint32_t[]){DBREAKC},
3519 }, {
3520 .name = "rsr.dbreakc1",
3521 .translate = translate_rsr,
3522 .par = (const uint32_t[]){DBREAKC + 1},
13f6a7cd
MF
3523 }, {
3524 .name = "rsr.ddr",
3525 .translate = translate_rsr,
3526 .par = (const uint32_t[]){DDR},
168c12b0
MF
3527 }, {
3528 .name = "rsr.debugcause",
3529 .translate = translate_rsr,
3530 .par = (const uint32_t[]){DEBUGCAUSE},
3531 }, {
3532 .name = "rsr.depc",
3533 .translate = translate_rsr,
3534 .par = (const uint32_t[]){DEPC},
3535 }, {
3536 .name = "rsr.dtlbcfg",
3537 .translate = translate_rsr,
3538 .par = (const uint32_t[]){DTLBCFG},
3539 }, {
3540 .name = "rsr.epc1",
3541 .translate = translate_rsr,
3542 .par = (const uint32_t[]){EPC1},
3543 }, {
3544 .name = "rsr.epc2",
3545 .translate = translate_rsr,
3546 .par = (const uint32_t[]){EPC1 + 1},
3547 }, {
3548 .name = "rsr.epc3",
3549 .translate = translate_rsr,
3550 .par = (const uint32_t[]){EPC1 + 2},
3551 }, {
3552 .name = "rsr.epc4",
3553 .translate = translate_rsr,
3554 .par = (const uint32_t[]){EPC1 + 3},
3555 }, {
3556 .name = "rsr.epc5",
3557 .translate = translate_rsr,
3558 .par = (const uint32_t[]){EPC1 + 4},
3559 }, {
3560 .name = "rsr.epc6",
3561 .translate = translate_rsr,
3562 .par = (const uint32_t[]){EPC1 + 5},
3563 }, {
3564 .name = "rsr.epc7",
3565 .translate = translate_rsr,
3566 .par = (const uint32_t[]){EPC1 + 6},
3567 }, {
3568 .name = "rsr.eps2",
3569 .translate = translate_rsr,
3570 .par = (const uint32_t[]){EPS2},
3571 }, {
3572 .name = "rsr.eps3",
3573 .translate = translate_rsr,
3574 .par = (const uint32_t[]){EPS2 + 1},
3575 }, {
3576 .name = "rsr.eps4",
3577 .translate = translate_rsr,
3578 .par = (const uint32_t[]){EPS2 + 2},
3579 }, {
3580 .name = "rsr.eps5",
3581 .translate = translate_rsr,
3582 .par = (const uint32_t[]){EPS2 + 3},
3583 }, {
3584 .name = "rsr.eps6",
3585 .translate = translate_rsr,
3586 .par = (const uint32_t[]){EPS2 + 4},
3587 }, {
3588 .name = "rsr.eps7",
3589 .translate = translate_rsr,
3590 .par = (const uint32_t[]){EPS2 + 5},
3591 }, {
3592 .name = "rsr.exccause",
3593 .translate = translate_rsr,
3594 .par = (const uint32_t[]){EXCCAUSE},
3595 }, {
3596 .name = "rsr.excsave1",
3597 .translate = translate_rsr,
3598 .par = (const uint32_t[]){EXCSAVE1},
3599 }, {
3600 .name = "rsr.excsave2",
3601 .translate = translate_rsr,
3602 .par = (const uint32_t[]){EXCSAVE1 + 1},
3603 }, {
3604 .name = "rsr.excsave3",
3605 .translate = translate_rsr,
3606 .par = (const uint32_t[]){EXCSAVE1 + 2},
3607 }, {
3608 .name = "rsr.excsave4",
3609 .translate = translate_rsr,
3610 .par = (const uint32_t[]){EXCSAVE1 + 3},
3611 }, {
3612 .name = "rsr.excsave5",
3613 .translate = translate_rsr,
3614 .par = (const uint32_t[]){EXCSAVE1 + 4},
3615 }, {
3616 .name = "rsr.excsave6",
3617 .translate = translate_rsr,
3618 .par = (const uint32_t[]){EXCSAVE1 + 5},
3619 }, {
3620 .name = "rsr.excsave7",
3621 .translate = translate_rsr,
3622 .par = (const uint32_t[]){EXCSAVE1 + 6},
3623 }, {
3624 .name = "rsr.excvaddr",
3625 .translate = translate_rsr,
3626 .par = (const uint32_t[]){EXCVADDR},
3627 }, {
3628 .name = "rsr.ibreaka0",
3629 .translate = translate_rsr,
3630 .par = (const uint32_t[]){IBREAKA},
3631 }, {
3632 .name = "rsr.ibreaka1",
3633 .translate = translate_rsr,
3634 .par = (const uint32_t[]){IBREAKA + 1},
3635 }, {
3636 .name = "rsr.ibreakenable",
3637 .translate = translate_rsr,
3638 .par = (const uint32_t[]){IBREAKENABLE},
3639 }, {
3640 .name = "rsr.icount",
3641 .translate = translate_rsr,
3642 .par = (const uint32_t[]){ICOUNT},
3643 }, {
3644 .name = "rsr.icountlevel",
3645 .translate = translate_rsr,
3646 .par = (const uint32_t[]){ICOUNTLEVEL},
3647 }, {
3648 .name = "rsr.intclear",
3649 .translate = translate_rsr,
3650 .par = (const uint32_t[]){INTCLEAR},
3651 }, {
3652 .name = "rsr.intenable",
3653 .translate = translate_rsr,
3654 .par = (const uint32_t[]){INTENABLE},
3655 }, {
3656 .name = "rsr.interrupt",
3657 .translate = translate_rsr,
3658 .par = (const uint32_t[]){INTSET},
3659 }, {
3660 .name = "rsr.intset",
3661 .translate = translate_rsr,
3662 .par = (const uint32_t[]){INTSET},
3663 }, {
3664 .name = "rsr.itlbcfg",
3665 .translate = translate_rsr,
3666 .par = (const uint32_t[]){ITLBCFG},
3667 }, {
3668 .name = "rsr.lbeg",
3669 .translate = translate_rsr,
3670 .par = (const uint32_t[]){LBEG},
3671 }, {
3672 .name = "rsr.lcount",
3673 .translate = translate_rsr,
3674 .par = (const uint32_t[]){LCOUNT},
3675 }, {
3676 .name = "rsr.lend",
3677 .translate = translate_rsr,
3678 .par = (const uint32_t[]){LEND},
3679 }, {
3680 .name = "rsr.litbase",
3681 .translate = translate_rsr,
3682 .par = (const uint32_t[]){LITBASE},
3683 }, {
3684 .name = "rsr.m0",
3685 .translate = translate_rsr,
3686 .par = (const uint32_t[]){MR},
3687 }, {
3688 .name = "rsr.m1",
3689 .translate = translate_rsr,
3690 .par = (const uint32_t[]){MR + 1},
3691 }, {
3692 .name = "rsr.m2",
3693 .translate = translate_rsr,
3694 .par = (const uint32_t[]){MR + 2},
3695 }, {
3696 .name = "rsr.m3",
3697 .translate = translate_rsr,
3698 .par = (const uint32_t[]){MR + 3},
3699 }, {
3700 .name = "rsr.memctl",
3701 .translate = translate_rsr,
3702 .par = (const uint32_t[]){MEMCTL},
3703 }, {
3704 .name = "rsr.misc0",
3705 .translate = translate_rsr,
3706 .par = (const uint32_t[]){MISC},
3707 }, {
3708 .name = "rsr.misc1",
3709 .translate = translate_rsr,
3710 .par = (const uint32_t[]){MISC + 1},
3711 }, {
3712 .name = "rsr.misc2",
3713 .translate = translate_rsr,
3714 .par = (const uint32_t[]){MISC + 2},
3715 }, {
3716 .name = "rsr.misc3",
3717 .translate = translate_rsr,
3718 .par = (const uint32_t[]){MISC + 3},
3719 }, {
3720 .name = "rsr.prid",
3721 .translate = translate_rsr,
3722 .par = (const uint32_t[]){PRID},
3723 }, {
3724 .name = "rsr.ps",
3725 .translate = translate_rsr,
3726 .par = (const uint32_t[]){PS},
3727 }, {
3728 .name = "rsr.ptevaddr",
3729 .translate = translate_rsr,
3730 .par = (const uint32_t[]){PTEVADDR},
3731 }, {
3732 .name = "rsr.rasid",
3733 .translate = translate_rsr,
3734 .par = (const uint32_t[]){RASID},
3735 }, {
3736 .name = "rsr.sar",
3737 .translate = translate_rsr,
3738 .par = (const uint32_t[]){SAR},
3739 }, {
3740 .name = "rsr.scompare1",
3741 .translate = translate_rsr,
3742 .par = (const uint32_t[]){SCOMPARE1},
3743 }, {
3744 .name = "rsr.vecbase",
3745 .translate = translate_rsr,
3746 .par = (const uint32_t[]){VECBASE},
3747 }, {
3748 .name = "rsr.windowbase",
3749 .translate = translate_rsr,
3750 .par = (const uint32_t[]){WINDOW_BASE},
3751 }, {
3752 .name = "rsr.windowstart",
3753 .translate = translate_rsr,
3754 .par = (const uint32_t[]){WINDOW_START},
3755 }, {
3756 .name = "rsync",
3757 .translate = translate_nop,
e9872741
MF
3758 }, {
3759 .name = "rur.expstate",
3760 .translate = translate_rur,
3761 .par = (const uint32_t[]){EXPSTATE},
168c12b0
MF
3762 }, {
3763 .name = "rur.fcr",
3764 .translate = translate_rur,
3765 .par = (const uint32_t[]){FCR},
3766 }, {
3767 .name = "rur.fsr",
3768 .translate = translate_rur,
3769 .par = (const uint32_t[]){FSR},
3770 }, {
3771 .name = "rur.threadptr",
3772 .translate = translate_rur,
3773 .par = (const uint32_t[]){THREADPTR},
3774 }, {
3775 .name = "s16i",
3776 .translate = translate_ldst,
3777 .par = (const uint32_t[]){MO_TEUW, false, true},
3778 }, {
3779 .name = "s32c1i",
3780 .translate = translate_s32c1i,
3781 }, {
3782 .name = "s32e",
3783 .translate = translate_s32e,
3784 }, {
3785 .name = "s32i",
3786 .translate = translate_ldst,
3787 .par = (const uint32_t[]){MO_TEUL, false, true},
3788 }, {
3789 .name = "s32i.n",
3790 .translate = translate_ldst,
3791 .par = (const uint32_t[]){MO_TEUL, false, true},
3792 }, {
3793 .name = "s32nb",
3794 .translate = translate_ldst,
3795 .par = (const uint32_t[]){MO_TEUL, false, true},
3796 }, {
3797 .name = "s32ri",
3798 .translate = translate_ldst,
3799 .par = (const uint32_t[]){MO_TEUL, true, true},
3800 }, {
3801 .name = "s8i",
3802 .translate = translate_ldst,
3803 .par = (const uint32_t[]){MO_UB, false, true},
d1e9b006
MF
3804 }, {
3805 .name = "salt",
3806 .translate = translate_salt,
3807 .par = (const uint32_t[]){TCG_COND_LT},
3808 }, {
3809 .name = "saltu",
3810 .translate = translate_salt,
3811 .par = (const uint32_t[]){TCG_COND_LTU},
e9872741
MF
3812 }, {
3813 .name = "setb_expstate",
3814 .translate = translate_setb_expstate,
168c12b0
MF
3815 }, {
3816 .name = "sext",
3817 .translate = translate_sext,
3818 }, {
3819 .name = "simcall",
3820 .translate = translate_simcall,
3821 }, {
3822 .name = "sll",
3823 .translate = translate_sll,
3824 }, {
3825 .name = "slli",
3826 .translate = translate_slli,
3827 }, {
3828 .name = "sra",
3829 .translate = translate_sra,
3830 }, {
3831 .name = "srai",
3832 .translate = translate_srai,
3833 }, {
3834 .name = "src",
3835 .translate = translate_src,
3836 }, {
3837 .name = "srl",
3838 .translate = translate_srl,
3839 }, {
3840 .name = "srli",
3841 .translate = translate_srli,
3842 }, {
3843 .name = "ssa8b",
3844 .translate = translate_ssa8b,
3845 }, {
3846 .name = "ssa8l",
3847 .translate = translate_ssa8l,
3848 }, {
3849 .name = "ssai",
3850 .translate = translate_ssai,
3851 }, {
3852 .name = "ssl",
3853 .translate = translate_ssl,
3854 }, {
3855 .name = "ssr",
3856 .translate = translate_ssr,
3857 }, {
3858 .name = "sub",
3859 .translate = translate_sub,
3860 }, {
3861 .name = "subx2",
3862 .translate = translate_subx,
3863 .par = (const uint32_t[]){1},
3864 }, {
3865 .name = "subx4",
3866 .translate = translate_subx,
3867 .par = (const uint32_t[]){2},
3868 }, {
3869 .name = "subx8",
3870 .translate = translate_subx,
3871 .par = (const uint32_t[]){3},
3872 }, {
3873 .name = "syscall",
3874 .translate = translate_syscall,
3875 }, {
3876 .name = "umul.aa.hh",
3877 .translate = translate_mac16,
3878 .par = (const uint32_t[]){MAC16_UMUL, MAC16_AA, MAC16_HH, 0},
3879 }, {
3880 .name = "umul.aa.hl",
3881 .translate = translate_mac16,
3882 .par = (const uint32_t[]){MAC16_UMUL, MAC16_AA, MAC16_HL, 0},
3883 }, {
3884 .name = "umul.aa.lh",
3885 .translate = translate_mac16,
3886 .par = (const uint32_t[]){MAC16_UMUL, MAC16_AA, MAC16_LH, 0},
3887 }, {
3888 .name = "umul.aa.ll",
3889 .translate = translate_mac16,
3890 .par = (const uint32_t[]){MAC16_UMUL, MAC16_AA, MAC16_LL, 0},
3891 }, {
3892 .name = "waiti",
3893 .translate = translate_waiti,
3894 }, {
3895 .name = "wdtlb",
3896 .translate = translate_wtlb,
3897 .par = (const uint32_t[]){true},
3898 }, {
3899 .name = "wer",
3900 .translate = translate_wer,
3901 }, {
3902 .name = "witlb",
3903 .translate = translate_wtlb,
3904 .par = (const uint32_t[]){false},
e9872741
MF
3905 }, {
3906 .name = "wrmsk_expstate",
3907 .translate = translate_wrmsk_expstate,
168c12b0
MF
3908 }, {
3909 .name = "wsr.176",
3910 .translate = translate_wsr,
3911 .par = (const uint32_t[]){176},
3912 }, {
3913 .name = "wsr.208",
3914 .translate = translate_wsr,
3915 .par = (const uint32_t[]){208},
3916 }, {
3917 .name = "wsr.acchi",
3918 .translate = translate_wsr,
3919 .par = (const uint32_t[]){ACCHI},
3920 }, {
3921 .name = "wsr.acclo",
3922 .translate = translate_wsr,
3923 .par = (const uint32_t[]){ACCLO},
3924 }, {
3925 .name = "wsr.atomctl",
3926 .translate = translate_wsr,
3927 .par = (const uint32_t[]){ATOMCTL},
3928 }, {
3929 .name = "wsr.br",
3930 .translate = translate_wsr,
3931 .par = (const uint32_t[]){BR},
3932 }, {
3933 .name = "wsr.cacheattr",
3934 .translate = translate_wsr,
3935 .par = (const uint32_t[]){CACHEATTR},
3936 }, {
3937 .name = "wsr.ccompare0",
3938 .translate = translate_wsr,
3939 .par = (const uint32_t[]){CCOMPARE},
3940 }, {
3941 .name = "wsr.ccompare1",
3942 .translate = translate_wsr,
3943 .par = (const uint32_t[]){CCOMPARE + 1},
3944 }, {
3945 .name = "wsr.ccompare2",
3946 .translate = translate_wsr,
3947 .par = (const uint32_t[]){CCOMPARE + 2},
3948 }, {
3949 .name = "wsr.ccount",
3950 .translate = translate_wsr,
3951 .par = (const uint32_t[]){CCOUNT},
3952 }, {
3953 .name = "wsr.configid0",
3954 .translate = translate_wsr,
3955 .par = (const uint32_t[]){CONFIGID0},
3956 }, {
3957 .name = "wsr.configid1",
3958 .translate = translate_wsr,
3959 .par = (const uint32_t[]){CONFIGID1},
3960 }, {
3961 .name = "wsr.cpenable",
3962 .translate = translate_wsr,
3963 .par = (const uint32_t[]){CPENABLE},
3964 }, {
3965 .name = "wsr.dbreaka0",
3966 .translate = translate_wsr,
3967 .par = (const uint32_t[]){DBREAKA},
3968 }, {
3969 .name = "wsr.dbreaka1",
3970 .translate = translate_wsr,
3971 .par = (const uint32_t[]){DBREAKA + 1},
3972 }, {
3973 .name = "wsr.dbreakc0",
3974 .translate = translate_wsr,
3975 .par = (const uint32_t[]){DBREAKC},
3976 }, {
3977 .name = "wsr.dbreakc1",
3978 .translate = translate_wsr,
3979 .par = (const uint32_t[]){DBREAKC + 1},
13f6a7cd
MF
3980 }, {
3981 .name = "wsr.ddr",
3982 .translate = translate_wsr,
3983 .par = (const uint32_t[]){DDR},
168c12b0
MF
3984 }, {
3985 .name = "wsr.debugcause",
3986 .translate = translate_wsr,
3987 .par = (const uint32_t[]){DEBUGCAUSE},
3988 }, {
3989 .name = "wsr.depc",
3990 .translate = translate_wsr,
3991 .par = (const uint32_t[]){DEPC},
3992 }, {
3993 .name = "wsr.dtlbcfg",
3994 .translate = translate_wsr,
3995 .par = (const uint32_t[]){DTLBCFG},
3996 }, {
3997 .name = "wsr.epc1",
3998 .translate = translate_wsr,
3999 .par = (const uint32_t[]){EPC1},
4000 }, {
4001 .name = "wsr.epc2",
4002 .translate = translate_wsr,
4003 .par = (const uint32_t[]){EPC1 + 1},
4004 }, {
4005 .name = "wsr.epc3",
4006 .translate = translate_wsr,
4007 .par = (const uint32_t[]){EPC1 + 2},
4008 }, {
4009 .name = "wsr.epc4",
4010 .translate = translate_wsr,
4011 .par = (const uint32_t[]){EPC1 + 3},
4012 }, {
4013 .name = "wsr.epc5",
4014 .translate = translate_wsr,
4015 .par = (const uint32_t[]){EPC1 + 4},
4016 }, {
4017 .name = "wsr.epc6",
4018 .translate = translate_wsr,
4019 .par = (const uint32_t[]){EPC1 + 5},
4020 }, {
4021 .name = "wsr.epc7",
4022 .translate = translate_wsr,
4023 .par = (const uint32_t[]){EPC1 + 6},
4024 }, {
4025 .name = "wsr.eps2",
4026 .translate = translate_wsr,
4027 .par = (const uint32_t[]){EPS2},
4028 }, {
4029 .name = "wsr.eps3",
4030 .translate = translate_wsr,
4031 .par = (const uint32_t[]){EPS2 + 1},
4032 }, {
4033 .name = "wsr.eps4",
4034 .translate = translate_wsr,
4035 .par = (const uint32_t[]){EPS2 + 2},
4036 }, {
4037 .name = "wsr.eps5",
4038 .translate = translate_wsr,
4039 .par = (const uint32_t[]){EPS2 + 3},
4040 }, {
4041 .name = "wsr.eps6",
4042 .translate = translate_wsr,
4043 .par = (const uint32_t[]){EPS2 + 4},
4044 }, {
4045 .name = "wsr.eps7",
4046 .translate = translate_wsr,
4047 .par = (const uint32_t[]){EPS2 + 5},
4048 }, {
4049 .name = "wsr.exccause",
4050 .translate = translate_wsr,
4051 .par = (const uint32_t[]){EXCCAUSE},
4052 }, {
4053 .name = "wsr.excsave1",
4054 .translate = translate_wsr,
4055 .par = (const uint32_t[]){EXCSAVE1},
4056 }, {
4057 .name = "wsr.excsave2",
4058 .translate = translate_wsr,
4059 .par = (const uint32_t[]){EXCSAVE1 + 1},
4060 }, {
4061 .name = "wsr.excsave3",
4062 .translate = translate_wsr,
4063 .par = (const uint32_t[]){EXCSAVE1 + 2},
4064 }, {
4065 .name = "wsr.excsave4",
4066 .translate = translate_wsr,
4067 .par = (const uint32_t[]){EXCSAVE1 + 3},
4068 }, {
4069 .name = "wsr.excsave5",
4070 .translate = translate_wsr,
4071 .par = (const uint32_t[]){EXCSAVE1 + 4},
4072 }, {
4073 .name = "wsr.excsave6",
4074 .translate = translate_wsr,
4075 .par = (const uint32_t[]){EXCSAVE1 + 5},
4076 }, {
4077 .name = "wsr.excsave7",
4078 .translate = translate_wsr,
4079 .par = (const uint32_t[]){EXCSAVE1 + 6},
4080 }, {
4081 .name = "wsr.excvaddr",
4082 .translate = translate_wsr,
4083 .par = (const uint32_t[]){EXCVADDR},
4084 }, {
4085 .name = "wsr.ibreaka0",
4086 .translate = translate_wsr,
4087 .par = (const uint32_t[]){IBREAKA},
4088 }, {
4089 .name = "wsr.ibreaka1",
4090 .translate = translate_wsr,
4091 .par = (const uint32_t[]){IBREAKA + 1},
4092 }, {
4093 .name = "wsr.ibreakenable",
4094 .translate = translate_wsr,
4095 .par = (const uint32_t[]){IBREAKENABLE},
4096 }, {
4097 .name = "wsr.icount",
4098 .translate = translate_wsr,
4099 .par = (const uint32_t[]){ICOUNT},
4100 }, {
4101 .name = "wsr.icountlevel",
4102 .translate = translate_wsr,
4103 .par = (const uint32_t[]){ICOUNTLEVEL},
4104 }, {
4105 .name = "wsr.intclear",
4106 .translate = translate_wsr,
4107 .par = (const uint32_t[]){INTCLEAR},
4108 }, {
4109 .name = "wsr.intenable",
4110 .translate = translate_wsr,
4111 .par = (const uint32_t[]){INTENABLE},
4112 }, {
4113 .name = "wsr.interrupt",
4114 .translate = translate_wsr,
4115 .par = (const uint32_t[]){INTSET},
4116 }, {
4117 .name = "wsr.intset",
4118 .translate = translate_wsr,
4119 .par = (const uint32_t[]){INTSET},
4120 }, {
4121 .name = "wsr.itlbcfg",
4122 .translate = translate_wsr,
4123 .par = (const uint32_t[]){ITLBCFG},
4124 }, {
4125 .name = "wsr.lbeg",
4126 .translate = translate_wsr,
4127 .par = (const uint32_t[]){LBEG},
4128 }, {
4129 .name = "wsr.lcount",
4130 .translate = translate_wsr,
4131 .par = (const uint32_t[]){LCOUNT},
4132 }, {
4133 .name = "wsr.lend",
4134 .translate = translate_wsr,
4135 .par = (const uint32_t[]){LEND},
4136 }, {
4137 .name = "wsr.litbase",
4138 .translate = translate_wsr,
4139 .par = (const uint32_t[]){LITBASE},
4140 }, {
4141 .name = "wsr.m0",
4142 .translate = translate_wsr,
4143 .par = (const uint32_t[]){MR},
4144 }, {
4145 .name = "wsr.m1",
4146 .translate = translate_wsr,
4147 .par = (const uint32_t[]){MR + 1},
4148 }, {
4149 .name = "wsr.m2",
4150 .translate = translate_wsr,
4151 .par = (const uint32_t[]){MR + 2},
4152 }, {
4153 .name = "wsr.m3",
4154 .translate = translate_wsr,
4155 .par = (const uint32_t[]){MR + 3},
4156 }, {
4157 .name = "wsr.memctl",
4158 .translate = translate_wsr,
4159 .par = (const uint32_t[]){MEMCTL},
4160 }, {
4161 .name = "wsr.misc0",
4162 .translate = translate_wsr,
4163 .par = (const uint32_t[]){MISC},
4164 }, {
4165 .name = "wsr.misc1",
4166 .translate = translate_wsr,
4167 .par = (const uint32_t[]){MISC + 1},
4168 }, {
4169 .name = "wsr.misc2",
4170 .translate = translate_wsr,
4171 .par = (const uint32_t[]){MISC + 2},
4172 }, {
4173 .name = "wsr.misc3",
4174 .translate = translate_wsr,
4175 .par = (const uint32_t[]){MISC + 3},
13f6a7cd
MF
4176 }, {
4177 .name = "wsr.mmid",
4178 .translate = translate_wsr,
4179 .par = (const uint32_t[]){MMID},
168c12b0
MF
4180 }, {
4181 .name = "wsr.prid",
4182 .translate = translate_wsr,
4183 .par = (const uint32_t[]){PRID},
4184 }, {
4185 .name = "wsr.ps",
4186 .translate = translate_wsr,
4187 .par = (const uint32_t[]){PS},
4188 }, {
4189 .name = "wsr.ptevaddr",
4190 .translate = translate_wsr,
4191 .par = (const uint32_t[]){PTEVADDR},
4192 }, {
4193 .name = "wsr.rasid",
4194 .translate = translate_wsr,
4195 .par = (const uint32_t[]){RASID},
4196 }, {
4197 .name = "wsr.sar",
4198 .translate = translate_wsr,
4199 .par = (const uint32_t[]){SAR},
4200 }, {
4201 .name = "wsr.scompare1",
4202 .translate = translate_wsr,
4203 .par = (const uint32_t[]){SCOMPARE1},
4204 }, {
4205 .name = "wsr.vecbase",
4206 .translate = translate_wsr,
4207 .par = (const uint32_t[]){VECBASE},
4208 }, {
4209 .name = "wsr.windowbase",
4210 .translate = translate_wsr,
4211 .par = (const uint32_t[]){WINDOW_BASE},
4212 }, {
4213 .name = "wsr.windowstart",
4214 .translate = translate_wsr,
4215 .par = (const uint32_t[]){WINDOW_START},
e9872741
MF
4216 }, {
4217 .name = "wur.expstate",
4218 .translate = translate_wur,
4219 .par = (const uint32_t[]){EXPSTATE},
168c12b0
MF
4220 }, {
4221 .name = "wur.fcr",
4222 .translate = translate_wur,
4223 .par = (const uint32_t[]){FCR},
4224 }, {
4225 .name = "wur.fsr",
4226 .translate = translate_wur,
4227 .par = (const uint32_t[]){FSR},
4228 }, {
4229 .name = "wur.threadptr",
4230 .translate = translate_wur,
4231 .par = (const uint32_t[]){THREADPTR},
4232 }, {
4233 .name = "xor",
4234 .translate = translate_xor,
4235 }, {
4236 .name = "xorb",
4237 .translate = translate_boolean,
4238 .par = (const uint32_t[]){BOOLEAN_XOR},
4239 }, {
4240 .name = "xsr.176",
4241 .translate = translate_xsr,
4242 .par = (const uint32_t[]){176},
4243 }, {
4244 .name = "xsr.208",
4245 .translate = translate_xsr,
4246 .par = (const uint32_t[]){208},
4247 }, {
4248 .name = "xsr.acchi",
4249 .translate = translate_xsr,
4250 .par = (const uint32_t[]){ACCHI},
4251 }, {
4252 .name = "xsr.acclo",
4253 .translate = translate_xsr,
4254 .par = (const uint32_t[]){ACCLO},
4255 }, {
4256 .name = "xsr.atomctl",
4257 .translate = translate_xsr,
4258 .par = (const uint32_t[]){ATOMCTL},
4259 }, {
4260 .name = "xsr.br",
4261 .translate = translate_xsr,
4262 .par = (const uint32_t[]){BR},
4263 }, {
4264 .name = "xsr.cacheattr",
4265 .translate = translate_xsr,
4266 .par = (const uint32_t[]){CACHEATTR},
4267 }, {
4268 .name = "xsr.ccompare0",
4269 .translate = translate_xsr,
4270 .par = (const uint32_t[]){CCOMPARE},
4271 }, {
4272 .name = "xsr.ccompare1",
4273 .translate = translate_xsr,
4274 .par = (const uint32_t[]){CCOMPARE + 1},
4275 }, {
4276 .name = "xsr.ccompare2",
4277 .translate = translate_xsr,
4278 .par = (const uint32_t[]){CCOMPARE + 2},
4279 }, {
4280 .name = "xsr.ccount",
4281 .translate = translate_xsr,
4282 .par = (const uint32_t[]){CCOUNT},
4283 }, {
4284 .name = "xsr.configid0",
4285 .translate = translate_xsr,
4286 .par = (const uint32_t[]){CONFIGID0},
4287 }, {
4288 .name = "xsr.configid1",
4289 .translate = translate_xsr,
4290 .par = (const uint32_t[]){CONFIGID1},
4291 }, {
4292 .name = "xsr.cpenable",
4293 .translate = translate_xsr,
4294 .par = (const uint32_t[]){CPENABLE},
4295 }, {
4296 .name = "xsr.dbreaka0",
4297 .translate = translate_xsr,
4298 .par = (const uint32_t[]){DBREAKA},
4299 }, {
4300 .name = "xsr.dbreaka1",
4301 .translate = translate_xsr,
4302 .par = (const uint32_t[]){DBREAKA + 1},
4303 }, {
4304 .name = "xsr.dbreakc0",
4305 .translate = translate_xsr,
4306 .par = (const uint32_t[]){DBREAKC},
4307 }, {
4308 .name = "xsr.dbreakc1",
4309 .translate = translate_xsr,
4310 .par = (const uint32_t[]){DBREAKC + 1},
13f6a7cd
MF
4311 }, {
4312 .name = "xsr.ddr",
4313 .translate = translate_xsr,
4314 .par = (const uint32_t[]){DDR},
168c12b0
MF
4315 }, {
4316 .name = "xsr.debugcause",
4317 .translate = translate_xsr,
4318 .par = (const uint32_t[]){DEBUGCAUSE},
4319 }, {
4320 .name = "xsr.depc",
4321 .translate = translate_xsr,
4322 .par = (const uint32_t[]){DEPC},
4323 }, {
4324 .name = "xsr.dtlbcfg",
4325 .translate = translate_xsr,
4326 .par = (const uint32_t[]){DTLBCFG},
4327 }, {
4328 .name = "xsr.epc1",
4329 .translate = translate_xsr,
4330 .par = (const uint32_t[]){EPC1},
4331 }, {
4332 .name = "xsr.epc2",
4333 .translate = translate_xsr,
4334 .par = (const uint32_t[]){EPC1 + 1},
4335 }, {
4336 .name = "xsr.epc3",
4337 .translate = translate_xsr,
4338 .par = (const uint32_t[]){EPC1 + 2},
4339 }, {
4340 .name = "xsr.epc4",
4341 .translate = translate_xsr,
4342 .par = (const uint32_t[]){EPC1 + 3},
4343 }, {
4344 .name = "xsr.epc5",
4345 .translate = translate_xsr,
4346 .par = (const uint32_t[]){EPC1 + 4},
4347 }, {
4348 .name = "xsr.epc6",
4349 .translate = translate_xsr,
4350 .par = (const uint32_t[]){EPC1 + 5},
4351 }, {
4352 .name = "xsr.epc7",
4353 .translate = translate_xsr,
4354 .par = (const uint32_t[]){EPC1 + 6},
4355 }, {
4356 .name = "xsr.eps2",
4357 .translate = translate_xsr,
4358 .par = (const uint32_t[]){EPS2},
4359 }, {
4360 .name = "xsr.eps3",
4361 .translate = translate_xsr,
4362 .par = (const uint32_t[]){EPS2 + 1},
4363 }, {
4364 .name = "xsr.eps4",
4365 .translate = translate_xsr,
4366 .par = (const uint32_t[]){EPS2 + 2},
4367 }, {
4368 .name = "xsr.eps5",
4369 .translate = translate_xsr,
4370 .par = (const uint32_t[]){EPS2 + 3},
4371 }, {
4372 .name = "xsr.eps6",
4373 .translate = translate_xsr,
4374 .par = (const uint32_t[]){EPS2 + 4},
4375 }, {
4376 .name = "xsr.eps7",
4377 .translate = translate_xsr,
4378 .par = (const uint32_t[]){EPS2 + 5},
4379 }, {
4380 .name = "xsr.exccause",
4381 .translate = translate_xsr,
4382 .par = (const uint32_t[]){EXCCAUSE},
4383 }, {
4384 .name = "xsr.excsave1",
4385 .translate = translate_xsr,
4386 .par = (const uint32_t[]){EXCSAVE1},
4387 }, {
4388 .name = "xsr.excsave2",
4389 .translate = translate_xsr,
4390 .par = (const uint32_t[]){EXCSAVE1 + 1},
4391 }, {
4392 .name = "xsr.excsave3",
4393 .translate = translate_xsr,
4394 .par = (const uint32_t[]){EXCSAVE1 + 2},
4395 }, {
4396 .name = "xsr.excsave4",
4397 .translate = translate_xsr,
4398 .par = (const uint32_t[]){EXCSAVE1 + 3},
4399 }, {
4400 .name = "xsr.excsave5",
4401 .translate = translate_xsr,
4402 .par = (const uint32_t[]){EXCSAVE1 + 4},
4403 }, {
4404 .name = "xsr.excsave6",
4405 .translate = translate_xsr,
4406 .par = (const uint32_t[]){EXCSAVE1 + 5},
4407 }, {
4408 .name = "xsr.excsave7",
4409 .translate = translate_xsr,
4410 .par = (const uint32_t[]){EXCSAVE1 + 6},
4411 }, {
4412 .name = "xsr.excvaddr",
4413 .translate = translate_xsr,
4414 .par = (const uint32_t[]){EXCVADDR},
4415 }, {
4416 .name = "xsr.ibreaka0",
4417 .translate = translate_xsr,
4418 .par = (const uint32_t[]){IBREAKA},
4419 }, {
4420 .name = "xsr.ibreaka1",
4421 .translate = translate_xsr,
4422 .par = (const uint32_t[]){IBREAKA + 1},
4423 }, {
4424 .name = "xsr.ibreakenable",
4425 .translate = translate_xsr,
4426 .par = (const uint32_t[]){IBREAKENABLE},
4427 }, {
4428 .name = "xsr.icount",
4429 .translate = translate_xsr,
4430 .par = (const uint32_t[]){ICOUNT},
4431 }, {
4432 .name = "xsr.icountlevel",
4433 .translate = translate_xsr,
4434 .par = (const uint32_t[]){ICOUNTLEVEL},
4435 }, {
4436 .name = "xsr.intclear",
4437 .translate = translate_xsr,
4438 .par = (const uint32_t[]){INTCLEAR},
4439 }, {
4440 .name = "xsr.intenable",
4441 .translate = translate_xsr,
4442 .par = (const uint32_t[]){INTENABLE},
4443 }, {
4444 .name = "xsr.interrupt",
4445 .translate = translate_xsr,
4446 .par = (const uint32_t[]){INTSET},
4447 }, {
4448 .name = "xsr.intset",
4449 .translate = translate_xsr,
4450 .par = (const uint32_t[]){INTSET},
4451 }, {
4452 .name = "xsr.itlbcfg",
4453 .translate = translate_xsr,
4454 .par = (const uint32_t[]){ITLBCFG},
4455 }, {
4456 .name = "xsr.lbeg",
4457 .translate = translate_xsr,
4458 .par = (const uint32_t[]){LBEG},
4459 }, {
4460 .name = "xsr.lcount",
4461 .translate = translate_xsr,
4462 .par = (const uint32_t[]){LCOUNT},
4463 }, {
4464 .name = "xsr.lend",
4465 .translate = translate_xsr,
4466 .par = (const uint32_t[]){LEND},
4467 }, {
4468 .name = "xsr.litbase",
4469 .translate = translate_xsr,
4470 .par = (const uint32_t[]){LITBASE},
4471 }, {
4472 .name = "xsr.m0",
4473 .translate = translate_xsr,
4474 .par = (const uint32_t[]){MR},
4475 }, {
4476 .name = "xsr.m1",
4477 .translate = translate_xsr,
4478 .par = (const uint32_t[]){MR + 1},
4479 }, {
4480 .name = "xsr.m2",
4481 .translate = translate_xsr,
4482 .par = (const uint32_t[]){MR + 2},
4483 }, {
4484 .name = "xsr.m3",
4485 .translate = translate_xsr,
4486 .par = (const uint32_t[]){MR + 3},
4487 }, {
4488 .name = "xsr.memctl",
4489 .translate = translate_xsr,
4490 .par = (const uint32_t[]){MEMCTL},
4491 }, {
4492 .name = "xsr.misc0",
4493 .translate = translate_xsr,
4494 .par = (const uint32_t[]){MISC},
4495 }, {
4496 .name = "xsr.misc1",
4497 .translate = translate_xsr,
4498 .par = (const uint32_t[]){MISC + 1},
4499 }, {
4500 .name = "xsr.misc2",
4501 .translate = translate_xsr,
4502 .par = (const uint32_t[]){MISC + 2},
4503 }, {
4504 .name = "xsr.misc3",
4505 .translate = translate_xsr,
4506 .par = (const uint32_t[]){MISC + 3},
4507 }, {
4508 .name = "xsr.prid",
4509 .translate = translate_xsr,
4510 .par = (const uint32_t[]){PRID},
4511 }, {
4512 .name = "xsr.ps",
4513 .translate = translate_xsr,
4514 .par = (const uint32_t[]){PS},
4515 }, {
4516 .name = "xsr.ptevaddr",
4517 .translate = translate_xsr,
4518 .par = (const uint32_t[]){PTEVADDR},
4519 }, {
4520 .name = "xsr.rasid",
4521 .translate = translate_xsr,
4522 .par = (const uint32_t[]){RASID},
4523 }, {
4524 .name = "xsr.sar",
4525 .translate = translate_xsr,
4526 .par = (const uint32_t[]){SAR},
4527 }, {
4528 .name = "xsr.scompare1",
4529 .translate = translate_xsr,
4530 .par = (const uint32_t[]){SCOMPARE1},
4531 }, {
4532 .name = "xsr.vecbase",
4533 .translate = translate_xsr,
4534 .par = (const uint32_t[]){VECBASE},
4535 }, {
4536 .name = "xsr.windowbase",
4537 .translate = translate_xsr,
4538 .par = (const uint32_t[]){WINDOW_BASE},
4539 }, {
4540 .name = "xsr.windowstart",
4541 .translate = translate_xsr,
4542 .par = (const uint32_t[]){WINDOW_START},
4543 },
4544};
4545
4546const XtensaOpcodeTranslators xtensa_core_opcodes = {
4547 .num_opcodes = ARRAY_SIZE(core_ops),
4548 .opcode = core_ops,
4549};
c04e1692
MF
4550
4551
4552static void translate_abs_s(DisasContext *dc, const uint32_t arg[],
4553 const uint32_t par[])
4554{
4555 if (gen_check_cpenable(dc, 0)) {
4556 gen_helper_abs_s(cpu_FR[arg[0]], cpu_FR[arg[1]]);
4557 }
4558}
4559
4560static void translate_add_s(DisasContext *dc, const uint32_t arg[],
4561 const uint32_t par[])
4562{
4563 if (gen_check_cpenable(dc, 0)) {
4564 gen_helper_add_s(cpu_FR[arg[0]], cpu_env,
4565 cpu_FR[arg[1]], cpu_FR[arg[2]]);
4566 }
4567}
4568
4569enum {
4570 COMPARE_UN,
4571 COMPARE_OEQ,
4572 COMPARE_UEQ,
4573 COMPARE_OLT,
4574 COMPARE_ULT,
4575 COMPARE_OLE,
4576 COMPARE_ULE,
4577};
4578
4579static void translate_compare_s(DisasContext *dc, const uint32_t arg[],
4580 const uint32_t par[])
4581{
4582 static void (* const helper[])(TCGv_env env, TCGv_i32 bit,
4583 TCGv_i32 s, TCGv_i32 t) = {
4584 [COMPARE_UN] = gen_helper_un_s,
4585 [COMPARE_OEQ] = gen_helper_oeq_s,
4586 [COMPARE_UEQ] = gen_helper_ueq_s,
4587 [COMPARE_OLT] = gen_helper_olt_s,
4588 [COMPARE_ULT] = gen_helper_ult_s,
4589 [COMPARE_OLE] = gen_helper_ole_s,
4590 [COMPARE_ULE] = gen_helper_ule_s,
4591 };
4592
4593 if (gen_check_cpenable(dc, 0)) {
4594 TCGv_i32 bit = tcg_const_i32(1 << arg[0]);
4595
4596 helper[par[0]](cpu_env, bit, cpu_FR[arg[1]], cpu_FR[arg[2]]);
4597 tcg_temp_free(bit);
4598 }
4599}
4600
4601static void translate_float_s(DisasContext *dc, const uint32_t arg[],
4602 const uint32_t par[])
4603{
4604 if (gen_window_check1(dc, arg[1]) && gen_check_cpenable(dc, 0)) {
4605 TCGv_i32 scale = tcg_const_i32(-arg[2]);
4606
4607 if (par[0]) {
4608 gen_helper_uitof(cpu_FR[arg[0]], cpu_env, cpu_R[arg[1]], scale);
4609 } else {
4610 gen_helper_itof(cpu_FR[arg[0]], cpu_env, cpu_R[arg[1]], scale);
4611 }
4612 tcg_temp_free(scale);
4613 }
4614}
4615
4616static void translate_ftoi_s(DisasContext *dc, const uint32_t arg[],
4617 const uint32_t par[])
4618{
4619 if (gen_window_check1(dc, arg[0]) && gen_check_cpenable(dc, 0)) {
4620 TCGv_i32 rounding_mode = tcg_const_i32(par[0]);
4621 TCGv_i32 scale = tcg_const_i32(arg[2]);
4622
4623 if (par[1]) {
4624 gen_helper_ftoui(cpu_R[arg[0]], cpu_FR[arg[1]],
4625 rounding_mode, scale);
4626 } else {
4627 gen_helper_ftoi(cpu_R[arg[0]], cpu_FR[arg[1]],
4628 rounding_mode, scale);
4629 }
4630 tcg_temp_free(rounding_mode);
4631 tcg_temp_free(scale);
4632 }
4633}
4634
4635static void translate_ldsti(DisasContext *dc, const uint32_t arg[],
4636 const uint32_t par[])
4637{
4638 if (gen_window_check1(dc, arg[1]) && gen_check_cpenable(dc, 0)) {
4639 TCGv_i32 addr = tcg_temp_new_i32();
4640
4641 tcg_gen_addi_i32(addr, cpu_R[arg[1]], arg[2]);
4642 gen_load_store_alignment(dc, 2, addr, false);
4643 if (par[0]) {
4644 tcg_gen_qemu_st32(cpu_FR[arg[0]], addr, dc->cring);
4645 } else {
4646 tcg_gen_qemu_ld32u(cpu_FR[arg[0]], addr, dc->cring);
4647 }
4648 if (par[1]) {
4649 tcg_gen_mov_i32(cpu_R[arg[1]], addr);
4650 }
4651 tcg_temp_free(addr);
4652 }
4653}
4654
4655static void translate_ldstx(DisasContext *dc, const uint32_t arg[],
4656 const uint32_t par[])
4657{
4658 if (gen_window_check2(dc, arg[1], arg[2]) && gen_check_cpenable(dc, 0)) {
4659 TCGv_i32 addr = tcg_temp_new_i32();
4660
4661 tcg_gen_add_i32(addr, cpu_R[arg[1]], cpu_R[arg[2]]);
4662 gen_load_store_alignment(dc, 2, addr, false);
4663 if (par[0]) {
4664 tcg_gen_qemu_st32(cpu_FR[arg[0]], addr, dc->cring);
4665 } else {
4666 tcg_gen_qemu_ld32u(cpu_FR[arg[0]], addr, dc->cring);
4667 }
4668 if (par[1]) {
4669 tcg_gen_mov_i32(cpu_R[arg[1]], addr);
4670 }
4671 tcg_temp_free(addr);
4672 }
4673}
4674
4675static void translate_madd_s(DisasContext *dc, const uint32_t arg[],
4676 const uint32_t par[])
4677{
4678 if (gen_check_cpenable(dc, 0)) {
4679 gen_helper_madd_s(cpu_FR[arg[0]], cpu_env,
4680 cpu_FR[arg[0]], cpu_FR[arg[1]], cpu_FR[arg[2]]);
4681 }
4682}
4683
4684static void translate_mov_s(DisasContext *dc, const uint32_t arg[],
4685 const uint32_t par[])
4686{
4687 if (gen_check_cpenable(dc, 0)) {
4688 tcg_gen_mov_i32(cpu_FR[arg[0]], cpu_FR[arg[1]]);
4689 }
4690}
4691
4692static void translate_movcond_s(DisasContext *dc, const uint32_t arg[],
4693 const uint32_t par[])
4694{
4695 if (gen_window_check1(dc, arg[2]) && gen_check_cpenable(dc, 0)) {
4696 TCGv_i32 zero = tcg_const_i32(0);
4697
4698 tcg_gen_movcond_i32(par[0], cpu_FR[arg[0]],
4699 cpu_R[arg[2]], zero,
4700 cpu_FR[arg[1]], cpu_FR[arg[2]]);
4701 tcg_temp_free(zero);
4702 }
4703}
4704
4705static void translate_movp_s(DisasContext *dc, const uint32_t arg[],
4706 const uint32_t par[])
4707{
4708 if (gen_check_cpenable(dc, 0)) {
4709 TCGv_i32 zero = tcg_const_i32(0);
4710 TCGv_i32 tmp = tcg_temp_new_i32();
4711
4712 tcg_gen_andi_i32(tmp, cpu_SR[BR], 1 << arg[2]);
4713 tcg_gen_movcond_i32(par[0],
4714 cpu_FR[arg[0]], tmp, zero,
4715 cpu_FR[arg[1]], cpu_FR[arg[0]]);
4716 tcg_temp_free(tmp);
4717 tcg_temp_free(zero);
4718 }
4719}
4720
4721static void translate_mul_s(DisasContext *dc, const uint32_t arg[],
4722 const uint32_t par[])
4723{
4724 if (gen_check_cpenable(dc, 0)) {
4725 gen_helper_mul_s(cpu_FR[arg[0]], cpu_env,
4726 cpu_FR[arg[1]], cpu_FR[arg[2]]);
4727 }
4728}
4729
4730static void translate_msub_s(DisasContext *dc, const uint32_t arg[],
4731 const uint32_t par[])
4732{
4733 if (gen_check_cpenable(dc, 0)) {
4734 gen_helper_msub_s(cpu_FR[arg[0]], cpu_env,
4735 cpu_FR[arg[0]], cpu_FR[arg[1]], cpu_FR[arg[2]]);
4736 }
4737}
4738
4739static void translate_neg_s(DisasContext *dc, const uint32_t arg[],
4740 const uint32_t par[])
4741{
4742 if (gen_check_cpenable(dc, 0)) {
4743 gen_helper_neg_s(cpu_FR[arg[0]], cpu_FR[arg[1]]);
4744 }
4745}
4746
4747static void translate_rfr_s(DisasContext *dc, const uint32_t arg[],
4748 const uint32_t par[])
4749{
4750 if (gen_window_check1(dc, arg[0]) &&
4751 gen_check_cpenable(dc, 0)) {
4752 tcg_gen_mov_i32(cpu_R[arg[0]], cpu_FR[arg[1]]);
4753 }
4754}
4755
4756static void translate_sub_s(DisasContext *dc, const uint32_t arg[],
4757 const uint32_t par[])
4758{
4759 if (gen_check_cpenable(dc, 0)) {
4760 gen_helper_sub_s(cpu_FR[arg[0]], cpu_env,
4761 cpu_FR[arg[1]], cpu_FR[arg[2]]);
4762 }
4763}
4764
4765static void translate_wfr_s(DisasContext *dc, const uint32_t arg[],
4766 const uint32_t par[])
4767{
4768 if (gen_window_check1(dc, arg[1]) &&
4769 gen_check_cpenable(dc, 0)) {
4770 tcg_gen_mov_i32(cpu_FR[arg[0]], cpu_R[arg[1]]);
4771 }
4772}
4773
4774static const XtensaOpcodeOps fpu2000_ops[] = {
4775 {
4776 .name = "abs.s",
4777 .translate = translate_abs_s,
4778 }, {
4779 .name = "add.s",
4780 .translate = translate_add_s,
4781 }, {
4782 .name = "ceil.s",
4783 .translate = translate_ftoi_s,
4784 .par = (const uint32_t[]){float_round_up, false},
4785 }, {
4786 .name = "float.s",
4787 .translate = translate_float_s,
4788 .par = (const uint32_t[]){false},
4789 }, {
4790 .name = "floor.s",
4791 .translate = translate_ftoi_s,
4792 .par = (const uint32_t[]){float_round_down, false},
4793 }, {
4794 .name = "lsi",
4795 .translate = translate_ldsti,
4796 .par = (const uint32_t[]){false, false},
4797 }, {
4798 .name = "lsiu",
4799 .translate = translate_ldsti,
4800 .par = (const uint32_t[]){false, true},
4801 }, {
4802 .name = "lsx",
4803 .translate = translate_ldstx,
4804 .par = (const uint32_t[]){false, false},
4805 }, {
4806 .name = "lsxu",
4807 .translate = translate_ldstx,
4808 .par = (const uint32_t[]){false, true},
4809 }, {
4810 .name = "madd.s",
4811 .translate = translate_madd_s,
4812 }, {
4813 .name = "mov.s",
4814 .translate = translate_mov_s,
4815 }, {
4816 .name = "moveqz.s",
4817 .translate = translate_movcond_s,
4818 .par = (const uint32_t[]){TCG_COND_EQ},
4819 }, {
4820 .name = "movf.s",
4821 .translate = translate_movp_s,
4822 .par = (const uint32_t[]){TCG_COND_EQ},
4823 }, {
4824 .name = "movgez.s",
4825 .translate = translate_movcond_s,
4826 .par = (const uint32_t[]){TCG_COND_GE},
4827 }, {
4828 .name = "movltz.s",
4829 .translate = translate_movcond_s,
4830 .par = (const uint32_t[]){TCG_COND_LT},
4831 }, {
4832 .name = "movnez.s",
4833 .translate = translate_movcond_s,
4834 .par = (const uint32_t[]){TCG_COND_NE},
4835 }, {
4836 .name = "movt.s",
4837 .translate = translate_movp_s,
4838 .par = (const uint32_t[]){TCG_COND_NE},
4839 }, {
4840 .name = "msub.s",
4841 .translate = translate_msub_s,
4842 }, {
4843 .name = "mul.s",
4844 .translate = translate_mul_s,
4845 }, {
4846 .name = "neg.s",
4847 .translate = translate_neg_s,
4848 }, {
4849 .name = "oeq.s",
4850 .translate = translate_compare_s,
4851 .par = (const uint32_t[]){COMPARE_OEQ},
4852 }, {
4853 .name = "ole.s",
4854 .translate = translate_compare_s,
4855 .par = (const uint32_t[]){COMPARE_OLE},
4856 }, {
4857 .name = "olt.s",
4858 .translate = translate_compare_s,
4859 .par = (const uint32_t[]){COMPARE_OLT},
4860 }, {
4861 .name = "rfr.s",
4862 .translate = translate_rfr_s,
4863 }, {
4864 .name = "round.s",
4865 .translate = translate_ftoi_s,
4866 .par = (const uint32_t[]){float_round_nearest_even, false},
4867 }, {
4868 .name = "ssi",
4869 .translate = translate_ldsti,
4870 .par = (const uint32_t[]){true, false},
4871 }, {
4872 .name = "ssiu",
4873 .translate = translate_ldsti,
4874 .par = (const uint32_t[]){true, true},
4875 }, {
4876 .name = "ssx",
4877 .translate = translate_ldstx,
4878 .par = (const uint32_t[]){true, false},
4879 }, {
4880 .name = "ssxu",
4881 .translate = translate_ldstx,
4882 .par = (const uint32_t[]){true, true},
4883 }, {
4884 .name = "sub.s",
4885 .translate = translate_sub_s,
4886 }, {
4887 .name = "trunc.s",
4888 .translate = translate_ftoi_s,
4889 .par = (const uint32_t[]){float_round_to_zero, false},
4890 }, {
4891 .name = "ueq.s",
4892 .translate = translate_compare_s,
4893 .par = (const uint32_t[]){COMPARE_UEQ},
4894 }, {
4895 .name = "ufloat.s",
4896 .translate = translate_float_s,
4897 .par = (const uint32_t[]){true},
4898 }, {
4899 .name = "ule.s",
4900 .translate = translate_compare_s,
4901 .par = (const uint32_t[]){COMPARE_ULE},
4902 }, {
4903 .name = "ult.s",
4904 .translate = translate_compare_s,
4905 .par = (const uint32_t[]){COMPARE_ULT},
4906 }, {
4907 .name = "un.s",
4908 .translate = translate_compare_s,
4909 .par = (const uint32_t[]){COMPARE_UN},
4910 }, {
4911 .name = "utrunc.s",
4912 .translate = translate_ftoi_s,
4913 .par = (const uint32_t[]){float_round_to_zero, true},
4914 }, {
4915 .name = "wfr.s",
4916 .translate = translate_wfr_s,
4917 },
4918};
4919
4920const XtensaOpcodeTranslators xtensa_fpu2000_opcodes = {
4921 .num_opcodes = ARRAY_SIZE(fpu2000_ops),
4922 .opcode = fpu2000_ops,
4923};
This page took 1.115779 seconds and 4 git commands to generate.