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