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