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