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