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