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