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