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