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