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