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