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/tcg-op.h"
37 #include "qemu/log.h"
38 #include "qemu/qemu-print.h"
39 #include "exec/cpu_ldst.h"
40 #include "semihosting/semihost.h"
41 #include "exec/translator.h"
42
43 #include "exec/helper-proto.h"
44 #include "exec/helper-gen.h"
45
46 #include "exec/log.h"
47
48 #define HELPER_H "helper.h"
49 #include "exec/helper-info.c.inc"
50 #undef HELPER_H
51
52
53 struct DisasContext {
54 DisasContextBase base;
55 const XtensaConfig *config;
56 uint32_t pc;
57 int cring;
58 int ring;
59 uint32_t lbeg_off;
60 uint32_t lend;
61
62 bool sar_5bit;
63 bool sar_m32_5bit;
64 TCGv_i32 sar_m32;
65
66 unsigned window;
67 unsigned callinc;
68 bool cwoe;
69
70 bool debug;
71 bool icount;
72 TCGv_i32 next_icount;
73
74 unsigned cpenable;
75
76 uint32_t op_flags;
77 xtensa_insnbuf_word insnbuf[MAX_INSNBUF_LENGTH];
78 xtensa_insnbuf_word slotbuf[MAX_INSNBUF_LENGTH];
79 };
80
81 static TCGv_i32 cpu_pc;
82 static TCGv_i32 cpu_R[16];
83 static TCGv_i32 cpu_FR[16];
84 static TCGv_i64 cpu_FRD[16];
85 static TCGv_i32 cpu_MR[4];
86 static TCGv_i32 cpu_BR[16];
87 static TCGv_i32 cpu_BR4[4];
88 static TCGv_i32 cpu_BR8[2];
89 static TCGv_i32 cpu_SR[256];
90 static TCGv_i32 cpu_UR[256];
91 static TCGv_i32 cpu_windowbase_next;
92 static TCGv_i32 cpu_exclusive_addr;
93 static TCGv_i32 cpu_exclusive_val;
94
95 static GHashTable *xtensa_regfile_table;
96
97 static char *sr_name[256];
98 static char *ur_name[256];
99
xtensa_collect_sr_names(const XtensaConfig * config)100 void xtensa_collect_sr_names(const XtensaConfig *config)
101 {
102 xtensa_isa isa = config->isa;
103 int n = xtensa_isa_num_sysregs(isa);
104 int i;
105
106 for (i = 0; i < n; ++i) {
107 int sr = xtensa_sysreg_number(isa, i);
108
109 if (sr >= 0 && sr < 256) {
110 const char *name = xtensa_sysreg_name(isa, i);
111 char **pname =
112 (xtensa_sysreg_is_user(isa, i) ? ur_name : sr_name) + sr;
113
114 if (*pname) {
115 if (strstr(*pname, name) == NULL) {
116 char *new_name =
117 malloc(strlen(*pname) + strlen(name) + 2);
118
119 strcpy(new_name, *pname);
120 strcat(new_name, "/");
121 strcat(new_name, name);
122 free(*pname);
123 *pname = new_name;
124 }
125 } else {
126 *pname = strdup(name);
127 }
128 }
129 }
130 }
131
xtensa_translate_init(void)132 void xtensa_translate_init(void)
133 {
134 static const char * const regnames[] = {
135 "ar0", "ar1", "ar2", "ar3",
136 "ar4", "ar5", "ar6", "ar7",
137 "ar8", "ar9", "ar10", "ar11",
138 "ar12", "ar13", "ar14", "ar15",
139 };
140 static const char * const fregnames[] = {
141 "f0", "f1", "f2", "f3",
142 "f4", "f5", "f6", "f7",
143 "f8", "f9", "f10", "f11",
144 "f12", "f13", "f14", "f15",
145 };
146 static const char * const mregnames[] = {
147 "m0", "m1", "m2", "m3",
148 };
149 static const char * const bregnames[] = {
150 "b0", "b1", "b2", "b3",
151 "b4", "b5", "b6", "b7",
152 "b8", "b9", "b10", "b11",
153 "b12", "b13", "b14", "b15",
154 };
155 int i;
156
157 cpu_pc = tcg_global_mem_new_i32(tcg_env,
158 offsetof(CPUXtensaState, pc), "pc");
159
160 for (i = 0; i < 16; i++) {
161 cpu_R[i] = tcg_global_mem_new_i32(tcg_env,
162 offsetof(CPUXtensaState, regs[i]),
163 regnames[i]);
164 }
165
166 for (i = 0; i < 16; i++) {
167 cpu_FR[i] = tcg_global_mem_new_i32(tcg_env,
168 offsetof(CPUXtensaState,
169 fregs[i].f32[FP_F32_LOW]),
170 fregnames[i]);
171 }
172
173 for (i = 0; i < 16; i++) {
174 cpu_FRD[i] = tcg_global_mem_new_i64(tcg_env,
175 offsetof(CPUXtensaState,
176 fregs[i].f64),
177 fregnames[i]);
178 }
179
180 for (i = 0; i < 4; i++) {
181 cpu_MR[i] = tcg_global_mem_new_i32(tcg_env,
182 offsetof(CPUXtensaState,
183 sregs[MR + i]),
184 mregnames[i]);
185 }
186
187 for (i = 0; i < 16; i++) {
188 cpu_BR[i] = tcg_global_mem_new_i32(tcg_env,
189 offsetof(CPUXtensaState,
190 sregs[BR]),
191 bregnames[i]);
192 if (i % 4 == 0) {
193 cpu_BR4[i / 4] = tcg_global_mem_new_i32(tcg_env,
194 offsetof(CPUXtensaState,
195 sregs[BR]),
196 bregnames[i]);
197 }
198 if (i % 8 == 0) {
199 cpu_BR8[i / 8] = tcg_global_mem_new_i32(tcg_env,
200 offsetof(CPUXtensaState,
201 sregs[BR]),
202 bregnames[i]);
203 }
204 }
205
206 for (i = 0; i < 256; ++i) {
207 if (sr_name[i]) {
208 cpu_SR[i] = tcg_global_mem_new_i32(tcg_env,
209 offsetof(CPUXtensaState,
210 sregs[i]),
211 sr_name[i]);
212 }
213 }
214
215 for (i = 0; i < 256; ++i) {
216 if (ur_name[i]) {
217 cpu_UR[i] = tcg_global_mem_new_i32(tcg_env,
218 offsetof(CPUXtensaState,
219 uregs[i]),
220 ur_name[i]);
221 }
222 }
223
224 cpu_windowbase_next =
225 tcg_global_mem_new_i32(tcg_env,
226 offsetof(CPUXtensaState, windowbase_next),
227 "windowbase_next");
228 cpu_exclusive_addr =
229 tcg_global_mem_new_i32(tcg_env,
230 offsetof(CPUXtensaState, exclusive_addr),
231 "exclusive_addr");
232 cpu_exclusive_val =
233 tcg_global_mem_new_i32(tcg_env,
234 offsetof(CPUXtensaState, exclusive_val),
235 "exclusive_val");
236 }
237
xtensa_get_regfile_by_name(const char * name,int entries,int bits)238 void **xtensa_get_regfile_by_name(const char *name, int entries, int bits)
239 {
240 char *geometry_name;
241 void **res;
242
243 if (xtensa_regfile_table == NULL) {
244 xtensa_regfile_table = g_hash_table_new(g_str_hash, g_str_equal);
245 /*
246 * AR is special. Xtensa translator uses it as a current register
247 * window, but configuration overlays represent it as a complete
248 * physical register file.
249 */
250 g_hash_table_insert(xtensa_regfile_table,
251 (void *)"AR 16x32", (void *)cpu_R);
252 g_hash_table_insert(xtensa_regfile_table,
253 (void *)"AR 32x32", (void *)cpu_R);
254 g_hash_table_insert(xtensa_regfile_table,
255 (void *)"AR 64x32", (void *)cpu_R);
256
257 g_hash_table_insert(xtensa_regfile_table,
258 (void *)"MR 4x32", (void *)cpu_MR);
259
260 g_hash_table_insert(xtensa_regfile_table,
261 (void *)"FR 16x32", (void *)cpu_FR);
262 g_hash_table_insert(xtensa_regfile_table,
263 (void *)"FR 16x64", (void *)cpu_FRD);
264
265 g_hash_table_insert(xtensa_regfile_table,
266 (void *)"BR 16x1", (void *)cpu_BR);
267 g_hash_table_insert(xtensa_regfile_table,
268 (void *)"BR4 4x4", (void *)cpu_BR4);
269 g_hash_table_insert(xtensa_regfile_table,
270 (void *)"BR8 2x8", (void *)cpu_BR8);
271 }
272
273 geometry_name = g_strdup_printf("%s %dx%d", name, entries, bits);
274 res = (void **)g_hash_table_lookup(xtensa_regfile_table, geometry_name);
275 g_free(geometry_name);
276 return res;
277 }
278
option_enabled(DisasContext * dc,int opt)279 static inline bool option_enabled(DisasContext *dc, int opt)
280 {
281 return xtensa_option_enabled(dc->config, opt);
282 }
283
init_sar_tracker(DisasContext * dc)284 static void init_sar_tracker(DisasContext *dc)
285 {
286 dc->sar_5bit = false;
287 dc->sar_m32_5bit = false;
288 dc->sar_m32 = NULL;
289 }
290
gen_right_shift_sar(DisasContext * dc,TCGv_i32 sa)291 static void gen_right_shift_sar(DisasContext *dc, TCGv_i32 sa)
292 {
293 tcg_gen_andi_i32(cpu_SR[SAR], sa, 0x1f);
294 if (dc->sar_m32_5bit) {
295 tcg_gen_discard_i32(dc->sar_m32);
296 }
297 dc->sar_5bit = true;
298 dc->sar_m32_5bit = false;
299 }
300
gen_left_shift_sar(DisasContext * dc,TCGv_i32 sa)301 static void gen_left_shift_sar(DisasContext *dc, TCGv_i32 sa)
302 {
303 if (!dc->sar_m32) {
304 dc->sar_m32 = tcg_temp_new_i32();
305 }
306 tcg_gen_andi_i32(dc->sar_m32, sa, 0x1f);
307 tcg_gen_sub_i32(cpu_SR[SAR], tcg_constant_i32(32), dc->sar_m32);
308 dc->sar_5bit = false;
309 dc->sar_m32_5bit = true;
310 }
311
gen_exception(DisasContext * dc,int excp)312 static void gen_exception(DisasContext *dc, int excp)
313 {
314 gen_helper_exception(tcg_env, tcg_constant_i32(excp));
315 }
316
gen_exception_cause(DisasContext * dc,uint32_t cause)317 static void gen_exception_cause(DisasContext *dc, uint32_t cause)
318 {
319 TCGv_i32 pc = tcg_constant_i32(dc->pc);
320 gen_helper_exception_cause(tcg_env, pc, tcg_constant_i32(cause));
321 if (cause == ILLEGAL_INSTRUCTION_CAUSE ||
322 cause == SYSCALL_CAUSE) {
323 dc->base.is_jmp = DISAS_NORETURN;
324 }
325 }
326
gen_debug_exception(DisasContext * dc,uint32_t cause)327 static void gen_debug_exception(DisasContext *dc, uint32_t cause)
328 {
329 TCGv_i32 pc = tcg_constant_i32(dc->pc);
330 gen_helper_debug_exception(tcg_env, pc, tcg_constant_i32(cause));
331 if (cause & (DEBUGCAUSE_IB | DEBUGCAUSE_BI | DEBUGCAUSE_BN)) {
332 dc->base.is_jmp = DISAS_NORETURN;
333 }
334 }
335
gen_check_privilege(DisasContext * dc)336 static bool gen_check_privilege(DisasContext *dc)
337 {
338 #ifndef CONFIG_USER_ONLY
339 if (!dc->cring) {
340 return true;
341 }
342 #endif
343 gen_exception_cause(dc, PRIVILEGED_CAUSE);
344 dc->base.is_jmp = DISAS_NORETURN;
345 return false;
346 }
347
gen_check_cpenable(DisasContext * dc,uint32_t cp_mask)348 static bool gen_check_cpenable(DisasContext *dc, uint32_t cp_mask)
349 {
350 cp_mask &= ~dc->cpenable;
351
352 if (option_enabled(dc, XTENSA_OPTION_COPROCESSOR) && cp_mask) {
353 gen_exception_cause(dc, COPROCESSOR0_DISABLED + ctz32(cp_mask));
354 dc->base.is_jmp = DISAS_NORETURN;
355 return false;
356 }
357 return true;
358 }
359
360 static int gen_postprocess(DisasContext *dc, int slot);
361
gen_jump_slot(DisasContext * dc,TCGv dest,int slot)362 static void gen_jump_slot(DisasContext *dc, TCGv dest, int slot)
363 {
364 tcg_gen_mov_i32(cpu_pc, dest);
365 if (dc->icount) {
366 tcg_gen_mov_i32(cpu_SR[ICOUNT], dc->next_icount);
367 }
368 if (dc->op_flags & XTENSA_OP_POSTPROCESS) {
369 slot = gen_postprocess(dc, slot);
370 }
371 if (slot >= 0) {
372 tcg_gen_goto_tb(slot);
373 tcg_gen_exit_tb(dc->base.tb, slot);
374 } else {
375 tcg_gen_exit_tb(NULL, 0);
376 }
377 dc->base.is_jmp = DISAS_NORETURN;
378 }
379
gen_jump(DisasContext * dc,TCGv dest)380 static void gen_jump(DisasContext *dc, TCGv dest)
381 {
382 gen_jump_slot(dc, dest, -1);
383 }
384
adjust_jump_slot(DisasContext * dc,uint32_t dest,int slot)385 static int adjust_jump_slot(DisasContext *dc, uint32_t dest, int slot)
386 {
387 return translator_use_goto_tb(&dc->base, dest) ? slot : -1;
388 }
389
gen_jumpi(DisasContext * dc,uint32_t dest,int slot)390 static void gen_jumpi(DisasContext *dc, uint32_t dest, int slot)
391 {
392 gen_jump_slot(dc, tcg_constant_i32(dest),
393 adjust_jump_slot(dc, dest, slot));
394 }
395
gen_callw_slot(DisasContext * dc,int callinc,TCGv_i32 dest,int slot)396 static void gen_callw_slot(DisasContext *dc, int callinc, TCGv_i32 dest,
397 int slot)
398 {
399 tcg_gen_deposit_i32(cpu_SR[PS], cpu_SR[PS],
400 tcg_constant_i32(callinc), PS_CALLINC_SHIFT, PS_CALLINC_LEN);
401 tcg_gen_movi_i32(cpu_R[callinc << 2],
402 (callinc << 30) | (dc->base.pc_next & 0x3fffffff));
403 gen_jump_slot(dc, dest, slot);
404 }
405
gen_check_loop_end(DisasContext * dc,int slot)406 static bool gen_check_loop_end(DisasContext *dc, int slot)
407 {
408 if (dc->base.pc_next == dc->lend) {
409 TCGLabel *label = gen_new_label();
410
411 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_SR[LCOUNT], 0, label);
412 tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_SR[LCOUNT], 1);
413 if (dc->lbeg_off) {
414 gen_jumpi(dc, dc->base.pc_next - dc->lbeg_off, slot);
415 } else {
416 gen_jump(dc, cpu_SR[LBEG]);
417 }
418 gen_set_label(label);
419 gen_jumpi(dc, dc->base.pc_next, -1);
420 return true;
421 }
422 return false;
423 }
424
gen_jumpi_check_loop_end(DisasContext * dc,int slot)425 static void gen_jumpi_check_loop_end(DisasContext *dc, int slot)
426 {
427 if (!gen_check_loop_end(dc, slot)) {
428 gen_jumpi(dc, dc->base.pc_next, slot);
429 }
430 }
431
gen_brcond(DisasContext * dc,TCGCond cond,TCGv_i32 t0,TCGv_i32 t1,uint32_t addr)432 static void gen_brcond(DisasContext *dc, TCGCond cond,
433 TCGv_i32 t0, TCGv_i32 t1, uint32_t addr)
434 {
435 TCGLabel *label = gen_new_label();
436
437 tcg_gen_brcond_i32(cond, t0, t1, label);
438 gen_jumpi_check_loop_end(dc, 0);
439 gen_set_label(label);
440 gen_jumpi(dc, addr, 1);
441 }
442
gen_brcondi(DisasContext * dc,TCGCond cond,TCGv_i32 t0,uint32_t t1,uint32_t addr)443 static void gen_brcondi(DisasContext *dc, TCGCond cond,
444 TCGv_i32 t0, uint32_t t1, uint32_t addr)
445 {
446 gen_brcond(dc, cond, t0, tcg_constant_i32(t1), addr);
447 }
448
test_exceptions_sr(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])449 static uint32_t test_exceptions_sr(DisasContext *dc, const OpcodeArg arg[],
450 const uint32_t par[])
451 {
452 return xtensa_option_enabled(dc->config, par[1]) ? 0 : XTENSA_OP_ILL;
453 }
454
test_exceptions_ccompare(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])455 static uint32_t test_exceptions_ccompare(DisasContext *dc,
456 const OpcodeArg arg[],
457 const uint32_t par[])
458 {
459 unsigned n = par[0] - CCOMPARE;
460
461 if (n >= dc->config->nccompare) {
462 return XTENSA_OP_ILL;
463 }
464 return test_exceptions_sr(dc, arg, par);
465 }
466
test_exceptions_dbreak(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])467 static uint32_t test_exceptions_dbreak(DisasContext *dc, const OpcodeArg arg[],
468 const uint32_t par[])
469 {
470 unsigned n = MAX_NDBREAK;
471
472 if (par[0] >= DBREAKA && par[0] < DBREAKA + MAX_NDBREAK) {
473 n = par[0] - DBREAKA;
474 }
475 if (par[0] >= DBREAKC && par[0] < DBREAKC + MAX_NDBREAK) {
476 n = par[0] - DBREAKC;
477 }
478 if (n >= dc->config->ndbreak) {
479 return XTENSA_OP_ILL;
480 }
481 return test_exceptions_sr(dc, arg, par);
482 }
483
test_exceptions_ibreak(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])484 static uint32_t test_exceptions_ibreak(DisasContext *dc, const OpcodeArg arg[],
485 const uint32_t par[])
486 {
487 unsigned n = par[0] - IBREAKA;
488
489 if (n >= dc->config->nibreak) {
490 return XTENSA_OP_ILL;
491 }
492 return test_exceptions_sr(dc, arg, par);
493 }
494
test_exceptions_hpi(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])495 static uint32_t test_exceptions_hpi(DisasContext *dc, const OpcodeArg arg[],
496 const uint32_t par[])
497 {
498 unsigned n = MAX_NLEVEL + 1;
499
500 if (par[0] >= EXCSAVE1 && par[0] < EXCSAVE1 + MAX_NLEVEL) {
501 n = par[0] - EXCSAVE1 + 1;
502 }
503 if (par[0] >= EPC1 && par[0] < EPC1 + MAX_NLEVEL) {
504 n = par[0] - EPC1 + 1;
505 }
506 if (par[0] >= EPS2 && par[0] < EPS2 + MAX_NLEVEL - 1) {
507 n = par[0] - EPS2 + 2;
508 }
509 if (n > dc->config->nlevel) {
510 return XTENSA_OP_ILL;
511 }
512 return test_exceptions_sr(dc, arg, par);
513 }
514
gen_load_store_alignment(DisasContext * dc,MemOp mop,TCGv_i32 addr)515 static MemOp gen_load_store_alignment(DisasContext *dc, MemOp mop,
516 TCGv_i32 addr)
517 {
518 if ((mop & MO_SIZE) == MO_8) {
519 return mop;
520 }
521 if ((mop & MO_AMASK) == MO_UNALN &&
522 !option_enabled(dc, XTENSA_OPTION_HW_ALIGNMENT)) {
523 mop |= MO_ALIGN;
524 }
525 if (!option_enabled(dc, XTENSA_OPTION_UNALIGNED_EXCEPTION)) {
526 tcg_gen_andi_i32(addr, addr, ~0 << get_alignment_bits(mop));
527 }
528 return mop;
529 }
530
gen_window_check(DisasContext * dc,uint32_t mask)531 static bool gen_window_check(DisasContext *dc, uint32_t mask)
532 {
533 unsigned r = 31 - clz32(mask);
534
535 if (r / 4 > dc->window) {
536 TCGv_i32 pc = tcg_constant_i32(dc->pc);
537 TCGv_i32 w = tcg_constant_i32(r / 4);
538
539 gen_helper_window_check(tcg_env, pc, w);
540 dc->base.is_jmp = DISAS_NORETURN;
541 return false;
542 }
543 return true;
544 }
545
gen_mac16_m(TCGv_i32 v,bool hi,bool is_unsigned)546 static TCGv_i32 gen_mac16_m(TCGv_i32 v, bool hi, bool is_unsigned)
547 {
548 TCGv_i32 m = tcg_temp_new_i32();
549
550 if (hi) {
551 (is_unsigned ? tcg_gen_shri_i32 : tcg_gen_sari_i32)(m, v, 16);
552 } else {
553 (is_unsigned ? tcg_gen_ext16u_i32 : tcg_gen_ext16s_i32)(m, v);
554 }
555 return m;
556 }
557
gen_zero_check(DisasContext * dc,const OpcodeArg arg[])558 static void gen_zero_check(DisasContext *dc, const OpcodeArg arg[])
559 {
560 TCGLabel *label = gen_new_label();
561
562 tcg_gen_brcondi_i32(TCG_COND_NE, arg[2].in, 0, label);
563 gen_exception_cause(dc, INTEGER_DIVIDE_BY_ZERO_CAUSE);
564 gen_set_label(label);
565 }
566
xtensa_op0_insn_len(DisasContext * dc,uint8_t op0)567 static inline unsigned xtensa_op0_insn_len(DisasContext *dc, uint8_t op0)
568 {
569 return xtensa_isa_length_from_chars(dc->config->isa, &op0);
570 }
571
gen_postprocess(DisasContext * dc,int slot)572 static int gen_postprocess(DisasContext *dc, int slot)
573 {
574 uint32_t op_flags = dc->op_flags;
575
576 #ifndef CONFIG_USER_ONLY
577 if (op_flags & XTENSA_OP_CHECK_INTERRUPTS) {
578 translator_io_start(&dc->base);
579 gen_helper_check_interrupts(tcg_env);
580 }
581 #endif
582 if (op_flags & XTENSA_OP_SYNC_REGISTER_WINDOW) {
583 gen_helper_sync_windowbase(tcg_env);
584 }
585 if (op_flags & XTENSA_OP_EXIT_TB_M1) {
586 slot = -1;
587 }
588 return slot;
589 }
590
591 struct opcode_arg_copy {
592 uint32_t resource;
593 void *temp;
594 OpcodeArg *arg;
595 };
596
597 struct opcode_arg_info {
598 uint32_t resource;
599 int index;
600 };
601
602 struct slot_prop {
603 XtensaOpcodeOps *ops;
604 OpcodeArg arg[MAX_OPCODE_ARGS];
605 struct opcode_arg_info in[MAX_OPCODE_ARGS];
606 struct opcode_arg_info out[MAX_OPCODE_ARGS];
607 unsigned n_in;
608 unsigned n_out;
609 uint32_t op_flags;
610 };
611
612 enum resource_type {
613 RES_REGFILE,
614 RES_STATE,
615 RES_MAX,
616 };
617
encode_resource(enum resource_type r,unsigned g,unsigned n)618 static uint32_t encode_resource(enum resource_type r, unsigned g, unsigned n)
619 {
620 assert(r < RES_MAX && g < 256 && n < 65536);
621 return (r << 24) | (g << 16) | n;
622 }
623
get_resource_type(uint32_t resource)624 static enum resource_type get_resource_type(uint32_t resource)
625 {
626 return resource >> 24;
627 }
628
629 /*
630 * a depends on b if b must be executed before a,
631 * because a's side effects will destroy b's inputs.
632 */
op_depends_on(const struct slot_prop * a,const struct slot_prop * b)633 static bool op_depends_on(const struct slot_prop *a,
634 const struct slot_prop *b)
635 {
636 unsigned i = 0;
637 unsigned j = 0;
638
639 if (a->op_flags & XTENSA_OP_CONTROL_FLOW) {
640 return true;
641 }
642 if ((a->op_flags & XTENSA_OP_LOAD_STORE) <
643 (b->op_flags & XTENSA_OP_LOAD_STORE)) {
644 return true;
645 }
646 while (i < a->n_out && j < b->n_in) {
647 if (a->out[i].resource < b->in[j].resource) {
648 ++i;
649 } else if (a->out[i].resource > b->in[j].resource) {
650 ++j;
651 } else {
652 return true;
653 }
654 }
655 return false;
656 }
657
658 /*
659 * Try to break a dependency on b, append temporary register copy records
660 * to the end of copy and update n_copy in case of success.
661 * This is not always possible: e.g. control flow must always be the last,
662 * load/store must be first and state dependencies are not supported yet.
663 */
break_dependency(struct slot_prop * a,struct slot_prop * b,struct opcode_arg_copy * copy,unsigned * n_copy)664 static bool break_dependency(struct slot_prop *a,
665 struct slot_prop *b,
666 struct opcode_arg_copy *copy,
667 unsigned *n_copy)
668 {
669 unsigned i = 0;
670 unsigned j = 0;
671 unsigned n = *n_copy;
672 bool rv = false;
673
674 if (a->op_flags & XTENSA_OP_CONTROL_FLOW) {
675 return false;
676 }
677 if ((a->op_flags & XTENSA_OP_LOAD_STORE) <
678 (b->op_flags & XTENSA_OP_LOAD_STORE)) {
679 return false;
680 }
681 while (i < a->n_out && j < b->n_in) {
682 if (a->out[i].resource < b->in[j].resource) {
683 ++i;
684 } else if (a->out[i].resource > b->in[j].resource) {
685 ++j;
686 } else {
687 int index = b->in[j].index;
688
689 if (get_resource_type(a->out[i].resource) != RES_REGFILE ||
690 index < 0) {
691 return false;
692 }
693 copy[n].resource = b->in[j].resource;
694 copy[n].arg = b->arg + index;
695 ++n;
696 ++j;
697 rv = true;
698 }
699 }
700 *n_copy = n;
701 return rv;
702 }
703
704 /*
705 * Calculate evaluation order for slot opcodes.
706 * Build opcode order graph and output its nodes in topological sort order.
707 * An edge a -> b in the graph means that opcode a must be followed by
708 * opcode b.
709 */
tsort(struct slot_prop * slot,struct slot_prop * sorted[],unsigned n,struct opcode_arg_copy * copy,unsigned * n_copy)710 static bool tsort(struct slot_prop *slot,
711 struct slot_prop *sorted[],
712 unsigned n,
713 struct opcode_arg_copy *copy,
714 unsigned *n_copy)
715 {
716 struct tsnode {
717 unsigned n_in_edge;
718 unsigned n_out_edge;
719 unsigned out_edge[MAX_INSN_SLOTS];
720 } node[MAX_INSN_SLOTS];
721
722 unsigned in[MAX_INSN_SLOTS];
723 unsigned i, j;
724 unsigned n_in = 0;
725 unsigned n_out = 0;
726 unsigned n_edge = 0;
727 unsigned in_idx = 0;
728 unsigned node_idx = 0;
729
730 for (i = 0; i < n; ++i) {
731 node[i].n_in_edge = 0;
732 node[i].n_out_edge = 0;
733 }
734
735 for (i = 0; i < n; ++i) {
736 unsigned n_out_edge = 0;
737
738 for (j = 0; j < n; ++j) {
739 if (i != j && op_depends_on(slot + j, slot + i)) {
740 node[i].out_edge[n_out_edge] = j;
741 ++node[j].n_in_edge;
742 ++n_out_edge;
743 ++n_edge;
744 }
745 }
746 node[i].n_out_edge = n_out_edge;
747 }
748
749 for (i = 0; i < n; ++i) {
750 if (!node[i].n_in_edge) {
751 in[n_in] = i;
752 ++n_in;
753 }
754 }
755
756 again:
757 for (; in_idx < n_in; ++in_idx) {
758 i = in[in_idx];
759 sorted[n_out] = slot + i;
760 ++n_out;
761 for (j = 0; j < node[i].n_out_edge; ++j) {
762 --n_edge;
763 if (--node[node[i].out_edge[j]].n_in_edge == 0) {
764 in[n_in] = node[i].out_edge[j];
765 ++n_in;
766 }
767 }
768 }
769 if (n_edge) {
770 for (; node_idx < n; ++node_idx) {
771 struct tsnode *cnode = node + node_idx;
772
773 if (cnode->n_in_edge) {
774 for (j = 0; j < cnode->n_out_edge; ++j) {
775 unsigned k = cnode->out_edge[j];
776
777 if (break_dependency(slot + k, slot + node_idx,
778 copy, n_copy) &&
779 --node[k].n_in_edge == 0) {
780 in[n_in] = k;
781 ++n_in;
782 --n_edge;
783 cnode->out_edge[j] =
784 cnode->out_edge[cnode->n_out_edge - 1];
785 --cnode->n_out_edge;
786 goto again;
787 }
788 }
789 }
790 }
791 }
792 return n_edge == 0;
793 }
794
opcode_add_resource(struct slot_prop * op,uint32_t resource,char direction,int index)795 static void opcode_add_resource(struct slot_prop *op,
796 uint32_t resource, char direction,
797 int index)
798 {
799 switch (direction) {
800 case 'm':
801 case 'i':
802 assert(op->n_in < ARRAY_SIZE(op->in));
803 op->in[op->n_in].resource = resource;
804 op->in[op->n_in].index = index;
805 ++op->n_in;
806 /* fall through */
807 case 'o':
808 if (direction == 'm' || direction == 'o') {
809 assert(op->n_out < ARRAY_SIZE(op->out));
810 op->out[op->n_out].resource = resource;
811 op->out[op->n_out].index = index;
812 ++op->n_out;
813 }
814 break;
815 default:
816 g_assert_not_reached();
817 }
818 }
819
resource_compare(const void * a,const void * b)820 static int resource_compare(const void *a, const void *b)
821 {
822 const struct opcode_arg_info *pa = a;
823 const struct opcode_arg_info *pb = b;
824
825 return pa->resource < pb->resource ?
826 -1 : (pa->resource > pb->resource ? 1 : 0);
827 }
828
arg_copy_compare(const void * a,const void * b)829 static int arg_copy_compare(const void *a, const void *b)
830 {
831 const struct opcode_arg_copy *pa = a;
832 const struct opcode_arg_copy *pb = b;
833
834 return pa->resource < pb->resource ?
835 -1 : (pa->resource > pb->resource ? 1 : 0);
836 }
837
disas_xtensa_insn(CPUXtensaState * env,DisasContext * dc)838 static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
839 {
840 xtensa_isa isa = dc->config->isa;
841 unsigned char b[MAX_INSN_LENGTH] = {translator_ldub(env, &dc->base,
842 dc->pc)};
843 unsigned len = xtensa_op0_insn_len(dc, b[0]);
844 xtensa_format fmt;
845 int slot, slots;
846 unsigned i;
847 uint32_t op_flags = 0;
848 struct slot_prop slot_prop[MAX_INSN_SLOTS];
849 struct slot_prop *ordered[MAX_INSN_SLOTS];
850 struct opcode_arg_copy arg_copy[MAX_INSN_SLOTS * MAX_OPCODE_ARGS];
851 unsigned n_arg_copy = 0;
852 uint32_t debug_cause = 0;
853 uint32_t windowed_register = 0;
854 uint32_t coprocessor = 0;
855
856 if (len == XTENSA_UNDEFINED) {
857 qemu_log_mask(LOG_GUEST_ERROR,
858 "unknown instruction length (pc = %08x)\n",
859 dc->pc);
860 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
861 dc->base.pc_next = dc->pc + 1;
862 return;
863 }
864
865 dc->base.pc_next = dc->pc + len;
866 for (i = 1; i < len; ++i) {
867 b[i] = translator_ldub(env, &dc->base, dc->pc + i);
868 }
869 xtensa_insnbuf_from_chars(isa, dc->insnbuf, b, len);
870 fmt = xtensa_format_decode(isa, dc->insnbuf);
871 if (fmt == XTENSA_UNDEFINED) {
872 qemu_log_mask(LOG_GUEST_ERROR,
873 "unrecognized instruction format (pc = %08x)\n",
874 dc->pc);
875 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
876 return;
877 }
878 slots = xtensa_format_num_slots(isa, fmt);
879 for (slot = 0; slot < slots; ++slot) {
880 xtensa_opcode opc;
881 int opnd, vopnd, opnds;
882 OpcodeArg *arg = slot_prop[slot].arg;
883 XtensaOpcodeOps *ops;
884
885 xtensa_format_get_slot(isa, fmt, slot, dc->insnbuf, dc->slotbuf);
886 opc = xtensa_opcode_decode(isa, fmt, slot, dc->slotbuf);
887 if (opc == XTENSA_UNDEFINED) {
888 qemu_log_mask(LOG_GUEST_ERROR,
889 "unrecognized opcode in slot %d (pc = %08x)\n",
890 slot, dc->pc);
891 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
892 return;
893 }
894 opnds = xtensa_opcode_num_operands(isa, opc);
895
896 for (opnd = vopnd = 0; opnd < opnds; ++opnd) {
897 void **register_file = NULL;
898 xtensa_regfile rf;
899
900 if (xtensa_operand_is_register(isa, opc, opnd)) {
901 rf = xtensa_operand_regfile(isa, opc, opnd);
902 register_file = dc->config->regfile[rf];
903
904 if (rf == dc->config->a_regfile) {
905 uint32_t v;
906
907 xtensa_operand_get_field(isa, opc, opnd, fmt, slot,
908 dc->slotbuf, &v);
909 xtensa_operand_decode(isa, opc, opnd, &v);
910 windowed_register |= 1u << v;
911 }
912 }
913 if (xtensa_operand_is_visible(isa, opc, opnd)) {
914 uint32_t v;
915
916 xtensa_operand_get_field(isa, opc, opnd, fmt, slot,
917 dc->slotbuf, &v);
918 xtensa_operand_decode(isa, opc, opnd, &v);
919 arg[vopnd].raw_imm = v;
920 if (xtensa_operand_is_PCrelative(isa, opc, opnd)) {
921 xtensa_operand_undo_reloc(isa, opc, opnd, &v, dc->pc);
922 }
923 arg[vopnd].imm = v;
924 if (register_file) {
925 arg[vopnd].in = register_file[v];
926 arg[vopnd].out = register_file[v];
927 arg[vopnd].num_bits = xtensa_regfile_num_bits(isa, rf);
928 } else {
929 arg[vopnd].num_bits = 32;
930 }
931 ++vopnd;
932 }
933 }
934 ops = dc->config->opcode_ops[opc];
935 slot_prop[slot].ops = ops;
936
937 if (ops) {
938 op_flags |= ops->op_flags;
939 if (ops->test_exceptions) {
940 op_flags |= ops->test_exceptions(dc, arg, ops->par);
941 }
942 } else {
943 qemu_log_mask(LOG_UNIMP,
944 "unimplemented opcode '%s' in slot %d (pc = %08x)\n",
945 xtensa_opcode_name(isa, opc), slot, dc->pc);
946 op_flags |= XTENSA_OP_ILL;
947 }
948 if (op_flags & XTENSA_OP_ILL) {
949 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
950 return;
951 }
952 if (op_flags & XTENSA_OP_DEBUG_BREAK) {
953 debug_cause |= ops->par[0];
954 }
955 if (ops->test_overflow) {
956 windowed_register |= ops->test_overflow(dc, arg, ops->par);
957 }
958 coprocessor |= ops->coprocessor;
959
960 if (slots > 1) {
961 slot_prop[slot].n_in = 0;
962 slot_prop[slot].n_out = 0;
963 slot_prop[slot].op_flags = ops->op_flags & XTENSA_OP_LOAD_STORE;
964
965 opnds = xtensa_opcode_num_operands(isa, opc);
966
967 for (opnd = vopnd = 0; opnd < opnds; ++opnd) {
968 bool visible = xtensa_operand_is_visible(isa, opc, opnd);
969
970 if (xtensa_operand_is_register(isa, opc, opnd)) {
971 xtensa_regfile rf = xtensa_operand_regfile(isa, opc, opnd);
972 uint32_t v = 0;
973
974 xtensa_operand_get_field(isa, opc, opnd, fmt, slot,
975 dc->slotbuf, &v);
976 xtensa_operand_decode(isa, opc, opnd, &v);
977 opcode_add_resource(slot_prop + slot,
978 encode_resource(RES_REGFILE, rf, v),
979 xtensa_operand_inout(isa, opc, opnd),
980 visible ? vopnd : -1);
981 }
982 if (visible) {
983 ++vopnd;
984 }
985 }
986
987 opnds = xtensa_opcode_num_stateOperands(isa, opc);
988
989 for (opnd = 0; opnd < opnds; ++opnd) {
990 xtensa_state state = xtensa_stateOperand_state(isa, opc, opnd);
991
992 opcode_add_resource(slot_prop + slot,
993 encode_resource(RES_STATE, 0, state),
994 xtensa_stateOperand_inout(isa, opc, opnd),
995 -1);
996 }
997 if (xtensa_opcode_is_branch(isa, opc) ||
998 xtensa_opcode_is_jump(isa, opc) ||
999 xtensa_opcode_is_loop(isa, opc) ||
1000 xtensa_opcode_is_call(isa, opc)) {
1001 slot_prop[slot].op_flags |= XTENSA_OP_CONTROL_FLOW;
1002 }
1003
1004 qsort(slot_prop[slot].in, slot_prop[slot].n_in,
1005 sizeof(slot_prop[slot].in[0]), resource_compare);
1006 qsort(slot_prop[slot].out, slot_prop[slot].n_out,
1007 sizeof(slot_prop[slot].out[0]), resource_compare);
1008 }
1009 }
1010
1011 if (slots > 1) {
1012 if (!tsort(slot_prop, ordered, slots, arg_copy, &n_arg_copy)) {
1013 qemu_log_mask(LOG_UNIMP,
1014 "Circular resource dependencies (pc = %08x)\n",
1015 dc->pc);
1016 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
1017 return;
1018 }
1019 } else {
1020 ordered[0] = slot_prop + 0;
1021 }
1022
1023 if ((op_flags & XTENSA_OP_PRIVILEGED) &&
1024 !gen_check_privilege(dc)) {
1025 return;
1026 }
1027
1028 if (op_flags & XTENSA_OP_SYSCALL) {
1029 gen_exception_cause(dc, SYSCALL_CAUSE);
1030 return;
1031 }
1032
1033 if ((op_flags & XTENSA_OP_DEBUG_BREAK) && dc->debug) {
1034 gen_debug_exception(dc, debug_cause);
1035 return;
1036 }
1037
1038 if (windowed_register && !gen_window_check(dc, windowed_register)) {
1039 return;
1040 }
1041
1042 if (op_flags & XTENSA_OP_UNDERFLOW) {
1043 TCGv_i32 pc = tcg_constant_i32(dc->pc);
1044
1045 gen_helper_test_underflow_retw(tcg_env, pc);
1046 }
1047
1048 if (op_flags & XTENSA_OP_ALLOCA) {
1049 TCGv_i32 pc = tcg_constant_i32(dc->pc);
1050
1051 gen_helper_movsp(tcg_env, pc);
1052 }
1053
1054 if (coprocessor && !gen_check_cpenable(dc, coprocessor)) {
1055 return;
1056 }
1057
1058 if (n_arg_copy) {
1059 uint32_t resource;
1060 void *temp;
1061 unsigned j;
1062
1063 qsort(arg_copy, n_arg_copy, sizeof(*arg_copy), arg_copy_compare);
1064 for (i = j = 0; i < n_arg_copy; ++i) {
1065 if (i == 0 || arg_copy[i].resource != resource) {
1066 resource = arg_copy[i].resource;
1067 if (arg_copy[i].arg->num_bits <= 32) {
1068 temp = tcg_temp_new_i32();
1069 tcg_gen_mov_i32(temp, arg_copy[i].arg->in);
1070 } else if (arg_copy[i].arg->num_bits <= 64) {
1071 temp = tcg_temp_new_i64();
1072 tcg_gen_mov_i64(temp, arg_copy[i].arg->in);
1073 } else {
1074 g_assert_not_reached();
1075 }
1076 arg_copy[i].temp = temp;
1077
1078 if (i != j) {
1079 arg_copy[j] = arg_copy[i];
1080 }
1081 ++j;
1082 }
1083 arg_copy[i].arg->in = temp;
1084 }
1085 n_arg_copy = j;
1086 }
1087
1088 if (op_flags & XTENSA_OP_DIVIDE_BY_ZERO) {
1089 for (slot = 0; slot < slots; ++slot) {
1090 if (slot_prop[slot].ops->op_flags & XTENSA_OP_DIVIDE_BY_ZERO) {
1091 gen_zero_check(dc, slot_prop[slot].arg);
1092 }
1093 }
1094 }
1095
1096 dc->op_flags = op_flags;
1097
1098 for (slot = 0; slot < slots; ++slot) {
1099 struct slot_prop *pslot = ordered[slot];
1100 XtensaOpcodeOps *ops = pslot->ops;
1101
1102 ops->translate(dc, pslot->arg, ops->par);
1103 }
1104
1105 if (dc->base.is_jmp == DISAS_NEXT) {
1106 gen_postprocess(dc, 0);
1107 dc->op_flags = 0;
1108 if (op_flags & XTENSA_OP_EXIT_TB_M1) {
1109 /* Change in mmu index, memory mapping or tb->flags; exit tb */
1110 gen_jumpi_check_loop_end(dc, -1);
1111 } else if (op_flags & XTENSA_OP_EXIT_TB_0) {
1112 gen_jumpi_check_loop_end(dc, 0);
1113 } else {
1114 gen_check_loop_end(dc, 0);
1115 }
1116 }
1117 dc->pc = dc->base.pc_next;
1118 }
1119
xtensa_insn_len(CPUXtensaState * env,DisasContext * dc)1120 static inline unsigned xtensa_insn_len(CPUXtensaState *env, DisasContext *dc)
1121 {
1122 uint8_t b0 = cpu_ldub_code(env, dc->pc);
1123 return xtensa_op0_insn_len(dc, b0);
1124 }
1125
gen_ibreak_check(CPUXtensaState * env,DisasContext * dc)1126 static void gen_ibreak_check(CPUXtensaState *env, DisasContext *dc)
1127 {
1128 unsigned i;
1129
1130 for (i = 0; i < dc->config->nibreak; ++i) {
1131 if ((env->sregs[IBREAKENABLE] & (1 << i)) &&
1132 env->sregs[IBREAKA + i] == dc->pc) {
1133 gen_debug_exception(dc, DEBUGCAUSE_IB);
1134 break;
1135 }
1136 }
1137 }
1138
xtensa_tr_init_disas_context(DisasContextBase * dcbase,CPUState * cpu)1139 static void xtensa_tr_init_disas_context(DisasContextBase *dcbase,
1140 CPUState *cpu)
1141 {
1142 DisasContext *dc = container_of(dcbase, DisasContext, base);
1143 CPUXtensaState *env = cpu_env(cpu);
1144 uint32_t tb_flags = dc->base.tb->flags;
1145
1146 dc->config = env->config;
1147 dc->pc = dc->base.pc_first;
1148 dc->ring = tb_flags & XTENSA_TBFLAG_RING_MASK;
1149 dc->cring = (tb_flags & XTENSA_TBFLAG_EXCM) ? 0 : dc->ring;
1150 dc->lbeg_off = (dc->base.tb->cs_base & XTENSA_CSBASE_LBEG_OFF_MASK) >>
1151 XTENSA_CSBASE_LBEG_OFF_SHIFT;
1152 dc->lend = (dc->base.tb->cs_base & XTENSA_CSBASE_LEND_MASK) +
1153 (dc->base.pc_first & TARGET_PAGE_MASK);
1154 dc->debug = tb_flags & XTENSA_TBFLAG_DEBUG;
1155 dc->icount = tb_flags & XTENSA_TBFLAG_ICOUNT;
1156 dc->cpenable = (tb_flags & XTENSA_TBFLAG_CPENABLE_MASK) >>
1157 XTENSA_TBFLAG_CPENABLE_SHIFT;
1158 dc->window = ((tb_flags & XTENSA_TBFLAG_WINDOW_MASK) >>
1159 XTENSA_TBFLAG_WINDOW_SHIFT);
1160 dc->cwoe = tb_flags & XTENSA_TBFLAG_CWOE;
1161 dc->callinc = ((tb_flags & XTENSA_TBFLAG_CALLINC_MASK) >>
1162 XTENSA_TBFLAG_CALLINC_SHIFT);
1163 init_sar_tracker(dc);
1164 }
1165
xtensa_tr_tb_start(DisasContextBase * dcbase,CPUState * cpu)1166 static void xtensa_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
1167 {
1168 DisasContext *dc = container_of(dcbase, DisasContext, base);
1169
1170 if (dc->icount) {
1171 dc->next_icount = tcg_temp_new_i32();
1172 }
1173 }
1174
xtensa_tr_insn_start(DisasContextBase * dcbase,CPUState * cpu)1175 static void xtensa_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
1176 {
1177 tcg_gen_insn_start(dcbase->pc_next);
1178 }
1179
xtensa_tr_translate_insn(DisasContextBase * dcbase,CPUState * cpu)1180 static void xtensa_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
1181 {
1182 DisasContext *dc = container_of(dcbase, DisasContext, base);
1183 CPUXtensaState *env = cpu_env(cpu);
1184 target_ulong page_start;
1185
1186 /* These two conditions only apply to the first insn in the TB,
1187 but this is the first TranslateOps hook that allows exiting. */
1188 if ((tb_cflags(dc->base.tb) & CF_USE_ICOUNT)
1189 && (dc->base.tb->flags & XTENSA_TBFLAG_YIELD)) {
1190 gen_exception(dc, EXCP_YIELD);
1191 dc->base.pc_next = dc->pc + 1;
1192 dc->base.is_jmp = DISAS_NORETURN;
1193 return;
1194 }
1195
1196 if (dc->icount) {
1197 TCGLabel *label = gen_new_label();
1198
1199 tcg_gen_addi_i32(dc->next_icount, cpu_SR[ICOUNT], 1);
1200 tcg_gen_brcondi_i32(TCG_COND_NE, dc->next_icount, 0, label);
1201 tcg_gen_mov_i32(dc->next_icount, cpu_SR[ICOUNT]);
1202 if (dc->debug) {
1203 gen_debug_exception(dc, DEBUGCAUSE_IC);
1204 }
1205 gen_set_label(label);
1206 }
1207
1208 if (dc->debug) {
1209 gen_ibreak_check(env, dc);
1210 }
1211
1212 disas_xtensa_insn(env, dc);
1213
1214 if (dc->icount) {
1215 tcg_gen_mov_i32(cpu_SR[ICOUNT], dc->next_icount);
1216 }
1217
1218 /* End the TB if the next insn will cross into the next page. */
1219 page_start = dc->base.pc_first & TARGET_PAGE_MASK;
1220 if (dc->base.is_jmp == DISAS_NEXT &&
1221 (dc->pc - page_start >= TARGET_PAGE_SIZE ||
1222 dc->pc - page_start + xtensa_insn_len(env, dc) > TARGET_PAGE_SIZE)) {
1223 dc->base.is_jmp = DISAS_TOO_MANY;
1224 }
1225 }
1226
xtensa_tr_tb_stop(DisasContextBase * dcbase,CPUState * cpu)1227 static void xtensa_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
1228 {
1229 DisasContext *dc = container_of(dcbase, DisasContext, base);
1230
1231 switch (dc->base.is_jmp) {
1232 case DISAS_NORETURN:
1233 break;
1234 case DISAS_TOO_MANY:
1235 gen_jumpi(dc, dc->pc, 0);
1236 break;
1237 default:
1238 g_assert_not_reached();
1239 }
1240 }
1241
xtensa_tr_disas_log(const DisasContextBase * dcbase,CPUState * cpu,FILE * logfile)1242 static void xtensa_tr_disas_log(const DisasContextBase *dcbase,
1243 CPUState *cpu, FILE *logfile)
1244 {
1245 fprintf(logfile, "IN: %s\n", lookup_symbol(dcbase->pc_first));
1246 target_disas(logfile, cpu, dcbase->pc_first, dcbase->tb->size);
1247 }
1248
1249 static const TranslatorOps xtensa_translator_ops = {
1250 .init_disas_context = xtensa_tr_init_disas_context,
1251 .tb_start = xtensa_tr_tb_start,
1252 .insn_start = xtensa_tr_insn_start,
1253 .translate_insn = xtensa_tr_translate_insn,
1254 .tb_stop = xtensa_tr_tb_stop,
1255 .disas_log = xtensa_tr_disas_log,
1256 };
1257
gen_intermediate_code(CPUState * cpu,TranslationBlock * tb,int * max_insns,target_ulong pc,void * host_pc)1258 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
1259 target_ulong pc, void *host_pc)
1260 {
1261 DisasContext dc = {};
1262 translator_loop(cpu, tb, max_insns, pc, host_pc,
1263 &xtensa_translator_ops, &dc.base);
1264 }
1265
xtensa_cpu_dump_state(CPUState * cs,FILE * f,int flags)1266 void xtensa_cpu_dump_state(CPUState *cs, FILE *f, int flags)
1267 {
1268 XtensaCPU *cpu = XTENSA_CPU(cs);
1269 CPUXtensaState *env = &cpu->env;
1270 xtensa_isa isa = env->config->isa;
1271 int i, j;
1272
1273 qemu_fprintf(f, "PC=%08x\n\n", env->pc);
1274
1275 for (i = j = 0; i < xtensa_isa_num_sysregs(isa); ++i) {
1276 const uint32_t *reg =
1277 xtensa_sysreg_is_user(isa, i) ? env->uregs : env->sregs;
1278 int regno = xtensa_sysreg_number(isa, i);
1279
1280 if (regno >= 0) {
1281 qemu_fprintf(f, "%12s=%08x%c",
1282 xtensa_sysreg_name(isa, i),
1283 reg[regno],
1284 (j++ % 4) == 3 ? '\n' : ' ');
1285 }
1286 }
1287
1288 qemu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n");
1289
1290 for (i = 0; i < 16; ++i) {
1291 qemu_fprintf(f, " A%02d=%08x%c",
1292 i, env->regs[i], (i % 4) == 3 ? '\n' : ' ');
1293 }
1294
1295 xtensa_sync_phys_from_window(env);
1296 qemu_fprintf(f, "\n");
1297
1298 for (i = 0; i < env->config->nareg; ++i) {
1299 qemu_fprintf(f, "AR%02d=%08x ", i, env->phys_regs[i]);
1300 if (i % 4 == 3) {
1301 bool ws = (env->sregs[WINDOW_START] & (1 << (i / 4))) != 0;
1302 bool cw = env->sregs[WINDOW_BASE] == i / 4;
1303
1304 qemu_fprintf(f, "%c%c\n", ws ? '<' : ' ', cw ? '=' : ' ');
1305 }
1306 }
1307
1308 if ((flags & CPU_DUMP_FPU) &&
1309 xtensa_option_enabled(env->config, XTENSA_OPTION_FP_COPROCESSOR)) {
1310 qemu_fprintf(f, "\n");
1311
1312 for (i = 0; i < 16; ++i) {
1313 qemu_fprintf(f, "F%02d=%08x (%-+15.8e)%c", i,
1314 float32_val(env->fregs[i].f32[FP_F32_LOW]),
1315 *(float *)(env->fregs[i].f32 + FP_F32_LOW),
1316 (i % 2) == 1 ? '\n' : ' ');
1317 }
1318 }
1319
1320 if ((flags & CPU_DUMP_FPU) &&
1321 xtensa_option_enabled(env->config, XTENSA_OPTION_DFP_COPROCESSOR) &&
1322 !xtensa_option_enabled(env->config, XTENSA_OPTION_DFPU_SINGLE_ONLY)) {
1323 qemu_fprintf(f, "\n");
1324
1325 for (i = 0; i < 16; ++i) {
1326 qemu_fprintf(f, "F%02d=%016"PRIx64" (%-+24.16le)%c", i,
1327 float64_val(env->fregs[i].f64),
1328 *(double *)(&env->fregs[i].f64),
1329 (i % 2) == 1 ? '\n' : ' ');
1330 }
1331 }
1332 }
1333
translate_abs(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1334 static void translate_abs(DisasContext *dc, const OpcodeArg arg[],
1335 const uint32_t par[])
1336 {
1337 tcg_gen_abs_i32(arg[0].out, arg[1].in);
1338 }
1339
translate_add(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1340 static void translate_add(DisasContext *dc, const OpcodeArg arg[],
1341 const uint32_t par[])
1342 {
1343 tcg_gen_add_i32(arg[0].out, arg[1].in, arg[2].in);
1344 }
1345
translate_addi(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1346 static void translate_addi(DisasContext *dc, const OpcodeArg arg[],
1347 const uint32_t par[])
1348 {
1349 tcg_gen_addi_i32(arg[0].out, arg[1].in, arg[2].imm);
1350 }
1351
translate_addx(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1352 static void translate_addx(DisasContext *dc, const OpcodeArg arg[],
1353 const uint32_t par[])
1354 {
1355 TCGv_i32 tmp = tcg_temp_new_i32();
1356 tcg_gen_shli_i32(tmp, arg[1].in, par[0]);
1357 tcg_gen_add_i32(arg[0].out, tmp, arg[2].in);
1358 }
1359
translate_all(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1360 static void translate_all(DisasContext *dc, const OpcodeArg arg[],
1361 const uint32_t par[])
1362 {
1363 uint32_t shift = par[1];
1364 TCGv_i32 mask = tcg_constant_i32(((1 << shift) - 1) << arg[1].imm);
1365 TCGv_i32 tmp = tcg_temp_new_i32();
1366
1367 tcg_gen_and_i32(tmp, arg[1].in, mask);
1368 if (par[0]) {
1369 tcg_gen_addi_i32(tmp, tmp, 1 << arg[1].imm);
1370 } else {
1371 tcg_gen_add_i32(tmp, tmp, mask);
1372 }
1373 tcg_gen_shri_i32(tmp, tmp, arg[1].imm + shift);
1374 tcg_gen_deposit_i32(arg[0].out, arg[0].out,
1375 tmp, arg[0].imm, 1);
1376 }
1377
translate_and(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1378 static void translate_and(DisasContext *dc, const OpcodeArg arg[],
1379 const uint32_t par[])
1380 {
1381 tcg_gen_and_i32(arg[0].out, arg[1].in, arg[2].in);
1382 }
1383
translate_ball(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1384 static void translate_ball(DisasContext *dc, const OpcodeArg arg[],
1385 const uint32_t par[])
1386 {
1387 TCGv_i32 tmp = tcg_temp_new_i32();
1388 tcg_gen_and_i32(tmp, arg[0].in, arg[1].in);
1389 gen_brcond(dc, par[0], tmp, arg[1].in, arg[2].imm);
1390 }
1391
translate_bany(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1392 static void translate_bany(DisasContext *dc, const OpcodeArg arg[],
1393 const uint32_t par[])
1394 {
1395 TCGv_i32 tmp = tcg_temp_new_i32();
1396 tcg_gen_and_i32(tmp, arg[0].in, arg[1].in);
1397 gen_brcondi(dc, par[0], tmp, 0, arg[2].imm);
1398 }
1399
translate_b(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1400 static void translate_b(DisasContext *dc, const OpcodeArg arg[],
1401 const uint32_t par[])
1402 {
1403 gen_brcond(dc, par[0], arg[0].in, arg[1].in, arg[2].imm);
1404 }
1405
translate_bb(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1406 static void translate_bb(DisasContext *dc, const OpcodeArg arg[],
1407 const uint32_t par[])
1408 {
1409 TCGv_i32 tmp = tcg_temp_new_i32();
1410
1411 tcg_gen_andi_i32(tmp, arg[1].in, 0x1f);
1412 if (TARGET_BIG_ENDIAN) {
1413 tcg_gen_shr_i32(tmp, tcg_constant_i32(0x80000000u), tmp);
1414 } else {
1415 tcg_gen_shl_i32(tmp, tcg_constant_i32(0x00000001u), tmp);
1416 }
1417 tcg_gen_and_i32(tmp, arg[0].in, tmp);
1418 gen_brcondi(dc, par[0], tmp, 0, arg[2].imm);
1419 }
1420
translate_bbi(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1421 static void translate_bbi(DisasContext *dc, const OpcodeArg arg[],
1422 const uint32_t par[])
1423 {
1424 TCGv_i32 tmp = tcg_temp_new_i32();
1425 #if TARGET_BIG_ENDIAN
1426 tcg_gen_andi_i32(tmp, arg[0].in, 0x80000000u >> arg[1].imm);
1427 #else
1428 tcg_gen_andi_i32(tmp, arg[0].in, 0x00000001u << arg[1].imm);
1429 #endif
1430 gen_brcondi(dc, par[0], tmp, 0, arg[2].imm);
1431 }
1432
translate_bi(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1433 static void translate_bi(DisasContext *dc, const OpcodeArg arg[],
1434 const uint32_t par[])
1435 {
1436 gen_brcondi(dc, par[0], arg[0].in, arg[1].imm, arg[2].imm);
1437 }
1438
translate_bz(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1439 static void translate_bz(DisasContext *dc, const OpcodeArg arg[],
1440 const uint32_t par[])
1441 {
1442 gen_brcondi(dc, par[0], arg[0].in, 0, arg[1].imm);
1443 }
1444
1445 enum {
1446 BOOLEAN_AND,
1447 BOOLEAN_ANDC,
1448 BOOLEAN_OR,
1449 BOOLEAN_ORC,
1450 BOOLEAN_XOR,
1451 };
1452
translate_boolean(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1453 static void translate_boolean(DisasContext *dc, const OpcodeArg arg[],
1454 const uint32_t par[])
1455 {
1456 static void (* const op[])(TCGv_i32, TCGv_i32, TCGv_i32) = {
1457 [BOOLEAN_AND] = tcg_gen_and_i32,
1458 [BOOLEAN_ANDC] = tcg_gen_andc_i32,
1459 [BOOLEAN_OR] = tcg_gen_or_i32,
1460 [BOOLEAN_ORC] = tcg_gen_orc_i32,
1461 [BOOLEAN_XOR] = tcg_gen_xor_i32,
1462 };
1463
1464 TCGv_i32 tmp1 = tcg_temp_new_i32();
1465 TCGv_i32 tmp2 = tcg_temp_new_i32();
1466
1467 tcg_gen_shri_i32(tmp1, arg[1].in, arg[1].imm);
1468 tcg_gen_shri_i32(tmp2, arg[2].in, arg[2].imm);
1469 op[par[0]](tmp1, tmp1, tmp2);
1470 tcg_gen_deposit_i32(arg[0].out, arg[0].out, tmp1, arg[0].imm, 1);
1471 }
1472
translate_bp(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1473 static void translate_bp(DisasContext *dc, const OpcodeArg arg[],
1474 const uint32_t par[])
1475 {
1476 TCGv_i32 tmp = tcg_temp_new_i32();
1477
1478 tcg_gen_andi_i32(tmp, arg[0].in, 1 << arg[0].imm);
1479 gen_brcondi(dc, par[0], tmp, 0, arg[1].imm);
1480 }
1481
translate_call0(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1482 static void translate_call0(DisasContext *dc, const OpcodeArg arg[],
1483 const uint32_t par[])
1484 {
1485 tcg_gen_movi_i32(cpu_R[0], dc->base.pc_next);
1486 gen_jumpi(dc, arg[0].imm, 0);
1487 }
1488
translate_callw(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1489 static void translate_callw(DisasContext *dc, const OpcodeArg arg[],
1490 const uint32_t par[])
1491 {
1492 TCGv_i32 tmp = tcg_constant_i32(arg[0].imm);
1493 gen_callw_slot(dc, par[0], tmp, adjust_jump_slot(dc, arg[0].imm, 0));
1494 }
1495
translate_callx0(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1496 static void translate_callx0(DisasContext *dc, const OpcodeArg arg[],
1497 const uint32_t par[])
1498 {
1499 TCGv_i32 tmp = tcg_temp_new_i32();
1500 tcg_gen_mov_i32(tmp, arg[0].in);
1501 tcg_gen_movi_i32(cpu_R[0], dc->base.pc_next);
1502 gen_jump(dc, tmp);
1503 }
1504
translate_callxw(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1505 static void translate_callxw(DisasContext *dc, const OpcodeArg arg[],
1506 const uint32_t par[])
1507 {
1508 TCGv_i32 tmp = tcg_temp_new_i32();
1509
1510 tcg_gen_mov_i32(tmp, arg[0].in);
1511 gen_callw_slot(dc, par[0], tmp, -1);
1512 }
1513
translate_clamps(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1514 static void translate_clamps(DisasContext *dc, const OpcodeArg arg[],
1515 const uint32_t par[])
1516 {
1517 TCGv_i32 tmp1 = tcg_constant_i32(-1u << arg[2].imm);
1518 TCGv_i32 tmp2 = tcg_constant_i32((1 << arg[2].imm) - 1);
1519
1520 tcg_gen_smax_i32(arg[0].out, tmp1, arg[1].in);
1521 tcg_gen_smin_i32(arg[0].out, arg[0].out, tmp2);
1522 }
1523
translate_clrb_expstate(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1524 static void translate_clrb_expstate(DisasContext *dc, const OpcodeArg arg[],
1525 const uint32_t par[])
1526 {
1527 /* TODO: GPIO32 may be a part of coprocessor */
1528 tcg_gen_andi_i32(cpu_UR[EXPSTATE], cpu_UR[EXPSTATE], ~(1u << arg[0].imm));
1529 }
1530
translate_clrex(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1531 static void translate_clrex(DisasContext *dc, const OpcodeArg arg[],
1532 const uint32_t par[])
1533 {
1534 tcg_gen_movi_i32(cpu_exclusive_addr, -1);
1535 }
1536
translate_const16(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1537 static void translate_const16(DisasContext *dc, const OpcodeArg arg[],
1538 const uint32_t par[])
1539 {
1540 TCGv_i32 c = tcg_constant_i32(arg[1].imm);
1541
1542 tcg_gen_deposit_i32(arg[0].out, c, arg[0].in, 16, 16);
1543 }
1544
translate_dcache(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1545 static void translate_dcache(DisasContext *dc, const OpcodeArg arg[],
1546 const uint32_t par[])
1547 {
1548 TCGv_i32 addr = tcg_temp_new_i32();
1549 TCGv_i32 res = tcg_temp_new_i32();
1550
1551 tcg_gen_addi_i32(addr, arg[0].in, arg[1].imm);
1552 tcg_gen_qemu_ld_i32(res, addr, dc->cring, MO_UB);
1553 }
1554
translate_depbits(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1555 static void translate_depbits(DisasContext *dc, const OpcodeArg arg[],
1556 const uint32_t par[])
1557 {
1558 tcg_gen_deposit_i32(arg[1].out, arg[1].in, arg[0].in,
1559 arg[2].imm, arg[3].imm);
1560 }
1561
translate_diwbuip(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1562 static void translate_diwbuip(DisasContext *dc, const OpcodeArg arg[],
1563 const uint32_t par[])
1564 {
1565 tcg_gen_addi_i32(arg[0].out, arg[0].in, dc->config->dcache_line_bytes);
1566 }
1567
test_exceptions_entry(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1568 static uint32_t test_exceptions_entry(DisasContext *dc, const OpcodeArg arg[],
1569 const uint32_t par[])
1570 {
1571 if (arg[0].imm > 3 || !dc->cwoe) {
1572 qemu_log_mask(LOG_GUEST_ERROR,
1573 "Illegal entry instruction(pc = %08x)\n", dc->pc);
1574 return XTENSA_OP_ILL;
1575 } else {
1576 return 0;
1577 }
1578 }
1579
test_overflow_entry(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1580 static uint32_t test_overflow_entry(DisasContext *dc, const OpcodeArg arg[],
1581 const uint32_t par[])
1582 {
1583 return 1 << (dc->callinc * 4);
1584 }
1585
translate_entry(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1586 static void translate_entry(DisasContext *dc, const OpcodeArg arg[],
1587 const uint32_t par[])
1588 {
1589 TCGv_i32 pc = tcg_constant_i32(dc->pc);
1590 TCGv_i32 s = tcg_constant_i32(arg[0].imm);
1591 TCGv_i32 imm = tcg_constant_i32(arg[1].imm);
1592 gen_helper_entry(tcg_env, pc, s, imm);
1593 }
1594
translate_extui(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1595 static void translate_extui(DisasContext *dc, const OpcodeArg arg[],
1596 const uint32_t par[])
1597 {
1598 int maskimm = (1 << arg[3].imm) - 1;
1599
1600 TCGv_i32 tmp = tcg_temp_new_i32();
1601 tcg_gen_shri_i32(tmp, arg[1].in, arg[2].imm);
1602 tcg_gen_andi_i32(arg[0].out, tmp, maskimm);
1603 }
1604
translate_getex(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1605 static void translate_getex(DisasContext *dc, const OpcodeArg arg[],
1606 const uint32_t par[])
1607 {
1608 TCGv_i32 tmp = tcg_temp_new_i32();
1609
1610 tcg_gen_extract_i32(tmp, cpu_SR[ATOMCTL], 8, 1);
1611 tcg_gen_deposit_i32(cpu_SR[ATOMCTL], cpu_SR[ATOMCTL], arg[0].in, 8, 1);
1612 tcg_gen_mov_i32(arg[0].out, tmp);
1613 }
1614
translate_icache(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1615 static void translate_icache(DisasContext *dc, const OpcodeArg arg[],
1616 const uint32_t par[])
1617 {
1618 #ifndef CONFIG_USER_ONLY
1619 TCGv_i32 addr = tcg_temp_new_i32();
1620
1621 tcg_gen_movi_i32(cpu_pc, dc->pc);
1622 tcg_gen_addi_i32(addr, arg[0].in, arg[1].imm);
1623 gen_helper_itlb_hit_test(tcg_env, addr);
1624 #endif
1625 }
1626
translate_itlb(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1627 static void translate_itlb(DisasContext *dc, const OpcodeArg arg[],
1628 const uint32_t par[])
1629 {
1630 #ifndef CONFIG_USER_ONLY
1631 TCGv_i32 dtlb = tcg_constant_i32(par[0]);
1632
1633 gen_helper_itlb(tcg_env, arg[0].in, dtlb);
1634 #endif
1635 }
1636
translate_j(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1637 static void translate_j(DisasContext *dc, const OpcodeArg arg[],
1638 const uint32_t par[])
1639 {
1640 gen_jumpi(dc, arg[0].imm, 0);
1641 }
1642
translate_jx(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1643 static void translate_jx(DisasContext *dc, const OpcodeArg arg[],
1644 const uint32_t par[])
1645 {
1646 gen_jump(dc, arg[0].in);
1647 }
1648
translate_l32e(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1649 static void translate_l32e(DisasContext *dc, const OpcodeArg arg[],
1650 const uint32_t par[])
1651 {
1652 TCGv_i32 addr = tcg_temp_new_i32();
1653 MemOp mop;
1654
1655 tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm);
1656 mop = gen_load_store_alignment(dc, MO_TEUL, addr);
1657 tcg_gen_qemu_ld_tl(arg[0].out, addr, dc->ring, mop);
1658 }
1659
1660 #ifdef CONFIG_USER_ONLY
gen_check_exclusive(DisasContext * dc,TCGv_i32 addr,bool is_write)1661 static void gen_check_exclusive(DisasContext *dc, TCGv_i32 addr, bool is_write)
1662 {
1663 }
1664 #else
gen_check_exclusive(DisasContext * dc,TCGv_i32 addr,bool is_write)1665 static void gen_check_exclusive(DisasContext *dc, TCGv_i32 addr, bool is_write)
1666 {
1667 if (!option_enabled(dc, XTENSA_OPTION_MPU)) {
1668 TCGv_i32 pc = tcg_constant_i32(dc->pc);
1669
1670 gen_helper_check_exclusive(tcg_env, pc, addr,
1671 tcg_constant_i32(is_write));
1672 }
1673 }
1674 #endif
1675
translate_l32ex(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1676 static void translate_l32ex(DisasContext *dc, const OpcodeArg arg[],
1677 const uint32_t par[])
1678 {
1679 TCGv_i32 addr = tcg_temp_new_i32();
1680 MemOp mop;
1681
1682 tcg_gen_mov_i32(addr, arg[1].in);
1683 mop = gen_load_store_alignment(dc, MO_TEUL | MO_ALIGN, addr);
1684 gen_check_exclusive(dc, addr, false);
1685 tcg_gen_qemu_ld_i32(arg[0].out, addr, dc->cring, mop);
1686 tcg_gen_mov_i32(cpu_exclusive_addr, addr);
1687 tcg_gen_mov_i32(cpu_exclusive_val, arg[0].out);
1688 }
1689
translate_ldst(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1690 static void translate_ldst(DisasContext *dc, const OpcodeArg arg[],
1691 const uint32_t par[])
1692 {
1693 TCGv_i32 addr = tcg_temp_new_i32();
1694 MemOp mop;
1695
1696 tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm);
1697 mop = gen_load_store_alignment(dc, par[0], addr);
1698
1699 if (par[2]) {
1700 if (par[1]) {
1701 tcg_gen_mb(TCG_BAR_STRL | TCG_MO_ALL);
1702 }
1703 tcg_gen_qemu_st_tl(arg[0].in, addr, dc->cring, mop);
1704 } else {
1705 tcg_gen_qemu_ld_tl(arg[0].out, addr, dc->cring, mop);
1706 if (par[1]) {
1707 tcg_gen_mb(TCG_BAR_LDAQ | TCG_MO_ALL);
1708 }
1709 }
1710 }
1711
translate_lct(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1712 static void translate_lct(DisasContext *dc, const OpcodeArg arg[],
1713 const uint32_t par[])
1714 {
1715 tcg_gen_movi_i32(arg[0].out, 0);
1716 }
1717
translate_l32r(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1718 static void translate_l32r(DisasContext *dc, const OpcodeArg arg[],
1719 const uint32_t par[])
1720 {
1721 TCGv_i32 tmp;
1722
1723 if (dc->base.tb->flags & XTENSA_TBFLAG_LITBASE) {
1724 tmp = tcg_temp_new();
1725 tcg_gen_addi_i32(tmp, cpu_SR[LITBASE], arg[1].raw_imm - 1);
1726 } else {
1727 tmp = tcg_constant_i32(arg[1].imm);
1728 }
1729 tcg_gen_qemu_ld_i32(arg[0].out, tmp, dc->cring, MO_TEUL);
1730 }
1731
translate_loop(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1732 static void translate_loop(DisasContext *dc, const OpcodeArg arg[],
1733 const uint32_t par[])
1734 {
1735 uint32_t lend = arg[1].imm;
1736
1737 tcg_gen_subi_i32(cpu_SR[LCOUNT], arg[0].in, 1);
1738 tcg_gen_movi_i32(cpu_SR[LBEG], dc->base.pc_next);
1739 tcg_gen_movi_i32(cpu_SR[LEND], lend);
1740
1741 if (par[0] != TCG_COND_NEVER) {
1742 TCGLabel *label = gen_new_label();
1743 tcg_gen_brcondi_i32(par[0], arg[0].in, 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 enum {
1752 MAC16_UMUL,
1753 MAC16_MUL,
1754 MAC16_MULA,
1755 MAC16_MULS,
1756 MAC16_NONE,
1757 };
1758
1759 enum {
1760 MAC16_LL,
1761 MAC16_HL,
1762 MAC16_LH,
1763 MAC16_HH,
1764
1765 MAC16_HX = 0x1,
1766 MAC16_XH = 0x2,
1767 };
1768
translate_mac16(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1769 static void translate_mac16(DisasContext *dc, const OpcodeArg arg[],
1770 const uint32_t par[])
1771 {
1772 int op = par[0];
1773 unsigned half = par[1];
1774 uint32_t ld_offset = par[2];
1775 unsigned off = ld_offset ? 2 : 0;
1776 TCGv_i32 vaddr = tcg_temp_new_i32();
1777 TCGv_i32 mem32 = tcg_temp_new_i32();
1778
1779 if (ld_offset) {
1780 MemOp mop;
1781
1782 tcg_gen_addi_i32(vaddr, arg[1].in, ld_offset);
1783 mop = gen_load_store_alignment(dc, MO_TEUL, vaddr);
1784 tcg_gen_qemu_ld_tl(mem32, vaddr, dc->cring, mop);
1785 }
1786 if (op != MAC16_NONE) {
1787 TCGv_i32 m1 = gen_mac16_m(arg[off].in,
1788 half & MAC16_HX, op == MAC16_UMUL);
1789 TCGv_i32 m2 = gen_mac16_m(arg[off + 1].in,
1790 half & MAC16_XH, op == MAC16_UMUL);
1791
1792 if (op == MAC16_MUL || op == MAC16_UMUL) {
1793 tcg_gen_mul_i32(cpu_SR[ACCLO], m1, m2);
1794 if (op == MAC16_UMUL) {
1795 tcg_gen_movi_i32(cpu_SR[ACCHI], 0);
1796 } else {
1797 tcg_gen_sari_i32(cpu_SR[ACCHI], cpu_SR[ACCLO], 31);
1798 }
1799 } else {
1800 TCGv_i32 lo = tcg_temp_new_i32();
1801 TCGv_i32 hi = tcg_temp_new_i32();
1802
1803 tcg_gen_mul_i32(lo, m1, m2);
1804 tcg_gen_sari_i32(hi, lo, 31);
1805 if (op == MAC16_MULA) {
1806 tcg_gen_add2_i32(cpu_SR[ACCLO], cpu_SR[ACCHI],
1807 cpu_SR[ACCLO], cpu_SR[ACCHI],
1808 lo, hi);
1809 } else {
1810 tcg_gen_sub2_i32(cpu_SR[ACCLO], cpu_SR[ACCHI],
1811 cpu_SR[ACCLO], cpu_SR[ACCHI],
1812 lo, hi);
1813 }
1814 tcg_gen_ext8s_i32(cpu_SR[ACCHI], cpu_SR[ACCHI]);
1815 }
1816 }
1817 if (ld_offset) {
1818 tcg_gen_mov_i32(arg[1].out, vaddr);
1819 tcg_gen_mov_i32(cpu_SR[MR + arg[0].imm], mem32);
1820 }
1821 }
1822
translate_memw(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1823 static void translate_memw(DisasContext *dc, const OpcodeArg arg[],
1824 const uint32_t par[])
1825 {
1826 tcg_gen_mb(TCG_BAR_SC | TCG_MO_ALL);
1827 }
1828
translate_smin(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1829 static void translate_smin(DisasContext *dc, const OpcodeArg arg[],
1830 const uint32_t par[])
1831 {
1832 tcg_gen_smin_i32(arg[0].out, arg[1].in, arg[2].in);
1833 }
1834
translate_umin(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1835 static void translate_umin(DisasContext *dc, const OpcodeArg arg[],
1836 const uint32_t par[])
1837 {
1838 tcg_gen_umin_i32(arg[0].out, arg[1].in, arg[2].in);
1839 }
1840
translate_smax(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1841 static void translate_smax(DisasContext *dc, const OpcodeArg arg[],
1842 const uint32_t par[])
1843 {
1844 tcg_gen_smax_i32(arg[0].out, arg[1].in, arg[2].in);
1845 }
1846
translate_umax(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1847 static void translate_umax(DisasContext *dc, const OpcodeArg arg[],
1848 const uint32_t par[])
1849 {
1850 tcg_gen_umax_i32(arg[0].out, arg[1].in, arg[2].in);
1851 }
1852
translate_mov(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1853 static void translate_mov(DisasContext *dc, const OpcodeArg arg[],
1854 const uint32_t par[])
1855 {
1856 tcg_gen_mov_i32(arg[0].out, arg[1].in);
1857 }
1858
translate_movcond(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1859 static void translate_movcond(DisasContext *dc, const OpcodeArg arg[],
1860 const uint32_t par[])
1861 {
1862 TCGv_i32 zero = tcg_constant_i32(0);
1863
1864 tcg_gen_movcond_i32(par[0], arg[0].out,
1865 arg[2].in, zero, arg[1].in, arg[0].in);
1866 }
1867
translate_movi(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1868 static void translate_movi(DisasContext *dc, const OpcodeArg arg[],
1869 const uint32_t par[])
1870 {
1871 tcg_gen_movi_i32(arg[0].out, arg[1].imm);
1872 }
1873
translate_movp(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1874 static void translate_movp(DisasContext *dc, const OpcodeArg arg[],
1875 const uint32_t par[])
1876 {
1877 TCGv_i32 zero = tcg_constant_i32(0);
1878 TCGv_i32 tmp = tcg_temp_new_i32();
1879
1880 tcg_gen_andi_i32(tmp, arg[2].in, 1 << arg[2].imm);
1881 tcg_gen_movcond_i32(par[0],
1882 arg[0].out, tmp, zero,
1883 arg[1].in, arg[0].in);
1884 }
1885
translate_movsp(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1886 static void translate_movsp(DisasContext *dc, const OpcodeArg arg[],
1887 const uint32_t par[])
1888 {
1889 tcg_gen_mov_i32(arg[0].out, arg[1].in);
1890 }
1891
translate_mul16(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1892 static void translate_mul16(DisasContext *dc, const OpcodeArg arg[],
1893 const uint32_t par[])
1894 {
1895 TCGv_i32 v1 = tcg_temp_new_i32();
1896 TCGv_i32 v2 = tcg_temp_new_i32();
1897
1898 if (par[0]) {
1899 tcg_gen_ext16s_i32(v1, arg[1].in);
1900 tcg_gen_ext16s_i32(v2, arg[2].in);
1901 } else {
1902 tcg_gen_ext16u_i32(v1, arg[1].in);
1903 tcg_gen_ext16u_i32(v2, arg[2].in);
1904 }
1905 tcg_gen_mul_i32(arg[0].out, v1, v2);
1906 }
1907
translate_mull(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1908 static void translate_mull(DisasContext *dc, const OpcodeArg arg[],
1909 const uint32_t par[])
1910 {
1911 tcg_gen_mul_i32(arg[0].out, arg[1].in, arg[2].in);
1912 }
1913
translate_mulh(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1914 static void translate_mulh(DisasContext *dc, const OpcodeArg arg[],
1915 const uint32_t par[])
1916 {
1917 TCGv_i32 lo = tcg_temp_new();
1918
1919 if (par[0]) {
1920 tcg_gen_muls2_i32(lo, arg[0].out, arg[1].in, arg[2].in);
1921 } else {
1922 tcg_gen_mulu2_i32(lo, arg[0].out, arg[1].in, arg[2].in);
1923 }
1924 }
1925
translate_neg(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1926 static void translate_neg(DisasContext *dc, const OpcodeArg arg[],
1927 const uint32_t par[])
1928 {
1929 tcg_gen_neg_i32(arg[0].out, arg[1].in);
1930 }
1931
translate_nop(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1932 static void translate_nop(DisasContext *dc, const OpcodeArg arg[],
1933 const uint32_t par[])
1934 {
1935 }
1936
translate_nsa(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1937 static void translate_nsa(DisasContext *dc, const OpcodeArg arg[],
1938 const uint32_t par[])
1939 {
1940 tcg_gen_clrsb_i32(arg[0].out, arg[1].in);
1941 }
1942
translate_nsau(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1943 static void translate_nsau(DisasContext *dc, const OpcodeArg arg[],
1944 const uint32_t par[])
1945 {
1946 tcg_gen_clzi_i32(arg[0].out, arg[1].in, 32);
1947 }
1948
translate_or(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1949 static void translate_or(DisasContext *dc, const OpcodeArg arg[],
1950 const uint32_t par[])
1951 {
1952 tcg_gen_or_i32(arg[0].out, arg[1].in, arg[2].in);
1953 }
1954
translate_ptlb(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1955 static void translate_ptlb(DisasContext *dc, const OpcodeArg arg[],
1956 const uint32_t par[])
1957 {
1958 #ifndef CONFIG_USER_ONLY
1959 TCGv_i32 dtlb = tcg_constant_i32(par[0]);
1960
1961 tcg_gen_movi_i32(cpu_pc, dc->pc);
1962 gen_helper_ptlb(arg[0].out, tcg_env, arg[1].in, dtlb);
1963 #endif
1964 }
1965
translate_pptlb(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1966 static void translate_pptlb(DisasContext *dc, const OpcodeArg arg[],
1967 const uint32_t par[])
1968 {
1969 #ifndef CONFIG_USER_ONLY
1970 tcg_gen_movi_i32(cpu_pc, dc->pc);
1971 gen_helper_pptlb(arg[0].out, tcg_env, arg[1].in);
1972 #endif
1973 }
1974
translate_quos(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1975 static void translate_quos(DisasContext *dc, const OpcodeArg arg[],
1976 const uint32_t par[])
1977 {
1978 TCGLabel *label1 = gen_new_label();
1979 TCGLabel *label2 = gen_new_label();
1980
1981 tcg_gen_brcondi_i32(TCG_COND_NE, arg[1].in, 0x80000000,
1982 label1);
1983 tcg_gen_brcondi_i32(TCG_COND_NE, arg[2].in, 0xffffffff,
1984 label1);
1985 tcg_gen_movi_i32(arg[0].out,
1986 par[0] ? 0x80000000 : 0);
1987 tcg_gen_br(label2);
1988 gen_set_label(label1);
1989 if (par[0]) {
1990 tcg_gen_div_i32(arg[0].out,
1991 arg[1].in, arg[2].in);
1992 } else {
1993 tcg_gen_rem_i32(arg[0].out,
1994 arg[1].in, arg[2].in);
1995 }
1996 gen_set_label(label2);
1997 }
1998
translate_quou(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])1999 static void translate_quou(DisasContext *dc, const OpcodeArg arg[],
2000 const uint32_t par[])
2001 {
2002 tcg_gen_divu_i32(arg[0].out,
2003 arg[1].in, arg[2].in);
2004 }
2005
translate_read_impwire(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2006 static void translate_read_impwire(DisasContext *dc, const OpcodeArg arg[],
2007 const uint32_t par[])
2008 {
2009 /* TODO: GPIO32 may be a part of coprocessor */
2010 tcg_gen_movi_i32(arg[0].out, 0);
2011 }
2012
translate_remu(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2013 static void translate_remu(DisasContext *dc, const OpcodeArg arg[],
2014 const uint32_t par[])
2015 {
2016 tcg_gen_remu_i32(arg[0].out,
2017 arg[1].in, arg[2].in);
2018 }
2019
translate_rer(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2020 static void translate_rer(DisasContext *dc, const OpcodeArg arg[],
2021 const uint32_t par[])
2022 {
2023 gen_helper_rer(arg[0].out, tcg_env, arg[1].in);
2024 }
2025
translate_ret(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2026 static void translate_ret(DisasContext *dc, const OpcodeArg arg[],
2027 const uint32_t par[])
2028 {
2029 gen_jump(dc, cpu_R[0]);
2030 }
2031
test_exceptions_retw(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2032 static uint32_t test_exceptions_retw(DisasContext *dc, const OpcodeArg arg[],
2033 const uint32_t par[])
2034 {
2035 if (!dc->cwoe) {
2036 qemu_log_mask(LOG_GUEST_ERROR,
2037 "Illegal retw instruction(pc = %08x)\n", dc->pc);
2038 return XTENSA_OP_ILL;
2039 } else {
2040 TCGv_i32 pc = tcg_constant_i32(dc->pc);
2041
2042 gen_helper_test_ill_retw(tcg_env, pc);
2043 return 0;
2044 }
2045 }
2046
translate_retw(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2047 static void translate_retw(DisasContext *dc, const OpcodeArg arg[],
2048 const uint32_t par[])
2049 {
2050 TCGv_i32 tmp = tcg_temp_new();
2051 tcg_gen_shl_i32(tmp, tcg_constant_i32(1), cpu_SR[WINDOW_BASE]);
2052 tcg_gen_andc_i32(cpu_SR[WINDOW_START],
2053 cpu_SR[WINDOW_START], tmp);
2054 tcg_gen_movi_i32(tmp, dc->pc);
2055 tcg_gen_deposit_i32(tmp, tmp, cpu_R[0], 0, 30);
2056 gen_helper_retw(tcg_env, cpu_R[0]);
2057 gen_jump(dc, tmp);
2058 }
2059
translate_rfde(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2060 static void translate_rfde(DisasContext *dc, const OpcodeArg arg[],
2061 const uint32_t par[])
2062 {
2063 gen_jump(dc, cpu_SR[dc->config->ndepc ? DEPC : EPC1]);
2064 }
2065
translate_rfe(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2066 static void translate_rfe(DisasContext *dc, const OpcodeArg arg[],
2067 const uint32_t par[])
2068 {
2069 tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_EXCM);
2070 gen_jump(dc, cpu_SR[EPC1]);
2071 }
2072
translate_rfi(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2073 static void translate_rfi(DisasContext *dc, const OpcodeArg arg[],
2074 const uint32_t par[])
2075 {
2076 tcg_gen_mov_i32(cpu_SR[PS], cpu_SR[EPS2 + arg[0].imm - 2]);
2077 gen_jump(dc, cpu_SR[EPC1 + arg[0].imm - 1]);
2078 }
2079
translate_rfw(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2080 static void translate_rfw(DisasContext *dc, const OpcodeArg arg[],
2081 const uint32_t par[])
2082 {
2083 TCGv_i32 tmp = tcg_temp_new();
2084
2085 tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_EXCM);
2086 tcg_gen_shl_i32(tmp, tcg_constant_i32(1), cpu_SR[WINDOW_BASE]);
2087
2088 if (par[0]) {
2089 tcg_gen_andc_i32(cpu_SR[WINDOW_START],
2090 cpu_SR[WINDOW_START], tmp);
2091 } else {
2092 tcg_gen_or_i32(cpu_SR[WINDOW_START],
2093 cpu_SR[WINDOW_START], tmp);
2094 }
2095
2096 gen_helper_restore_owb(tcg_env);
2097 gen_jump(dc, cpu_SR[EPC1]);
2098 }
2099
translate_rotw(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2100 static void translate_rotw(DisasContext *dc, const OpcodeArg arg[],
2101 const uint32_t par[])
2102 {
2103 tcg_gen_addi_i32(cpu_windowbase_next, cpu_SR[WINDOW_BASE], arg[0].imm);
2104 }
2105
translate_rsil(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2106 static void translate_rsil(DisasContext *dc, const OpcodeArg arg[],
2107 const uint32_t par[])
2108 {
2109 tcg_gen_mov_i32(arg[0].out, cpu_SR[PS]);
2110 tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_INTLEVEL);
2111 tcg_gen_ori_i32(cpu_SR[PS], cpu_SR[PS], arg[1].imm);
2112 }
2113
translate_rsr(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2114 static void translate_rsr(DisasContext *dc, const OpcodeArg arg[],
2115 const uint32_t par[])
2116 {
2117 if (sr_name[par[0]]) {
2118 tcg_gen_mov_i32(arg[0].out, cpu_SR[par[0]]);
2119 } else {
2120 tcg_gen_movi_i32(arg[0].out, 0);
2121 }
2122 }
2123
translate_rsr_ccount(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2124 static void translate_rsr_ccount(DisasContext *dc, const OpcodeArg arg[],
2125 const uint32_t par[])
2126 {
2127 #ifndef CONFIG_USER_ONLY
2128 translator_io_start(&dc->base);
2129 gen_helper_update_ccount(tcg_env);
2130 tcg_gen_mov_i32(arg[0].out, cpu_SR[par[0]]);
2131 #endif
2132 }
2133
translate_rsr_ptevaddr(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2134 static void translate_rsr_ptevaddr(DisasContext *dc, const OpcodeArg arg[],
2135 const uint32_t par[])
2136 {
2137 #ifndef CONFIG_USER_ONLY
2138 TCGv_i32 tmp = tcg_temp_new_i32();
2139
2140 tcg_gen_shri_i32(tmp, cpu_SR[EXCVADDR], 10);
2141 tcg_gen_or_i32(tmp, tmp, cpu_SR[PTEVADDR]);
2142 tcg_gen_andi_i32(arg[0].out, tmp, 0xfffffffc);
2143 #endif
2144 }
2145
translate_rtlb(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2146 static void translate_rtlb(DisasContext *dc, const OpcodeArg arg[],
2147 const uint32_t par[])
2148 {
2149 #ifndef CONFIG_USER_ONLY
2150 static void (* const helper[])(TCGv_i32 r, TCGv_env env, TCGv_i32 a1,
2151 TCGv_i32 a2) = {
2152 gen_helper_rtlb0,
2153 gen_helper_rtlb1,
2154 };
2155 TCGv_i32 dtlb = tcg_constant_i32(par[0]);
2156
2157 helper[par[1]](arg[0].out, tcg_env, arg[1].in, dtlb);
2158 #endif
2159 }
2160
translate_rptlb0(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2161 static void translate_rptlb0(DisasContext *dc, const OpcodeArg arg[],
2162 const uint32_t par[])
2163 {
2164 #ifndef CONFIG_USER_ONLY
2165 gen_helper_rptlb0(arg[0].out, tcg_env, arg[1].in);
2166 #endif
2167 }
2168
translate_rptlb1(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2169 static void translate_rptlb1(DisasContext *dc, const OpcodeArg arg[],
2170 const uint32_t par[])
2171 {
2172 #ifndef CONFIG_USER_ONLY
2173 gen_helper_rptlb1(arg[0].out, tcg_env, arg[1].in);
2174 #endif
2175 }
2176
translate_rur(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2177 static void translate_rur(DisasContext *dc, const OpcodeArg arg[],
2178 const uint32_t par[])
2179 {
2180 tcg_gen_mov_i32(arg[0].out, cpu_UR[par[0]]);
2181 }
2182
translate_setb_expstate(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2183 static void translate_setb_expstate(DisasContext *dc, const OpcodeArg arg[],
2184 const uint32_t par[])
2185 {
2186 /* TODO: GPIO32 may be a part of coprocessor */
2187 tcg_gen_ori_i32(cpu_UR[EXPSTATE], cpu_UR[EXPSTATE], 1u << arg[0].imm);
2188 }
2189
2190 #ifdef CONFIG_USER_ONLY
gen_check_atomctl(DisasContext * dc,TCGv_i32 addr)2191 static void gen_check_atomctl(DisasContext *dc, TCGv_i32 addr)
2192 {
2193 }
2194 #else
gen_check_atomctl(DisasContext * dc,TCGv_i32 addr)2195 static void gen_check_atomctl(DisasContext *dc, TCGv_i32 addr)
2196 {
2197 TCGv_i32 pc = tcg_constant_i32(dc->pc);
2198
2199 gen_helper_check_atomctl(tcg_env, pc, addr);
2200 }
2201 #endif
2202
translate_s32c1i(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2203 static void translate_s32c1i(DisasContext *dc, const OpcodeArg arg[],
2204 const uint32_t par[])
2205 {
2206 TCGv_i32 tmp = tcg_temp_new_i32();
2207 TCGv_i32 addr = tcg_temp_new_i32();
2208 MemOp mop;
2209
2210 tcg_gen_mov_i32(tmp, arg[0].in);
2211 tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm);
2212 mop = gen_load_store_alignment(dc, MO_TEUL | MO_ALIGN, addr);
2213 gen_check_atomctl(dc, addr);
2214 tcg_gen_atomic_cmpxchg_i32(arg[0].out, addr, cpu_SR[SCOMPARE1],
2215 tmp, dc->cring, mop);
2216 }
2217
translate_s32e(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2218 static void translate_s32e(DisasContext *dc, const OpcodeArg arg[],
2219 const uint32_t par[])
2220 {
2221 TCGv_i32 addr = tcg_temp_new_i32();
2222 MemOp mop;
2223
2224 tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm);
2225 mop = gen_load_store_alignment(dc, MO_TEUL, addr);
2226 tcg_gen_qemu_st_tl(arg[0].in, addr, dc->ring, mop);
2227 }
2228
translate_s32ex(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2229 static void translate_s32ex(DisasContext *dc, const OpcodeArg arg[],
2230 const uint32_t par[])
2231 {
2232 TCGv_i32 prev = tcg_temp_new_i32();
2233 TCGv_i32 addr = tcg_temp_new_i32();
2234 TCGv_i32 res = tcg_temp_new_i32();
2235 TCGLabel *label = gen_new_label();
2236 MemOp mop;
2237
2238 tcg_gen_movi_i32(res, 0);
2239 tcg_gen_mov_i32(addr, arg[1].in);
2240 mop = gen_load_store_alignment(dc, MO_TEUL | MO_ALIGN, addr);
2241 tcg_gen_brcond_i32(TCG_COND_NE, addr, cpu_exclusive_addr, label);
2242 gen_check_exclusive(dc, addr, true);
2243 tcg_gen_atomic_cmpxchg_i32(prev, cpu_exclusive_addr, cpu_exclusive_val,
2244 arg[0].in, dc->cring, mop);
2245 tcg_gen_setcond_i32(TCG_COND_EQ, res, prev, cpu_exclusive_val);
2246 tcg_gen_movcond_i32(TCG_COND_EQ, cpu_exclusive_val,
2247 prev, cpu_exclusive_val, prev, cpu_exclusive_val);
2248 tcg_gen_movi_i32(cpu_exclusive_addr, -1);
2249 gen_set_label(label);
2250 tcg_gen_extract_i32(arg[0].out, cpu_SR[ATOMCTL], 8, 1);
2251 tcg_gen_deposit_i32(cpu_SR[ATOMCTL], cpu_SR[ATOMCTL], res, 8, 1);
2252 }
2253
translate_salt(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2254 static void translate_salt(DisasContext *dc, const OpcodeArg arg[],
2255 const uint32_t par[])
2256 {
2257 tcg_gen_setcond_i32(par[0],
2258 arg[0].out,
2259 arg[1].in, arg[2].in);
2260 }
2261
translate_sext(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2262 static void translate_sext(DisasContext *dc, const OpcodeArg arg[],
2263 const uint32_t par[])
2264 {
2265 tcg_gen_sextract_i32(arg[0].out, arg[1].in, 0, arg[2].imm + 1);
2266 }
2267
test_exceptions_simcall(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2268 static uint32_t test_exceptions_simcall(DisasContext *dc,
2269 const OpcodeArg arg[],
2270 const uint32_t par[])
2271 {
2272 bool is_semi = semihosting_enabled(dc->cring != 0);
2273 #ifdef CONFIG_USER_ONLY
2274 bool ill = true;
2275 #else
2276 /* Between RE.2 and RE.3 simcall opcode's become nop for the hardware. */
2277 bool ill = dc->config->hw_version <= 250002 && !is_semi;
2278 #endif
2279 if (ill || !is_semi) {
2280 qemu_log_mask(LOG_GUEST_ERROR, "SIMCALL but semihosting is disabled\n");
2281 }
2282 return ill ? XTENSA_OP_ILL : 0;
2283 }
2284
translate_simcall(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2285 static void translate_simcall(DisasContext *dc, const OpcodeArg arg[],
2286 const uint32_t par[])
2287 {
2288 #ifndef CONFIG_USER_ONLY
2289 if (semihosting_enabled(dc->cring != 0)) {
2290 gen_helper_simcall(tcg_env);
2291 }
2292 #endif
2293 }
2294
2295 /*
2296 * Note: 64 bit ops are used here solely because SAR values
2297 * have range 0..63
2298 */
2299 #define gen_shift_reg(cmd, reg) do { \
2300 TCGv_i64 tmp = tcg_temp_new_i64(); \
2301 tcg_gen_extu_i32_i64(tmp, reg); \
2302 tcg_gen_##cmd##_i64(v, v, tmp); \
2303 tcg_gen_extrl_i64_i32(arg[0].out, v); \
2304 } while (0)
2305
2306 #define gen_shift(cmd) gen_shift_reg(cmd, cpu_SR[SAR])
2307
translate_sll(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2308 static void translate_sll(DisasContext *dc, const OpcodeArg arg[],
2309 const uint32_t par[])
2310 {
2311 if (dc->sar_m32_5bit) {
2312 tcg_gen_shl_i32(arg[0].out, arg[1].in, dc->sar_m32);
2313 } else {
2314 TCGv_i64 v = tcg_temp_new_i64();
2315 TCGv_i32 s = tcg_temp_new();
2316 tcg_gen_subfi_i32(s, 32, cpu_SR[SAR]);
2317 tcg_gen_andi_i32(s, s, 0x3f);
2318 tcg_gen_extu_i32_i64(v, arg[1].in);
2319 gen_shift_reg(shl, s);
2320 }
2321 }
2322
translate_slli(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2323 static void translate_slli(DisasContext *dc, const OpcodeArg arg[],
2324 const uint32_t par[])
2325 {
2326 if (arg[2].imm == 32) {
2327 qemu_log_mask(LOG_GUEST_ERROR, "slli a%d, a%d, 32 is undefined\n",
2328 arg[0].imm, arg[1].imm);
2329 }
2330 tcg_gen_shli_i32(arg[0].out, arg[1].in, arg[2].imm & 0x1f);
2331 }
2332
translate_sra(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2333 static void translate_sra(DisasContext *dc, const OpcodeArg arg[],
2334 const uint32_t par[])
2335 {
2336 if (dc->sar_m32_5bit) {
2337 tcg_gen_sar_i32(arg[0].out, arg[1].in, cpu_SR[SAR]);
2338 } else {
2339 TCGv_i64 v = tcg_temp_new_i64();
2340 tcg_gen_ext_i32_i64(v, arg[1].in);
2341 gen_shift(sar);
2342 }
2343 }
2344
translate_srai(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2345 static void translate_srai(DisasContext *dc, const OpcodeArg arg[],
2346 const uint32_t par[])
2347 {
2348 tcg_gen_sari_i32(arg[0].out, arg[1].in, arg[2].imm);
2349 }
2350
translate_src(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2351 static void translate_src(DisasContext *dc, const OpcodeArg arg[],
2352 const uint32_t par[])
2353 {
2354 TCGv_i64 v = tcg_temp_new_i64();
2355 tcg_gen_concat_i32_i64(v, arg[2].in, arg[1].in);
2356 gen_shift(shr);
2357 }
2358
translate_srl(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2359 static void translate_srl(DisasContext *dc, const OpcodeArg arg[],
2360 const uint32_t par[])
2361 {
2362 if (dc->sar_m32_5bit) {
2363 tcg_gen_shr_i32(arg[0].out, arg[1].in, cpu_SR[SAR]);
2364 } else {
2365 TCGv_i64 v = tcg_temp_new_i64();
2366 tcg_gen_extu_i32_i64(v, arg[1].in);
2367 gen_shift(shr);
2368 }
2369 }
2370
2371 #undef gen_shift
2372 #undef gen_shift_reg
2373
translate_srli(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2374 static void translate_srli(DisasContext *dc, const OpcodeArg arg[],
2375 const uint32_t par[])
2376 {
2377 tcg_gen_shri_i32(arg[0].out, arg[1].in, arg[2].imm);
2378 }
2379
translate_ssa8b(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2380 static void translate_ssa8b(DisasContext *dc, const OpcodeArg arg[],
2381 const uint32_t par[])
2382 {
2383 TCGv_i32 tmp = tcg_temp_new_i32();
2384 tcg_gen_shli_i32(tmp, arg[0].in, 3);
2385 gen_left_shift_sar(dc, tmp);
2386 }
2387
translate_ssa8l(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2388 static void translate_ssa8l(DisasContext *dc, const OpcodeArg arg[],
2389 const uint32_t par[])
2390 {
2391 TCGv_i32 tmp = tcg_temp_new_i32();
2392 tcg_gen_shli_i32(tmp, arg[0].in, 3);
2393 gen_right_shift_sar(dc, tmp);
2394 }
2395
translate_ssai(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2396 static void translate_ssai(DisasContext *dc, const OpcodeArg arg[],
2397 const uint32_t par[])
2398 {
2399 gen_right_shift_sar(dc, tcg_constant_i32(arg[0].imm));
2400 }
2401
translate_ssl(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2402 static void translate_ssl(DisasContext *dc, const OpcodeArg arg[],
2403 const uint32_t par[])
2404 {
2405 gen_left_shift_sar(dc, arg[0].in);
2406 }
2407
translate_ssr(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2408 static void translate_ssr(DisasContext *dc, const OpcodeArg arg[],
2409 const uint32_t par[])
2410 {
2411 gen_right_shift_sar(dc, arg[0].in);
2412 }
2413
translate_sub(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2414 static void translate_sub(DisasContext *dc, const OpcodeArg arg[],
2415 const uint32_t par[])
2416 {
2417 tcg_gen_sub_i32(arg[0].out, arg[1].in, arg[2].in);
2418 }
2419
translate_subx(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2420 static void translate_subx(DisasContext *dc, const OpcodeArg arg[],
2421 const uint32_t par[])
2422 {
2423 TCGv_i32 tmp = tcg_temp_new_i32();
2424 tcg_gen_shli_i32(tmp, arg[1].in, par[0]);
2425 tcg_gen_sub_i32(arg[0].out, tmp, arg[2].in);
2426 }
2427
translate_waiti(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2428 static void translate_waiti(DisasContext *dc, const OpcodeArg arg[],
2429 const uint32_t par[])
2430 {
2431 #ifndef CONFIG_USER_ONLY
2432 TCGv_i32 pc = tcg_constant_i32(dc->base.pc_next);
2433
2434 translator_io_start(&dc->base);
2435 gen_helper_waiti(tcg_env, pc, tcg_constant_i32(arg[0].imm));
2436 #endif
2437 }
2438
translate_wtlb(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2439 static void translate_wtlb(DisasContext *dc, const OpcodeArg arg[],
2440 const uint32_t par[])
2441 {
2442 #ifndef CONFIG_USER_ONLY
2443 TCGv_i32 dtlb = tcg_constant_i32(par[0]);
2444
2445 gen_helper_wtlb(tcg_env, arg[0].in, arg[1].in, dtlb);
2446 #endif
2447 }
2448
translate_wptlb(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2449 static void translate_wptlb(DisasContext *dc, const OpcodeArg arg[],
2450 const uint32_t par[])
2451 {
2452 #ifndef CONFIG_USER_ONLY
2453 gen_helper_wptlb(tcg_env, arg[0].in, arg[1].in);
2454 #endif
2455 }
2456
translate_wer(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2457 static void translate_wer(DisasContext *dc, const OpcodeArg arg[],
2458 const uint32_t par[])
2459 {
2460 gen_helper_wer(tcg_env, arg[0].in, arg[1].in);
2461 }
2462
translate_wrmsk_expstate(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2463 static void translate_wrmsk_expstate(DisasContext *dc, const OpcodeArg arg[],
2464 const uint32_t par[])
2465 {
2466 /* TODO: GPIO32 may be a part of coprocessor */
2467 tcg_gen_and_i32(cpu_UR[EXPSTATE], arg[0].in, arg[1].in);
2468 }
2469
translate_wsr(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2470 static void translate_wsr(DisasContext *dc, const OpcodeArg arg[],
2471 const uint32_t par[])
2472 {
2473 if (sr_name[par[0]]) {
2474 tcg_gen_mov_i32(cpu_SR[par[0]], arg[0].in);
2475 }
2476 }
2477
translate_wsr_mask(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2478 static void translate_wsr_mask(DisasContext *dc, const OpcodeArg arg[],
2479 const uint32_t par[])
2480 {
2481 if (sr_name[par[0]]) {
2482 tcg_gen_andi_i32(cpu_SR[par[0]], arg[0].in, par[2]);
2483 }
2484 }
2485
translate_wsr_acchi(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2486 static void translate_wsr_acchi(DisasContext *dc, const OpcodeArg arg[],
2487 const uint32_t par[])
2488 {
2489 tcg_gen_ext8s_i32(cpu_SR[par[0]], arg[0].in);
2490 }
2491
translate_wsr_ccompare(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2492 static void translate_wsr_ccompare(DisasContext *dc, const OpcodeArg arg[],
2493 const uint32_t par[])
2494 {
2495 #ifndef CONFIG_USER_ONLY
2496 uint32_t id = par[0] - CCOMPARE;
2497
2498 assert(id < dc->config->nccompare);
2499 translator_io_start(&dc->base);
2500 tcg_gen_mov_i32(cpu_SR[par[0]], arg[0].in);
2501 gen_helper_update_ccompare(tcg_env, tcg_constant_i32(id));
2502 #endif
2503 }
2504
translate_wsr_ccount(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2505 static void translate_wsr_ccount(DisasContext *dc, const OpcodeArg arg[],
2506 const uint32_t par[])
2507 {
2508 #ifndef CONFIG_USER_ONLY
2509 translator_io_start(&dc->base);
2510 gen_helper_wsr_ccount(tcg_env, arg[0].in);
2511 #endif
2512 }
2513
translate_wsr_dbreaka(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2514 static void translate_wsr_dbreaka(DisasContext *dc, const OpcodeArg arg[],
2515 const uint32_t par[])
2516 {
2517 #ifndef CONFIG_USER_ONLY
2518 unsigned id = par[0] - DBREAKA;
2519
2520 assert(id < dc->config->ndbreak);
2521 gen_helper_wsr_dbreaka(tcg_env, tcg_constant_i32(id), arg[0].in);
2522 #endif
2523 }
2524
translate_wsr_dbreakc(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2525 static void translate_wsr_dbreakc(DisasContext *dc, const OpcodeArg arg[],
2526 const uint32_t par[])
2527 {
2528 #ifndef CONFIG_USER_ONLY
2529 unsigned id = par[0] - DBREAKC;
2530
2531 assert(id < dc->config->ndbreak);
2532 gen_helper_wsr_dbreakc(tcg_env, tcg_constant_i32(id), arg[0].in);
2533 #endif
2534 }
2535
translate_wsr_ibreaka(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2536 static void translate_wsr_ibreaka(DisasContext *dc, const OpcodeArg arg[],
2537 const uint32_t par[])
2538 {
2539 #ifndef CONFIG_USER_ONLY
2540 unsigned id = par[0] - IBREAKA;
2541
2542 assert(id < dc->config->nibreak);
2543 gen_helper_wsr_ibreaka(tcg_env, tcg_constant_i32(id), arg[0].in);
2544 #endif
2545 }
2546
translate_wsr_ibreakenable(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2547 static void translate_wsr_ibreakenable(DisasContext *dc, const OpcodeArg arg[],
2548 const uint32_t par[])
2549 {
2550 #ifndef CONFIG_USER_ONLY
2551 gen_helper_wsr_ibreakenable(tcg_env, arg[0].in);
2552 #endif
2553 }
2554
translate_wsr_icount(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2555 static void translate_wsr_icount(DisasContext *dc, const OpcodeArg arg[],
2556 const uint32_t par[])
2557 {
2558 #ifndef CONFIG_USER_ONLY
2559 if (dc->icount) {
2560 tcg_gen_mov_i32(dc->next_icount, arg[0].in);
2561 } else {
2562 tcg_gen_mov_i32(cpu_SR[par[0]], arg[0].in);
2563 }
2564 #endif
2565 }
2566
translate_wsr_intclear(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2567 static void translate_wsr_intclear(DisasContext *dc, const OpcodeArg arg[],
2568 const uint32_t par[])
2569 {
2570 #ifndef CONFIG_USER_ONLY
2571 gen_helper_intclear(tcg_env, arg[0].in);
2572 #endif
2573 }
2574
translate_wsr_intset(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2575 static void translate_wsr_intset(DisasContext *dc, const OpcodeArg arg[],
2576 const uint32_t par[])
2577 {
2578 #ifndef CONFIG_USER_ONLY
2579 gen_helper_intset(tcg_env, arg[0].in);
2580 #endif
2581 }
2582
translate_wsr_memctl(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2583 static void translate_wsr_memctl(DisasContext *dc, const OpcodeArg arg[],
2584 const uint32_t par[])
2585 {
2586 #ifndef CONFIG_USER_ONLY
2587 gen_helper_wsr_memctl(tcg_env, arg[0].in);
2588 #endif
2589 }
2590
translate_wsr_mpuenb(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2591 static void translate_wsr_mpuenb(DisasContext *dc, const OpcodeArg arg[],
2592 const uint32_t par[])
2593 {
2594 #ifndef CONFIG_USER_ONLY
2595 gen_helper_wsr_mpuenb(tcg_env, arg[0].in);
2596 #endif
2597 }
2598
translate_wsr_ps(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2599 static void translate_wsr_ps(DisasContext *dc, const OpcodeArg arg[],
2600 const uint32_t par[])
2601 {
2602 #ifndef CONFIG_USER_ONLY
2603 uint32_t mask = PS_WOE | PS_CALLINC | PS_OWB |
2604 PS_UM | PS_EXCM | PS_INTLEVEL;
2605
2606 if (option_enabled(dc, XTENSA_OPTION_MMU) ||
2607 option_enabled(dc, XTENSA_OPTION_MPU)) {
2608 mask |= PS_RING;
2609 }
2610 tcg_gen_andi_i32(cpu_SR[par[0]], arg[0].in, mask);
2611 #endif
2612 }
2613
translate_wsr_rasid(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2614 static void translate_wsr_rasid(DisasContext *dc, const OpcodeArg arg[],
2615 const uint32_t par[])
2616 {
2617 #ifndef CONFIG_USER_ONLY
2618 gen_helper_wsr_rasid(tcg_env, arg[0].in);
2619 #endif
2620 }
2621
translate_wsr_sar(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2622 static void translate_wsr_sar(DisasContext *dc, const OpcodeArg arg[],
2623 const uint32_t par[])
2624 {
2625 tcg_gen_andi_i32(cpu_SR[par[0]], arg[0].in, 0x3f);
2626 if (dc->sar_m32_5bit) {
2627 tcg_gen_discard_i32(dc->sar_m32);
2628 }
2629 dc->sar_5bit = false;
2630 dc->sar_m32_5bit = false;
2631 }
2632
translate_wsr_windowbase(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2633 static void translate_wsr_windowbase(DisasContext *dc, const OpcodeArg arg[],
2634 const uint32_t par[])
2635 {
2636 #ifndef CONFIG_USER_ONLY
2637 tcg_gen_mov_i32(cpu_windowbase_next, arg[0].in);
2638 #endif
2639 }
2640
translate_wsr_windowstart(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2641 static void translate_wsr_windowstart(DisasContext *dc, const OpcodeArg arg[],
2642 const uint32_t par[])
2643 {
2644 #ifndef CONFIG_USER_ONLY
2645 tcg_gen_andi_i32(cpu_SR[par[0]], arg[0].in,
2646 (1 << dc->config->nareg / 4) - 1);
2647 #endif
2648 }
2649
translate_wur(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2650 static void translate_wur(DisasContext *dc, const OpcodeArg arg[],
2651 const uint32_t par[])
2652 {
2653 tcg_gen_mov_i32(cpu_UR[par[0]], arg[0].in);
2654 }
2655
translate_xor(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2656 static void translate_xor(DisasContext *dc, const OpcodeArg arg[],
2657 const uint32_t par[])
2658 {
2659 tcg_gen_xor_i32(arg[0].out, arg[1].in, arg[2].in);
2660 }
2661
translate_xsr(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2662 static void translate_xsr(DisasContext *dc, const OpcodeArg arg[],
2663 const uint32_t par[])
2664 {
2665 if (sr_name[par[0]]) {
2666 TCGv_i32 tmp = tcg_temp_new_i32();
2667
2668 tcg_gen_mov_i32(tmp, arg[0].in);
2669 tcg_gen_mov_i32(arg[0].out, cpu_SR[par[0]]);
2670 tcg_gen_mov_i32(cpu_SR[par[0]], tmp);
2671 } else {
2672 tcg_gen_movi_i32(arg[0].out, 0);
2673 }
2674 }
2675
translate_xsr_mask(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2676 static void translate_xsr_mask(DisasContext *dc, const OpcodeArg arg[],
2677 const uint32_t par[])
2678 {
2679 if (sr_name[par[0]]) {
2680 TCGv_i32 tmp = tcg_temp_new_i32();
2681
2682 tcg_gen_mov_i32(tmp, arg[0].in);
2683 tcg_gen_mov_i32(arg[0].out, cpu_SR[par[0]]);
2684 tcg_gen_andi_i32(cpu_SR[par[0]], tmp, par[2]);
2685 } else {
2686 tcg_gen_movi_i32(arg[0].out, 0);
2687 }
2688 }
2689
translate_xsr_ccount(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])2690 static void translate_xsr_ccount(DisasContext *dc, const OpcodeArg arg[],
2691 const uint32_t par[])
2692 {
2693 #ifndef CONFIG_USER_ONLY
2694 TCGv_i32 tmp = tcg_temp_new_i32();
2695
2696 translator_io_start(&dc->base);
2697 gen_helper_update_ccount(tcg_env);
2698 tcg_gen_mov_i32(tmp, cpu_SR[par[0]]);
2699 gen_helper_wsr_ccount(tcg_env, arg[0].in);
2700 tcg_gen_mov_i32(arg[0].out, tmp);
2701
2702 #endif
2703 }
2704
2705 #define gen_translate_xsr(name) \
2706 static void translate_xsr_##name(DisasContext *dc, const OpcodeArg arg[], \
2707 const uint32_t par[]) \
2708 { \
2709 TCGv_i32 tmp = tcg_temp_new_i32(); \
2710 \
2711 if (sr_name[par[0]]) { \
2712 tcg_gen_mov_i32(tmp, cpu_SR[par[0]]); \
2713 } else { \
2714 tcg_gen_movi_i32(tmp, 0); \
2715 } \
2716 translate_wsr_##name(dc, arg, par); \
2717 tcg_gen_mov_i32(arg[0].out, tmp); \
2718 }
2719
2720 gen_translate_xsr(acchi)
2721 gen_translate_xsr(ccompare)
2722 gen_translate_xsr(dbreaka)
2723 gen_translate_xsr(dbreakc)
2724 gen_translate_xsr(ibreaka)
2725 gen_translate_xsr(ibreakenable)
2726 gen_translate_xsr(icount)
2727 gen_translate_xsr(memctl)
2728 gen_translate_xsr(mpuenb)
2729 gen_translate_xsr(ps)
2730 gen_translate_xsr(rasid)
2731 gen_translate_xsr(sar)
2732 gen_translate_xsr(windowbase)
2733 gen_translate_xsr(windowstart)
2734
2735 #undef gen_translate_xsr
2736
2737 static const XtensaOpcodeOps core_ops[] = {
2738 {
2739 .name = "abs",
2740 .translate = translate_abs,
2741 }, {
2742 .name = (const char * const[]) {
2743 "add", "add.n", NULL,
2744 },
2745 .translate = translate_add,
2746 .op_flags = XTENSA_OP_NAME_ARRAY,
2747 }, {
2748 .name = (const char * const[]) {
2749 "addi", "addi.n", NULL,
2750 },
2751 .translate = translate_addi,
2752 .op_flags = XTENSA_OP_NAME_ARRAY,
2753 }, {
2754 .name = "addmi",
2755 .translate = translate_addi,
2756 }, {
2757 .name = "addx2",
2758 .translate = translate_addx,
2759 .par = (const uint32_t[]){1},
2760 }, {
2761 .name = "addx4",
2762 .translate = translate_addx,
2763 .par = (const uint32_t[]){2},
2764 }, {
2765 .name = "addx8",
2766 .translate = translate_addx,
2767 .par = (const uint32_t[]){3},
2768 }, {
2769 .name = "all4",
2770 .translate = translate_all,
2771 .par = (const uint32_t[]){true, 4},
2772 }, {
2773 .name = "all8",
2774 .translate = translate_all,
2775 .par = (const uint32_t[]){true, 8},
2776 }, {
2777 .name = "and",
2778 .translate = translate_and,
2779 }, {
2780 .name = "andb",
2781 .translate = translate_boolean,
2782 .par = (const uint32_t[]){BOOLEAN_AND},
2783 }, {
2784 .name = "andbc",
2785 .translate = translate_boolean,
2786 .par = (const uint32_t[]){BOOLEAN_ANDC},
2787 }, {
2788 .name = "any4",
2789 .translate = translate_all,
2790 .par = (const uint32_t[]){false, 4},
2791 }, {
2792 .name = "any8",
2793 .translate = translate_all,
2794 .par = (const uint32_t[]){false, 8},
2795 }, {
2796 .name = (const char * const[]) {
2797 "ball", "ball.w15", "ball.w18", NULL,
2798 },
2799 .translate = translate_ball,
2800 .par = (const uint32_t[]){TCG_COND_EQ},
2801 .op_flags = XTENSA_OP_NAME_ARRAY,
2802 }, {
2803 .name = (const char * const[]) {
2804 "bany", "bany.w15", "bany.w18", NULL,
2805 },
2806 .translate = translate_bany,
2807 .par = (const uint32_t[]){TCG_COND_NE},
2808 .op_flags = XTENSA_OP_NAME_ARRAY,
2809 }, {
2810 .name = (const char * const[]) {
2811 "bbc", "bbc.w15", "bbc.w18", NULL,
2812 },
2813 .translate = translate_bb,
2814 .par = (const uint32_t[]){TCG_COND_EQ},
2815 .op_flags = XTENSA_OP_NAME_ARRAY,
2816 }, {
2817 .name = (const char * const[]) {
2818 "bbci", "bbci.w15", "bbci.w18", NULL,
2819 },
2820 .translate = translate_bbi,
2821 .par = (const uint32_t[]){TCG_COND_EQ},
2822 .op_flags = XTENSA_OP_NAME_ARRAY,
2823 }, {
2824 .name = (const char * const[]) {
2825 "bbs", "bbs.w15", "bbs.w18", NULL,
2826 },
2827 .translate = translate_bb,
2828 .par = (const uint32_t[]){TCG_COND_NE},
2829 .op_flags = XTENSA_OP_NAME_ARRAY,
2830 }, {
2831 .name = (const char * const[]) {
2832 "bbsi", "bbsi.w15", "bbsi.w18", NULL,
2833 },
2834 .translate = translate_bbi,
2835 .par = (const uint32_t[]){TCG_COND_NE},
2836 .op_flags = XTENSA_OP_NAME_ARRAY,
2837 }, {
2838 .name = (const char * const[]) {
2839 "beq", "beq.w15", "beq.w18", NULL,
2840 },
2841 .translate = translate_b,
2842 .par = (const uint32_t[]){TCG_COND_EQ},
2843 .op_flags = XTENSA_OP_NAME_ARRAY,
2844 }, {
2845 .name = (const char * const[]) {
2846 "beqi", "beqi.w15", "beqi.w18", NULL,
2847 },
2848 .translate = translate_bi,
2849 .par = (const uint32_t[]){TCG_COND_EQ},
2850 .op_flags = XTENSA_OP_NAME_ARRAY,
2851 }, {
2852 .name = (const char * const[]) {
2853 "beqz", "beqz.n", "beqz.w15", "beqz.w18", NULL,
2854 },
2855 .translate = translate_bz,
2856 .par = (const uint32_t[]){TCG_COND_EQ},
2857 .op_flags = XTENSA_OP_NAME_ARRAY,
2858 }, {
2859 .name = "bf",
2860 .translate = translate_bp,
2861 .par = (const uint32_t[]){TCG_COND_EQ},
2862 }, {
2863 .name = (const char * const[]) {
2864 "bge", "bge.w15", "bge.w18", NULL,
2865 },
2866 .translate = translate_b,
2867 .par = (const uint32_t[]){TCG_COND_GE},
2868 .op_flags = XTENSA_OP_NAME_ARRAY,
2869 }, {
2870 .name = (const char * const[]) {
2871 "bgei", "bgei.w15", "bgei.w18", NULL,
2872 },
2873 .translate = translate_bi,
2874 .par = (const uint32_t[]){TCG_COND_GE},
2875 .op_flags = XTENSA_OP_NAME_ARRAY,
2876 }, {
2877 .name = (const char * const[]) {
2878 "bgeu", "bgeu.w15", "bgeu.w18", NULL,
2879 },
2880 .translate = translate_b,
2881 .par = (const uint32_t[]){TCG_COND_GEU},
2882 .op_flags = XTENSA_OP_NAME_ARRAY,
2883 }, {
2884 .name = (const char * const[]) {
2885 "bgeui", "bgeui.w15", "bgeui.w18", NULL,
2886 },
2887 .translate = translate_bi,
2888 .par = (const uint32_t[]){TCG_COND_GEU},
2889 .op_flags = XTENSA_OP_NAME_ARRAY,
2890 }, {
2891 .name = (const char * const[]) {
2892 "bgez", "bgez.w15", "bgez.w18", NULL,
2893 },
2894 .translate = translate_bz,
2895 .par = (const uint32_t[]){TCG_COND_GE},
2896 .op_flags = XTENSA_OP_NAME_ARRAY,
2897 }, {
2898 .name = (const char * const[]) {
2899 "blt", "blt.w15", "blt.w18", NULL,
2900 },
2901 .translate = translate_b,
2902 .par = (const uint32_t[]){TCG_COND_LT},
2903 .op_flags = XTENSA_OP_NAME_ARRAY,
2904 }, {
2905 .name = (const char * const[]) {
2906 "blti", "blti.w15", "blti.w18", NULL,
2907 },
2908 .translate = translate_bi,
2909 .par = (const uint32_t[]){TCG_COND_LT},
2910 .op_flags = XTENSA_OP_NAME_ARRAY,
2911 }, {
2912 .name = (const char * const[]) {
2913 "bltu", "bltu.w15", "bltu.w18", NULL,
2914 },
2915 .translate = translate_b,
2916 .par = (const uint32_t[]){TCG_COND_LTU},
2917 .op_flags = XTENSA_OP_NAME_ARRAY,
2918 }, {
2919 .name = (const char * const[]) {
2920 "bltui", "bltui.w15", "bltui.w18", NULL,
2921 },
2922 .translate = translate_bi,
2923 .par = (const uint32_t[]){TCG_COND_LTU},
2924 .op_flags = XTENSA_OP_NAME_ARRAY,
2925 }, {
2926 .name = (const char * const[]) {
2927 "bltz", "bltz.w15", "bltz.w18", NULL,
2928 },
2929 .translate = translate_bz,
2930 .par = (const uint32_t[]){TCG_COND_LT},
2931 .op_flags = XTENSA_OP_NAME_ARRAY,
2932 }, {
2933 .name = (const char * const[]) {
2934 "bnall", "bnall.w15", "bnall.w18", NULL,
2935 },
2936 .translate = translate_ball,
2937 .par = (const uint32_t[]){TCG_COND_NE},
2938 .op_flags = XTENSA_OP_NAME_ARRAY,
2939 }, {
2940 .name = (const char * const[]) {
2941 "bne", "bne.w15", "bne.w18", NULL,
2942 },
2943 .translate = translate_b,
2944 .par = (const uint32_t[]){TCG_COND_NE},
2945 .op_flags = XTENSA_OP_NAME_ARRAY,
2946 }, {
2947 .name = (const char * const[]) {
2948 "bnei", "bnei.w15", "bnei.w18", NULL,
2949 },
2950 .translate = translate_bi,
2951 .par = (const uint32_t[]){TCG_COND_NE},
2952 .op_flags = XTENSA_OP_NAME_ARRAY,
2953 }, {
2954 .name = (const char * const[]) {
2955 "bnez", "bnez.n", "bnez.w15", "bnez.w18", NULL,
2956 },
2957 .translate = translate_bz,
2958 .par = (const uint32_t[]){TCG_COND_NE},
2959 .op_flags = XTENSA_OP_NAME_ARRAY,
2960 }, {
2961 .name = (const char * const[]) {
2962 "bnone", "bnone.w15", "bnone.w18", NULL,
2963 },
2964 .translate = translate_bany,
2965 .par = (const uint32_t[]){TCG_COND_EQ},
2966 .op_flags = XTENSA_OP_NAME_ARRAY,
2967 }, {
2968 .name = "break",
2969 .translate = translate_nop,
2970 .par = (const uint32_t[]){DEBUGCAUSE_BI},
2971 .op_flags = XTENSA_OP_DEBUG_BREAK,
2972 }, {
2973 .name = "break.n",
2974 .translate = translate_nop,
2975 .par = (const uint32_t[]){DEBUGCAUSE_BN},
2976 .op_flags = XTENSA_OP_DEBUG_BREAK,
2977 }, {
2978 .name = "bt",
2979 .translate = translate_bp,
2980 .par = (const uint32_t[]){TCG_COND_NE},
2981 }, {
2982 .name = "call0",
2983 .translate = translate_call0,
2984 }, {
2985 .name = "call12",
2986 .translate = translate_callw,
2987 .par = (const uint32_t[]){3},
2988 }, {
2989 .name = "call4",
2990 .translate = translate_callw,
2991 .par = (const uint32_t[]){1},
2992 }, {
2993 .name = "call8",
2994 .translate = translate_callw,
2995 .par = (const uint32_t[]){2},
2996 }, {
2997 .name = "callx0",
2998 .translate = translate_callx0,
2999 }, {
3000 .name = "callx12",
3001 .translate = translate_callxw,
3002 .par = (const uint32_t[]){3},
3003 }, {
3004 .name = "callx4",
3005 .translate = translate_callxw,
3006 .par = (const uint32_t[]){1},
3007 }, {
3008 .name = "callx8",
3009 .translate = translate_callxw,
3010 .par = (const uint32_t[]){2},
3011 }, {
3012 .name = "clamps",
3013 .translate = translate_clamps,
3014 }, {
3015 .name = "clrb_expstate",
3016 .translate = translate_clrb_expstate,
3017 }, {
3018 .name = "clrex",
3019 .translate = translate_clrex,
3020 }, {
3021 .name = "const16",
3022 .translate = translate_const16,
3023 }, {
3024 .name = "depbits",
3025 .translate = translate_depbits,
3026 }, {
3027 .name = "dhi",
3028 .translate = translate_dcache,
3029 .op_flags = XTENSA_OP_PRIVILEGED,
3030 }, {
3031 .name = "dhi.b",
3032 .translate = translate_nop,
3033 }, {
3034 .name = "dhu",
3035 .translate = translate_dcache,
3036 .op_flags = XTENSA_OP_PRIVILEGED,
3037 }, {
3038 .name = "dhwb",
3039 .translate = translate_dcache,
3040 }, {
3041 .name = "dhwb.b",
3042 .translate = translate_nop,
3043 }, {
3044 .name = "dhwbi",
3045 .translate = translate_dcache,
3046 }, {
3047 .name = "dhwbi.b",
3048 .translate = translate_nop,
3049 }, {
3050 .name = "dii",
3051 .translate = translate_nop,
3052 .op_flags = XTENSA_OP_PRIVILEGED,
3053 }, {
3054 .name = "diu",
3055 .translate = translate_nop,
3056 .op_flags = XTENSA_OP_PRIVILEGED,
3057 }, {
3058 .name = "diwb",
3059 .translate = translate_nop,
3060 .op_flags = XTENSA_OP_PRIVILEGED,
3061 }, {
3062 .name = "diwbi",
3063 .translate = translate_nop,
3064 .op_flags = XTENSA_OP_PRIVILEGED,
3065 }, {
3066 .name = "diwbui.p",
3067 .translate = translate_diwbuip,
3068 .op_flags = XTENSA_OP_PRIVILEGED,
3069 }, {
3070 .name = "dpfl",
3071 .translate = translate_dcache,
3072 .op_flags = XTENSA_OP_PRIVILEGED,
3073 }, {
3074 .name = "dpfm.b",
3075 .translate = translate_nop,
3076 }, {
3077 .name = "dpfm.bf",
3078 .translate = translate_nop,
3079 }, {
3080 .name = "dpfr",
3081 .translate = translate_nop,
3082 }, {
3083 .name = "dpfr.b",
3084 .translate = translate_nop,
3085 }, {
3086 .name = "dpfr.bf",
3087 .translate = translate_nop,
3088 }, {
3089 .name = "dpfro",
3090 .translate = translate_nop,
3091 }, {
3092 .name = "dpfw",
3093 .translate = translate_nop,
3094 }, {
3095 .name = "dpfw.b",
3096 .translate = translate_nop,
3097 }, {
3098 .name = "dpfw.bf",
3099 .translate = translate_nop,
3100 }, {
3101 .name = "dpfwo",
3102 .translate = translate_nop,
3103 }, {
3104 .name = "dsync",
3105 .translate = translate_nop,
3106 }, {
3107 .name = "entry",
3108 .translate = translate_entry,
3109 .test_exceptions = test_exceptions_entry,
3110 .test_overflow = test_overflow_entry,
3111 .op_flags = XTENSA_OP_EXIT_TB_M1 |
3112 XTENSA_OP_SYNC_REGISTER_WINDOW,
3113 }, {
3114 .name = "esync",
3115 .translate = translate_nop,
3116 }, {
3117 .name = "excw",
3118 .translate = translate_nop,
3119 }, {
3120 .name = "extui",
3121 .translate = translate_extui,
3122 }, {
3123 .name = "extw",
3124 .translate = translate_memw,
3125 }, {
3126 .name = "getex",
3127 .translate = translate_getex,
3128 }, {
3129 .name = "hwwdtlba",
3130 .op_flags = XTENSA_OP_ILL,
3131 }, {
3132 .name = "hwwitlba",
3133 .op_flags = XTENSA_OP_ILL,
3134 }, {
3135 .name = "idtlb",
3136 .translate = translate_itlb,
3137 .par = (const uint32_t[]){true},
3138 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
3139 }, {
3140 .name = "ihi",
3141 .translate = translate_icache,
3142 }, {
3143 .name = "ihu",
3144 .translate = translate_icache,
3145 .op_flags = XTENSA_OP_PRIVILEGED,
3146 }, {
3147 .name = "iii",
3148 .translate = translate_nop,
3149 .op_flags = XTENSA_OP_PRIVILEGED,
3150 }, {
3151 .name = "iitlb",
3152 .translate = translate_itlb,
3153 .par = (const uint32_t[]){false},
3154 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
3155 }, {
3156 .name = "iiu",
3157 .translate = translate_nop,
3158 .op_flags = XTENSA_OP_PRIVILEGED,
3159 }, {
3160 .name = (const char * const[]) {
3161 "ill", "ill.n", NULL,
3162 },
3163 .op_flags = XTENSA_OP_ILL | XTENSA_OP_NAME_ARRAY,
3164 }, {
3165 .name = "ipf",
3166 .translate = translate_nop,
3167 }, {
3168 .name = "ipfl",
3169 .translate = translate_icache,
3170 .op_flags = XTENSA_OP_PRIVILEGED,
3171 }, {
3172 .name = "isync",
3173 .translate = translate_nop,
3174 }, {
3175 .name = "j",
3176 .translate = translate_j,
3177 }, {
3178 .name = "jx",
3179 .translate = translate_jx,
3180 }, {
3181 .name = "l16si",
3182 .translate = translate_ldst,
3183 .par = (const uint32_t[]){MO_TESW, false, false},
3184 .op_flags = XTENSA_OP_LOAD,
3185 }, {
3186 .name = "l16ui",
3187 .translate = translate_ldst,
3188 .par = (const uint32_t[]){MO_TEUW, false, false},
3189 .op_flags = XTENSA_OP_LOAD,
3190 }, {
3191 .name = "l32ai",
3192 .translate = translate_ldst,
3193 .par = (const uint32_t[]){MO_TEUL | MO_ALIGN, true, false},
3194 .op_flags = XTENSA_OP_LOAD,
3195 }, {
3196 .name = "l32e",
3197 .translate = translate_l32e,
3198 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_LOAD,
3199 }, {
3200 .name = "l32ex",
3201 .translate = translate_l32ex,
3202 .op_flags = XTENSA_OP_LOAD,
3203 }, {
3204 .name = (const char * const[]) {
3205 "l32i", "l32i.n", NULL,
3206 },
3207 .translate = translate_ldst,
3208 .par = (const uint32_t[]){MO_TEUL, false, false},
3209 .op_flags = XTENSA_OP_NAME_ARRAY | XTENSA_OP_LOAD,
3210 }, {
3211 .name = "l32r",
3212 .translate = translate_l32r,
3213 .op_flags = XTENSA_OP_LOAD,
3214 }, {
3215 .name = "l8ui",
3216 .translate = translate_ldst,
3217 .par = (const uint32_t[]){MO_UB, false, false},
3218 .op_flags = XTENSA_OP_LOAD,
3219 }, {
3220 .name = "ldct",
3221 .translate = translate_lct,
3222 .op_flags = XTENSA_OP_PRIVILEGED,
3223 }, {
3224 .name = "ldcw",
3225 .translate = translate_nop,
3226 .op_flags = XTENSA_OP_PRIVILEGED,
3227 }, {
3228 .name = "lddec",
3229 .translate = translate_mac16,
3230 .par = (const uint32_t[]){MAC16_NONE, 0, -4},
3231 .op_flags = XTENSA_OP_LOAD,
3232 }, {
3233 .name = "ldinc",
3234 .translate = translate_mac16,
3235 .par = (const uint32_t[]){MAC16_NONE, 0, 4},
3236 .op_flags = XTENSA_OP_LOAD,
3237 }, {
3238 .name = "ldpte",
3239 .op_flags = XTENSA_OP_ILL,
3240 }, {
3241 .name = "lict",
3242 .translate = translate_lct,
3243 .op_flags = XTENSA_OP_PRIVILEGED,
3244 }, {
3245 .name = "licw",
3246 .translate = translate_nop,
3247 .op_flags = XTENSA_OP_PRIVILEGED,
3248 }, {
3249 .name = (const char * const[]) {
3250 "loop", "loop.w15", NULL,
3251 },
3252 .translate = translate_loop,
3253 .par = (const uint32_t[]){TCG_COND_NEVER},
3254 .op_flags = XTENSA_OP_NAME_ARRAY,
3255 }, {
3256 .name = (const char * const[]) {
3257 "loopgtz", "loopgtz.w15", NULL,
3258 },
3259 .translate = translate_loop,
3260 .par = (const uint32_t[]){TCG_COND_GT},
3261 .op_flags = XTENSA_OP_NAME_ARRAY,
3262 }, {
3263 .name = (const char * const[]) {
3264 "loopnez", "loopnez.w15", NULL,
3265 },
3266 .translate = translate_loop,
3267 .par = (const uint32_t[]){TCG_COND_NE},
3268 .op_flags = XTENSA_OP_NAME_ARRAY,
3269 }, {
3270 .name = "max",
3271 .translate = translate_smax,
3272 }, {
3273 .name = "maxu",
3274 .translate = translate_umax,
3275 }, {
3276 .name = "memw",
3277 .translate = translate_memw,
3278 }, {
3279 .name = "min",
3280 .translate = translate_smin,
3281 }, {
3282 .name = "minu",
3283 .translate = translate_umin,
3284 }, {
3285 .name = (const char * const[]) {
3286 "mov", "mov.n", NULL,
3287 },
3288 .translate = translate_mov,
3289 .op_flags = XTENSA_OP_NAME_ARRAY,
3290 }, {
3291 .name = "moveqz",
3292 .translate = translate_movcond,
3293 .par = (const uint32_t[]){TCG_COND_EQ},
3294 }, {
3295 .name = "movf",
3296 .translate = translate_movp,
3297 .par = (const uint32_t[]){TCG_COND_EQ},
3298 }, {
3299 .name = "movgez",
3300 .translate = translate_movcond,
3301 .par = (const uint32_t[]){TCG_COND_GE},
3302 }, {
3303 .name = "movi",
3304 .translate = translate_movi,
3305 }, {
3306 .name = "movi.n",
3307 .translate = translate_movi,
3308 }, {
3309 .name = "movltz",
3310 .translate = translate_movcond,
3311 .par = (const uint32_t[]){TCG_COND_LT},
3312 }, {
3313 .name = "movnez",
3314 .translate = translate_movcond,
3315 .par = (const uint32_t[]){TCG_COND_NE},
3316 }, {
3317 .name = "movsp",
3318 .translate = translate_movsp,
3319 .op_flags = XTENSA_OP_ALLOCA,
3320 }, {
3321 .name = "movt",
3322 .translate = translate_movp,
3323 .par = (const uint32_t[]){TCG_COND_NE},
3324 }, {
3325 .name = "mul.aa.hh",
3326 .translate = translate_mac16,
3327 .par = (const uint32_t[]){MAC16_MUL, MAC16_HH, 0},
3328 }, {
3329 .name = "mul.aa.hl",
3330 .translate = translate_mac16,
3331 .par = (const uint32_t[]){MAC16_MUL, MAC16_HL, 0},
3332 }, {
3333 .name = "mul.aa.lh",
3334 .translate = translate_mac16,
3335 .par = (const uint32_t[]){MAC16_MUL, MAC16_LH, 0},
3336 }, {
3337 .name = "mul.aa.ll",
3338 .translate = translate_mac16,
3339 .par = (const uint32_t[]){MAC16_MUL, MAC16_LL, 0},
3340 }, {
3341 .name = "mul.ad.hh",
3342 .translate = translate_mac16,
3343 .par = (const uint32_t[]){MAC16_MUL, MAC16_HH, 0},
3344 }, {
3345 .name = "mul.ad.hl",
3346 .translate = translate_mac16,
3347 .par = (const uint32_t[]){MAC16_MUL, MAC16_HL, 0},
3348 }, {
3349 .name = "mul.ad.lh",
3350 .translate = translate_mac16,
3351 .par = (const uint32_t[]){MAC16_MUL, MAC16_LH, 0},
3352 }, {
3353 .name = "mul.ad.ll",
3354 .translate = translate_mac16,
3355 .par = (const uint32_t[]){MAC16_MUL, MAC16_LL, 0},
3356 }, {
3357 .name = "mul.da.hh",
3358 .translate = translate_mac16,
3359 .par = (const uint32_t[]){MAC16_MUL, MAC16_HH, 0},
3360 }, {
3361 .name = "mul.da.hl",
3362 .translate = translate_mac16,
3363 .par = (const uint32_t[]){MAC16_MUL, MAC16_HL, 0},
3364 }, {
3365 .name = "mul.da.lh",
3366 .translate = translate_mac16,
3367 .par = (const uint32_t[]){MAC16_MUL, MAC16_LH, 0},
3368 }, {
3369 .name = "mul.da.ll",
3370 .translate = translate_mac16,
3371 .par = (const uint32_t[]){MAC16_MUL, MAC16_LL, 0},
3372 }, {
3373 .name = "mul.dd.hh",
3374 .translate = translate_mac16,
3375 .par = (const uint32_t[]){MAC16_MUL, MAC16_HH, 0},
3376 }, {
3377 .name = "mul.dd.hl",
3378 .translate = translate_mac16,
3379 .par = (const uint32_t[]){MAC16_MUL, MAC16_HL, 0},
3380 }, {
3381 .name = "mul.dd.lh",
3382 .translate = translate_mac16,
3383 .par = (const uint32_t[]){MAC16_MUL, MAC16_LH, 0},
3384 }, {
3385 .name = "mul.dd.ll",
3386 .translate = translate_mac16,
3387 .par = (const uint32_t[]){MAC16_MUL, MAC16_LL, 0},
3388 }, {
3389 .name = "mul16s",
3390 .translate = translate_mul16,
3391 .par = (const uint32_t[]){true},
3392 }, {
3393 .name = "mul16u",
3394 .translate = translate_mul16,
3395 .par = (const uint32_t[]){false},
3396 }, {
3397 .name = "mula.aa.hh",
3398 .translate = translate_mac16,
3399 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 0},
3400 }, {
3401 .name = "mula.aa.hl",
3402 .translate = translate_mac16,
3403 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 0},
3404 }, {
3405 .name = "mula.aa.lh",
3406 .translate = translate_mac16,
3407 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 0},
3408 }, {
3409 .name = "mula.aa.ll",
3410 .translate = translate_mac16,
3411 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 0},
3412 }, {
3413 .name = "mula.ad.hh",
3414 .translate = translate_mac16,
3415 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 0},
3416 }, {
3417 .name = "mula.ad.hl",
3418 .translate = translate_mac16,
3419 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 0},
3420 }, {
3421 .name = "mula.ad.lh",
3422 .translate = translate_mac16,
3423 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 0},
3424 }, {
3425 .name = "mula.ad.ll",
3426 .translate = translate_mac16,
3427 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 0},
3428 }, {
3429 .name = "mula.da.hh",
3430 .translate = translate_mac16,
3431 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 0},
3432 }, {
3433 .name = "mula.da.hh.lddec",
3434 .translate = translate_mac16,
3435 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, -4},
3436 }, {
3437 .name = "mula.da.hh.ldinc",
3438 .translate = translate_mac16,
3439 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 4},
3440 }, {
3441 .name = "mula.da.hl",
3442 .translate = translate_mac16,
3443 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 0},
3444 }, {
3445 .name = "mula.da.hl.lddec",
3446 .translate = translate_mac16,
3447 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, -4},
3448 }, {
3449 .name = "mula.da.hl.ldinc",
3450 .translate = translate_mac16,
3451 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 4},
3452 }, {
3453 .name = "mula.da.lh",
3454 .translate = translate_mac16,
3455 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 0},
3456 }, {
3457 .name = "mula.da.lh.lddec",
3458 .translate = translate_mac16,
3459 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, -4},
3460 }, {
3461 .name = "mula.da.lh.ldinc",
3462 .translate = translate_mac16,
3463 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 4},
3464 }, {
3465 .name = "mula.da.ll",
3466 .translate = translate_mac16,
3467 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 0},
3468 }, {
3469 .name = "mula.da.ll.lddec",
3470 .translate = translate_mac16,
3471 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, -4},
3472 }, {
3473 .name = "mula.da.ll.ldinc",
3474 .translate = translate_mac16,
3475 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 4},
3476 }, {
3477 .name = "mula.dd.hh",
3478 .translate = translate_mac16,
3479 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 0},
3480 }, {
3481 .name = "mula.dd.hh.lddec",
3482 .translate = translate_mac16,
3483 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, -4},
3484 }, {
3485 .name = "mula.dd.hh.ldinc",
3486 .translate = translate_mac16,
3487 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 4},
3488 }, {
3489 .name = "mula.dd.hl",
3490 .translate = translate_mac16,
3491 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 0},
3492 }, {
3493 .name = "mula.dd.hl.lddec",
3494 .translate = translate_mac16,
3495 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, -4},
3496 }, {
3497 .name = "mula.dd.hl.ldinc",
3498 .translate = translate_mac16,
3499 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 4},
3500 }, {
3501 .name = "mula.dd.lh",
3502 .translate = translate_mac16,
3503 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 0},
3504 }, {
3505 .name = "mula.dd.lh.lddec",
3506 .translate = translate_mac16,
3507 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, -4},
3508 }, {
3509 .name = "mula.dd.lh.ldinc",
3510 .translate = translate_mac16,
3511 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 4},
3512 }, {
3513 .name = "mula.dd.ll",
3514 .translate = translate_mac16,
3515 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 0},
3516 }, {
3517 .name = "mula.dd.ll.lddec",
3518 .translate = translate_mac16,
3519 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, -4},
3520 }, {
3521 .name = "mula.dd.ll.ldinc",
3522 .translate = translate_mac16,
3523 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 4},
3524 }, {
3525 .name = "mull",
3526 .translate = translate_mull,
3527 }, {
3528 .name = "muls.aa.hh",
3529 .translate = translate_mac16,
3530 .par = (const uint32_t[]){MAC16_MULS, MAC16_HH, 0},
3531 }, {
3532 .name = "muls.aa.hl",
3533 .translate = translate_mac16,
3534 .par = (const uint32_t[]){MAC16_MULS, MAC16_HL, 0},
3535 }, {
3536 .name = "muls.aa.lh",
3537 .translate = translate_mac16,
3538 .par = (const uint32_t[]){MAC16_MULS, MAC16_LH, 0},
3539 }, {
3540 .name = "muls.aa.ll",
3541 .translate = translate_mac16,
3542 .par = (const uint32_t[]){MAC16_MULS, MAC16_LL, 0},
3543 }, {
3544 .name = "muls.ad.hh",
3545 .translate = translate_mac16,
3546 .par = (const uint32_t[]){MAC16_MULS, MAC16_HH, 0},
3547 }, {
3548 .name = "muls.ad.hl",
3549 .translate = translate_mac16,
3550 .par = (const uint32_t[]){MAC16_MULS, MAC16_HL, 0},
3551 }, {
3552 .name = "muls.ad.lh",
3553 .translate = translate_mac16,
3554 .par = (const uint32_t[]){MAC16_MULS, MAC16_LH, 0},
3555 }, {
3556 .name = "muls.ad.ll",
3557 .translate = translate_mac16,
3558 .par = (const uint32_t[]){MAC16_MULS, MAC16_LL, 0},
3559 }, {
3560 .name = "muls.da.hh",
3561 .translate = translate_mac16,
3562 .par = (const uint32_t[]){MAC16_MULS, MAC16_HH, 0},
3563 }, {
3564 .name = "muls.da.hl",
3565 .translate = translate_mac16,
3566 .par = (const uint32_t[]){MAC16_MULS, MAC16_HL, 0},
3567 }, {
3568 .name = "muls.da.lh",
3569 .translate = translate_mac16,
3570 .par = (const uint32_t[]){MAC16_MULS, MAC16_LH, 0},
3571 }, {
3572 .name = "muls.da.ll",
3573 .translate = translate_mac16,
3574 .par = (const uint32_t[]){MAC16_MULS, MAC16_LL, 0},
3575 }, {
3576 .name = "muls.dd.hh",
3577 .translate = translate_mac16,
3578 .par = (const uint32_t[]){MAC16_MULS, MAC16_HH, 0},
3579 }, {
3580 .name = "muls.dd.hl",
3581 .translate = translate_mac16,
3582 .par = (const uint32_t[]){MAC16_MULS, MAC16_HL, 0},
3583 }, {
3584 .name = "muls.dd.lh",
3585 .translate = translate_mac16,
3586 .par = (const uint32_t[]){MAC16_MULS, MAC16_LH, 0},
3587 }, {
3588 .name = "muls.dd.ll",
3589 .translate = translate_mac16,
3590 .par = (const uint32_t[]){MAC16_MULS, MAC16_LL, 0},
3591 }, {
3592 .name = "mulsh",
3593 .translate = translate_mulh,
3594 .par = (const uint32_t[]){true},
3595 }, {
3596 .name = "muluh",
3597 .translate = translate_mulh,
3598 .par = (const uint32_t[]){false},
3599 }, {
3600 .name = "neg",
3601 .translate = translate_neg,
3602 }, {
3603 .name = (const char * const[]) {
3604 "nop", "nop.n", NULL,
3605 },
3606 .translate = translate_nop,
3607 .op_flags = XTENSA_OP_NAME_ARRAY,
3608 }, {
3609 .name = "nsa",
3610 .translate = translate_nsa,
3611 }, {
3612 .name = "nsau",
3613 .translate = translate_nsau,
3614 }, {
3615 .name = "or",
3616 .translate = translate_or,
3617 }, {
3618 .name = "orb",
3619 .translate = translate_boolean,
3620 .par = (const uint32_t[]){BOOLEAN_OR},
3621 }, {
3622 .name = "orbc",
3623 .translate = translate_boolean,
3624 .par = (const uint32_t[]){BOOLEAN_ORC},
3625 }, {
3626 .name = "pdtlb",
3627 .translate = translate_ptlb,
3628 .par = (const uint32_t[]){true},
3629 .op_flags = XTENSA_OP_PRIVILEGED,
3630 }, {
3631 .name = "pfend.a",
3632 .translate = translate_nop,
3633 }, {
3634 .name = "pfend.o",
3635 .translate = translate_nop,
3636 }, {
3637 .name = "pfnxt.f",
3638 .translate = translate_nop,
3639 }, {
3640 .name = "pfwait.a",
3641 .translate = translate_nop,
3642 }, {
3643 .name = "pfwait.r",
3644 .translate = translate_nop,
3645 }, {
3646 .name = "pitlb",
3647 .translate = translate_ptlb,
3648 .par = (const uint32_t[]){false},
3649 .op_flags = XTENSA_OP_PRIVILEGED,
3650 }, {
3651 .name = "pptlb",
3652 .translate = translate_pptlb,
3653 .op_flags = XTENSA_OP_PRIVILEGED,
3654 }, {
3655 .name = "quos",
3656 .translate = translate_quos,
3657 .par = (const uint32_t[]){true},
3658 .op_flags = XTENSA_OP_DIVIDE_BY_ZERO,
3659 }, {
3660 .name = "quou",
3661 .translate = translate_quou,
3662 .op_flags = XTENSA_OP_DIVIDE_BY_ZERO,
3663 }, {
3664 .name = "rdtlb0",
3665 .translate = translate_rtlb,
3666 .par = (const uint32_t[]){true, 0},
3667 .op_flags = XTENSA_OP_PRIVILEGED,
3668 }, {
3669 .name = "rdtlb1",
3670 .translate = translate_rtlb,
3671 .par = (const uint32_t[]){true, 1},
3672 .op_flags = XTENSA_OP_PRIVILEGED,
3673 }, {
3674 .name = "read_impwire",
3675 .translate = translate_read_impwire,
3676 }, {
3677 .name = "rems",
3678 .translate = translate_quos,
3679 .par = (const uint32_t[]){false},
3680 .op_flags = XTENSA_OP_DIVIDE_BY_ZERO,
3681 }, {
3682 .name = "remu",
3683 .translate = translate_remu,
3684 .op_flags = XTENSA_OP_DIVIDE_BY_ZERO,
3685 }, {
3686 .name = "rer",
3687 .translate = translate_rer,
3688 .op_flags = XTENSA_OP_PRIVILEGED,
3689 }, {
3690 .name = (const char * const[]) {
3691 "ret", "ret.n", NULL,
3692 },
3693 .translate = translate_ret,
3694 .op_flags = XTENSA_OP_NAME_ARRAY,
3695 }, {
3696 .name = (const char * const[]) {
3697 "retw", "retw.n", NULL,
3698 },
3699 .translate = translate_retw,
3700 .test_exceptions = test_exceptions_retw,
3701 .op_flags = XTENSA_OP_UNDERFLOW | XTENSA_OP_NAME_ARRAY,
3702 }, {
3703 .name = "rfdd",
3704 .op_flags = XTENSA_OP_ILL,
3705 }, {
3706 .name = "rfde",
3707 .translate = translate_rfde,
3708 .op_flags = XTENSA_OP_PRIVILEGED,
3709 }, {
3710 .name = "rfdo",
3711 .op_flags = XTENSA_OP_ILL,
3712 }, {
3713 .name = "rfe",
3714 .translate = translate_rfe,
3715 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_CHECK_INTERRUPTS,
3716 }, {
3717 .name = "rfi",
3718 .translate = translate_rfi,
3719 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_CHECK_INTERRUPTS,
3720 }, {
3721 .name = "rfwo",
3722 .translate = translate_rfw,
3723 .par = (const uint32_t[]){true},
3724 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_CHECK_INTERRUPTS,
3725 }, {
3726 .name = "rfwu",
3727 .translate = translate_rfw,
3728 .par = (const uint32_t[]){false},
3729 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_CHECK_INTERRUPTS,
3730 }, {
3731 .name = "ritlb0",
3732 .translate = translate_rtlb,
3733 .par = (const uint32_t[]){false, 0},
3734 .op_flags = XTENSA_OP_PRIVILEGED,
3735 }, {
3736 .name = "ritlb1",
3737 .translate = translate_rtlb,
3738 .par = (const uint32_t[]){false, 1},
3739 .op_flags = XTENSA_OP_PRIVILEGED,
3740 }, {
3741 .name = "rptlb0",
3742 .translate = translate_rptlb0,
3743 .op_flags = XTENSA_OP_PRIVILEGED,
3744 }, {
3745 .name = "rptlb1",
3746 .translate = translate_rptlb1,
3747 .op_flags = XTENSA_OP_PRIVILEGED,
3748 }, {
3749 .name = "rotw",
3750 .translate = translate_rotw,
3751 .op_flags = XTENSA_OP_PRIVILEGED |
3752 XTENSA_OP_EXIT_TB_M1 |
3753 XTENSA_OP_SYNC_REGISTER_WINDOW,
3754 }, {
3755 .name = "rsil",
3756 .translate = translate_rsil,
3757 .op_flags =
3758 XTENSA_OP_PRIVILEGED |
3759 XTENSA_OP_EXIT_TB_0 |
3760 XTENSA_OP_CHECK_INTERRUPTS,
3761 }, {
3762 .name = "rsr.176",
3763 .translate = translate_rsr,
3764 .par = (const uint32_t[]){176},
3765 .op_flags = XTENSA_OP_PRIVILEGED,
3766 }, {
3767 .name = "rsr.208",
3768 .translate = translate_rsr,
3769 .par = (const uint32_t[]){208},
3770 .op_flags = XTENSA_OP_PRIVILEGED,
3771 }, {
3772 .name = "rsr.acchi",
3773 .translate = translate_rsr,
3774 .test_exceptions = test_exceptions_sr,
3775 .par = (const uint32_t[]){
3776 ACCHI,
3777 XTENSA_OPTION_MAC16,
3778 },
3779 }, {
3780 .name = "rsr.acclo",
3781 .translate = translate_rsr,
3782 .test_exceptions = test_exceptions_sr,
3783 .par = (const uint32_t[]){
3784 ACCLO,
3785 XTENSA_OPTION_MAC16,
3786 },
3787 }, {
3788 .name = "rsr.atomctl",
3789 .translate = translate_rsr,
3790 .test_exceptions = test_exceptions_sr,
3791 .par = (const uint32_t[]){
3792 ATOMCTL,
3793 XTENSA_OPTION_ATOMCTL,
3794 },
3795 .op_flags = XTENSA_OP_PRIVILEGED,
3796 }, {
3797 .name = "rsr.br",
3798 .translate = translate_rsr,
3799 .test_exceptions = test_exceptions_sr,
3800 .par = (const uint32_t[]){
3801 BR,
3802 XTENSA_OPTION_BOOLEAN,
3803 },
3804 }, {
3805 .name = "rsr.cacheadrdis",
3806 .translate = translate_rsr,
3807 .test_exceptions = test_exceptions_sr,
3808 .par = (const uint32_t[]){
3809 CACHEADRDIS,
3810 XTENSA_OPTION_MPU,
3811 },
3812 .op_flags = XTENSA_OP_PRIVILEGED,
3813 }, {
3814 .name = "rsr.cacheattr",
3815 .translate = translate_rsr,
3816 .test_exceptions = test_exceptions_sr,
3817 .par = (const uint32_t[]){
3818 CACHEATTR,
3819 XTENSA_OPTION_CACHEATTR,
3820 },
3821 .op_flags = XTENSA_OP_PRIVILEGED,
3822 }, {
3823 .name = "rsr.ccompare0",
3824 .translate = translate_rsr,
3825 .test_exceptions = test_exceptions_ccompare,
3826 .par = (const uint32_t[]){
3827 CCOMPARE,
3828 XTENSA_OPTION_TIMER_INTERRUPT,
3829 },
3830 .op_flags = XTENSA_OP_PRIVILEGED,
3831 }, {
3832 .name = "rsr.ccompare1",
3833 .translate = translate_rsr,
3834 .test_exceptions = test_exceptions_ccompare,
3835 .par = (const uint32_t[]){
3836 CCOMPARE + 1,
3837 XTENSA_OPTION_TIMER_INTERRUPT,
3838 },
3839 .op_flags = XTENSA_OP_PRIVILEGED,
3840 }, {
3841 .name = "rsr.ccompare2",
3842 .translate = translate_rsr,
3843 .test_exceptions = test_exceptions_ccompare,
3844 .par = (const uint32_t[]){
3845 CCOMPARE + 2,
3846 XTENSA_OPTION_TIMER_INTERRUPT,
3847 },
3848 .op_flags = XTENSA_OP_PRIVILEGED,
3849 }, {
3850 .name = "rsr.ccount",
3851 .translate = translate_rsr_ccount,
3852 .test_exceptions = test_exceptions_sr,
3853 .par = (const uint32_t[]){
3854 CCOUNT,
3855 XTENSA_OPTION_TIMER_INTERRUPT,
3856 },
3857 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
3858 }, {
3859 .name = "rsr.configid0",
3860 .translate = translate_rsr,
3861 .par = (const uint32_t[]){CONFIGID0},
3862 .op_flags = XTENSA_OP_PRIVILEGED,
3863 }, {
3864 .name = "rsr.configid1",
3865 .translate = translate_rsr,
3866 .par = (const uint32_t[]){CONFIGID1},
3867 .op_flags = XTENSA_OP_PRIVILEGED,
3868 }, {
3869 .name = "rsr.cpenable",
3870 .translate = translate_rsr,
3871 .test_exceptions = test_exceptions_sr,
3872 .par = (const uint32_t[]){
3873 CPENABLE,
3874 XTENSA_OPTION_COPROCESSOR,
3875 },
3876 .op_flags = XTENSA_OP_PRIVILEGED,
3877 }, {
3878 .name = "rsr.dbreaka0",
3879 .translate = translate_rsr,
3880 .test_exceptions = test_exceptions_dbreak,
3881 .par = (const uint32_t[]){
3882 DBREAKA,
3883 XTENSA_OPTION_DEBUG,
3884 },
3885 .op_flags = XTENSA_OP_PRIVILEGED,
3886 }, {
3887 .name = "rsr.dbreaka1",
3888 .translate = translate_rsr,
3889 .test_exceptions = test_exceptions_dbreak,
3890 .par = (const uint32_t[]){
3891 DBREAKA + 1,
3892 XTENSA_OPTION_DEBUG,
3893 },
3894 .op_flags = XTENSA_OP_PRIVILEGED,
3895 }, {
3896 .name = "rsr.dbreakc0",
3897 .translate = translate_rsr,
3898 .test_exceptions = test_exceptions_dbreak,
3899 .par = (const uint32_t[]){
3900 DBREAKC,
3901 XTENSA_OPTION_DEBUG,
3902 },
3903 .op_flags = XTENSA_OP_PRIVILEGED,
3904 }, {
3905 .name = "rsr.dbreakc1",
3906 .translate = translate_rsr,
3907 .test_exceptions = test_exceptions_dbreak,
3908 .par = (const uint32_t[]){
3909 DBREAKC + 1,
3910 XTENSA_OPTION_DEBUG,
3911 },
3912 .op_flags = XTENSA_OP_PRIVILEGED,
3913 }, {
3914 .name = "rsr.ddr",
3915 .translate = translate_rsr,
3916 .test_exceptions = test_exceptions_sr,
3917 .par = (const uint32_t[]){
3918 DDR,
3919 XTENSA_OPTION_DEBUG,
3920 },
3921 .op_flags = XTENSA_OP_PRIVILEGED,
3922 }, {
3923 .name = "rsr.debugcause",
3924 .translate = translate_rsr,
3925 .test_exceptions = test_exceptions_sr,
3926 .par = (const uint32_t[]){
3927 DEBUGCAUSE,
3928 XTENSA_OPTION_DEBUG,
3929 },
3930 .op_flags = XTENSA_OP_PRIVILEGED,
3931 }, {
3932 .name = "rsr.depc",
3933 .translate = translate_rsr,
3934 .test_exceptions = test_exceptions_sr,
3935 .par = (const uint32_t[]){
3936 DEPC,
3937 XTENSA_OPTION_EXCEPTION,
3938 },
3939 .op_flags = XTENSA_OP_PRIVILEGED,
3940 }, {
3941 .name = "rsr.dtlbcfg",
3942 .translate = translate_rsr,
3943 .test_exceptions = test_exceptions_sr,
3944 .par = (const uint32_t[]){
3945 DTLBCFG,
3946 XTENSA_OPTION_MMU,
3947 },
3948 .op_flags = XTENSA_OP_PRIVILEGED,
3949 }, {
3950 .name = "rsr.epc1",
3951 .translate = translate_rsr,
3952 .test_exceptions = test_exceptions_sr,
3953 .par = (const uint32_t[]){
3954 EPC1,
3955 XTENSA_OPTION_EXCEPTION,
3956 },
3957 .op_flags = XTENSA_OP_PRIVILEGED,
3958 }, {
3959 .name = "rsr.epc2",
3960 .translate = translate_rsr,
3961 .test_exceptions = test_exceptions_hpi,
3962 .par = (const uint32_t[]){
3963 EPC1 + 1,
3964 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
3965 },
3966 .op_flags = XTENSA_OP_PRIVILEGED,
3967 }, {
3968 .name = "rsr.epc3",
3969 .translate = translate_rsr,
3970 .test_exceptions = test_exceptions_hpi,
3971 .par = (const uint32_t[]){
3972 EPC1 + 2,
3973 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
3974 },
3975 .op_flags = XTENSA_OP_PRIVILEGED,
3976 }, {
3977 .name = "rsr.epc4",
3978 .translate = translate_rsr,
3979 .test_exceptions = test_exceptions_hpi,
3980 .par = (const uint32_t[]){
3981 EPC1 + 3,
3982 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
3983 },
3984 .op_flags = XTENSA_OP_PRIVILEGED,
3985 }, {
3986 .name = "rsr.epc5",
3987 .translate = translate_rsr,
3988 .test_exceptions = test_exceptions_hpi,
3989 .par = (const uint32_t[]){
3990 EPC1 + 4,
3991 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
3992 },
3993 .op_flags = XTENSA_OP_PRIVILEGED,
3994 }, {
3995 .name = "rsr.epc6",
3996 .translate = translate_rsr,
3997 .test_exceptions = test_exceptions_hpi,
3998 .par = (const uint32_t[]){
3999 EPC1 + 5,
4000 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4001 },
4002 .op_flags = XTENSA_OP_PRIVILEGED,
4003 }, {
4004 .name = "rsr.epc7",
4005 .translate = translate_rsr,
4006 .test_exceptions = test_exceptions_hpi,
4007 .par = (const uint32_t[]){
4008 EPC1 + 6,
4009 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4010 },
4011 .op_flags = XTENSA_OP_PRIVILEGED,
4012 }, {
4013 .name = "rsr.eps2",
4014 .translate = translate_rsr,
4015 .test_exceptions = test_exceptions_hpi,
4016 .par = (const uint32_t[]){
4017 EPS2,
4018 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4019 },
4020 .op_flags = XTENSA_OP_PRIVILEGED,
4021 }, {
4022 .name = "rsr.eps3",
4023 .translate = translate_rsr,
4024 .test_exceptions = test_exceptions_hpi,
4025 .par = (const uint32_t[]){
4026 EPS2 + 1,
4027 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4028 },
4029 .op_flags = XTENSA_OP_PRIVILEGED,
4030 }, {
4031 .name = "rsr.eps4",
4032 .translate = translate_rsr,
4033 .test_exceptions = test_exceptions_hpi,
4034 .par = (const uint32_t[]){
4035 EPS2 + 2,
4036 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4037 },
4038 .op_flags = XTENSA_OP_PRIVILEGED,
4039 }, {
4040 .name = "rsr.eps5",
4041 .translate = translate_rsr,
4042 .test_exceptions = test_exceptions_hpi,
4043 .par = (const uint32_t[]){
4044 EPS2 + 3,
4045 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4046 },
4047 .op_flags = XTENSA_OP_PRIVILEGED,
4048 }, {
4049 .name = "rsr.eps6",
4050 .translate = translate_rsr,
4051 .test_exceptions = test_exceptions_hpi,
4052 .par = (const uint32_t[]){
4053 EPS2 + 4,
4054 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4055 },
4056 .op_flags = XTENSA_OP_PRIVILEGED,
4057 }, {
4058 .name = "rsr.eps7",
4059 .translate = translate_rsr,
4060 .test_exceptions = test_exceptions_hpi,
4061 .par = (const uint32_t[]){
4062 EPS2 + 5,
4063 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4064 },
4065 .op_flags = XTENSA_OP_PRIVILEGED,
4066 }, {
4067 .name = "rsr.eraccess",
4068 .translate = translate_rsr,
4069 .par = (const uint32_t[]){ERACCESS},
4070 .op_flags = XTENSA_OP_PRIVILEGED,
4071 }, {
4072 .name = "rsr.exccause",
4073 .translate = translate_rsr,
4074 .test_exceptions = test_exceptions_sr,
4075 .par = (const uint32_t[]){
4076 EXCCAUSE,
4077 XTENSA_OPTION_EXCEPTION,
4078 },
4079 .op_flags = XTENSA_OP_PRIVILEGED,
4080 }, {
4081 .name = "rsr.excsave1",
4082 .translate = translate_rsr,
4083 .test_exceptions = test_exceptions_sr,
4084 .par = (const uint32_t[]){
4085 EXCSAVE1,
4086 XTENSA_OPTION_EXCEPTION,
4087 },
4088 .op_flags = XTENSA_OP_PRIVILEGED,
4089 }, {
4090 .name = "rsr.excsave2",
4091 .translate = translate_rsr,
4092 .test_exceptions = test_exceptions_hpi,
4093 .par = (const uint32_t[]){
4094 EXCSAVE1 + 1,
4095 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4096 },
4097 .op_flags = XTENSA_OP_PRIVILEGED,
4098 }, {
4099 .name = "rsr.excsave3",
4100 .translate = translate_rsr,
4101 .test_exceptions = test_exceptions_hpi,
4102 .par = (const uint32_t[]){
4103 EXCSAVE1 + 2,
4104 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4105 },
4106 .op_flags = XTENSA_OP_PRIVILEGED,
4107 }, {
4108 .name = "rsr.excsave4",
4109 .translate = translate_rsr,
4110 .test_exceptions = test_exceptions_hpi,
4111 .par = (const uint32_t[]){
4112 EXCSAVE1 + 3,
4113 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4114 },
4115 .op_flags = XTENSA_OP_PRIVILEGED,
4116 }, {
4117 .name = "rsr.excsave5",
4118 .translate = translate_rsr,
4119 .test_exceptions = test_exceptions_hpi,
4120 .par = (const uint32_t[]){
4121 EXCSAVE1 + 4,
4122 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4123 },
4124 .op_flags = XTENSA_OP_PRIVILEGED,
4125 }, {
4126 .name = "rsr.excsave6",
4127 .translate = translate_rsr,
4128 .test_exceptions = test_exceptions_hpi,
4129 .par = (const uint32_t[]){
4130 EXCSAVE1 + 5,
4131 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4132 },
4133 .op_flags = XTENSA_OP_PRIVILEGED,
4134 }, {
4135 .name = "rsr.excsave7",
4136 .translate = translate_rsr,
4137 .test_exceptions = test_exceptions_hpi,
4138 .par = (const uint32_t[]){
4139 EXCSAVE1 + 6,
4140 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4141 },
4142 .op_flags = XTENSA_OP_PRIVILEGED,
4143 }, {
4144 .name = "rsr.excvaddr",
4145 .translate = translate_rsr,
4146 .test_exceptions = test_exceptions_sr,
4147 .par = (const uint32_t[]){
4148 EXCVADDR,
4149 XTENSA_OPTION_EXCEPTION,
4150 },
4151 .op_flags = XTENSA_OP_PRIVILEGED,
4152 }, {
4153 .name = "rsr.ibreaka0",
4154 .translate = translate_rsr,
4155 .test_exceptions = test_exceptions_ibreak,
4156 .par = (const uint32_t[]){
4157 IBREAKA,
4158 XTENSA_OPTION_DEBUG,
4159 },
4160 .op_flags = XTENSA_OP_PRIVILEGED,
4161 }, {
4162 .name = "rsr.ibreaka1",
4163 .translate = translate_rsr,
4164 .test_exceptions = test_exceptions_ibreak,
4165 .par = (const uint32_t[]){
4166 IBREAKA + 1,
4167 XTENSA_OPTION_DEBUG,
4168 },
4169 .op_flags = XTENSA_OP_PRIVILEGED,
4170 }, {
4171 .name = "rsr.ibreakenable",
4172 .translate = translate_rsr,
4173 .test_exceptions = test_exceptions_sr,
4174 .par = (const uint32_t[]){
4175 IBREAKENABLE,
4176 XTENSA_OPTION_DEBUG,
4177 },
4178 .op_flags = XTENSA_OP_PRIVILEGED,
4179 }, {
4180 .name = "rsr.icount",
4181 .translate = translate_rsr,
4182 .test_exceptions = test_exceptions_sr,
4183 .par = (const uint32_t[]){
4184 ICOUNT,
4185 XTENSA_OPTION_DEBUG,
4186 },
4187 .op_flags = XTENSA_OP_PRIVILEGED,
4188 }, {
4189 .name = "rsr.icountlevel",
4190 .translate = translate_rsr,
4191 .test_exceptions = test_exceptions_sr,
4192 .par = (const uint32_t[]){
4193 ICOUNTLEVEL,
4194 XTENSA_OPTION_DEBUG,
4195 },
4196 .op_flags = XTENSA_OP_PRIVILEGED,
4197 }, {
4198 .name = "rsr.intclear",
4199 .translate = translate_rsr,
4200 .test_exceptions = test_exceptions_sr,
4201 .par = (const uint32_t[]){
4202 INTCLEAR,
4203 XTENSA_OPTION_INTERRUPT,
4204 },
4205 .op_flags = XTENSA_OP_PRIVILEGED,
4206 }, {
4207 .name = "rsr.intenable",
4208 .translate = translate_rsr,
4209 .test_exceptions = test_exceptions_sr,
4210 .par = (const uint32_t[]){
4211 INTENABLE,
4212 XTENSA_OPTION_INTERRUPT,
4213 },
4214 .op_flags = XTENSA_OP_PRIVILEGED,
4215 }, {
4216 .name = "rsr.interrupt",
4217 .translate = translate_rsr_ccount,
4218 .test_exceptions = test_exceptions_sr,
4219 .par = (const uint32_t[]){
4220 INTSET,
4221 XTENSA_OPTION_INTERRUPT,
4222 },
4223 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
4224 }, {
4225 .name = "rsr.intset",
4226 .translate = translate_rsr_ccount,
4227 .test_exceptions = test_exceptions_sr,
4228 .par = (const uint32_t[]){
4229 INTSET,
4230 XTENSA_OPTION_INTERRUPT,
4231 },
4232 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
4233 }, {
4234 .name = "rsr.itlbcfg",
4235 .translate = translate_rsr,
4236 .test_exceptions = test_exceptions_sr,
4237 .par = (const uint32_t[]){
4238 ITLBCFG,
4239 XTENSA_OPTION_MMU,
4240 },
4241 .op_flags = XTENSA_OP_PRIVILEGED,
4242 }, {
4243 .name = "rsr.lbeg",
4244 .translate = translate_rsr,
4245 .test_exceptions = test_exceptions_sr,
4246 .par = (const uint32_t[]){
4247 LBEG,
4248 XTENSA_OPTION_LOOP,
4249 },
4250 }, {
4251 .name = "rsr.lcount",
4252 .translate = translate_rsr,
4253 .test_exceptions = test_exceptions_sr,
4254 .par = (const uint32_t[]){
4255 LCOUNT,
4256 XTENSA_OPTION_LOOP,
4257 },
4258 }, {
4259 .name = "rsr.lend",
4260 .translate = translate_rsr,
4261 .test_exceptions = test_exceptions_sr,
4262 .par = (const uint32_t[]){
4263 LEND,
4264 XTENSA_OPTION_LOOP,
4265 },
4266 }, {
4267 .name = "rsr.litbase",
4268 .translate = translate_rsr,
4269 .test_exceptions = test_exceptions_sr,
4270 .par = (const uint32_t[]){
4271 LITBASE,
4272 XTENSA_OPTION_EXTENDED_L32R,
4273 },
4274 }, {
4275 .name = "rsr.m0",
4276 .translate = translate_rsr,
4277 .test_exceptions = test_exceptions_sr,
4278 .par = (const uint32_t[]){
4279 MR,
4280 XTENSA_OPTION_MAC16,
4281 },
4282 }, {
4283 .name = "rsr.m1",
4284 .translate = translate_rsr,
4285 .test_exceptions = test_exceptions_sr,
4286 .par = (const uint32_t[]){
4287 MR + 1,
4288 XTENSA_OPTION_MAC16,
4289 },
4290 }, {
4291 .name = "rsr.m2",
4292 .translate = translate_rsr,
4293 .test_exceptions = test_exceptions_sr,
4294 .par = (const uint32_t[]){
4295 MR + 2,
4296 XTENSA_OPTION_MAC16,
4297 },
4298 }, {
4299 .name = "rsr.m3",
4300 .translate = translate_rsr,
4301 .test_exceptions = test_exceptions_sr,
4302 .par = (const uint32_t[]){
4303 MR + 3,
4304 XTENSA_OPTION_MAC16,
4305 },
4306 }, {
4307 .name = "rsr.memctl",
4308 .translate = translate_rsr,
4309 .par = (const uint32_t[]){MEMCTL},
4310 .op_flags = XTENSA_OP_PRIVILEGED,
4311 }, {
4312 .name = "rsr.mecr",
4313 .translate = translate_rsr,
4314 .test_exceptions = test_exceptions_sr,
4315 .par = (const uint32_t[]){
4316 MECR,
4317 XTENSA_OPTION_MEMORY_ECC_PARITY,
4318 },
4319 .op_flags = XTENSA_OP_PRIVILEGED,
4320 }, {
4321 .name = "rsr.mepc",
4322 .translate = translate_rsr,
4323 .test_exceptions = test_exceptions_sr,
4324 .par = (const uint32_t[]){
4325 MEPC,
4326 XTENSA_OPTION_MEMORY_ECC_PARITY,
4327 },
4328 .op_flags = XTENSA_OP_PRIVILEGED,
4329 }, {
4330 .name = "rsr.meps",
4331 .translate = translate_rsr,
4332 .test_exceptions = test_exceptions_sr,
4333 .par = (const uint32_t[]){
4334 MEPS,
4335 XTENSA_OPTION_MEMORY_ECC_PARITY,
4336 },
4337 .op_flags = XTENSA_OP_PRIVILEGED,
4338 }, {
4339 .name = "rsr.mesave",
4340 .translate = translate_rsr,
4341 .test_exceptions = test_exceptions_sr,
4342 .par = (const uint32_t[]){
4343 MESAVE,
4344 XTENSA_OPTION_MEMORY_ECC_PARITY,
4345 },
4346 .op_flags = XTENSA_OP_PRIVILEGED,
4347 }, {
4348 .name = "rsr.mesr",
4349 .translate = translate_rsr,
4350 .test_exceptions = test_exceptions_sr,
4351 .par = (const uint32_t[]){
4352 MESR,
4353 XTENSA_OPTION_MEMORY_ECC_PARITY,
4354 },
4355 .op_flags = XTENSA_OP_PRIVILEGED,
4356 }, {
4357 .name = "rsr.mevaddr",
4358 .translate = translate_rsr,
4359 .test_exceptions = test_exceptions_sr,
4360 .par = (const uint32_t[]){
4361 MESR,
4362 XTENSA_OPTION_MEMORY_ECC_PARITY,
4363 },
4364 .op_flags = XTENSA_OP_PRIVILEGED,
4365 }, {
4366 .name = "rsr.misc0",
4367 .translate = translate_rsr,
4368 .test_exceptions = test_exceptions_sr,
4369 .par = (const uint32_t[]){
4370 MISC,
4371 XTENSA_OPTION_MISC_SR,
4372 },
4373 .op_flags = XTENSA_OP_PRIVILEGED,
4374 }, {
4375 .name = "rsr.misc1",
4376 .translate = translate_rsr,
4377 .test_exceptions = test_exceptions_sr,
4378 .par = (const uint32_t[]){
4379 MISC + 1,
4380 XTENSA_OPTION_MISC_SR,
4381 },
4382 .op_flags = XTENSA_OP_PRIVILEGED,
4383 }, {
4384 .name = "rsr.misc2",
4385 .translate = translate_rsr,
4386 .test_exceptions = test_exceptions_sr,
4387 .par = (const uint32_t[]){
4388 MISC + 2,
4389 XTENSA_OPTION_MISC_SR,
4390 },
4391 .op_flags = XTENSA_OP_PRIVILEGED,
4392 }, {
4393 .name = "rsr.misc3",
4394 .translate = translate_rsr,
4395 .test_exceptions = test_exceptions_sr,
4396 .par = (const uint32_t[]){
4397 MISC + 3,
4398 XTENSA_OPTION_MISC_SR,
4399 },
4400 .op_flags = XTENSA_OP_PRIVILEGED,
4401 }, {
4402 .name = "rsr.mpucfg",
4403 .translate = translate_rsr,
4404 .test_exceptions = test_exceptions_sr,
4405 .par = (const uint32_t[]){
4406 MPUCFG,
4407 XTENSA_OPTION_MPU,
4408 },
4409 .op_flags = XTENSA_OP_PRIVILEGED,
4410 }, {
4411 .name = "rsr.mpuenb",
4412 .translate = translate_rsr,
4413 .test_exceptions = test_exceptions_sr,
4414 .par = (const uint32_t[]){
4415 MPUENB,
4416 XTENSA_OPTION_MPU,
4417 },
4418 .op_flags = XTENSA_OP_PRIVILEGED,
4419 }, {
4420 .name = "rsr.prefctl",
4421 .translate = translate_rsr,
4422 .par = (const uint32_t[]){PREFCTL},
4423 }, {
4424 .name = "rsr.prid",
4425 .translate = translate_rsr,
4426 .test_exceptions = test_exceptions_sr,
4427 .par = (const uint32_t[]){
4428 PRID,
4429 XTENSA_OPTION_PROCESSOR_ID,
4430 },
4431 .op_flags = XTENSA_OP_PRIVILEGED,
4432 }, {
4433 .name = "rsr.ps",
4434 .translate = translate_rsr,
4435 .test_exceptions = test_exceptions_sr,
4436 .par = (const uint32_t[]){
4437 PS,
4438 XTENSA_OPTION_EXCEPTION,
4439 },
4440 .op_flags = XTENSA_OP_PRIVILEGED,
4441 }, {
4442 .name = "rsr.ptevaddr",
4443 .translate = translate_rsr_ptevaddr,
4444 .test_exceptions = test_exceptions_sr,
4445 .par = (const uint32_t[]){
4446 PTEVADDR,
4447 XTENSA_OPTION_MMU,
4448 },
4449 .op_flags = XTENSA_OP_PRIVILEGED,
4450 }, {
4451 .name = "rsr.rasid",
4452 .translate = translate_rsr,
4453 .test_exceptions = test_exceptions_sr,
4454 .par = (const uint32_t[]){
4455 RASID,
4456 XTENSA_OPTION_MMU,
4457 },
4458 .op_flags = XTENSA_OP_PRIVILEGED,
4459 }, {
4460 .name = "rsr.sar",
4461 .translate = translate_rsr,
4462 .par = (const uint32_t[]){SAR},
4463 }, {
4464 .name = "rsr.scompare1",
4465 .translate = translate_rsr,
4466 .test_exceptions = test_exceptions_sr,
4467 .par = (const uint32_t[]){
4468 SCOMPARE1,
4469 XTENSA_OPTION_CONDITIONAL_STORE,
4470 },
4471 }, {
4472 .name = "rsr.vecbase",
4473 .translate = translate_rsr,
4474 .test_exceptions = test_exceptions_sr,
4475 .par = (const uint32_t[]){
4476 VECBASE,
4477 XTENSA_OPTION_RELOCATABLE_VECTOR,
4478 },
4479 .op_flags = XTENSA_OP_PRIVILEGED,
4480 }, {
4481 .name = "rsr.windowbase",
4482 .translate = translate_rsr,
4483 .test_exceptions = test_exceptions_sr,
4484 .par = (const uint32_t[]){
4485 WINDOW_BASE,
4486 XTENSA_OPTION_WINDOWED_REGISTER,
4487 },
4488 .op_flags = XTENSA_OP_PRIVILEGED,
4489 }, {
4490 .name = "rsr.windowstart",
4491 .translate = translate_rsr,
4492 .test_exceptions = test_exceptions_sr,
4493 .par = (const uint32_t[]){
4494 WINDOW_START,
4495 XTENSA_OPTION_WINDOWED_REGISTER,
4496 },
4497 .op_flags = XTENSA_OP_PRIVILEGED,
4498 }, {
4499 .name = "rsync",
4500 .translate = translate_nop,
4501 }, {
4502 .name = "rur.expstate",
4503 .translate = translate_rur,
4504 .par = (const uint32_t[]){EXPSTATE},
4505 }, {
4506 .name = "rur.threadptr",
4507 .translate = translate_rur,
4508 .par = (const uint32_t[]){THREADPTR},
4509 }, {
4510 .name = "s16i",
4511 .translate = translate_ldst,
4512 .par = (const uint32_t[]){MO_TEUW, false, true},
4513 .op_flags = XTENSA_OP_STORE,
4514 }, {
4515 .name = "s32c1i",
4516 .translate = translate_s32c1i,
4517 .op_flags = XTENSA_OP_LOAD | XTENSA_OP_STORE,
4518 }, {
4519 .name = "s32e",
4520 .translate = translate_s32e,
4521 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_STORE,
4522 }, {
4523 .name = "s32ex",
4524 .translate = translate_s32ex,
4525 .op_flags = XTENSA_OP_LOAD | XTENSA_OP_STORE,
4526 }, {
4527 .name = (const char * const[]) {
4528 "s32i", "s32i.n", "s32nb", NULL,
4529 },
4530 .translate = translate_ldst,
4531 .par = (const uint32_t[]){MO_TEUL, false, true},
4532 .op_flags = XTENSA_OP_NAME_ARRAY | XTENSA_OP_STORE,
4533 }, {
4534 .name = "s32ri",
4535 .translate = translate_ldst,
4536 .par = (const uint32_t[]){MO_TEUL | MO_ALIGN, true, true},
4537 .op_flags = XTENSA_OP_STORE,
4538 }, {
4539 .name = "s8i",
4540 .translate = translate_ldst,
4541 .par = (const uint32_t[]){MO_UB, false, true},
4542 .op_flags = XTENSA_OP_STORE,
4543 }, {
4544 .name = "salt",
4545 .translate = translate_salt,
4546 .par = (const uint32_t[]){TCG_COND_LT},
4547 }, {
4548 .name = "saltu",
4549 .translate = translate_salt,
4550 .par = (const uint32_t[]){TCG_COND_LTU},
4551 }, {
4552 .name = "sdct",
4553 .translate = translate_nop,
4554 .op_flags = XTENSA_OP_PRIVILEGED,
4555 }, {
4556 .name = "sdcw",
4557 .translate = translate_nop,
4558 .op_flags = XTENSA_OP_PRIVILEGED,
4559 }, {
4560 .name = "setb_expstate",
4561 .translate = translate_setb_expstate,
4562 }, {
4563 .name = "sext",
4564 .translate = translate_sext,
4565 }, {
4566 .name = "sict",
4567 .translate = translate_nop,
4568 .op_flags = XTENSA_OP_PRIVILEGED,
4569 }, {
4570 .name = "sicw",
4571 .translate = translate_nop,
4572 .op_flags = XTENSA_OP_PRIVILEGED,
4573 }, {
4574 .name = "simcall",
4575 .translate = translate_simcall,
4576 .test_exceptions = test_exceptions_simcall,
4577 .op_flags = XTENSA_OP_PRIVILEGED,
4578 }, {
4579 .name = "sll",
4580 .translate = translate_sll,
4581 }, {
4582 .name = "slli",
4583 .translate = translate_slli,
4584 }, {
4585 .name = "sra",
4586 .translate = translate_sra,
4587 }, {
4588 .name = "srai",
4589 .translate = translate_srai,
4590 }, {
4591 .name = "src",
4592 .translate = translate_src,
4593 }, {
4594 .name = "srl",
4595 .translate = translate_srl,
4596 }, {
4597 .name = "srli",
4598 .translate = translate_srli,
4599 }, {
4600 .name = "ssa8b",
4601 .translate = translate_ssa8b,
4602 }, {
4603 .name = "ssa8l",
4604 .translate = translate_ssa8l,
4605 }, {
4606 .name = "ssai",
4607 .translate = translate_ssai,
4608 }, {
4609 .name = "ssl",
4610 .translate = translate_ssl,
4611 }, {
4612 .name = "ssr",
4613 .translate = translate_ssr,
4614 }, {
4615 .name = "sub",
4616 .translate = translate_sub,
4617 }, {
4618 .name = "subx2",
4619 .translate = translate_subx,
4620 .par = (const uint32_t[]){1},
4621 }, {
4622 .name = "subx4",
4623 .translate = translate_subx,
4624 .par = (const uint32_t[]){2},
4625 }, {
4626 .name = "subx8",
4627 .translate = translate_subx,
4628 .par = (const uint32_t[]){3},
4629 }, {
4630 .name = "syscall",
4631 .op_flags = XTENSA_OP_SYSCALL,
4632 }, {
4633 .name = "umul.aa.hh",
4634 .translate = translate_mac16,
4635 .par = (const uint32_t[]){MAC16_UMUL, MAC16_HH, 0},
4636 }, {
4637 .name = "umul.aa.hl",
4638 .translate = translate_mac16,
4639 .par = (const uint32_t[]){MAC16_UMUL, MAC16_HL, 0},
4640 }, {
4641 .name = "umul.aa.lh",
4642 .translate = translate_mac16,
4643 .par = (const uint32_t[]){MAC16_UMUL, MAC16_LH, 0},
4644 }, {
4645 .name = "umul.aa.ll",
4646 .translate = translate_mac16,
4647 .par = (const uint32_t[]){MAC16_UMUL, MAC16_LL, 0},
4648 }, {
4649 .name = "waiti",
4650 .translate = translate_waiti,
4651 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
4652 }, {
4653 .name = "wdtlb",
4654 .translate = translate_wtlb,
4655 .par = (const uint32_t[]){true},
4656 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
4657 }, {
4658 .name = "wer",
4659 .translate = translate_wer,
4660 .op_flags = XTENSA_OP_PRIVILEGED,
4661 }, {
4662 .name = "witlb",
4663 .translate = translate_wtlb,
4664 .par = (const uint32_t[]){false},
4665 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
4666 }, {
4667 .name = "wptlb",
4668 .translate = translate_wptlb,
4669 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
4670 }, {
4671 .name = "wrmsk_expstate",
4672 .translate = translate_wrmsk_expstate,
4673 }, {
4674 .name = "wsr.176",
4675 .op_flags = XTENSA_OP_ILL,
4676 }, {
4677 .name = "wsr.208",
4678 .op_flags = XTENSA_OP_ILL,
4679 }, {
4680 .name = "wsr.acchi",
4681 .translate = translate_wsr_acchi,
4682 .test_exceptions = test_exceptions_sr,
4683 .par = (const uint32_t[]){
4684 ACCHI,
4685 XTENSA_OPTION_MAC16,
4686 },
4687 }, {
4688 .name = "wsr.acclo",
4689 .translate = translate_wsr,
4690 .test_exceptions = test_exceptions_sr,
4691 .par = (const uint32_t[]){
4692 ACCLO,
4693 XTENSA_OPTION_MAC16,
4694 },
4695 }, {
4696 .name = "wsr.atomctl",
4697 .translate = translate_wsr_mask,
4698 .test_exceptions = test_exceptions_sr,
4699 .par = (const uint32_t[]){
4700 ATOMCTL,
4701 XTENSA_OPTION_ATOMCTL,
4702 0x3f,
4703 },
4704 .op_flags = XTENSA_OP_PRIVILEGED,
4705 }, {
4706 .name = "wsr.br",
4707 .translate = translate_wsr_mask,
4708 .test_exceptions = test_exceptions_sr,
4709 .par = (const uint32_t[]){
4710 BR,
4711 XTENSA_OPTION_BOOLEAN,
4712 0xffff,
4713 },
4714 }, {
4715 .name = "wsr.cacheadrdis",
4716 .translate = translate_wsr_mask,
4717 .test_exceptions = test_exceptions_sr,
4718 .par = (const uint32_t[]){
4719 CACHEADRDIS,
4720 XTENSA_OPTION_MPU,
4721 0xff,
4722 },
4723 .op_flags = XTENSA_OP_PRIVILEGED,
4724 }, {
4725 .name = "wsr.cacheattr",
4726 .translate = translate_wsr,
4727 .test_exceptions = test_exceptions_sr,
4728 .par = (const uint32_t[]){
4729 CACHEATTR,
4730 XTENSA_OPTION_CACHEATTR,
4731 },
4732 .op_flags = XTENSA_OP_PRIVILEGED,
4733 }, {
4734 .name = "wsr.ccompare0",
4735 .translate = translate_wsr_ccompare,
4736 .test_exceptions = test_exceptions_ccompare,
4737 .par = (const uint32_t[]){
4738 CCOMPARE,
4739 XTENSA_OPTION_TIMER_INTERRUPT,
4740 },
4741 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
4742 }, {
4743 .name = "wsr.ccompare1",
4744 .translate = translate_wsr_ccompare,
4745 .test_exceptions = test_exceptions_ccompare,
4746 .par = (const uint32_t[]){
4747 CCOMPARE + 1,
4748 XTENSA_OPTION_TIMER_INTERRUPT,
4749 },
4750 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
4751 }, {
4752 .name = "wsr.ccompare2",
4753 .translate = translate_wsr_ccompare,
4754 .test_exceptions = test_exceptions_ccompare,
4755 .par = (const uint32_t[]){
4756 CCOMPARE + 2,
4757 XTENSA_OPTION_TIMER_INTERRUPT,
4758 },
4759 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
4760 }, {
4761 .name = "wsr.ccount",
4762 .translate = translate_wsr_ccount,
4763 .test_exceptions = test_exceptions_sr,
4764 .par = (const uint32_t[]){
4765 CCOUNT,
4766 XTENSA_OPTION_TIMER_INTERRUPT,
4767 },
4768 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
4769 }, {
4770 .name = "wsr.configid0",
4771 .op_flags = XTENSA_OP_ILL,
4772 }, {
4773 .name = "wsr.configid1",
4774 .op_flags = XTENSA_OP_ILL,
4775 }, {
4776 .name = "wsr.cpenable",
4777 .translate = translate_wsr_mask,
4778 .test_exceptions = test_exceptions_sr,
4779 .par = (const uint32_t[]){
4780 CPENABLE,
4781 XTENSA_OPTION_COPROCESSOR,
4782 0xff,
4783 },
4784 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
4785 }, {
4786 .name = "wsr.dbreaka0",
4787 .translate = translate_wsr_dbreaka,
4788 .test_exceptions = test_exceptions_dbreak,
4789 .par = (const uint32_t[]){
4790 DBREAKA,
4791 XTENSA_OPTION_DEBUG,
4792 },
4793 .op_flags = XTENSA_OP_PRIVILEGED,
4794 }, {
4795 .name = "wsr.dbreaka1",
4796 .translate = translate_wsr_dbreaka,
4797 .test_exceptions = test_exceptions_dbreak,
4798 .par = (const uint32_t[]){
4799 DBREAKA + 1,
4800 XTENSA_OPTION_DEBUG,
4801 },
4802 .op_flags = XTENSA_OP_PRIVILEGED,
4803 }, {
4804 .name = "wsr.dbreakc0",
4805 .translate = translate_wsr_dbreakc,
4806 .test_exceptions = test_exceptions_dbreak,
4807 .par = (const uint32_t[]){
4808 DBREAKC,
4809 XTENSA_OPTION_DEBUG,
4810 },
4811 .op_flags = XTENSA_OP_PRIVILEGED,
4812 }, {
4813 .name = "wsr.dbreakc1",
4814 .translate = translate_wsr_dbreakc,
4815 .test_exceptions = test_exceptions_dbreak,
4816 .par = (const uint32_t[]){
4817 DBREAKC + 1,
4818 XTENSA_OPTION_DEBUG,
4819 },
4820 .op_flags = XTENSA_OP_PRIVILEGED,
4821 }, {
4822 .name = "wsr.ddr",
4823 .translate = translate_wsr,
4824 .test_exceptions = test_exceptions_sr,
4825 .par = (const uint32_t[]){
4826 DDR,
4827 XTENSA_OPTION_DEBUG,
4828 },
4829 .op_flags = XTENSA_OP_PRIVILEGED,
4830 }, {
4831 .name = "wsr.debugcause",
4832 .op_flags = XTENSA_OP_ILL,
4833 }, {
4834 .name = "wsr.depc",
4835 .translate = translate_wsr,
4836 .test_exceptions = test_exceptions_sr,
4837 .par = (const uint32_t[]){
4838 DEPC,
4839 XTENSA_OPTION_EXCEPTION,
4840 },
4841 .op_flags = XTENSA_OP_PRIVILEGED,
4842 }, {
4843 .name = "wsr.dtlbcfg",
4844 .translate = translate_wsr_mask,
4845 .test_exceptions = test_exceptions_sr,
4846 .par = (const uint32_t[]){
4847 DTLBCFG,
4848 XTENSA_OPTION_MMU,
4849 0x01130000,
4850 },
4851 .op_flags = XTENSA_OP_PRIVILEGED,
4852 }, {
4853 .name = "wsr.epc1",
4854 .translate = translate_wsr,
4855 .test_exceptions = test_exceptions_sr,
4856 .par = (const uint32_t[]){
4857 EPC1,
4858 XTENSA_OPTION_EXCEPTION,
4859 },
4860 .op_flags = XTENSA_OP_PRIVILEGED,
4861 }, {
4862 .name = "wsr.epc2",
4863 .translate = translate_wsr,
4864 .test_exceptions = test_exceptions_hpi,
4865 .par = (const uint32_t[]){
4866 EPC1 + 1,
4867 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4868 },
4869 .op_flags = XTENSA_OP_PRIVILEGED,
4870 }, {
4871 .name = "wsr.epc3",
4872 .translate = translate_wsr,
4873 .test_exceptions = test_exceptions_hpi,
4874 .par = (const uint32_t[]){
4875 EPC1 + 2,
4876 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4877 },
4878 .op_flags = XTENSA_OP_PRIVILEGED,
4879 }, {
4880 .name = "wsr.epc4",
4881 .translate = translate_wsr,
4882 .test_exceptions = test_exceptions_hpi,
4883 .par = (const uint32_t[]){
4884 EPC1 + 3,
4885 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4886 },
4887 .op_flags = XTENSA_OP_PRIVILEGED,
4888 }, {
4889 .name = "wsr.epc5",
4890 .translate = translate_wsr,
4891 .test_exceptions = test_exceptions_hpi,
4892 .par = (const uint32_t[]){
4893 EPC1 + 4,
4894 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4895 },
4896 .op_flags = XTENSA_OP_PRIVILEGED,
4897 }, {
4898 .name = "wsr.epc6",
4899 .translate = translate_wsr,
4900 .test_exceptions = test_exceptions_hpi,
4901 .par = (const uint32_t[]){
4902 EPC1 + 5,
4903 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4904 },
4905 .op_flags = XTENSA_OP_PRIVILEGED,
4906 }, {
4907 .name = "wsr.epc7",
4908 .translate = translate_wsr,
4909 .test_exceptions = test_exceptions_hpi,
4910 .par = (const uint32_t[]){
4911 EPC1 + 6,
4912 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4913 },
4914 .op_flags = XTENSA_OP_PRIVILEGED,
4915 }, {
4916 .name = "wsr.eps2",
4917 .translate = translate_wsr,
4918 .test_exceptions = test_exceptions_hpi,
4919 .par = (const uint32_t[]){
4920 EPS2,
4921 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4922 },
4923 .op_flags = XTENSA_OP_PRIVILEGED,
4924 }, {
4925 .name = "wsr.eps3",
4926 .translate = translate_wsr,
4927 .test_exceptions = test_exceptions_hpi,
4928 .par = (const uint32_t[]){
4929 EPS2 + 1,
4930 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4931 },
4932 .op_flags = XTENSA_OP_PRIVILEGED,
4933 }, {
4934 .name = "wsr.eps4",
4935 .translate = translate_wsr,
4936 .test_exceptions = test_exceptions_hpi,
4937 .par = (const uint32_t[]){
4938 EPS2 + 2,
4939 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4940 },
4941 .op_flags = XTENSA_OP_PRIVILEGED,
4942 }, {
4943 .name = "wsr.eps5",
4944 .translate = translate_wsr,
4945 .test_exceptions = test_exceptions_hpi,
4946 .par = (const uint32_t[]){
4947 EPS2 + 3,
4948 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4949 },
4950 .op_flags = XTENSA_OP_PRIVILEGED,
4951 }, {
4952 .name = "wsr.eps6",
4953 .translate = translate_wsr,
4954 .test_exceptions = test_exceptions_hpi,
4955 .par = (const uint32_t[]){
4956 EPS2 + 4,
4957 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4958 },
4959 .op_flags = XTENSA_OP_PRIVILEGED,
4960 }, {
4961 .name = "wsr.eps7",
4962 .translate = translate_wsr,
4963 .test_exceptions = test_exceptions_hpi,
4964 .par = (const uint32_t[]){
4965 EPS2 + 5,
4966 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4967 },
4968 .op_flags = XTENSA_OP_PRIVILEGED,
4969 }, {
4970 .name = "wsr.eraccess",
4971 .translate = translate_wsr_mask,
4972 .par = (const uint32_t[]){
4973 ERACCESS,
4974 0,
4975 0xffff,
4976 },
4977 .op_flags = XTENSA_OP_PRIVILEGED,
4978 }, {
4979 .name = "wsr.exccause",
4980 .translate = translate_wsr,
4981 .test_exceptions = test_exceptions_sr,
4982 .par = (const uint32_t[]){
4983 EXCCAUSE,
4984 XTENSA_OPTION_EXCEPTION,
4985 },
4986 .op_flags = XTENSA_OP_PRIVILEGED,
4987 }, {
4988 .name = "wsr.excsave1",
4989 .translate = translate_wsr,
4990 .test_exceptions = test_exceptions_sr,
4991 .par = (const uint32_t[]){
4992 EXCSAVE1,
4993 XTENSA_OPTION_EXCEPTION,
4994 },
4995 .op_flags = XTENSA_OP_PRIVILEGED,
4996 }, {
4997 .name = "wsr.excsave2",
4998 .translate = translate_wsr,
4999 .test_exceptions = test_exceptions_hpi,
5000 .par = (const uint32_t[]){
5001 EXCSAVE1 + 1,
5002 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5003 },
5004 .op_flags = XTENSA_OP_PRIVILEGED,
5005 }, {
5006 .name = "wsr.excsave3",
5007 .translate = translate_wsr,
5008 .test_exceptions = test_exceptions_hpi,
5009 .par = (const uint32_t[]){
5010 EXCSAVE1 + 2,
5011 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5012 },
5013 .op_flags = XTENSA_OP_PRIVILEGED,
5014 }, {
5015 .name = "wsr.excsave4",
5016 .translate = translate_wsr,
5017 .test_exceptions = test_exceptions_hpi,
5018 .par = (const uint32_t[]){
5019 EXCSAVE1 + 3,
5020 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5021 },
5022 .op_flags = XTENSA_OP_PRIVILEGED,
5023 }, {
5024 .name = "wsr.excsave5",
5025 .translate = translate_wsr,
5026 .test_exceptions = test_exceptions_hpi,
5027 .par = (const uint32_t[]){
5028 EXCSAVE1 + 4,
5029 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5030 },
5031 .op_flags = XTENSA_OP_PRIVILEGED,
5032 }, {
5033 .name = "wsr.excsave6",
5034 .translate = translate_wsr,
5035 .test_exceptions = test_exceptions_hpi,
5036 .par = (const uint32_t[]){
5037 EXCSAVE1 + 5,
5038 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5039 },
5040 .op_flags = XTENSA_OP_PRIVILEGED,
5041 }, {
5042 .name = "wsr.excsave7",
5043 .translate = translate_wsr,
5044 .test_exceptions = test_exceptions_hpi,
5045 .par = (const uint32_t[]){
5046 EXCSAVE1 + 6,
5047 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5048 },
5049 .op_flags = XTENSA_OP_PRIVILEGED,
5050 }, {
5051 .name = "wsr.excvaddr",
5052 .translate = translate_wsr,
5053 .test_exceptions = test_exceptions_sr,
5054 .par = (const uint32_t[]){
5055 EXCVADDR,
5056 XTENSA_OPTION_EXCEPTION,
5057 },
5058 .op_flags = XTENSA_OP_PRIVILEGED,
5059 }, {
5060 .name = "wsr.ibreaka0",
5061 .translate = translate_wsr_ibreaka,
5062 .test_exceptions = test_exceptions_ibreak,
5063 .par = (const uint32_t[]){
5064 IBREAKA,
5065 XTENSA_OPTION_DEBUG,
5066 },
5067 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5068 }, {
5069 .name = "wsr.ibreaka1",
5070 .translate = translate_wsr_ibreaka,
5071 .test_exceptions = test_exceptions_ibreak,
5072 .par = (const uint32_t[]){
5073 IBREAKA + 1,
5074 XTENSA_OPTION_DEBUG,
5075 },
5076 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5077 }, {
5078 .name = "wsr.ibreakenable",
5079 .translate = translate_wsr_ibreakenable,
5080 .test_exceptions = test_exceptions_sr,
5081 .par = (const uint32_t[]){
5082 IBREAKENABLE,
5083 XTENSA_OPTION_DEBUG,
5084 },
5085 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5086 }, {
5087 .name = "wsr.icount",
5088 .translate = translate_wsr_icount,
5089 .test_exceptions = test_exceptions_sr,
5090 .par = (const uint32_t[]){
5091 ICOUNT,
5092 XTENSA_OPTION_DEBUG,
5093 },
5094 .op_flags = XTENSA_OP_PRIVILEGED,
5095 }, {
5096 .name = "wsr.icountlevel",
5097 .translate = translate_wsr_mask,
5098 .test_exceptions = test_exceptions_sr,
5099 .par = (const uint32_t[]){
5100 ICOUNTLEVEL,
5101 XTENSA_OPTION_DEBUG,
5102 0xf,
5103 },
5104 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
5105 }, {
5106 .name = "wsr.intclear",
5107 .translate = translate_wsr_intclear,
5108 .test_exceptions = test_exceptions_sr,
5109 .par = (const uint32_t[]){
5110 INTCLEAR,
5111 XTENSA_OPTION_INTERRUPT,
5112 },
5113 .op_flags =
5114 XTENSA_OP_PRIVILEGED |
5115 XTENSA_OP_EXIT_TB_0 |
5116 XTENSA_OP_CHECK_INTERRUPTS,
5117 }, {
5118 .name = "wsr.intenable",
5119 .translate = translate_wsr,
5120 .test_exceptions = test_exceptions_sr,
5121 .par = (const uint32_t[]){
5122 INTENABLE,
5123 XTENSA_OPTION_INTERRUPT,
5124 },
5125 .op_flags =
5126 XTENSA_OP_PRIVILEGED |
5127 XTENSA_OP_EXIT_TB_0 |
5128 XTENSA_OP_CHECK_INTERRUPTS,
5129 }, {
5130 .name = "wsr.interrupt",
5131 .translate = translate_wsr,
5132 .test_exceptions = test_exceptions_sr,
5133 .par = (const uint32_t[]){
5134 INTSET,
5135 XTENSA_OPTION_INTERRUPT,
5136 },
5137 .op_flags =
5138 XTENSA_OP_PRIVILEGED |
5139 XTENSA_OP_EXIT_TB_0 |
5140 XTENSA_OP_CHECK_INTERRUPTS,
5141 }, {
5142 .name = "wsr.intset",
5143 .translate = translate_wsr_intset,
5144 .test_exceptions = test_exceptions_sr,
5145 .par = (const uint32_t[]){
5146 INTSET,
5147 XTENSA_OPTION_INTERRUPT,
5148 },
5149 .op_flags =
5150 XTENSA_OP_PRIVILEGED |
5151 XTENSA_OP_EXIT_TB_0 |
5152 XTENSA_OP_CHECK_INTERRUPTS,
5153 }, {
5154 .name = "wsr.itlbcfg",
5155 .translate = translate_wsr_mask,
5156 .test_exceptions = test_exceptions_sr,
5157 .par = (const uint32_t[]){
5158 ITLBCFG,
5159 XTENSA_OPTION_MMU,
5160 0x01130000,
5161 },
5162 .op_flags = XTENSA_OP_PRIVILEGED,
5163 }, {
5164 .name = "wsr.lbeg",
5165 .translate = translate_wsr,
5166 .test_exceptions = test_exceptions_sr,
5167 .par = (const uint32_t[]){
5168 LBEG,
5169 XTENSA_OPTION_LOOP,
5170 },
5171 .op_flags = XTENSA_OP_EXIT_TB_M1,
5172 }, {
5173 .name = "wsr.lcount",
5174 .translate = translate_wsr,
5175 .test_exceptions = test_exceptions_sr,
5176 .par = (const uint32_t[]){
5177 LCOUNT,
5178 XTENSA_OPTION_LOOP,
5179 },
5180 }, {
5181 .name = "wsr.lend",
5182 .translate = translate_wsr,
5183 .test_exceptions = test_exceptions_sr,
5184 .par = (const uint32_t[]){
5185 LEND,
5186 XTENSA_OPTION_LOOP,
5187 },
5188 .op_flags = XTENSA_OP_EXIT_TB_M1,
5189 }, {
5190 .name = "wsr.litbase",
5191 .translate = translate_wsr_mask,
5192 .test_exceptions = test_exceptions_sr,
5193 .par = (const uint32_t[]){
5194 LITBASE,
5195 XTENSA_OPTION_EXTENDED_L32R,
5196 0xfffff001,
5197 },
5198 .op_flags = XTENSA_OP_EXIT_TB_M1,
5199 }, {
5200 .name = "wsr.m0",
5201 .translate = translate_wsr,
5202 .test_exceptions = test_exceptions_sr,
5203 .par = (const uint32_t[]){
5204 MR,
5205 XTENSA_OPTION_MAC16,
5206 },
5207 }, {
5208 .name = "wsr.m1",
5209 .translate = translate_wsr,
5210 .test_exceptions = test_exceptions_sr,
5211 .par = (const uint32_t[]){
5212 MR + 1,
5213 XTENSA_OPTION_MAC16,
5214 },
5215 }, {
5216 .name = "wsr.m2",
5217 .translate = translate_wsr,
5218 .test_exceptions = test_exceptions_sr,
5219 .par = (const uint32_t[]){
5220 MR + 2,
5221 XTENSA_OPTION_MAC16,
5222 },
5223 }, {
5224 .name = "wsr.m3",
5225 .translate = translate_wsr,
5226 .test_exceptions = test_exceptions_sr,
5227 .par = (const uint32_t[]){
5228 MR + 3,
5229 XTENSA_OPTION_MAC16,
5230 },
5231 }, {
5232 .name = "wsr.memctl",
5233 .translate = translate_wsr_memctl,
5234 .par = (const uint32_t[]){MEMCTL},
5235 .op_flags = XTENSA_OP_PRIVILEGED,
5236 }, {
5237 .name = "wsr.mecr",
5238 .translate = translate_wsr,
5239 .test_exceptions = test_exceptions_sr,
5240 .par = (const uint32_t[]){
5241 MECR,
5242 XTENSA_OPTION_MEMORY_ECC_PARITY,
5243 },
5244 .op_flags = XTENSA_OP_PRIVILEGED,
5245 }, {
5246 .name = "wsr.mepc",
5247 .translate = translate_wsr,
5248 .test_exceptions = test_exceptions_sr,
5249 .par = (const uint32_t[]){
5250 MEPC,
5251 XTENSA_OPTION_MEMORY_ECC_PARITY,
5252 },
5253 .op_flags = XTENSA_OP_PRIVILEGED,
5254 }, {
5255 .name = "wsr.meps",
5256 .translate = translate_wsr,
5257 .test_exceptions = test_exceptions_sr,
5258 .par = (const uint32_t[]){
5259 MEPS,
5260 XTENSA_OPTION_MEMORY_ECC_PARITY,
5261 },
5262 .op_flags = XTENSA_OP_PRIVILEGED,
5263 }, {
5264 .name = "wsr.mesave",
5265 .translate = translate_wsr,
5266 .test_exceptions = test_exceptions_sr,
5267 .par = (const uint32_t[]){
5268 MESAVE,
5269 XTENSA_OPTION_MEMORY_ECC_PARITY,
5270 },
5271 .op_flags = XTENSA_OP_PRIVILEGED,
5272 }, {
5273 .name = "wsr.mesr",
5274 .translate = translate_wsr,
5275 .test_exceptions = test_exceptions_sr,
5276 .par = (const uint32_t[]){
5277 MESR,
5278 XTENSA_OPTION_MEMORY_ECC_PARITY,
5279 },
5280 .op_flags = XTENSA_OP_PRIVILEGED,
5281 }, {
5282 .name = "wsr.mevaddr",
5283 .translate = translate_wsr,
5284 .test_exceptions = test_exceptions_sr,
5285 .par = (const uint32_t[]){
5286 MESR,
5287 XTENSA_OPTION_MEMORY_ECC_PARITY,
5288 },
5289 .op_flags = XTENSA_OP_PRIVILEGED,
5290 }, {
5291 .name = "wsr.misc0",
5292 .translate = translate_wsr,
5293 .test_exceptions = test_exceptions_sr,
5294 .par = (const uint32_t[]){
5295 MISC,
5296 XTENSA_OPTION_MISC_SR,
5297 },
5298 .op_flags = XTENSA_OP_PRIVILEGED,
5299 }, {
5300 .name = "wsr.misc1",
5301 .translate = translate_wsr,
5302 .test_exceptions = test_exceptions_sr,
5303 .par = (const uint32_t[]){
5304 MISC + 1,
5305 XTENSA_OPTION_MISC_SR,
5306 },
5307 .op_flags = XTENSA_OP_PRIVILEGED,
5308 }, {
5309 .name = "wsr.misc2",
5310 .translate = translate_wsr,
5311 .test_exceptions = test_exceptions_sr,
5312 .par = (const uint32_t[]){
5313 MISC + 2,
5314 XTENSA_OPTION_MISC_SR,
5315 },
5316 .op_flags = XTENSA_OP_PRIVILEGED,
5317 }, {
5318 .name = "wsr.misc3",
5319 .translate = translate_wsr,
5320 .test_exceptions = test_exceptions_sr,
5321 .par = (const uint32_t[]){
5322 MISC + 3,
5323 XTENSA_OPTION_MISC_SR,
5324 },
5325 .op_flags = XTENSA_OP_PRIVILEGED,
5326 }, {
5327 .name = "wsr.mmid",
5328 .translate = translate_wsr,
5329 .test_exceptions = test_exceptions_sr,
5330 .par = (const uint32_t[]){
5331 MMID,
5332 XTENSA_OPTION_TRACE_PORT,
5333 },
5334 .op_flags = XTENSA_OP_PRIVILEGED,
5335 }, {
5336 .name = "wsr.mpuenb",
5337 .translate = translate_wsr_mpuenb,
5338 .test_exceptions = test_exceptions_sr,
5339 .par = (const uint32_t[]){
5340 MPUENB,
5341 XTENSA_OPTION_MPU,
5342 },
5343 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
5344 }, {
5345 .name = "wsr.prefctl",
5346 .translate = translate_wsr,
5347 .par = (const uint32_t[]){PREFCTL},
5348 }, {
5349 .name = "wsr.prid",
5350 .op_flags = XTENSA_OP_ILL,
5351 }, {
5352 .name = "wsr.ps",
5353 .translate = translate_wsr_ps,
5354 .test_exceptions = test_exceptions_sr,
5355 .par = (const uint32_t[]){
5356 PS,
5357 XTENSA_OPTION_EXCEPTION,
5358 },
5359 .op_flags =
5360 XTENSA_OP_PRIVILEGED |
5361 XTENSA_OP_EXIT_TB_M1 |
5362 XTENSA_OP_CHECK_INTERRUPTS,
5363 }, {
5364 .name = "wsr.ptevaddr",
5365 .translate = translate_wsr_mask,
5366 .test_exceptions = test_exceptions_sr,
5367 .par = (const uint32_t[]){
5368 PTEVADDR,
5369 XTENSA_OPTION_MMU,
5370 0xffc00000,
5371 },
5372 .op_flags = XTENSA_OP_PRIVILEGED,
5373 }, {
5374 .name = "wsr.rasid",
5375 .translate = translate_wsr_rasid,
5376 .test_exceptions = test_exceptions_sr,
5377 .par = (const uint32_t[]){
5378 RASID,
5379 XTENSA_OPTION_MMU,
5380 },
5381 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
5382 }, {
5383 .name = "wsr.sar",
5384 .translate = translate_wsr_sar,
5385 .par = (const uint32_t[]){SAR},
5386 }, {
5387 .name = "wsr.scompare1",
5388 .translate = translate_wsr,
5389 .test_exceptions = test_exceptions_sr,
5390 .par = (const uint32_t[]){
5391 SCOMPARE1,
5392 XTENSA_OPTION_CONDITIONAL_STORE,
5393 },
5394 }, {
5395 .name = "wsr.vecbase",
5396 .translate = translate_wsr,
5397 .test_exceptions = test_exceptions_sr,
5398 .par = (const uint32_t[]){
5399 VECBASE,
5400 XTENSA_OPTION_RELOCATABLE_VECTOR,
5401 },
5402 .op_flags = XTENSA_OP_PRIVILEGED,
5403 }, {
5404 .name = "wsr.windowbase",
5405 .translate = translate_wsr_windowbase,
5406 .test_exceptions = test_exceptions_sr,
5407 .par = (const uint32_t[]){
5408 WINDOW_BASE,
5409 XTENSA_OPTION_WINDOWED_REGISTER,
5410 },
5411 .op_flags = XTENSA_OP_PRIVILEGED |
5412 XTENSA_OP_EXIT_TB_M1 |
5413 XTENSA_OP_SYNC_REGISTER_WINDOW,
5414 }, {
5415 .name = "wsr.windowstart",
5416 .translate = translate_wsr_windowstart,
5417 .test_exceptions = test_exceptions_sr,
5418 .par = (const uint32_t[]){
5419 WINDOW_START,
5420 XTENSA_OPTION_WINDOWED_REGISTER,
5421 },
5422 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
5423 }, {
5424 .name = "wur.expstate",
5425 .translate = translate_wur,
5426 .par = (const uint32_t[]){EXPSTATE},
5427 }, {
5428 .name = "wur.threadptr",
5429 .translate = translate_wur,
5430 .par = (const uint32_t[]){THREADPTR},
5431 }, {
5432 .name = "xor",
5433 .translate = translate_xor,
5434 }, {
5435 .name = "xorb",
5436 .translate = translate_boolean,
5437 .par = (const uint32_t[]){BOOLEAN_XOR},
5438 }, {
5439 .name = "xsr.176",
5440 .op_flags = XTENSA_OP_ILL,
5441 }, {
5442 .name = "xsr.208",
5443 .op_flags = XTENSA_OP_ILL,
5444 }, {
5445 .name = "xsr.acchi",
5446 .translate = translate_xsr_acchi,
5447 .test_exceptions = test_exceptions_sr,
5448 .par = (const uint32_t[]){
5449 ACCHI,
5450 XTENSA_OPTION_MAC16,
5451 },
5452 }, {
5453 .name = "xsr.acclo",
5454 .translate = translate_xsr,
5455 .test_exceptions = test_exceptions_sr,
5456 .par = (const uint32_t[]){
5457 ACCLO,
5458 XTENSA_OPTION_MAC16,
5459 },
5460 }, {
5461 .name = "xsr.atomctl",
5462 .translate = translate_xsr_mask,
5463 .test_exceptions = test_exceptions_sr,
5464 .par = (const uint32_t[]){
5465 ATOMCTL,
5466 XTENSA_OPTION_ATOMCTL,
5467 0x3f,
5468 },
5469 .op_flags = XTENSA_OP_PRIVILEGED,
5470 }, {
5471 .name = "xsr.br",
5472 .translate = translate_xsr_mask,
5473 .test_exceptions = test_exceptions_sr,
5474 .par = (const uint32_t[]){
5475 BR,
5476 XTENSA_OPTION_BOOLEAN,
5477 0xffff,
5478 },
5479 }, {
5480 .name = "xsr.cacheadrdis",
5481 .translate = translate_xsr_mask,
5482 .test_exceptions = test_exceptions_sr,
5483 .par = (const uint32_t[]){
5484 CACHEADRDIS,
5485 XTENSA_OPTION_MPU,
5486 0xff,
5487 },
5488 .op_flags = XTENSA_OP_PRIVILEGED,
5489 }, {
5490 .name = "xsr.cacheattr",
5491 .translate = translate_xsr,
5492 .test_exceptions = test_exceptions_sr,
5493 .par = (const uint32_t[]){
5494 CACHEATTR,
5495 XTENSA_OPTION_CACHEATTR,
5496 },
5497 .op_flags = XTENSA_OP_PRIVILEGED,
5498 }, {
5499 .name = "xsr.ccompare0",
5500 .translate = translate_xsr_ccompare,
5501 .test_exceptions = test_exceptions_ccompare,
5502 .par = (const uint32_t[]){
5503 CCOMPARE,
5504 XTENSA_OPTION_TIMER_INTERRUPT,
5505 },
5506 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5507 }, {
5508 .name = "xsr.ccompare1",
5509 .translate = translate_xsr_ccompare,
5510 .test_exceptions = test_exceptions_ccompare,
5511 .par = (const uint32_t[]){
5512 CCOMPARE + 1,
5513 XTENSA_OPTION_TIMER_INTERRUPT,
5514 },
5515 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5516 }, {
5517 .name = "xsr.ccompare2",
5518 .translate = translate_xsr_ccompare,
5519 .test_exceptions = test_exceptions_ccompare,
5520 .par = (const uint32_t[]){
5521 CCOMPARE + 2,
5522 XTENSA_OPTION_TIMER_INTERRUPT,
5523 },
5524 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5525 }, {
5526 .name = "xsr.ccount",
5527 .translate = translate_xsr_ccount,
5528 .test_exceptions = test_exceptions_sr,
5529 .par = (const uint32_t[]){
5530 CCOUNT,
5531 XTENSA_OPTION_TIMER_INTERRUPT,
5532 },
5533 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5534 }, {
5535 .name = "xsr.configid0",
5536 .op_flags = XTENSA_OP_ILL,
5537 }, {
5538 .name = "xsr.configid1",
5539 .op_flags = XTENSA_OP_ILL,
5540 }, {
5541 .name = "xsr.cpenable",
5542 .translate = translate_xsr_mask,
5543 .test_exceptions = test_exceptions_sr,
5544 .par = (const uint32_t[]){
5545 CPENABLE,
5546 XTENSA_OPTION_COPROCESSOR,
5547 0xff,
5548 },
5549 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
5550 }, {
5551 .name = "xsr.dbreaka0",
5552 .translate = translate_xsr_dbreaka,
5553 .test_exceptions = test_exceptions_dbreak,
5554 .par = (const uint32_t[]){
5555 DBREAKA,
5556 XTENSA_OPTION_DEBUG,
5557 },
5558 .op_flags = XTENSA_OP_PRIVILEGED,
5559 }, {
5560 .name = "xsr.dbreaka1",
5561 .translate = translate_xsr_dbreaka,
5562 .test_exceptions = test_exceptions_dbreak,
5563 .par = (const uint32_t[]){
5564 DBREAKA + 1,
5565 XTENSA_OPTION_DEBUG,
5566 },
5567 .op_flags = XTENSA_OP_PRIVILEGED,
5568 }, {
5569 .name = "xsr.dbreakc0",
5570 .translate = translate_xsr_dbreakc,
5571 .test_exceptions = test_exceptions_dbreak,
5572 .par = (const uint32_t[]){
5573 DBREAKC,
5574 XTENSA_OPTION_DEBUG,
5575 },
5576 .op_flags = XTENSA_OP_PRIVILEGED,
5577 }, {
5578 .name = "xsr.dbreakc1",
5579 .translate = translate_xsr_dbreakc,
5580 .test_exceptions = test_exceptions_dbreak,
5581 .par = (const uint32_t[]){
5582 DBREAKC + 1,
5583 XTENSA_OPTION_DEBUG,
5584 },
5585 .op_flags = XTENSA_OP_PRIVILEGED,
5586 }, {
5587 .name = "xsr.ddr",
5588 .translate = translate_xsr,
5589 .test_exceptions = test_exceptions_sr,
5590 .par = (const uint32_t[]){
5591 DDR,
5592 XTENSA_OPTION_DEBUG,
5593 },
5594 .op_flags = XTENSA_OP_PRIVILEGED,
5595 }, {
5596 .name = "xsr.debugcause",
5597 .op_flags = XTENSA_OP_ILL,
5598 }, {
5599 .name = "xsr.depc",
5600 .translate = translate_xsr,
5601 .test_exceptions = test_exceptions_sr,
5602 .par = (const uint32_t[]){
5603 DEPC,
5604 XTENSA_OPTION_EXCEPTION,
5605 },
5606 .op_flags = XTENSA_OP_PRIVILEGED,
5607 }, {
5608 .name = "xsr.dtlbcfg",
5609 .translate = translate_xsr_mask,
5610 .test_exceptions = test_exceptions_sr,
5611 .par = (const uint32_t[]){
5612 DTLBCFG,
5613 XTENSA_OPTION_MMU,
5614 0x01130000,
5615 },
5616 .op_flags = XTENSA_OP_PRIVILEGED,
5617 }, {
5618 .name = "xsr.epc1",
5619 .translate = translate_xsr,
5620 .test_exceptions = test_exceptions_sr,
5621 .par = (const uint32_t[]){
5622 EPC1,
5623 XTENSA_OPTION_EXCEPTION,
5624 },
5625 .op_flags = XTENSA_OP_PRIVILEGED,
5626 }, {
5627 .name = "xsr.epc2",
5628 .translate = translate_xsr,
5629 .test_exceptions = test_exceptions_hpi,
5630 .par = (const uint32_t[]){
5631 EPC1 + 1,
5632 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5633 },
5634 .op_flags = XTENSA_OP_PRIVILEGED,
5635 }, {
5636 .name = "xsr.epc3",
5637 .translate = translate_xsr,
5638 .test_exceptions = test_exceptions_hpi,
5639 .par = (const uint32_t[]){
5640 EPC1 + 2,
5641 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5642 },
5643 .op_flags = XTENSA_OP_PRIVILEGED,
5644 }, {
5645 .name = "xsr.epc4",
5646 .translate = translate_xsr,
5647 .test_exceptions = test_exceptions_hpi,
5648 .par = (const uint32_t[]){
5649 EPC1 + 3,
5650 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5651 },
5652 .op_flags = XTENSA_OP_PRIVILEGED,
5653 }, {
5654 .name = "xsr.epc5",
5655 .translate = translate_xsr,
5656 .test_exceptions = test_exceptions_hpi,
5657 .par = (const uint32_t[]){
5658 EPC1 + 4,
5659 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5660 },
5661 .op_flags = XTENSA_OP_PRIVILEGED,
5662 }, {
5663 .name = "xsr.epc6",
5664 .translate = translate_xsr,
5665 .test_exceptions = test_exceptions_hpi,
5666 .par = (const uint32_t[]){
5667 EPC1 + 5,
5668 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5669 },
5670 .op_flags = XTENSA_OP_PRIVILEGED,
5671 }, {
5672 .name = "xsr.epc7",
5673 .translate = translate_xsr,
5674 .test_exceptions = test_exceptions_hpi,
5675 .par = (const uint32_t[]){
5676 EPC1 + 6,
5677 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5678 },
5679 .op_flags = XTENSA_OP_PRIVILEGED,
5680 }, {
5681 .name = "xsr.eps2",
5682 .translate = translate_xsr,
5683 .test_exceptions = test_exceptions_hpi,
5684 .par = (const uint32_t[]){
5685 EPS2,
5686 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5687 },
5688 .op_flags = XTENSA_OP_PRIVILEGED,
5689 }, {
5690 .name = "xsr.eps3",
5691 .translate = translate_xsr,
5692 .test_exceptions = test_exceptions_hpi,
5693 .par = (const uint32_t[]){
5694 EPS2 + 1,
5695 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5696 },
5697 .op_flags = XTENSA_OP_PRIVILEGED,
5698 }, {
5699 .name = "xsr.eps4",
5700 .translate = translate_xsr,
5701 .test_exceptions = test_exceptions_hpi,
5702 .par = (const uint32_t[]){
5703 EPS2 + 2,
5704 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5705 },
5706 .op_flags = XTENSA_OP_PRIVILEGED,
5707 }, {
5708 .name = "xsr.eps5",
5709 .translate = translate_xsr,
5710 .test_exceptions = test_exceptions_hpi,
5711 .par = (const uint32_t[]){
5712 EPS2 + 3,
5713 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5714 },
5715 .op_flags = XTENSA_OP_PRIVILEGED,
5716 }, {
5717 .name = "xsr.eps6",
5718 .translate = translate_xsr,
5719 .test_exceptions = test_exceptions_hpi,
5720 .par = (const uint32_t[]){
5721 EPS2 + 4,
5722 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5723 },
5724 .op_flags = XTENSA_OP_PRIVILEGED,
5725 }, {
5726 .name = "xsr.eps7",
5727 .translate = translate_xsr,
5728 .test_exceptions = test_exceptions_hpi,
5729 .par = (const uint32_t[]){
5730 EPS2 + 5,
5731 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5732 },
5733 .op_flags = XTENSA_OP_PRIVILEGED,
5734 }, {
5735 .name = "xsr.eraccess",
5736 .translate = translate_xsr_mask,
5737 .par = (const uint32_t[]){
5738 ERACCESS,
5739 0,
5740 0xffff,
5741 },
5742 .op_flags = XTENSA_OP_PRIVILEGED,
5743 }, {
5744 .name = "xsr.exccause",
5745 .translate = translate_xsr,
5746 .test_exceptions = test_exceptions_sr,
5747 .par = (const uint32_t[]){
5748 EXCCAUSE,
5749 XTENSA_OPTION_EXCEPTION,
5750 },
5751 .op_flags = XTENSA_OP_PRIVILEGED,
5752 }, {
5753 .name = "xsr.excsave1",
5754 .translate = translate_xsr,
5755 .test_exceptions = test_exceptions_sr,
5756 .par = (const uint32_t[]){
5757 EXCSAVE1,
5758 XTENSA_OPTION_EXCEPTION,
5759 },
5760 .op_flags = XTENSA_OP_PRIVILEGED,
5761 }, {
5762 .name = "xsr.excsave2",
5763 .translate = translate_xsr,
5764 .test_exceptions = test_exceptions_hpi,
5765 .par = (const uint32_t[]){
5766 EXCSAVE1 + 1,
5767 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5768 },
5769 .op_flags = XTENSA_OP_PRIVILEGED,
5770 }, {
5771 .name = "xsr.excsave3",
5772 .translate = translate_xsr,
5773 .test_exceptions = test_exceptions_hpi,
5774 .par = (const uint32_t[]){
5775 EXCSAVE1 + 2,
5776 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5777 },
5778 .op_flags = XTENSA_OP_PRIVILEGED,
5779 }, {
5780 .name = "xsr.excsave4",
5781 .translate = translate_xsr,
5782 .test_exceptions = test_exceptions_hpi,
5783 .par = (const uint32_t[]){
5784 EXCSAVE1 + 3,
5785 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5786 },
5787 .op_flags = XTENSA_OP_PRIVILEGED,
5788 }, {
5789 .name = "xsr.excsave5",
5790 .translate = translate_xsr,
5791 .test_exceptions = test_exceptions_hpi,
5792 .par = (const uint32_t[]){
5793 EXCSAVE1 + 4,
5794 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5795 },
5796 .op_flags = XTENSA_OP_PRIVILEGED,
5797 }, {
5798 .name = "xsr.excsave6",
5799 .translate = translate_xsr,
5800 .test_exceptions = test_exceptions_hpi,
5801 .par = (const uint32_t[]){
5802 EXCSAVE1 + 5,
5803 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5804 },
5805 .op_flags = XTENSA_OP_PRIVILEGED,
5806 }, {
5807 .name = "xsr.excsave7",
5808 .translate = translate_xsr,
5809 .test_exceptions = test_exceptions_hpi,
5810 .par = (const uint32_t[]){
5811 EXCSAVE1 + 6,
5812 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5813 },
5814 .op_flags = XTENSA_OP_PRIVILEGED,
5815 }, {
5816 .name = "xsr.excvaddr",
5817 .translate = translate_xsr,
5818 .test_exceptions = test_exceptions_sr,
5819 .par = (const uint32_t[]){
5820 EXCVADDR,
5821 XTENSA_OPTION_EXCEPTION,
5822 },
5823 .op_flags = XTENSA_OP_PRIVILEGED,
5824 }, {
5825 .name = "xsr.ibreaka0",
5826 .translate = translate_xsr_ibreaka,
5827 .test_exceptions = test_exceptions_ibreak,
5828 .par = (const uint32_t[]){
5829 IBREAKA,
5830 XTENSA_OPTION_DEBUG,
5831 },
5832 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5833 }, {
5834 .name = "xsr.ibreaka1",
5835 .translate = translate_xsr_ibreaka,
5836 .test_exceptions = test_exceptions_ibreak,
5837 .par = (const uint32_t[]){
5838 IBREAKA + 1,
5839 XTENSA_OPTION_DEBUG,
5840 },
5841 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5842 }, {
5843 .name = "xsr.ibreakenable",
5844 .translate = translate_xsr_ibreakenable,
5845 .test_exceptions = test_exceptions_sr,
5846 .par = (const uint32_t[]){
5847 IBREAKENABLE,
5848 XTENSA_OPTION_DEBUG,
5849 },
5850 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5851 }, {
5852 .name = "xsr.icount",
5853 .translate = translate_xsr_icount,
5854 .test_exceptions = test_exceptions_sr,
5855 .par = (const uint32_t[]){
5856 ICOUNT,
5857 XTENSA_OPTION_DEBUG,
5858 },
5859 .op_flags = XTENSA_OP_PRIVILEGED,
5860 }, {
5861 .name = "xsr.icountlevel",
5862 .translate = translate_xsr_mask,
5863 .test_exceptions = test_exceptions_sr,
5864 .par = (const uint32_t[]){
5865 ICOUNTLEVEL,
5866 XTENSA_OPTION_DEBUG,
5867 0xf,
5868 },
5869 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
5870 }, {
5871 .name = "xsr.intclear",
5872 .op_flags = XTENSA_OP_ILL,
5873 }, {
5874 .name = "xsr.intenable",
5875 .translate = translate_xsr,
5876 .test_exceptions = test_exceptions_sr,
5877 .par = (const uint32_t[]){
5878 INTENABLE,
5879 XTENSA_OPTION_INTERRUPT,
5880 },
5881 .op_flags =
5882 XTENSA_OP_PRIVILEGED |
5883 XTENSA_OP_EXIT_TB_0 |
5884 XTENSA_OP_CHECK_INTERRUPTS,
5885 }, {
5886 .name = "xsr.interrupt",
5887 .op_flags = XTENSA_OP_ILL,
5888 }, {
5889 .name = "xsr.intset",
5890 .op_flags = XTENSA_OP_ILL,
5891 }, {
5892 .name = "xsr.itlbcfg",
5893 .translate = translate_xsr_mask,
5894 .test_exceptions = test_exceptions_sr,
5895 .par = (const uint32_t[]){
5896 ITLBCFG,
5897 XTENSA_OPTION_MMU,
5898 0x01130000,
5899 },
5900 .op_flags = XTENSA_OP_PRIVILEGED,
5901 }, {
5902 .name = "xsr.lbeg",
5903 .translate = translate_xsr,
5904 .test_exceptions = test_exceptions_sr,
5905 .par = (const uint32_t[]){
5906 LBEG,
5907 XTENSA_OPTION_LOOP,
5908 },
5909 .op_flags = XTENSA_OP_EXIT_TB_M1,
5910 }, {
5911 .name = "xsr.lcount",
5912 .translate = translate_xsr,
5913 .test_exceptions = test_exceptions_sr,
5914 .par = (const uint32_t[]){
5915 LCOUNT,
5916 XTENSA_OPTION_LOOP,
5917 },
5918 }, {
5919 .name = "xsr.lend",
5920 .translate = translate_xsr,
5921 .test_exceptions = test_exceptions_sr,
5922 .par = (const uint32_t[]){
5923 LEND,
5924 XTENSA_OPTION_LOOP,
5925 },
5926 .op_flags = XTENSA_OP_EXIT_TB_M1,
5927 }, {
5928 .name = "xsr.litbase",
5929 .translate = translate_xsr_mask,
5930 .test_exceptions = test_exceptions_sr,
5931 .par = (const uint32_t[]){
5932 LITBASE,
5933 XTENSA_OPTION_EXTENDED_L32R,
5934 0xfffff001,
5935 },
5936 .op_flags = XTENSA_OP_EXIT_TB_M1,
5937 }, {
5938 .name = "xsr.m0",
5939 .translate = translate_xsr,
5940 .test_exceptions = test_exceptions_sr,
5941 .par = (const uint32_t[]){
5942 MR,
5943 XTENSA_OPTION_MAC16,
5944 },
5945 }, {
5946 .name = "xsr.m1",
5947 .translate = translate_xsr,
5948 .test_exceptions = test_exceptions_sr,
5949 .par = (const uint32_t[]){
5950 MR + 1,
5951 XTENSA_OPTION_MAC16,
5952 },
5953 }, {
5954 .name = "xsr.m2",
5955 .translate = translate_xsr,
5956 .test_exceptions = test_exceptions_sr,
5957 .par = (const uint32_t[]){
5958 MR + 2,
5959 XTENSA_OPTION_MAC16,
5960 },
5961 }, {
5962 .name = "xsr.m3",
5963 .translate = translate_xsr,
5964 .test_exceptions = test_exceptions_sr,
5965 .par = (const uint32_t[]){
5966 MR + 3,
5967 XTENSA_OPTION_MAC16,
5968 },
5969 }, {
5970 .name = "xsr.memctl",
5971 .translate = translate_xsr_memctl,
5972 .par = (const uint32_t[]){MEMCTL},
5973 .op_flags = XTENSA_OP_PRIVILEGED,
5974 }, {
5975 .name = "xsr.mecr",
5976 .translate = translate_xsr,
5977 .test_exceptions = test_exceptions_sr,
5978 .par = (const uint32_t[]){
5979 MECR,
5980 XTENSA_OPTION_MEMORY_ECC_PARITY,
5981 },
5982 .op_flags = XTENSA_OP_PRIVILEGED,
5983 }, {
5984 .name = "xsr.mepc",
5985 .translate = translate_xsr,
5986 .test_exceptions = test_exceptions_sr,
5987 .par = (const uint32_t[]){
5988 MEPC,
5989 XTENSA_OPTION_MEMORY_ECC_PARITY,
5990 },
5991 .op_flags = XTENSA_OP_PRIVILEGED,
5992 }, {
5993 .name = "xsr.meps",
5994 .translate = translate_xsr,
5995 .test_exceptions = test_exceptions_sr,
5996 .par = (const uint32_t[]){
5997 MEPS,
5998 XTENSA_OPTION_MEMORY_ECC_PARITY,
5999 },
6000 .op_flags = XTENSA_OP_PRIVILEGED,
6001 }, {
6002 .name = "xsr.mesave",
6003 .translate = translate_xsr,
6004 .test_exceptions = test_exceptions_sr,
6005 .par = (const uint32_t[]){
6006 MESAVE,
6007 XTENSA_OPTION_MEMORY_ECC_PARITY,
6008 },
6009 .op_flags = XTENSA_OP_PRIVILEGED,
6010 }, {
6011 .name = "xsr.mesr",
6012 .translate = translate_xsr,
6013 .test_exceptions = test_exceptions_sr,
6014 .par = (const uint32_t[]){
6015 MESR,
6016 XTENSA_OPTION_MEMORY_ECC_PARITY,
6017 },
6018 .op_flags = XTENSA_OP_PRIVILEGED,
6019 }, {
6020 .name = "xsr.mevaddr",
6021 .translate = translate_xsr,
6022 .test_exceptions = test_exceptions_sr,
6023 .par = (const uint32_t[]){
6024 MESR,
6025 XTENSA_OPTION_MEMORY_ECC_PARITY,
6026 },
6027 .op_flags = XTENSA_OP_PRIVILEGED,
6028 }, {
6029 .name = "xsr.misc0",
6030 .translate = translate_xsr,
6031 .test_exceptions = test_exceptions_sr,
6032 .par = (const uint32_t[]){
6033 MISC,
6034 XTENSA_OPTION_MISC_SR,
6035 },
6036 .op_flags = XTENSA_OP_PRIVILEGED,
6037 }, {
6038 .name = "xsr.misc1",
6039 .translate = translate_xsr,
6040 .test_exceptions = test_exceptions_sr,
6041 .par = (const uint32_t[]){
6042 MISC + 1,
6043 XTENSA_OPTION_MISC_SR,
6044 },
6045 .op_flags = XTENSA_OP_PRIVILEGED,
6046 }, {
6047 .name = "xsr.misc2",
6048 .translate = translate_xsr,
6049 .test_exceptions = test_exceptions_sr,
6050 .par = (const uint32_t[]){
6051 MISC + 2,
6052 XTENSA_OPTION_MISC_SR,
6053 },
6054 .op_flags = XTENSA_OP_PRIVILEGED,
6055 }, {
6056 .name = "xsr.misc3",
6057 .translate = translate_xsr,
6058 .test_exceptions = test_exceptions_sr,
6059 .par = (const uint32_t[]){
6060 MISC + 3,
6061 XTENSA_OPTION_MISC_SR,
6062 },
6063 .op_flags = XTENSA_OP_PRIVILEGED,
6064 }, {
6065 .name = "xsr.mpuenb",
6066 .translate = translate_xsr_mpuenb,
6067 .test_exceptions = test_exceptions_sr,
6068 .par = (const uint32_t[]){
6069 MPUENB,
6070 XTENSA_OPTION_MPU,
6071 },
6072 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
6073 }, {
6074 .name = "xsr.prefctl",
6075 .translate = translate_xsr,
6076 .par = (const uint32_t[]){PREFCTL},
6077 }, {
6078 .name = "xsr.prid",
6079 .op_flags = XTENSA_OP_ILL,
6080 }, {
6081 .name = "xsr.ps",
6082 .translate = translate_xsr_ps,
6083 .test_exceptions = test_exceptions_sr,
6084 .par = (const uint32_t[]){
6085 PS,
6086 XTENSA_OPTION_EXCEPTION,
6087 },
6088 .op_flags =
6089 XTENSA_OP_PRIVILEGED |
6090 XTENSA_OP_EXIT_TB_M1 |
6091 XTENSA_OP_CHECK_INTERRUPTS,
6092 }, {
6093 .name = "xsr.ptevaddr",
6094 .translate = translate_xsr_mask,
6095 .test_exceptions = test_exceptions_sr,
6096 .par = (const uint32_t[]){
6097 PTEVADDR,
6098 XTENSA_OPTION_MMU,
6099 0xffc00000,
6100 },
6101 .op_flags = XTENSA_OP_PRIVILEGED,
6102 }, {
6103 .name = "xsr.rasid",
6104 .translate = translate_xsr_rasid,
6105 .test_exceptions = test_exceptions_sr,
6106 .par = (const uint32_t[]){
6107 RASID,
6108 XTENSA_OPTION_MMU,
6109 },
6110 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
6111 }, {
6112 .name = "xsr.sar",
6113 .translate = translate_xsr_sar,
6114 .par = (const uint32_t[]){SAR},
6115 }, {
6116 .name = "xsr.scompare1",
6117 .translate = translate_xsr,
6118 .test_exceptions = test_exceptions_sr,
6119 .par = (const uint32_t[]){
6120 SCOMPARE1,
6121 XTENSA_OPTION_CONDITIONAL_STORE,
6122 },
6123 }, {
6124 .name = "xsr.vecbase",
6125 .translate = translate_xsr,
6126 .test_exceptions = test_exceptions_sr,
6127 .par = (const uint32_t[]){
6128 VECBASE,
6129 XTENSA_OPTION_RELOCATABLE_VECTOR,
6130 },
6131 .op_flags = XTENSA_OP_PRIVILEGED,
6132 }, {
6133 .name = "xsr.windowbase",
6134 .translate = translate_xsr_windowbase,
6135 .test_exceptions = test_exceptions_sr,
6136 .par = (const uint32_t[]){
6137 WINDOW_BASE,
6138 XTENSA_OPTION_WINDOWED_REGISTER,
6139 },
6140 .op_flags = XTENSA_OP_PRIVILEGED |
6141 XTENSA_OP_EXIT_TB_M1 |
6142 XTENSA_OP_SYNC_REGISTER_WINDOW,
6143 }, {
6144 .name = "xsr.windowstart",
6145 .translate = translate_xsr_windowstart,
6146 .test_exceptions = test_exceptions_sr,
6147 .par = (const uint32_t[]){
6148 WINDOW_START,
6149 XTENSA_OPTION_WINDOWED_REGISTER,
6150 },
6151 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
6152 },
6153 };
6154
6155 const XtensaOpcodeTranslators xtensa_core_opcodes = {
6156 .num_opcodes = ARRAY_SIZE(core_ops),
6157 .opcode = core_ops,
6158 };
6159
6160
get_f32_o1_i3(const OpcodeArg * arg,OpcodeArg * arg32,int o0,int i0,int i1,int i2)6161 static inline void get_f32_o1_i3(const OpcodeArg *arg, OpcodeArg *arg32,
6162 int o0, int i0, int i1, int i2)
6163 {
6164 if ((i0 >= 0 && arg[i0].num_bits == 64) ||
6165 (o0 >= 0 && arg[o0].num_bits == 64)) {
6166 if (o0 >= 0) {
6167 arg32[o0].out = tcg_temp_new_i32();
6168 }
6169 if (i0 >= 0) {
6170 arg32[i0].in = tcg_temp_new_i32();
6171 tcg_gen_extrl_i64_i32(arg32[i0].in, arg[i0].in);
6172 }
6173 if (i1 >= 0) {
6174 arg32[i1].in = tcg_temp_new_i32();
6175 tcg_gen_extrl_i64_i32(arg32[i1].in, arg[i1].in);
6176 }
6177 if (i2 >= 0) {
6178 arg32[i2].in = tcg_temp_new_i32();
6179 tcg_gen_extrl_i64_i32(arg32[i2].in, arg[i2].in);
6180 }
6181 } else {
6182 if (o0 >= 0) {
6183 arg32[o0].out = arg[o0].out;
6184 }
6185 if (i0 >= 0) {
6186 arg32[i0].in = arg[i0].in;
6187 }
6188 if (i1 >= 0) {
6189 arg32[i1].in = arg[i1].in;
6190 }
6191 if (i2 >= 0) {
6192 arg32[i2].in = arg[i2].in;
6193 }
6194 }
6195 }
6196
put_f32_o1_i3(const OpcodeArg * arg,const OpcodeArg * arg32,int o0,int i0,int i1,int i2)6197 static inline void put_f32_o1_i3(const OpcodeArg *arg, const OpcodeArg *arg32,
6198 int o0, int i0, int i1, int i2)
6199 {
6200 if ((i0 >= 0 && arg[i0].num_bits == 64) ||
6201 (o0 >= 0 && arg[o0].num_bits == 64)) {
6202 if (o0 >= 0) {
6203 tcg_gen_extu_i32_i64(arg[o0].out, arg32[o0].out);
6204 }
6205 }
6206 }
6207
get_f32_o1_i2(const OpcodeArg * arg,OpcodeArg * arg32,int o0,int i0,int i1)6208 static inline void get_f32_o1_i2(const OpcodeArg *arg, OpcodeArg *arg32,
6209 int o0, int i0, int i1)
6210 {
6211 get_f32_o1_i3(arg, arg32, o0, i0, i1, -1);
6212 }
6213
put_f32_o1_i2(const OpcodeArg * arg,const OpcodeArg * arg32,int o0,int i0,int i1)6214 static inline void put_f32_o1_i2(const OpcodeArg *arg, const OpcodeArg *arg32,
6215 int o0, int i0, int i1)
6216 {
6217 put_f32_o1_i3(arg, arg32, o0, i0, i1, -1);
6218 }
6219
get_f32_o1_i1(const OpcodeArg * arg,OpcodeArg * arg32,int o0,int i0)6220 static inline void get_f32_o1_i1(const OpcodeArg *arg, OpcodeArg *arg32,
6221 int o0, int i0)
6222 {
6223 get_f32_o1_i2(arg, arg32, o0, i0, -1);
6224 }
6225
put_f32_o1_i1(const OpcodeArg * arg,const OpcodeArg * arg32,int o0,int i0)6226 static inline void put_f32_o1_i1(const OpcodeArg *arg, const OpcodeArg *arg32,
6227 int o0, int i0)
6228 {
6229 put_f32_o1_i2(arg, arg32, o0, i0, -1);
6230 }
6231
get_f32_o1(const OpcodeArg * arg,OpcodeArg * arg32,int o0)6232 static inline void get_f32_o1(const OpcodeArg *arg, OpcodeArg *arg32,
6233 int o0)
6234 {
6235 get_f32_o1_i1(arg, arg32, o0, -1);
6236 }
6237
put_f32_o1(const OpcodeArg * arg,const OpcodeArg * arg32,int o0)6238 static inline void put_f32_o1(const OpcodeArg *arg, const OpcodeArg *arg32,
6239 int o0)
6240 {
6241 put_f32_o1_i1(arg, arg32, o0, -1);
6242 }
6243
get_f32_i2(const OpcodeArg * arg,OpcodeArg * arg32,int i0,int i1)6244 static inline void get_f32_i2(const OpcodeArg *arg, OpcodeArg *arg32,
6245 int i0, int i1)
6246 {
6247 get_f32_o1_i2(arg, arg32, -1, i0, i1);
6248 }
6249
put_f32_i2(const OpcodeArg * arg,const OpcodeArg * arg32,int i0,int i1)6250 static inline void put_f32_i2(const OpcodeArg *arg, const OpcodeArg *arg32,
6251 int i0, int i1)
6252 {
6253 put_f32_o1_i2(arg, arg32, -1, i0, i1);
6254 }
6255
get_f32_i1(const OpcodeArg * arg,OpcodeArg * arg32,int i0)6256 static inline void get_f32_i1(const OpcodeArg *arg, OpcodeArg *arg32,
6257 int i0)
6258 {
6259 get_f32_i2(arg, arg32, i0, -1);
6260 }
6261
put_f32_i1(const OpcodeArg * arg,const OpcodeArg * arg32,int i0)6262 static inline void put_f32_i1(const OpcodeArg *arg, const OpcodeArg *arg32,
6263 int i0)
6264 {
6265 put_f32_i2(arg, arg32, i0, -1);
6266 }
6267
6268
translate_abs_d(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6269 static void translate_abs_d(DisasContext *dc, const OpcodeArg arg[],
6270 const uint32_t par[])
6271 {
6272 gen_helper_abs_d(arg[0].out, arg[1].in);
6273 }
6274
translate_abs_s(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6275 static void translate_abs_s(DisasContext *dc, const OpcodeArg arg[],
6276 const uint32_t par[])
6277 {
6278 OpcodeArg arg32[2];
6279
6280 get_f32_o1_i1(arg, arg32, 0, 1);
6281 gen_helper_abs_s(arg32[0].out, arg32[1].in);
6282 put_f32_o1_i1(arg, arg32, 0, 1);
6283 }
6284
translate_fpu2k_add_s(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6285 static void translate_fpu2k_add_s(DisasContext *dc, const OpcodeArg arg[],
6286 const uint32_t par[])
6287 {
6288 gen_helper_fpu2k_add_s(arg[0].out, tcg_env,
6289 arg[1].in, arg[2].in);
6290 }
6291
6292 enum {
6293 COMPARE_UN,
6294 COMPARE_OEQ,
6295 COMPARE_UEQ,
6296 COMPARE_OLT,
6297 COMPARE_ULT,
6298 COMPARE_OLE,
6299 COMPARE_ULE,
6300 };
6301
translate_compare_d(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6302 static void translate_compare_d(DisasContext *dc, const OpcodeArg arg[],
6303 const uint32_t par[])
6304 {
6305 static void (* const helper[])(TCGv_i32 res, TCGv_env env,
6306 TCGv_i64 s, TCGv_i64 t) = {
6307 [COMPARE_UN] = gen_helper_un_d,
6308 [COMPARE_OEQ] = gen_helper_oeq_d,
6309 [COMPARE_UEQ] = gen_helper_ueq_d,
6310 [COMPARE_OLT] = gen_helper_olt_d,
6311 [COMPARE_ULT] = gen_helper_ult_d,
6312 [COMPARE_OLE] = gen_helper_ole_d,
6313 [COMPARE_ULE] = gen_helper_ule_d,
6314 };
6315 TCGv_i32 zero = tcg_constant_i32(0);
6316 TCGv_i32 res = tcg_temp_new_i32();
6317 TCGv_i32 set_br = tcg_temp_new_i32();
6318 TCGv_i32 clr_br = tcg_temp_new_i32();
6319
6320 tcg_gen_ori_i32(set_br, arg[0].in, 1 << arg[0].imm);
6321 tcg_gen_andi_i32(clr_br, arg[0].in, ~(1 << arg[0].imm));
6322
6323 helper[par[0]](res, tcg_env, arg[1].in, arg[2].in);
6324 tcg_gen_movcond_i32(TCG_COND_NE,
6325 arg[0].out, res, zero,
6326 set_br, clr_br);
6327 }
6328
translate_compare_s(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6329 static void translate_compare_s(DisasContext *dc, const OpcodeArg arg[],
6330 const uint32_t par[])
6331 {
6332 static void (* const helper[])(TCGv_i32 res, TCGv_env env,
6333 TCGv_i32 s, TCGv_i32 t) = {
6334 [COMPARE_UN] = gen_helper_un_s,
6335 [COMPARE_OEQ] = gen_helper_oeq_s,
6336 [COMPARE_UEQ] = gen_helper_ueq_s,
6337 [COMPARE_OLT] = gen_helper_olt_s,
6338 [COMPARE_ULT] = gen_helper_ult_s,
6339 [COMPARE_OLE] = gen_helper_ole_s,
6340 [COMPARE_ULE] = gen_helper_ule_s,
6341 };
6342 OpcodeArg arg32[3];
6343 TCGv_i32 zero = tcg_constant_i32(0);
6344 TCGv_i32 res = tcg_temp_new_i32();
6345 TCGv_i32 set_br = tcg_temp_new_i32();
6346 TCGv_i32 clr_br = tcg_temp_new_i32();
6347
6348 tcg_gen_ori_i32(set_br, arg[0].in, 1 << arg[0].imm);
6349 tcg_gen_andi_i32(clr_br, arg[0].in, ~(1 << arg[0].imm));
6350
6351 get_f32_i2(arg, arg32, 1, 2);
6352 helper[par[0]](res, tcg_env, arg32[1].in, arg32[2].in);
6353 tcg_gen_movcond_i32(TCG_COND_NE,
6354 arg[0].out, res, zero,
6355 set_br, clr_br);
6356 put_f32_i2(arg, arg32, 1, 2);
6357 }
6358
translate_const_d(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6359 static void translate_const_d(DisasContext *dc, const OpcodeArg arg[],
6360 const uint32_t par[])
6361 {
6362 static const uint64_t v[] = {
6363 UINT64_C(0x0000000000000000),
6364 UINT64_C(0x3ff0000000000000),
6365 UINT64_C(0x4000000000000000),
6366 UINT64_C(0x3fe0000000000000),
6367 };
6368
6369 tcg_gen_movi_i64(arg[0].out, v[arg[1].imm % ARRAY_SIZE(v)]);
6370 if (arg[1].imm >= ARRAY_SIZE(v)) {
6371 qemu_log_mask(LOG_GUEST_ERROR,
6372 "const.d f%d, #%d, immediate value is reserved\n",
6373 arg[0].imm, arg[1].imm);
6374 }
6375 }
6376
translate_const_s(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6377 static void translate_const_s(DisasContext *dc, const OpcodeArg arg[],
6378 const uint32_t par[])
6379 {
6380 static const uint32_t v[] = {
6381 0x00000000,
6382 0x3f800000,
6383 0x40000000,
6384 0x3f000000,
6385 };
6386
6387 if (arg[0].num_bits == 32) {
6388 tcg_gen_movi_i32(arg[0].out, v[arg[1].imm % ARRAY_SIZE(v)]);
6389 } else {
6390 tcg_gen_movi_i64(arg[0].out, v[arg[1].imm % ARRAY_SIZE(v)]);
6391 }
6392 if (arg[1].imm >= ARRAY_SIZE(v)) {
6393 qemu_log_mask(LOG_GUEST_ERROR,
6394 "const.s f%d, #%d, immediate value is reserved\n",
6395 arg[0].imm, arg[1].imm);
6396 }
6397 }
6398
translate_float_d(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6399 static void translate_float_d(DisasContext *dc, const OpcodeArg arg[],
6400 const uint32_t par[])
6401 {
6402 TCGv_i32 scale = tcg_constant_i32(-arg[2].imm);
6403
6404 if (par[0]) {
6405 gen_helper_uitof_d(arg[0].out, tcg_env, arg[1].in, scale);
6406 } else {
6407 gen_helper_itof_d(arg[0].out, tcg_env, arg[1].in, scale);
6408 }
6409 }
6410
translate_float_s(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6411 static void translate_float_s(DisasContext *dc, const OpcodeArg arg[],
6412 const uint32_t par[])
6413 {
6414 TCGv_i32 scale = tcg_constant_i32(-arg[2].imm);
6415 OpcodeArg arg32[1];
6416
6417 get_f32_o1(arg, arg32, 0);
6418 if (par[0]) {
6419 gen_helper_uitof_s(arg32[0].out, tcg_env, arg[1].in, scale);
6420 } else {
6421 gen_helper_itof_s(arg32[0].out, tcg_env, arg[1].in, scale);
6422 }
6423 put_f32_o1(arg, arg32, 0);
6424 }
6425
translate_ftoi_d(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6426 static void translate_ftoi_d(DisasContext *dc, const OpcodeArg arg[],
6427 const uint32_t par[])
6428 {
6429 TCGv_i32 rounding_mode = tcg_constant_i32(par[0]);
6430 TCGv_i32 scale = tcg_constant_i32(arg[2].imm);
6431
6432 if (par[1]) {
6433 gen_helper_ftoui_d(arg[0].out, tcg_env, arg[1].in,
6434 rounding_mode, scale);
6435 } else {
6436 gen_helper_ftoi_d(arg[0].out, tcg_env, arg[1].in,
6437 rounding_mode, scale);
6438 }
6439 }
6440
translate_ftoi_s(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6441 static void translate_ftoi_s(DisasContext *dc, const OpcodeArg arg[],
6442 const uint32_t par[])
6443 {
6444 TCGv_i32 rounding_mode = tcg_constant_i32(par[0]);
6445 TCGv_i32 scale = tcg_constant_i32(arg[2].imm);
6446 OpcodeArg arg32[2];
6447
6448 get_f32_i1(arg, arg32, 1);
6449 if (par[1]) {
6450 gen_helper_ftoui_s(arg[0].out, tcg_env, arg32[1].in,
6451 rounding_mode, scale);
6452 } else {
6453 gen_helper_ftoi_s(arg[0].out, tcg_env, arg32[1].in,
6454 rounding_mode, scale);
6455 }
6456 put_f32_i1(arg, arg32, 1);
6457 }
6458
translate_ldsti(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6459 static void translate_ldsti(DisasContext *dc, const OpcodeArg arg[],
6460 const uint32_t par[])
6461 {
6462 TCGv_i32 addr = tcg_temp_new_i32();
6463 MemOp mop;
6464
6465 tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm);
6466 mop = gen_load_store_alignment(dc, MO_TEUL, addr);
6467 if (par[0]) {
6468 tcg_gen_qemu_st_tl(arg[0].in, addr, dc->cring, mop);
6469 } else {
6470 tcg_gen_qemu_ld_tl(arg[0].out, addr, dc->cring, mop);
6471 }
6472 if (par[1]) {
6473 tcg_gen_mov_i32(arg[1].out, addr);
6474 }
6475 }
6476
translate_ldstx(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6477 static void translate_ldstx(DisasContext *dc, const OpcodeArg arg[],
6478 const uint32_t par[])
6479 {
6480 TCGv_i32 addr = tcg_temp_new_i32();
6481 MemOp mop;
6482
6483 tcg_gen_add_i32(addr, arg[1].in, arg[2].in);
6484 mop = gen_load_store_alignment(dc, MO_TEUL, addr);
6485 if (par[0]) {
6486 tcg_gen_qemu_st_tl(arg[0].in, addr, dc->cring, mop);
6487 } else {
6488 tcg_gen_qemu_ld_tl(arg[0].out, addr, dc->cring, mop);
6489 }
6490 if (par[1]) {
6491 tcg_gen_mov_i32(arg[1].out, addr);
6492 }
6493 }
6494
translate_fpu2k_madd_s(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6495 static void translate_fpu2k_madd_s(DisasContext *dc, const OpcodeArg arg[],
6496 const uint32_t par[])
6497 {
6498 gen_helper_fpu2k_madd_s(arg[0].out, tcg_env,
6499 arg[0].in, arg[1].in, arg[2].in);
6500 }
6501
translate_mov_d(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6502 static void translate_mov_d(DisasContext *dc, const OpcodeArg arg[],
6503 const uint32_t par[])
6504 {
6505 tcg_gen_mov_i64(arg[0].out, arg[1].in);
6506 }
6507
translate_mov_s(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6508 static void translate_mov_s(DisasContext *dc, const OpcodeArg arg[],
6509 const uint32_t par[])
6510 {
6511 if (arg[0].num_bits == 32) {
6512 tcg_gen_mov_i32(arg[0].out, arg[1].in);
6513 } else {
6514 tcg_gen_mov_i64(arg[0].out, arg[1].in);
6515 }
6516 }
6517
translate_movcond_d(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6518 static void translate_movcond_d(DisasContext *dc, const OpcodeArg arg[],
6519 const uint32_t par[])
6520 {
6521 TCGv_i64 zero = tcg_constant_i64(0);
6522 TCGv_i64 arg2 = tcg_temp_new_i64();
6523
6524 tcg_gen_ext_i32_i64(arg2, arg[2].in);
6525 tcg_gen_movcond_i64(par[0], arg[0].out,
6526 arg2, zero,
6527 arg[1].in, arg[0].in);
6528 }
6529
translate_movcond_s(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6530 static void translate_movcond_s(DisasContext *dc, const OpcodeArg arg[],
6531 const uint32_t par[])
6532 {
6533 if (arg[0].num_bits == 32) {
6534 TCGv_i32 zero = tcg_constant_i32(0);
6535
6536 tcg_gen_movcond_i32(par[0], arg[0].out,
6537 arg[2].in, zero,
6538 arg[1].in, arg[0].in);
6539 } else {
6540 translate_movcond_d(dc, arg, par);
6541 }
6542 }
6543
translate_movp_d(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6544 static void translate_movp_d(DisasContext *dc, const OpcodeArg arg[],
6545 const uint32_t par[])
6546 {
6547 TCGv_i64 zero = tcg_constant_i64(0);
6548 TCGv_i32 tmp1 = tcg_temp_new_i32();
6549 TCGv_i64 tmp2 = tcg_temp_new_i64();
6550
6551 tcg_gen_andi_i32(tmp1, arg[2].in, 1 << arg[2].imm);
6552 tcg_gen_extu_i32_i64(tmp2, tmp1);
6553 tcg_gen_movcond_i64(par[0],
6554 arg[0].out, tmp2, zero,
6555 arg[1].in, arg[0].in);
6556 }
6557
translate_movp_s(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6558 static void translate_movp_s(DisasContext *dc, const OpcodeArg arg[],
6559 const uint32_t par[])
6560 {
6561 if (arg[0].num_bits == 32) {
6562 TCGv_i32 zero = tcg_constant_i32(0);
6563 TCGv_i32 tmp = tcg_temp_new_i32();
6564
6565 tcg_gen_andi_i32(tmp, arg[2].in, 1 << arg[2].imm);
6566 tcg_gen_movcond_i32(par[0],
6567 arg[0].out, tmp, zero,
6568 arg[1].in, arg[0].in);
6569 } else {
6570 translate_movp_d(dc, arg, par);
6571 }
6572 }
6573
translate_fpu2k_mul_s(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6574 static void translate_fpu2k_mul_s(DisasContext *dc, const OpcodeArg arg[],
6575 const uint32_t par[])
6576 {
6577 gen_helper_fpu2k_mul_s(arg[0].out, tcg_env,
6578 arg[1].in, arg[2].in);
6579 }
6580
translate_fpu2k_msub_s(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6581 static void translate_fpu2k_msub_s(DisasContext *dc, const OpcodeArg arg[],
6582 const uint32_t par[])
6583 {
6584 gen_helper_fpu2k_msub_s(arg[0].out, tcg_env,
6585 arg[0].in, arg[1].in, arg[2].in);
6586 }
6587
translate_neg_d(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6588 static void translate_neg_d(DisasContext *dc, const OpcodeArg arg[],
6589 const uint32_t par[])
6590 {
6591 gen_helper_neg_d(arg[0].out, arg[1].in);
6592 }
6593
translate_neg_s(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6594 static void translate_neg_s(DisasContext *dc, const OpcodeArg arg[],
6595 const uint32_t par[])
6596 {
6597 OpcodeArg arg32[2];
6598
6599 get_f32_o1_i1(arg, arg32, 0, 1);
6600 gen_helper_neg_s(arg32[0].out, arg32[1].in);
6601 put_f32_o1_i1(arg, arg32, 0, 1);
6602 }
6603
translate_rfr_d(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6604 static void translate_rfr_d(DisasContext *dc, const OpcodeArg arg[],
6605 const uint32_t par[])
6606 {
6607 tcg_gen_extrh_i64_i32(arg[0].out, arg[1].in);
6608 }
6609
translate_rfr_s(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6610 static void translate_rfr_s(DisasContext *dc, const OpcodeArg arg[],
6611 const uint32_t par[])
6612 {
6613 if (arg[1].num_bits == 32) {
6614 tcg_gen_mov_i32(arg[0].out, arg[1].in);
6615 } else {
6616 tcg_gen_extrl_i64_i32(arg[0].out, arg[1].in);
6617 }
6618 }
6619
translate_fpu2k_sub_s(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6620 static void translate_fpu2k_sub_s(DisasContext *dc, const OpcodeArg arg[],
6621 const uint32_t par[])
6622 {
6623 gen_helper_fpu2k_sub_s(arg[0].out, tcg_env,
6624 arg[1].in, arg[2].in);
6625 }
6626
translate_wfr_d(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6627 static void translate_wfr_d(DisasContext *dc, const OpcodeArg arg[],
6628 const uint32_t par[])
6629 {
6630 tcg_gen_concat_i32_i64(arg[0].out, arg[2].in, arg[1].in);
6631 }
6632
translate_wfr_s(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6633 static void translate_wfr_s(DisasContext *dc, const OpcodeArg arg[],
6634 const uint32_t par[])
6635 {
6636 if (arg[0].num_bits == 32) {
6637 tcg_gen_mov_i32(arg[0].out, arg[1].in);
6638 } else {
6639 tcg_gen_ext_i32_i64(arg[0].out, arg[1].in);
6640 }
6641 }
6642
translate_wur_fpu2k_fcr(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6643 static void translate_wur_fpu2k_fcr(DisasContext *dc, const OpcodeArg arg[],
6644 const uint32_t par[])
6645 {
6646 gen_helper_wur_fpu2k_fcr(tcg_env, arg[0].in);
6647 }
6648
translate_wur_fpu2k_fsr(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6649 static void translate_wur_fpu2k_fsr(DisasContext *dc, const OpcodeArg arg[],
6650 const uint32_t par[])
6651 {
6652 tcg_gen_andi_i32(cpu_UR[par[0]], arg[0].in, 0xffffff80);
6653 }
6654
6655 static const XtensaOpcodeOps fpu2000_ops[] = {
6656 {
6657 .name = "abs.s",
6658 .translate = translate_abs_s,
6659 .coprocessor = 0x1,
6660 }, {
6661 .name = "add.s",
6662 .translate = translate_fpu2k_add_s,
6663 .coprocessor = 0x1,
6664 }, {
6665 .name = "ceil.s",
6666 .translate = translate_ftoi_s,
6667 .par = (const uint32_t[]){float_round_up, false},
6668 .coprocessor = 0x1,
6669 }, {
6670 .name = "float.s",
6671 .translate = translate_float_s,
6672 .par = (const uint32_t[]){false},
6673 .coprocessor = 0x1,
6674 }, {
6675 .name = "floor.s",
6676 .translate = translate_ftoi_s,
6677 .par = (const uint32_t[]){float_round_down, false},
6678 .coprocessor = 0x1,
6679 }, {
6680 .name = "lsi",
6681 .translate = translate_ldsti,
6682 .par = (const uint32_t[]){false, false},
6683 .op_flags = XTENSA_OP_LOAD,
6684 .coprocessor = 0x1,
6685 }, {
6686 .name = "lsiu",
6687 .translate = translate_ldsti,
6688 .par = (const uint32_t[]){false, true},
6689 .op_flags = XTENSA_OP_LOAD,
6690 .coprocessor = 0x1,
6691 }, {
6692 .name = "lsx",
6693 .translate = translate_ldstx,
6694 .par = (const uint32_t[]){false, false},
6695 .op_flags = XTENSA_OP_LOAD,
6696 .coprocessor = 0x1,
6697 }, {
6698 .name = "lsxu",
6699 .translate = translate_ldstx,
6700 .par = (const uint32_t[]){false, true},
6701 .op_flags = XTENSA_OP_LOAD,
6702 .coprocessor = 0x1,
6703 }, {
6704 .name = "madd.s",
6705 .translate = translate_fpu2k_madd_s,
6706 .coprocessor = 0x1,
6707 }, {
6708 .name = "mov.s",
6709 .translate = translate_mov_s,
6710 .coprocessor = 0x1,
6711 }, {
6712 .name = "moveqz.s",
6713 .translate = translate_movcond_s,
6714 .par = (const uint32_t[]){TCG_COND_EQ},
6715 .coprocessor = 0x1,
6716 }, {
6717 .name = "movf.s",
6718 .translate = translate_movp_s,
6719 .par = (const uint32_t[]){TCG_COND_EQ},
6720 .coprocessor = 0x1,
6721 }, {
6722 .name = "movgez.s",
6723 .translate = translate_movcond_s,
6724 .par = (const uint32_t[]){TCG_COND_GE},
6725 .coprocessor = 0x1,
6726 }, {
6727 .name = "movltz.s",
6728 .translate = translate_movcond_s,
6729 .par = (const uint32_t[]){TCG_COND_LT},
6730 .coprocessor = 0x1,
6731 }, {
6732 .name = "movnez.s",
6733 .translate = translate_movcond_s,
6734 .par = (const uint32_t[]){TCG_COND_NE},
6735 .coprocessor = 0x1,
6736 }, {
6737 .name = "movt.s",
6738 .translate = translate_movp_s,
6739 .par = (const uint32_t[]){TCG_COND_NE},
6740 .coprocessor = 0x1,
6741 }, {
6742 .name = "msub.s",
6743 .translate = translate_fpu2k_msub_s,
6744 .coprocessor = 0x1,
6745 }, {
6746 .name = "mul.s",
6747 .translate = translate_fpu2k_mul_s,
6748 .coprocessor = 0x1,
6749 }, {
6750 .name = "neg.s",
6751 .translate = translate_neg_s,
6752 .coprocessor = 0x1,
6753 }, {
6754 .name = "oeq.s",
6755 .translate = translate_compare_s,
6756 .par = (const uint32_t[]){COMPARE_OEQ},
6757 .coprocessor = 0x1,
6758 }, {
6759 .name = "ole.s",
6760 .translate = translate_compare_s,
6761 .par = (const uint32_t[]){COMPARE_OLE},
6762 .coprocessor = 0x1,
6763 }, {
6764 .name = "olt.s",
6765 .translate = translate_compare_s,
6766 .par = (const uint32_t[]){COMPARE_OLT},
6767 .coprocessor = 0x1,
6768 }, {
6769 .name = "rfr",
6770 .translate = translate_rfr_s,
6771 .coprocessor = 0x1,
6772 }, {
6773 .name = "round.s",
6774 .translate = translate_ftoi_s,
6775 .par = (const uint32_t[]){float_round_nearest_even, false},
6776 .coprocessor = 0x1,
6777 }, {
6778 .name = "rur.fcr",
6779 .translate = translate_rur,
6780 .par = (const uint32_t[]){FCR},
6781 .coprocessor = 0x1,
6782 }, {
6783 .name = "rur.fsr",
6784 .translate = translate_rur,
6785 .par = (const uint32_t[]){FSR},
6786 .coprocessor = 0x1,
6787 }, {
6788 .name = "ssi",
6789 .translate = translate_ldsti,
6790 .par = (const uint32_t[]){true, false},
6791 .op_flags = XTENSA_OP_STORE,
6792 .coprocessor = 0x1,
6793 }, {
6794 .name = "ssiu",
6795 .translate = translate_ldsti,
6796 .par = (const uint32_t[]){true, true},
6797 .op_flags = XTENSA_OP_STORE,
6798 .coprocessor = 0x1,
6799 }, {
6800 .name = "ssx",
6801 .translate = translate_ldstx,
6802 .par = (const uint32_t[]){true, false},
6803 .op_flags = XTENSA_OP_STORE,
6804 .coprocessor = 0x1,
6805 }, {
6806 .name = "ssxu",
6807 .translate = translate_ldstx,
6808 .par = (const uint32_t[]){true, true},
6809 .op_flags = XTENSA_OP_STORE,
6810 .coprocessor = 0x1,
6811 }, {
6812 .name = "sub.s",
6813 .translate = translate_fpu2k_sub_s,
6814 .coprocessor = 0x1,
6815 }, {
6816 .name = "trunc.s",
6817 .translate = translate_ftoi_s,
6818 .par = (const uint32_t[]){float_round_to_zero, false},
6819 .coprocessor = 0x1,
6820 }, {
6821 .name = "ueq.s",
6822 .translate = translate_compare_s,
6823 .par = (const uint32_t[]){COMPARE_UEQ},
6824 .coprocessor = 0x1,
6825 }, {
6826 .name = "ufloat.s",
6827 .translate = translate_float_s,
6828 .par = (const uint32_t[]){true},
6829 .coprocessor = 0x1,
6830 }, {
6831 .name = "ule.s",
6832 .translate = translate_compare_s,
6833 .par = (const uint32_t[]){COMPARE_ULE},
6834 .coprocessor = 0x1,
6835 }, {
6836 .name = "ult.s",
6837 .translate = translate_compare_s,
6838 .par = (const uint32_t[]){COMPARE_ULT},
6839 .coprocessor = 0x1,
6840 }, {
6841 .name = "un.s",
6842 .translate = translate_compare_s,
6843 .par = (const uint32_t[]){COMPARE_UN},
6844 .coprocessor = 0x1,
6845 }, {
6846 .name = "utrunc.s",
6847 .translate = translate_ftoi_s,
6848 .par = (const uint32_t[]){float_round_to_zero, true},
6849 .coprocessor = 0x1,
6850 }, {
6851 .name = "wfr",
6852 .translate = translate_wfr_s,
6853 .coprocessor = 0x1,
6854 }, {
6855 .name = "wur.fcr",
6856 .translate = translate_wur_fpu2k_fcr,
6857 .par = (const uint32_t[]){FCR},
6858 .coprocessor = 0x1,
6859 }, {
6860 .name = "wur.fsr",
6861 .translate = translate_wur_fpu2k_fsr,
6862 .par = (const uint32_t[]){FSR},
6863 .coprocessor = 0x1,
6864 },
6865 };
6866
6867 const XtensaOpcodeTranslators xtensa_fpu2000_opcodes = {
6868 .num_opcodes = ARRAY_SIZE(fpu2000_ops),
6869 .opcode = fpu2000_ops,
6870 };
6871
translate_add_d(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6872 static void translate_add_d(DisasContext *dc, const OpcodeArg arg[],
6873 const uint32_t par[])
6874 {
6875 gen_helper_add_d(arg[0].out, tcg_env, arg[1].in, arg[2].in);
6876 }
6877
translate_add_s(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6878 static void translate_add_s(DisasContext *dc, const OpcodeArg arg[],
6879 const uint32_t par[])
6880 {
6881 if (option_enabled(dc, XTENSA_OPTION_DFPU_SINGLE_ONLY)) {
6882 gen_helper_fpu2k_add_s(arg[0].out, tcg_env,
6883 arg[1].in, arg[2].in);
6884 } else {
6885 OpcodeArg arg32[3];
6886
6887 get_f32_o1_i2(arg, arg32, 0, 1, 2);
6888 gen_helper_add_s(arg32[0].out, tcg_env, arg32[1].in, arg32[2].in);
6889 put_f32_o1_i2(arg, arg32, 0, 1, 2);
6890 }
6891 }
6892
translate_cvtd_s(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6893 static void translate_cvtd_s(DisasContext *dc, const OpcodeArg arg[],
6894 const uint32_t par[])
6895 {
6896 TCGv_i32 v = tcg_temp_new_i32();
6897
6898 tcg_gen_extrl_i64_i32(v, arg[1].in);
6899 gen_helper_cvtd_s(arg[0].out, tcg_env, v);
6900 }
6901
translate_cvts_d(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6902 static void translate_cvts_d(DisasContext *dc, const OpcodeArg arg[],
6903 const uint32_t par[])
6904 {
6905 TCGv_i32 v = tcg_temp_new_i32();
6906
6907 gen_helper_cvts_d(v, tcg_env, arg[1].in);
6908 tcg_gen_extu_i32_i64(arg[0].out, v);
6909 }
6910
translate_ldsti_d(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6911 static void translate_ldsti_d(DisasContext *dc, const OpcodeArg arg[],
6912 const uint32_t par[])
6913 {
6914 TCGv_i32 addr;
6915 MemOp mop;
6916
6917 if (par[1]) {
6918 addr = tcg_temp_new_i32();
6919 tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm);
6920 } else {
6921 addr = arg[1].in;
6922 }
6923 mop = gen_load_store_alignment(dc, MO_TEUQ, addr);
6924 if (par[0]) {
6925 tcg_gen_qemu_st_i64(arg[0].in, addr, dc->cring, mop);
6926 } else {
6927 tcg_gen_qemu_ld_i64(arg[0].out, addr, dc->cring, mop);
6928 }
6929 if (par[2]) {
6930 if (par[1]) {
6931 tcg_gen_mov_i32(arg[1].out, addr);
6932 } else {
6933 tcg_gen_addi_i32(arg[1].out, arg[1].in, arg[2].imm);
6934 }
6935 }
6936 }
6937
translate_ldsti_s(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6938 static void translate_ldsti_s(DisasContext *dc, const OpcodeArg arg[],
6939 const uint32_t par[])
6940 {
6941 TCGv_i32 addr;
6942 OpcodeArg arg32[1];
6943 MemOp mop;
6944
6945 if (par[1]) {
6946 addr = tcg_temp_new_i32();
6947 tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm);
6948 } else {
6949 addr = arg[1].in;
6950 }
6951 mop = gen_load_store_alignment(dc, MO_TEUL, addr);
6952 if (par[0]) {
6953 get_f32_i1(arg, arg32, 0);
6954 tcg_gen_qemu_st_tl(arg32[0].in, addr, dc->cring, mop);
6955 put_f32_i1(arg, arg32, 0);
6956 } else {
6957 get_f32_o1(arg, arg32, 0);
6958 tcg_gen_qemu_ld_tl(arg32[0].out, addr, dc->cring, mop);
6959 put_f32_o1(arg, arg32, 0);
6960 }
6961 if (par[2]) {
6962 if (par[1]) {
6963 tcg_gen_mov_i32(arg[1].out, addr);
6964 } else {
6965 tcg_gen_addi_i32(arg[1].out, arg[1].in, arg[2].imm);
6966 }
6967 }
6968 }
6969
translate_ldstx_d(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6970 static void translate_ldstx_d(DisasContext *dc, const OpcodeArg arg[],
6971 const uint32_t par[])
6972 {
6973 TCGv_i32 addr;
6974 MemOp mop;
6975
6976 if (par[1]) {
6977 addr = tcg_temp_new_i32();
6978 tcg_gen_add_i32(addr, arg[1].in, arg[2].in);
6979 } else {
6980 addr = arg[1].in;
6981 }
6982 mop = gen_load_store_alignment(dc, MO_TEUQ, addr);
6983 if (par[0]) {
6984 tcg_gen_qemu_st_i64(arg[0].in, addr, dc->cring, mop);
6985 } else {
6986 tcg_gen_qemu_ld_i64(arg[0].out, addr, dc->cring, mop);
6987 }
6988 if (par[2]) {
6989 if (par[1]) {
6990 tcg_gen_mov_i32(arg[1].out, addr);
6991 } else {
6992 tcg_gen_add_i32(arg[1].out, arg[1].in, arg[2].in);
6993 }
6994 }
6995 }
6996
translate_ldstx_s(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])6997 static void translate_ldstx_s(DisasContext *dc, const OpcodeArg arg[],
6998 const uint32_t par[])
6999 {
7000 TCGv_i32 addr;
7001 OpcodeArg arg32[1];
7002 MemOp mop;
7003
7004 if (par[1]) {
7005 addr = tcg_temp_new_i32();
7006 tcg_gen_add_i32(addr, arg[1].in, arg[2].in);
7007 } else {
7008 addr = arg[1].in;
7009 }
7010 mop = gen_load_store_alignment(dc, MO_TEUL, addr);
7011 if (par[0]) {
7012 get_f32_i1(arg, arg32, 0);
7013 tcg_gen_qemu_st_tl(arg32[0].in, addr, dc->cring, mop);
7014 put_f32_i1(arg, arg32, 0);
7015 } else {
7016 get_f32_o1(arg, arg32, 0);
7017 tcg_gen_qemu_ld_tl(arg32[0].out, addr, dc->cring, mop);
7018 put_f32_o1(arg, arg32, 0);
7019 }
7020 if (par[2]) {
7021 if (par[1]) {
7022 tcg_gen_mov_i32(arg[1].out, addr);
7023 } else {
7024 tcg_gen_add_i32(arg[1].out, arg[1].in, arg[2].in);
7025 }
7026 }
7027 }
7028
translate_madd_d(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])7029 static void translate_madd_d(DisasContext *dc, const OpcodeArg arg[],
7030 const uint32_t par[])
7031 {
7032 gen_helper_madd_d(arg[0].out, tcg_env,
7033 arg[0].in, arg[1].in, arg[2].in);
7034 }
7035
translate_madd_s(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])7036 static void translate_madd_s(DisasContext *dc, const OpcodeArg arg[],
7037 const uint32_t par[])
7038 {
7039 if (option_enabled(dc, XTENSA_OPTION_DFPU_SINGLE_ONLY)) {
7040 gen_helper_fpu2k_madd_s(arg[0].out, tcg_env,
7041 arg[0].in, arg[1].in, arg[2].in);
7042 } else {
7043 OpcodeArg arg32[3];
7044
7045 get_f32_o1_i3(arg, arg32, 0, 0, 1, 2);
7046 gen_helper_madd_s(arg32[0].out, tcg_env,
7047 arg32[0].in, arg32[1].in, arg32[2].in);
7048 put_f32_o1_i3(arg, arg32, 0, 0, 1, 2);
7049 }
7050 }
7051
translate_mul_d(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])7052 static void translate_mul_d(DisasContext *dc, const OpcodeArg arg[],
7053 const uint32_t par[])
7054 {
7055 gen_helper_mul_d(arg[0].out, tcg_env, arg[1].in, arg[2].in);
7056 }
7057
translate_mul_s(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])7058 static void translate_mul_s(DisasContext *dc, const OpcodeArg arg[],
7059 const uint32_t par[])
7060 {
7061 if (option_enabled(dc, XTENSA_OPTION_DFPU_SINGLE_ONLY)) {
7062 gen_helper_fpu2k_mul_s(arg[0].out, tcg_env,
7063 arg[1].in, arg[2].in);
7064 } else {
7065 OpcodeArg arg32[3];
7066
7067 get_f32_o1_i2(arg, arg32, 0, 1, 2);
7068 gen_helper_mul_s(arg32[0].out, tcg_env, arg32[1].in, arg32[2].in);
7069 put_f32_o1_i2(arg, arg32, 0, 1, 2);
7070 }
7071 }
7072
translate_msub_d(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])7073 static void translate_msub_d(DisasContext *dc, const OpcodeArg arg[],
7074 const uint32_t par[])
7075 {
7076 gen_helper_msub_d(arg[0].out, tcg_env,
7077 arg[0].in, arg[1].in, arg[2].in);
7078 }
7079
translate_msub_s(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])7080 static void translate_msub_s(DisasContext *dc, const OpcodeArg arg[],
7081 const uint32_t par[])
7082 {
7083 if (option_enabled(dc, XTENSA_OPTION_DFPU_SINGLE_ONLY)) {
7084 gen_helper_fpu2k_msub_s(arg[0].out, tcg_env,
7085 arg[0].in, arg[1].in, arg[2].in);
7086 } else {
7087 OpcodeArg arg32[3];
7088
7089 get_f32_o1_i3(arg, arg32, 0, 0, 1, 2);
7090 gen_helper_msub_s(arg32[0].out, tcg_env,
7091 arg32[0].in, arg32[1].in, arg32[2].in);
7092 put_f32_o1_i3(arg, arg32, 0, 0, 1, 2);
7093 }
7094 }
7095
translate_sub_d(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])7096 static void translate_sub_d(DisasContext *dc, const OpcodeArg arg[],
7097 const uint32_t par[])
7098 {
7099 gen_helper_sub_d(arg[0].out, tcg_env, arg[1].in, arg[2].in);
7100 }
7101
translate_sub_s(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])7102 static void translate_sub_s(DisasContext *dc, const OpcodeArg arg[],
7103 const uint32_t par[])
7104 {
7105 if (option_enabled(dc, XTENSA_OPTION_DFPU_SINGLE_ONLY)) {
7106 gen_helper_fpu2k_sub_s(arg[0].out, tcg_env,
7107 arg[1].in, arg[2].in);
7108 } else {
7109 OpcodeArg arg32[3];
7110
7111 get_f32_o1_i2(arg, arg32, 0, 1, 2);
7112 gen_helper_sub_s(arg32[0].out, tcg_env, arg32[1].in, arg32[2].in);
7113 put_f32_o1_i2(arg, arg32, 0, 1, 2);
7114 }
7115 }
7116
translate_mkdadj_d(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])7117 static void translate_mkdadj_d(DisasContext *dc, const OpcodeArg arg[],
7118 const uint32_t par[])
7119 {
7120 gen_helper_mkdadj_d(arg[0].out, tcg_env, arg[0].in, arg[1].in);
7121 }
7122
translate_mkdadj_s(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])7123 static void translate_mkdadj_s(DisasContext *dc, const OpcodeArg arg[],
7124 const uint32_t par[])
7125 {
7126 OpcodeArg arg32[2];
7127
7128 get_f32_o1_i2(arg, arg32, 0, 0, 1);
7129 gen_helper_mkdadj_s(arg32[0].out, tcg_env, arg32[0].in, arg32[1].in);
7130 put_f32_o1_i2(arg, arg32, 0, 0, 1);
7131 }
7132
translate_mksadj_d(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])7133 static void translate_mksadj_d(DisasContext *dc, const OpcodeArg arg[],
7134 const uint32_t par[])
7135 {
7136 gen_helper_mksadj_d(arg[0].out, tcg_env, arg[1].in);
7137 }
7138
translate_mksadj_s(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])7139 static void translate_mksadj_s(DisasContext *dc, const OpcodeArg arg[],
7140 const uint32_t par[])
7141 {
7142 OpcodeArg arg32[2];
7143
7144 get_f32_o1_i1(arg, arg32, 0, 1);
7145 gen_helper_mksadj_s(arg32[0].out, tcg_env, arg32[1].in);
7146 put_f32_o1_i1(arg, arg32, 0, 1);
7147 }
7148
translate_wur_fpu_fcr(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])7149 static void translate_wur_fpu_fcr(DisasContext *dc, const OpcodeArg arg[],
7150 const uint32_t par[])
7151 {
7152 gen_helper_wur_fpu_fcr(tcg_env, arg[0].in);
7153 }
7154
translate_rur_fpu_fsr(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])7155 static void translate_rur_fpu_fsr(DisasContext *dc, const OpcodeArg arg[],
7156 const uint32_t par[])
7157 {
7158 gen_helper_rur_fpu_fsr(arg[0].out, tcg_env);
7159 }
7160
translate_wur_fpu_fsr(DisasContext * dc,const OpcodeArg arg[],const uint32_t par[])7161 static void translate_wur_fpu_fsr(DisasContext *dc, const OpcodeArg arg[],
7162 const uint32_t par[])
7163 {
7164 gen_helper_wur_fpu_fsr(tcg_env, arg[0].in);
7165 }
7166
7167 static const XtensaOpcodeOps fpu_ops[] = {
7168 {
7169 .name = "abs.d",
7170 .translate = translate_abs_d,
7171 .coprocessor = 0x1,
7172 }, {
7173 .name = "abs.s",
7174 .translate = translate_abs_s,
7175 .coprocessor = 0x1,
7176 }, {
7177 .name = "add.d",
7178 .translate = translate_add_d,
7179 .coprocessor = 0x1,
7180 }, {
7181 .name = "add.s",
7182 .translate = translate_add_s,
7183 .coprocessor = 0x1,
7184 }, {
7185 .name = "addexp.d",
7186 .translate = translate_nop,
7187 .coprocessor = 0x1,
7188 }, {
7189 .name = "addexp.s",
7190 .translate = translate_nop,
7191 .coprocessor = 0x1,
7192 }, {
7193 .name = "addexpm.d",
7194 .translate = translate_mov_s,
7195 .coprocessor = 0x1,
7196 }, {
7197 .name = "addexpm.s",
7198 .translate = translate_mov_s,
7199 .coprocessor = 0x1,
7200 }, {
7201 .name = "ceil.d",
7202 .translate = translate_ftoi_d,
7203 .par = (const uint32_t[]){float_round_up, false},
7204 .coprocessor = 0x1,
7205 }, {
7206 .name = "ceil.s",
7207 .translate = translate_ftoi_s,
7208 .par = (const uint32_t[]){float_round_up, false},
7209 .coprocessor = 0x1,
7210 }, {
7211 .name = "const.d",
7212 .translate = translate_const_d,
7213 .coprocessor = 0x1,
7214 }, {
7215 .name = "const.s",
7216 .translate = translate_const_s,
7217 .coprocessor = 0x1,
7218 }, {
7219 .name = "cvtd.s",
7220 .translate = translate_cvtd_s,
7221 .coprocessor = 0x1,
7222 }, {
7223 .name = "cvts.d",
7224 .translate = translate_cvts_d,
7225 .coprocessor = 0x1,
7226 }, {
7227 .name = "div0.d",
7228 .translate = translate_nop,
7229 .coprocessor = 0x1,
7230 }, {
7231 .name = "div0.s",
7232 .translate = translate_nop,
7233 .coprocessor = 0x1,
7234 }, {
7235 .name = "divn.d",
7236 .translate = translate_nop,
7237 .coprocessor = 0x1,
7238 }, {
7239 .name = "divn.s",
7240 .translate = translate_nop,
7241 .coprocessor = 0x1,
7242 }, {
7243 .name = "float.d",
7244 .translate = translate_float_d,
7245 .par = (const uint32_t[]){false},
7246 .coprocessor = 0x1,
7247 }, {
7248 .name = "float.s",
7249 .translate = translate_float_s,
7250 .par = (const uint32_t[]){false},
7251 .coprocessor = 0x1,
7252 }, {
7253 .name = "floor.d",
7254 .translate = translate_ftoi_d,
7255 .par = (const uint32_t[]){float_round_down, false},
7256 .coprocessor = 0x1,
7257 }, {
7258 .name = "floor.s",
7259 .translate = translate_ftoi_s,
7260 .par = (const uint32_t[]){float_round_down, false},
7261 .coprocessor = 0x1,
7262 }, {
7263 .name = "ldi",
7264 .translate = translate_ldsti_d,
7265 .par = (const uint32_t[]){false, true, false},
7266 .op_flags = XTENSA_OP_LOAD,
7267 .coprocessor = 0x1,
7268 }, {
7269 .name = "ldip",
7270 .translate = translate_ldsti_d,
7271 .par = (const uint32_t[]){false, false, true},
7272 .op_flags = XTENSA_OP_LOAD,
7273 .coprocessor = 0x1,
7274 }, {
7275 .name = "ldiu",
7276 .translate = translate_ldsti_d,
7277 .par = (const uint32_t[]){false, true, true},
7278 .op_flags = XTENSA_OP_LOAD,
7279 .coprocessor = 0x1,
7280 }, {
7281 .name = "ldx",
7282 .translate = translate_ldstx_d,
7283 .par = (const uint32_t[]){false, true, false},
7284 .op_flags = XTENSA_OP_LOAD,
7285 .coprocessor = 0x1,
7286 }, {
7287 .name = "ldxp",
7288 .translate = translate_ldstx_d,
7289 .par = (const uint32_t[]){false, false, true},
7290 .op_flags = XTENSA_OP_LOAD,
7291 .coprocessor = 0x1,
7292 }, {
7293 .name = "ldxu",
7294 .translate = translate_ldstx_d,
7295 .par = (const uint32_t[]){false, true, true},
7296 .op_flags = XTENSA_OP_LOAD,
7297 .coprocessor = 0x1,
7298 }, {
7299 .name = "lsi",
7300 .translate = translate_ldsti_s,
7301 .par = (const uint32_t[]){false, true, false},
7302 .op_flags = XTENSA_OP_LOAD,
7303 .coprocessor = 0x1,
7304 }, {
7305 .name = "lsip",
7306 .translate = translate_ldsti_s,
7307 .par = (const uint32_t[]){false, false, true},
7308 .op_flags = XTENSA_OP_LOAD,
7309 .coprocessor = 0x1,
7310 }, {
7311 .name = "lsiu",
7312 .translate = translate_ldsti_s,
7313 .par = (const uint32_t[]){false, true, true},
7314 .op_flags = XTENSA_OP_LOAD,
7315 .coprocessor = 0x1,
7316 }, {
7317 .name = "lsx",
7318 .translate = translate_ldstx_s,
7319 .par = (const uint32_t[]){false, true, false},
7320 .op_flags = XTENSA_OP_LOAD,
7321 .coprocessor = 0x1,
7322 }, {
7323 .name = "lsxp",
7324 .translate = translate_ldstx_s,
7325 .par = (const uint32_t[]){false, false, true},
7326 .op_flags = XTENSA_OP_LOAD,
7327 .coprocessor = 0x1,
7328 }, {
7329 .name = "lsxu",
7330 .translate = translate_ldstx_s,
7331 .par = (const uint32_t[]){false, true, true},
7332 .op_flags = XTENSA_OP_LOAD,
7333 .coprocessor = 0x1,
7334 }, {
7335 .name = "madd.d",
7336 .translate = translate_madd_d,
7337 .coprocessor = 0x1,
7338 }, {
7339 .name = "madd.s",
7340 .translate = translate_madd_s,
7341 .coprocessor = 0x1,
7342 }, {
7343 .name = "maddn.d",
7344 .translate = translate_nop,
7345 .coprocessor = 0x1,
7346 }, {
7347 .name = "maddn.s",
7348 .translate = translate_nop,
7349 .coprocessor = 0x1,
7350 }, {
7351 .name = "mkdadj.d",
7352 .translate = translate_mkdadj_d,
7353 .coprocessor = 0x1,
7354 }, {
7355 .name = "mkdadj.s",
7356 .translate = translate_mkdadj_s,
7357 .coprocessor = 0x1,
7358 }, {
7359 .name = "mksadj.d",
7360 .translate = translate_mksadj_d,
7361 .coprocessor = 0x1,
7362 }, {
7363 .name = "mksadj.s",
7364 .translate = translate_mksadj_s,
7365 .coprocessor = 0x1,
7366 }, {
7367 .name = "mov.d",
7368 .translate = translate_mov_d,
7369 .coprocessor = 0x1,
7370 }, {
7371 .name = "mov.s",
7372 .translate = translate_mov_s,
7373 .coprocessor = 0x1,
7374 }, {
7375 .name = "moveqz.d",
7376 .translate = translate_movcond_d,
7377 .par = (const uint32_t[]){TCG_COND_EQ},
7378 .coprocessor = 0x1,
7379 }, {
7380 .name = "moveqz.s",
7381 .translate = translate_movcond_s,
7382 .par = (const uint32_t[]){TCG_COND_EQ},
7383 .coprocessor = 0x1,
7384 }, {
7385 .name = "movf.d",
7386 .translate = translate_movp_d,
7387 .par = (const uint32_t[]){TCG_COND_EQ},
7388 .coprocessor = 0x1,
7389 }, {
7390 .name = "movf.s",
7391 .translate = translate_movp_s,
7392 .par = (const uint32_t[]){TCG_COND_EQ},
7393 .coprocessor = 0x1,
7394 }, {
7395 .name = "movgez.d",
7396 .translate = translate_movcond_d,
7397 .par = (const uint32_t[]){TCG_COND_GE},
7398 .coprocessor = 0x1,
7399 }, {
7400 .name = "movgez.s",
7401 .translate = translate_movcond_s,
7402 .par = (const uint32_t[]){TCG_COND_GE},
7403 .coprocessor = 0x1,
7404 }, {
7405 .name = "movltz.d",
7406 .translate = translate_movcond_d,
7407 .par = (const uint32_t[]){TCG_COND_LT},
7408 .coprocessor = 0x1,
7409 }, {
7410 .name = "movltz.s",
7411 .translate = translate_movcond_s,
7412 .par = (const uint32_t[]){TCG_COND_LT},
7413 .coprocessor = 0x1,
7414 }, {
7415 .name = "movnez.d",
7416 .translate = translate_movcond_d,
7417 .par = (const uint32_t[]){TCG_COND_NE},
7418 .coprocessor = 0x1,
7419 }, {
7420 .name = "movnez.s",
7421 .translate = translate_movcond_s,
7422 .par = (const uint32_t[]){TCG_COND_NE},
7423 .coprocessor = 0x1,
7424 }, {
7425 .name = "movt.d",
7426 .translate = translate_movp_d,
7427 .par = (const uint32_t[]){TCG_COND_NE},
7428 .coprocessor = 0x1,
7429 }, {
7430 .name = "movt.s",
7431 .translate = translate_movp_s,
7432 .par = (const uint32_t[]){TCG_COND_NE},
7433 .coprocessor = 0x1,
7434 }, {
7435 .name = "msub.d",
7436 .translate = translate_msub_d,
7437 .coprocessor = 0x1,
7438 }, {
7439 .name = "msub.s",
7440 .translate = translate_msub_s,
7441 .coprocessor = 0x1,
7442 }, {
7443 .name = "mul.d",
7444 .translate = translate_mul_d,
7445 .coprocessor = 0x1,
7446 }, {
7447 .name = "mul.s",
7448 .translate = translate_mul_s,
7449 .coprocessor = 0x1,
7450 }, {
7451 .name = "neg.d",
7452 .translate = translate_neg_d,
7453 .coprocessor = 0x1,
7454 }, {
7455 .name = "neg.s",
7456 .translate = translate_neg_s,
7457 .coprocessor = 0x1,
7458 }, {
7459 .name = "nexp01.d",
7460 .translate = translate_nop,
7461 .coprocessor = 0x1,
7462 }, {
7463 .name = "nexp01.s",
7464 .translate = translate_nop,
7465 .coprocessor = 0x1,
7466 }, {
7467 .name = "oeq.d",
7468 .translate = translate_compare_d,
7469 .par = (const uint32_t[]){COMPARE_OEQ},
7470 .coprocessor = 0x1,
7471 }, {
7472 .name = "oeq.s",
7473 .translate = translate_compare_s,
7474 .par = (const uint32_t[]){COMPARE_OEQ},
7475 .coprocessor = 0x1,
7476 }, {
7477 .name = "ole.d",
7478 .translate = translate_compare_d,
7479 .par = (const uint32_t[]){COMPARE_OLE},
7480 .coprocessor = 0x1,
7481 }, {
7482 .name = "ole.s",
7483 .translate = translate_compare_s,
7484 .par = (const uint32_t[]){COMPARE_OLE},
7485 .coprocessor = 0x1,
7486 }, {
7487 .name = "olt.d",
7488 .translate = translate_compare_d,
7489 .par = (const uint32_t[]){COMPARE_OLT},
7490 .coprocessor = 0x1,
7491 }, {
7492 .name = "olt.s",
7493 .translate = translate_compare_s,
7494 .par = (const uint32_t[]){COMPARE_OLT},
7495 .coprocessor = 0x1,
7496 }, {
7497 .name = "rfr",
7498 .translate = translate_rfr_s,
7499 .coprocessor = 0x1,
7500 }, {
7501 .name = "rfrd",
7502 .translate = translate_rfr_d,
7503 .coprocessor = 0x1,
7504 }, {
7505 .name = "round.d",
7506 .translate = translate_ftoi_d,
7507 .par = (const uint32_t[]){float_round_nearest_even, false},
7508 .coprocessor = 0x1,
7509 }, {
7510 .name = "round.s",
7511 .translate = translate_ftoi_s,
7512 .par = (const uint32_t[]){float_round_nearest_even, false},
7513 .coprocessor = 0x1,
7514 }, {
7515 .name = "rur.fcr",
7516 .translate = translate_rur,
7517 .par = (const uint32_t[]){FCR},
7518 .coprocessor = 0x1,
7519 }, {
7520 .name = "rur.fsr",
7521 .translate = translate_rur_fpu_fsr,
7522 .coprocessor = 0x1,
7523 }, {
7524 .name = "sdi",
7525 .translate = translate_ldsti_d,
7526 .par = (const uint32_t[]){true, true, false},
7527 .op_flags = XTENSA_OP_STORE,
7528 .coprocessor = 0x1,
7529 }, {
7530 .name = "sdip",
7531 .translate = translate_ldsti_d,
7532 .par = (const uint32_t[]){true, false, true},
7533 .op_flags = XTENSA_OP_STORE,
7534 .coprocessor = 0x1,
7535 }, {
7536 .name = "sdiu",
7537 .translate = translate_ldsti_d,
7538 .par = (const uint32_t[]){true, true, true},
7539 .op_flags = XTENSA_OP_STORE,
7540 .coprocessor = 0x1,
7541 }, {
7542 .name = "sdx",
7543 .translate = translate_ldstx_d,
7544 .par = (const uint32_t[]){true, true, false},
7545 .op_flags = XTENSA_OP_STORE,
7546 .coprocessor = 0x1,
7547 }, {
7548 .name = "sdxp",
7549 .translate = translate_ldstx_d,
7550 .par = (const uint32_t[]){true, false, true},
7551 .op_flags = XTENSA_OP_STORE,
7552 .coprocessor = 0x1,
7553 }, {
7554 .name = "sdxu",
7555 .translate = translate_ldstx_d,
7556 .par = (const uint32_t[]){true, true, true},
7557 .op_flags = XTENSA_OP_STORE,
7558 .coprocessor = 0x1,
7559 }, {
7560 .name = "sqrt0.d",
7561 .translate = translate_nop,
7562 .coprocessor = 0x1,
7563 }, {
7564 .name = "sqrt0.s",
7565 .translate = translate_nop,
7566 .coprocessor = 0x1,
7567 }, {
7568 .name = "ssi",
7569 .translate = translate_ldsti_s,
7570 .par = (const uint32_t[]){true, true, false},
7571 .op_flags = XTENSA_OP_STORE,
7572 .coprocessor = 0x1,
7573 }, {
7574 .name = "ssip",
7575 .translate = translate_ldsti_s,
7576 .par = (const uint32_t[]){true, false, true},
7577 .op_flags = XTENSA_OP_STORE,
7578 .coprocessor = 0x1,
7579 }, {
7580 .name = "ssiu",
7581 .translate = translate_ldsti_s,
7582 .par = (const uint32_t[]){true, true, true},
7583 .op_flags = XTENSA_OP_STORE,
7584 .coprocessor = 0x1,
7585 }, {
7586 .name = "ssx",
7587 .translate = translate_ldstx_s,
7588 .par = (const uint32_t[]){true, true, false},
7589 .op_flags = XTENSA_OP_STORE,
7590 .coprocessor = 0x1,
7591 }, {
7592 .name = "ssxp",
7593 .translate = translate_ldstx_s,
7594 .par = (const uint32_t[]){true, false, true},
7595 .op_flags = XTENSA_OP_STORE,
7596 .coprocessor = 0x1,
7597 }, {
7598 .name = "ssxu",
7599 .translate = translate_ldstx_s,
7600 .par = (const uint32_t[]){true, true, true},
7601 .op_flags = XTENSA_OP_STORE,
7602 .coprocessor = 0x1,
7603 }, {
7604 .name = "sub.d",
7605 .translate = translate_sub_d,
7606 .coprocessor = 0x1,
7607 }, {
7608 .name = "sub.s",
7609 .translate = translate_sub_s,
7610 .coprocessor = 0x1,
7611 }, {
7612 .name = "trunc.d",
7613 .translate = translate_ftoi_d,
7614 .par = (const uint32_t[]){float_round_to_zero, false},
7615 .coprocessor = 0x1,
7616 }, {
7617 .name = "trunc.s",
7618 .translate = translate_ftoi_s,
7619 .par = (const uint32_t[]){float_round_to_zero, false},
7620 .coprocessor = 0x1,
7621 }, {
7622 .name = "ueq.d",
7623 .translate = translate_compare_d,
7624 .par = (const uint32_t[]){COMPARE_UEQ},
7625 .coprocessor = 0x1,
7626 }, {
7627 .name = "ueq.s",
7628 .translate = translate_compare_s,
7629 .par = (const uint32_t[]){COMPARE_UEQ},
7630 .coprocessor = 0x1,
7631 }, {
7632 .name = "ufloat.d",
7633 .translate = translate_float_d,
7634 .par = (const uint32_t[]){true},
7635 .coprocessor = 0x1,
7636 }, {
7637 .name = "ufloat.s",
7638 .translate = translate_float_s,
7639 .par = (const uint32_t[]){true},
7640 .coprocessor = 0x1,
7641 }, {
7642 .name = "ule.d",
7643 .translate = translate_compare_d,
7644 .par = (const uint32_t[]){COMPARE_ULE},
7645 .coprocessor = 0x1,
7646 }, {
7647 .name = "ule.s",
7648 .translate = translate_compare_s,
7649 .par = (const uint32_t[]){COMPARE_ULE},
7650 .coprocessor = 0x1,
7651 }, {
7652 .name = "ult.d",
7653 .translate = translate_compare_d,
7654 .par = (const uint32_t[]){COMPARE_ULT},
7655 .coprocessor = 0x1,
7656 }, {
7657 .name = "ult.s",
7658 .translate = translate_compare_s,
7659 .par = (const uint32_t[]){COMPARE_ULT},
7660 .coprocessor = 0x1,
7661 }, {
7662 .name = "un.d",
7663 .translate = translate_compare_d,
7664 .par = (const uint32_t[]){COMPARE_UN},
7665 .coprocessor = 0x1,
7666 }, {
7667 .name = "un.s",
7668 .translate = translate_compare_s,
7669 .par = (const uint32_t[]){COMPARE_UN},
7670 .coprocessor = 0x1,
7671 }, {
7672 .name = "utrunc.d",
7673 .translate = translate_ftoi_d,
7674 .par = (const uint32_t[]){float_round_to_zero, true},
7675 .coprocessor = 0x1,
7676 }, {
7677 .name = "utrunc.s",
7678 .translate = translate_ftoi_s,
7679 .par = (const uint32_t[]){float_round_to_zero, true},
7680 .coprocessor = 0x1,
7681 }, {
7682 .name = "wfr",
7683 .translate = translate_wfr_s,
7684 .coprocessor = 0x1,
7685 }, {
7686 .name = "wfrd",
7687 .translate = translate_wfr_d,
7688 .coprocessor = 0x1,
7689 }, {
7690 .name = "wur.fcr",
7691 .translate = translate_wur_fpu_fcr,
7692 .par = (const uint32_t[]){FCR},
7693 .coprocessor = 0x1,
7694 }, {
7695 .name = "wur.fsr",
7696 .translate = translate_wur_fpu_fsr,
7697 .coprocessor = 0x1,
7698 },
7699 };
7700
7701 const XtensaOpcodeTranslators xtensa_fpu_opcodes = {
7702 .num_opcodes = ARRAY_SIZE(fpu_ops),
7703 .opcode = fpu_ops,
7704 };
7705