xref: /qemu/target/xtensa/translate.c (revision de6cd759)
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(cpu_env,
158             offsetof(CPUXtensaState, pc), "pc");
159 
160     for (i = 0; i < 16; i++) {
161         cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
162                                           offsetof(CPUXtensaState, regs[i]),
163                                           regnames[i]);
164     }
165 
166     for (i = 0; i < 16; i++) {
167         cpu_FR[i] = tcg_global_mem_new_i32(cpu_env,
168                                            offsetof(CPUXtensaState,
169                                                     fregs[i].f32[FP_F32_LOW]),
170                                            fregnames[i]);
171     }
172 
173     for (i = 0; i < 16; i++) {
174         cpu_FRD[i] = tcg_global_mem_new_i64(cpu_env,
175                                             offsetof(CPUXtensaState,
176                                                      fregs[i].f64),
177                                             fregnames[i]);
178     }
179 
180     for (i = 0; i < 4; i++) {
181         cpu_MR[i] = tcg_global_mem_new_i32(cpu_env,
182                                            offsetof(CPUXtensaState,
183                                                     sregs[MR + i]),
184                                            mregnames[i]);
185     }
186 
187     for (i = 0; i < 16; i++) {
188         cpu_BR[i] = tcg_global_mem_new_i32(cpu_env,
189                                            offsetof(CPUXtensaState,
190                                                     sregs[BR]),
191                                            bregnames[i]);
192         if (i % 4 == 0) {
193             cpu_BR4[i / 4] = tcg_global_mem_new_i32(cpu_env,
194                                                     offsetof(CPUXtensaState,
195                                                              sregs[BR]),
196                                                     bregnames[i]);
197         }
198         if (i % 8 == 0) {
199             cpu_BR8[i / 8] = tcg_global_mem_new_i32(cpu_env,
200                                                     offsetof(CPUXtensaState,
201                                                              sregs[BR]),
202                                                     bregnames[i]);
203         }
204     }
205 
206     for (i = 0; i < 256; ++i) {
207         if (sr_name[i]) {
208             cpu_SR[i] = tcg_global_mem_new_i32(cpu_env,
209                                                offsetof(CPUXtensaState,
210                                                         sregs[i]),
211                                                sr_name[i]);
212         }
213     }
214 
215     for (i = 0; i < 256; ++i) {
216         if (ur_name[i]) {
217             cpu_UR[i] = tcg_global_mem_new_i32(cpu_env,
218                                                offsetof(CPUXtensaState,
219                                                         uregs[i]),
220                                                ur_name[i]);
221         }
222     }
223 
224     cpu_windowbase_next =
225         tcg_global_mem_new_i32(cpu_env,
226                                offsetof(CPUXtensaState, windowbase_next),
227                                "windowbase_next");
228     cpu_exclusive_addr =
229         tcg_global_mem_new_i32(cpu_env,
230                                offsetof(CPUXtensaState, exclusive_addr),
231                                "exclusive_addr");
232     cpu_exclusive_val =
233         tcg_global_mem_new_i32(cpu_env,
234                                offsetof(CPUXtensaState, exclusive_val),
235                                "exclusive_val");
236 }
237 
238 void **xtensa_get_regfile_by_name(const char *name, int entries, int bits)
239 {
240     char *geometry_name;
241     void **res;
242 
243     if (xtensa_regfile_table == NULL) {
244         xtensa_regfile_table = g_hash_table_new(g_str_hash, g_str_equal);
245         /*
246          * AR is special. Xtensa translator uses it as a current register
247          * window, but configuration overlays represent it as a complete
248          * physical register file.
249          */
250         g_hash_table_insert(xtensa_regfile_table,
251                             (void *)"AR 16x32", (void *)cpu_R);
252         g_hash_table_insert(xtensa_regfile_table,
253                             (void *)"AR 32x32", (void *)cpu_R);
254         g_hash_table_insert(xtensa_regfile_table,
255                             (void *)"AR 64x32", (void *)cpu_R);
256 
257         g_hash_table_insert(xtensa_regfile_table,
258                             (void *)"MR 4x32", (void *)cpu_MR);
259 
260         g_hash_table_insert(xtensa_regfile_table,
261                             (void *)"FR 16x32", (void *)cpu_FR);
262         g_hash_table_insert(xtensa_regfile_table,
263                             (void *)"FR 16x64", (void *)cpu_FRD);
264 
265         g_hash_table_insert(xtensa_regfile_table,
266                             (void *)"BR 16x1", (void *)cpu_BR);
267         g_hash_table_insert(xtensa_regfile_table,
268                             (void *)"BR4 4x4", (void *)cpu_BR4);
269         g_hash_table_insert(xtensa_regfile_table,
270                             (void *)"BR8 2x8", (void *)cpu_BR8);
271     }
272 
273     geometry_name = g_strdup_printf("%s %dx%d", name, entries, bits);
274     res = (void **)g_hash_table_lookup(xtensa_regfile_table, geometry_name);
275     g_free(geometry_name);
276     return res;
277 }
278 
279 static inline bool option_enabled(DisasContext *dc, int opt)
280 {
281     return xtensa_option_enabled(dc->config, opt);
282 }
283 
284 static void init_sar_tracker(DisasContext *dc)
285 {
286     dc->sar_5bit = false;
287     dc->sar_m32_5bit = false;
288     dc->sar_m32 = 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(cpu_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(cpu_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(cpu_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(cpu_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(cpu_env);
580     }
581 #endif
582     if (op_flags & XTENSA_OP_SYNC_REGISTER_WINDOW) {
583         gen_helper_sync_windowbase(cpu_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(cpu_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(cpu_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_ptr;
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_ptr;
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(cpu_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(cpu_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(cpu_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(cpu_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, cpu_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, cpu_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, cpu_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(cpu_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(cpu_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(cpu_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(cpu_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, cpu_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, cpu_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, cpu_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(cpu_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     int shift = 31 - arg[2].imm;
2266 
2267     if (shift == 24) {
2268         tcg_gen_ext8s_i32(arg[0].out, arg[1].in);
2269     } else if (shift == 16) {
2270         tcg_gen_ext16s_i32(arg[0].out, arg[1].in);
2271     } else {
2272         TCGv_i32 tmp = tcg_temp_new_i32();
2273         tcg_gen_shli_i32(tmp, arg[1].in, shift);
2274         tcg_gen_sari_i32(arg[0].out, tmp, shift);
2275     }
2276 }
2277 
2278 static uint32_t test_exceptions_simcall(DisasContext *dc,
2279                                         const OpcodeArg arg[],
2280                                         const uint32_t par[])
2281 {
2282     bool is_semi = semihosting_enabled(dc->cring != 0);
2283 #ifdef CONFIG_USER_ONLY
2284     bool ill = true;
2285 #else
2286     /* Between RE.2 and RE.3 simcall opcode's become nop for the hardware. */
2287     bool ill = dc->config->hw_version <= 250002 && !is_semi;
2288 #endif
2289     if (ill || !is_semi) {
2290         qemu_log_mask(LOG_GUEST_ERROR, "SIMCALL but semihosting is disabled\n");
2291     }
2292     return ill ? XTENSA_OP_ILL : 0;
2293 }
2294 
2295 static void translate_simcall(DisasContext *dc, const OpcodeArg arg[],
2296                               const uint32_t par[])
2297 {
2298 #ifndef CONFIG_USER_ONLY
2299     if (semihosting_enabled(dc->cring != 0)) {
2300         gen_helper_simcall(cpu_env);
2301     }
2302 #endif
2303 }
2304 
2305 /*
2306  * Note: 64 bit ops are used here solely because SAR values
2307  * have range 0..63
2308  */
2309 #define gen_shift_reg(cmd, reg) do { \
2310                     TCGv_i64 tmp = tcg_temp_new_i64(); \
2311                     tcg_gen_extu_i32_i64(tmp, reg); \
2312                     tcg_gen_##cmd##_i64(v, v, tmp); \
2313                     tcg_gen_extrl_i64_i32(arg[0].out, v); \
2314                 } while (0)
2315 
2316 #define gen_shift(cmd) gen_shift_reg(cmd, cpu_SR[SAR])
2317 
2318 static void translate_sll(DisasContext *dc, const OpcodeArg arg[],
2319                           const uint32_t par[])
2320 {
2321     if (dc->sar_m32_5bit) {
2322         tcg_gen_shl_i32(arg[0].out, arg[1].in, dc->sar_m32);
2323     } else {
2324         TCGv_i64 v = tcg_temp_new_i64();
2325         TCGv_i32 s = tcg_temp_new();
2326         tcg_gen_subfi_i32(s, 32, cpu_SR[SAR]);
2327         tcg_gen_andi_i32(s, s, 0x3f);
2328         tcg_gen_extu_i32_i64(v, arg[1].in);
2329         gen_shift_reg(shl, s);
2330     }
2331 }
2332 
2333 static void translate_slli(DisasContext *dc, const OpcodeArg arg[],
2334                            const uint32_t par[])
2335 {
2336     if (arg[2].imm == 32) {
2337         qemu_log_mask(LOG_GUEST_ERROR, "slli a%d, a%d, 32 is undefined\n",
2338                       arg[0].imm, arg[1].imm);
2339     }
2340     tcg_gen_shli_i32(arg[0].out, arg[1].in, arg[2].imm & 0x1f);
2341 }
2342 
2343 static void translate_sra(DisasContext *dc, const OpcodeArg arg[],
2344                           const uint32_t par[])
2345 {
2346     if (dc->sar_m32_5bit) {
2347         tcg_gen_sar_i32(arg[0].out, arg[1].in, cpu_SR[SAR]);
2348     } else {
2349         TCGv_i64 v = tcg_temp_new_i64();
2350         tcg_gen_ext_i32_i64(v, arg[1].in);
2351         gen_shift(sar);
2352     }
2353 }
2354 
2355 static void translate_srai(DisasContext *dc, const OpcodeArg arg[],
2356                            const uint32_t par[])
2357 {
2358     tcg_gen_sari_i32(arg[0].out, arg[1].in, arg[2].imm);
2359 }
2360 
2361 static void translate_src(DisasContext *dc, const OpcodeArg arg[],
2362                           const uint32_t par[])
2363 {
2364     TCGv_i64 v = tcg_temp_new_i64();
2365     tcg_gen_concat_i32_i64(v, arg[2].in, arg[1].in);
2366     gen_shift(shr);
2367 }
2368 
2369 static void translate_srl(DisasContext *dc, const OpcodeArg arg[],
2370                           const uint32_t par[])
2371 {
2372     if (dc->sar_m32_5bit) {
2373         tcg_gen_shr_i32(arg[0].out, arg[1].in, cpu_SR[SAR]);
2374     } else {
2375         TCGv_i64 v = tcg_temp_new_i64();
2376         tcg_gen_extu_i32_i64(v, arg[1].in);
2377         gen_shift(shr);
2378     }
2379 }
2380 
2381 #undef gen_shift
2382 #undef gen_shift_reg
2383 
2384 static void translate_srli(DisasContext *dc, const OpcodeArg arg[],
2385                            const uint32_t par[])
2386 {
2387     tcg_gen_shri_i32(arg[0].out, arg[1].in, arg[2].imm);
2388 }
2389 
2390 static void translate_ssa8b(DisasContext *dc, const OpcodeArg arg[],
2391                             const uint32_t par[])
2392 {
2393     TCGv_i32 tmp = tcg_temp_new_i32();
2394     tcg_gen_shli_i32(tmp, arg[0].in, 3);
2395     gen_left_shift_sar(dc, tmp);
2396 }
2397 
2398 static void translate_ssa8l(DisasContext *dc, const OpcodeArg arg[],
2399                             const uint32_t par[])
2400 {
2401     TCGv_i32 tmp = tcg_temp_new_i32();
2402     tcg_gen_shli_i32(tmp, arg[0].in, 3);
2403     gen_right_shift_sar(dc, tmp);
2404 }
2405 
2406 static void translate_ssai(DisasContext *dc, const OpcodeArg arg[],
2407                            const uint32_t par[])
2408 {
2409     gen_right_shift_sar(dc, tcg_constant_i32(arg[0].imm));
2410 }
2411 
2412 static void translate_ssl(DisasContext *dc, const OpcodeArg arg[],
2413                           const uint32_t par[])
2414 {
2415     gen_left_shift_sar(dc, arg[0].in);
2416 }
2417 
2418 static void translate_ssr(DisasContext *dc, const OpcodeArg arg[],
2419                           const uint32_t par[])
2420 {
2421     gen_right_shift_sar(dc, arg[0].in);
2422 }
2423 
2424 static void translate_sub(DisasContext *dc, const OpcodeArg arg[],
2425                           const uint32_t par[])
2426 {
2427     tcg_gen_sub_i32(arg[0].out, arg[1].in, arg[2].in);
2428 }
2429 
2430 static void translate_subx(DisasContext *dc, const OpcodeArg arg[],
2431                            const uint32_t par[])
2432 {
2433     TCGv_i32 tmp = tcg_temp_new_i32();
2434     tcg_gen_shli_i32(tmp, arg[1].in, par[0]);
2435     tcg_gen_sub_i32(arg[0].out, tmp, arg[2].in);
2436 }
2437 
2438 static void translate_waiti(DisasContext *dc, const OpcodeArg arg[],
2439                             const uint32_t par[])
2440 {
2441 #ifndef CONFIG_USER_ONLY
2442     TCGv_i32 pc = tcg_constant_i32(dc->base.pc_next);
2443 
2444     translator_io_start(&dc->base);
2445     gen_helper_waiti(cpu_env, pc, tcg_constant_i32(arg[0].imm));
2446 #endif
2447 }
2448 
2449 static void translate_wtlb(DisasContext *dc, const OpcodeArg arg[],
2450                            const uint32_t par[])
2451 {
2452 #ifndef CONFIG_USER_ONLY
2453     TCGv_i32 dtlb = tcg_constant_i32(par[0]);
2454 
2455     gen_helper_wtlb(cpu_env, arg[0].in, arg[1].in, dtlb);
2456 #endif
2457 }
2458 
2459 static void translate_wptlb(DisasContext *dc, const OpcodeArg arg[],
2460                             const uint32_t par[])
2461 {
2462 #ifndef CONFIG_USER_ONLY
2463     gen_helper_wptlb(cpu_env, arg[0].in, arg[1].in);
2464 #endif
2465 }
2466 
2467 static void translate_wer(DisasContext *dc, const OpcodeArg arg[],
2468                           const uint32_t par[])
2469 {
2470     gen_helper_wer(cpu_env, arg[0].in, arg[1].in);
2471 }
2472 
2473 static void translate_wrmsk_expstate(DisasContext *dc, const OpcodeArg arg[],
2474                                      const uint32_t par[])
2475 {
2476     /* TODO: GPIO32 may be a part of coprocessor */
2477     tcg_gen_and_i32(cpu_UR[EXPSTATE], arg[0].in, arg[1].in);
2478 }
2479 
2480 static void translate_wsr(DisasContext *dc, const OpcodeArg arg[],
2481                           const uint32_t par[])
2482 {
2483     if (sr_name[par[0]]) {
2484         tcg_gen_mov_i32(cpu_SR[par[0]], arg[0].in);
2485     }
2486 }
2487 
2488 static void translate_wsr_mask(DisasContext *dc, const OpcodeArg arg[],
2489                                const uint32_t par[])
2490 {
2491     if (sr_name[par[0]]) {
2492         tcg_gen_andi_i32(cpu_SR[par[0]], arg[0].in, par[2]);
2493     }
2494 }
2495 
2496 static void translate_wsr_acchi(DisasContext *dc, const OpcodeArg arg[],
2497                                 const uint32_t par[])
2498 {
2499     tcg_gen_ext8s_i32(cpu_SR[par[0]], arg[0].in);
2500 }
2501 
2502 static void translate_wsr_ccompare(DisasContext *dc, const OpcodeArg arg[],
2503                                    const uint32_t par[])
2504 {
2505 #ifndef CONFIG_USER_ONLY
2506     uint32_t id = par[0] - CCOMPARE;
2507 
2508     assert(id < dc->config->nccompare);
2509     translator_io_start(&dc->base);
2510     tcg_gen_mov_i32(cpu_SR[par[0]], arg[0].in);
2511     gen_helper_update_ccompare(cpu_env, tcg_constant_i32(id));
2512 #endif
2513 }
2514 
2515 static void translate_wsr_ccount(DisasContext *dc, const OpcodeArg arg[],
2516                                  const uint32_t par[])
2517 {
2518 #ifndef CONFIG_USER_ONLY
2519     translator_io_start(&dc->base);
2520     gen_helper_wsr_ccount(cpu_env, arg[0].in);
2521 #endif
2522 }
2523 
2524 static void translate_wsr_dbreaka(DisasContext *dc, const OpcodeArg arg[],
2525                                   const uint32_t par[])
2526 {
2527 #ifndef CONFIG_USER_ONLY
2528     unsigned id = par[0] - DBREAKA;
2529 
2530     assert(id < dc->config->ndbreak);
2531     gen_helper_wsr_dbreaka(cpu_env, tcg_constant_i32(id), arg[0].in);
2532 #endif
2533 }
2534 
2535 static void translate_wsr_dbreakc(DisasContext *dc, const OpcodeArg arg[],
2536                                   const uint32_t par[])
2537 {
2538 #ifndef CONFIG_USER_ONLY
2539     unsigned id = par[0] - DBREAKC;
2540 
2541     assert(id < dc->config->ndbreak);
2542     gen_helper_wsr_dbreakc(cpu_env, tcg_constant_i32(id), arg[0].in);
2543 #endif
2544 }
2545 
2546 static void translate_wsr_ibreaka(DisasContext *dc, const OpcodeArg arg[],
2547                                   const uint32_t par[])
2548 {
2549 #ifndef CONFIG_USER_ONLY
2550     unsigned id = par[0] - IBREAKA;
2551 
2552     assert(id < dc->config->nibreak);
2553     gen_helper_wsr_ibreaka(cpu_env, tcg_constant_i32(id), arg[0].in);
2554 #endif
2555 }
2556 
2557 static void translate_wsr_ibreakenable(DisasContext *dc, const OpcodeArg arg[],
2558                                        const uint32_t par[])
2559 {
2560 #ifndef CONFIG_USER_ONLY
2561     gen_helper_wsr_ibreakenable(cpu_env, arg[0].in);
2562 #endif
2563 }
2564 
2565 static void translate_wsr_icount(DisasContext *dc, const OpcodeArg arg[],
2566                                  const uint32_t par[])
2567 {
2568 #ifndef CONFIG_USER_ONLY
2569     if (dc->icount) {
2570         tcg_gen_mov_i32(dc->next_icount, arg[0].in);
2571     } else {
2572         tcg_gen_mov_i32(cpu_SR[par[0]], arg[0].in);
2573     }
2574 #endif
2575 }
2576 
2577 static void translate_wsr_intclear(DisasContext *dc, const OpcodeArg arg[],
2578                                    const uint32_t par[])
2579 {
2580 #ifndef CONFIG_USER_ONLY
2581     gen_helper_intclear(cpu_env, arg[0].in);
2582 #endif
2583 }
2584 
2585 static void translate_wsr_intset(DisasContext *dc, const OpcodeArg arg[],
2586                                  const uint32_t par[])
2587 {
2588 #ifndef CONFIG_USER_ONLY
2589     gen_helper_intset(cpu_env, arg[0].in);
2590 #endif
2591 }
2592 
2593 static void translate_wsr_memctl(DisasContext *dc, const OpcodeArg arg[],
2594                                  const uint32_t par[])
2595 {
2596 #ifndef CONFIG_USER_ONLY
2597     gen_helper_wsr_memctl(cpu_env, arg[0].in);
2598 #endif
2599 }
2600 
2601 static void translate_wsr_mpuenb(DisasContext *dc, const OpcodeArg arg[],
2602                                  const uint32_t par[])
2603 {
2604 #ifndef CONFIG_USER_ONLY
2605     gen_helper_wsr_mpuenb(cpu_env, arg[0].in);
2606 #endif
2607 }
2608 
2609 static void translate_wsr_ps(DisasContext *dc, const OpcodeArg arg[],
2610                              const uint32_t par[])
2611 {
2612 #ifndef CONFIG_USER_ONLY
2613     uint32_t mask = PS_WOE | PS_CALLINC | PS_OWB |
2614         PS_UM | PS_EXCM | PS_INTLEVEL;
2615 
2616     if (option_enabled(dc, XTENSA_OPTION_MMU) ||
2617         option_enabled(dc, XTENSA_OPTION_MPU)) {
2618         mask |= PS_RING;
2619     }
2620     tcg_gen_andi_i32(cpu_SR[par[0]], arg[0].in, mask);
2621 #endif
2622 }
2623 
2624 static void translate_wsr_rasid(DisasContext *dc, const OpcodeArg arg[],
2625                                 const uint32_t par[])
2626 {
2627 #ifndef CONFIG_USER_ONLY
2628     gen_helper_wsr_rasid(cpu_env, arg[0].in);
2629 #endif
2630 }
2631 
2632 static void translate_wsr_sar(DisasContext *dc, const OpcodeArg arg[],
2633                               const uint32_t par[])
2634 {
2635     tcg_gen_andi_i32(cpu_SR[par[0]], arg[0].in, 0x3f);
2636     if (dc->sar_m32_5bit) {
2637         tcg_gen_discard_i32(dc->sar_m32);
2638     }
2639     dc->sar_5bit = false;
2640     dc->sar_m32_5bit = false;
2641 }
2642 
2643 static void translate_wsr_windowbase(DisasContext *dc, const OpcodeArg arg[],
2644                                      const uint32_t par[])
2645 {
2646 #ifndef CONFIG_USER_ONLY
2647     tcg_gen_mov_i32(cpu_windowbase_next, arg[0].in);
2648 #endif
2649 }
2650 
2651 static void translate_wsr_windowstart(DisasContext *dc, const OpcodeArg arg[],
2652                                       const uint32_t par[])
2653 {
2654 #ifndef CONFIG_USER_ONLY
2655     tcg_gen_andi_i32(cpu_SR[par[0]], arg[0].in,
2656                      (1 << dc->config->nareg / 4) - 1);
2657 #endif
2658 }
2659 
2660 static void translate_wur(DisasContext *dc, const OpcodeArg arg[],
2661                           const uint32_t par[])
2662 {
2663     tcg_gen_mov_i32(cpu_UR[par[0]], arg[0].in);
2664 }
2665 
2666 static void translate_xor(DisasContext *dc, const OpcodeArg arg[],
2667                           const uint32_t par[])
2668 {
2669     tcg_gen_xor_i32(arg[0].out, arg[1].in, arg[2].in);
2670 }
2671 
2672 static void translate_xsr(DisasContext *dc, const OpcodeArg arg[],
2673                           const uint32_t par[])
2674 {
2675     if (sr_name[par[0]]) {
2676         TCGv_i32 tmp = tcg_temp_new_i32();
2677 
2678         tcg_gen_mov_i32(tmp, arg[0].in);
2679         tcg_gen_mov_i32(arg[0].out, cpu_SR[par[0]]);
2680         tcg_gen_mov_i32(cpu_SR[par[0]], tmp);
2681     } else {
2682         tcg_gen_movi_i32(arg[0].out, 0);
2683     }
2684 }
2685 
2686 static void translate_xsr_mask(DisasContext *dc, const OpcodeArg arg[],
2687                                const uint32_t par[])
2688 {
2689     if (sr_name[par[0]]) {
2690         TCGv_i32 tmp = tcg_temp_new_i32();
2691 
2692         tcg_gen_mov_i32(tmp, arg[0].in);
2693         tcg_gen_mov_i32(arg[0].out, cpu_SR[par[0]]);
2694         tcg_gen_andi_i32(cpu_SR[par[0]], tmp, par[2]);
2695     } else {
2696         tcg_gen_movi_i32(arg[0].out, 0);
2697     }
2698 }
2699 
2700 static void translate_xsr_ccount(DisasContext *dc, const OpcodeArg arg[],
2701                                  const uint32_t par[])
2702 {
2703 #ifndef CONFIG_USER_ONLY
2704     TCGv_i32 tmp = tcg_temp_new_i32();
2705 
2706     translator_io_start(&dc->base);
2707     gen_helper_update_ccount(cpu_env);
2708     tcg_gen_mov_i32(tmp, cpu_SR[par[0]]);
2709     gen_helper_wsr_ccount(cpu_env, arg[0].in);
2710     tcg_gen_mov_i32(arg[0].out, tmp);
2711 
2712 #endif
2713 }
2714 
2715 #define gen_translate_xsr(name) \
2716     static void translate_xsr_##name(DisasContext *dc, const OpcodeArg arg[], \
2717                                      const uint32_t par[]) \
2718 { \
2719     TCGv_i32 tmp = tcg_temp_new_i32(); \
2720  \
2721     if (sr_name[par[0]]) { \
2722         tcg_gen_mov_i32(tmp, cpu_SR[par[0]]); \
2723     } else { \
2724         tcg_gen_movi_i32(tmp, 0); \
2725     } \
2726     translate_wsr_##name(dc, arg, par); \
2727     tcg_gen_mov_i32(arg[0].out, tmp); \
2728 }
2729 
2730 gen_translate_xsr(acchi)
2731 gen_translate_xsr(ccompare)
2732 gen_translate_xsr(dbreaka)
2733 gen_translate_xsr(dbreakc)
2734 gen_translate_xsr(ibreaka)
2735 gen_translate_xsr(ibreakenable)
2736 gen_translate_xsr(icount)
2737 gen_translate_xsr(memctl)
2738 gen_translate_xsr(mpuenb)
2739 gen_translate_xsr(ps)
2740 gen_translate_xsr(rasid)
2741 gen_translate_xsr(sar)
2742 gen_translate_xsr(windowbase)
2743 gen_translate_xsr(windowstart)
2744 
2745 #undef gen_translate_xsr
2746 
2747 static const XtensaOpcodeOps core_ops[] = {
2748     {
2749         .name = "abs",
2750         .translate = translate_abs,
2751     }, {
2752         .name = (const char * const[]) {
2753             "add", "add.n", NULL,
2754         },
2755         .translate = translate_add,
2756         .op_flags = XTENSA_OP_NAME_ARRAY,
2757     }, {
2758         .name = (const char * const[]) {
2759             "addi", "addi.n", NULL,
2760         },
2761         .translate = translate_addi,
2762         .op_flags = XTENSA_OP_NAME_ARRAY,
2763     }, {
2764         .name = "addmi",
2765         .translate = translate_addi,
2766     }, {
2767         .name = "addx2",
2768         .translate = translate_addx,
2769         .par = (const uint32_t[]){1},
2770     }, {
2771         .name = "addx4",
2772         .translate = translate_addx,
2773         .par = (const uint32_t[]){2},
2774     }, {
2775         .name = "addx8",
2776         .translate = translate_addx,
2777         .par = (const uint32_t[]){3},
2778     }, {
2779         .name = "all4",
2780         .translate = translate_all,
2781         .par = (const uint32_t[]){true, 4},
2782     }, {
2783         .name = "all8",
2784         .translate = translate_all,
2785         .par = (const uint32_t[]){true, 8},
2786     }, {
2787         .name = "and",
2788         .translate = translate_and,
2789     }, {
2790         .name = "andb",
2791         .translate = translate_boolean,
2792         .par = (const uint32_t[]){BOOLEAN_AND},
2793     }, {
2794         .name = "andbc",
2795         .translate = translate_boolean,
2796         .par = (const uint32_t[]){BOOLEAN_ANDC},
2797     }, {
2798         .name = "any4",
2799         .translate = translate_all,
2800         .par = (const uint32_t[]){false, 4},
2801     }, {
2802         .name = "any8",
2803         .translate = translate_all,
2804         .par = (const uint32_t[]){false, 8},
2805     }, {
2806         .name = (const char * const[]) {
2807             "ball", "ball.w15", "ball.w18", NULL,
2808         },
2809         .translate = translate_ball,
2810         .par = (const uint32_t[]){TCG_COND_EQ},
2811         .op_flags = XTENSA_OP_NAME_ARRAY,
2812     }, {
2813         .name = (const char * const[]) {
2814             "bany", "bany.w15", "bany.w18", NULL,
2815         },
2816         .translate = translate_bany,
2817         .par = (const uint32_t[]){TCG_COND_NE},
2818         .op_flags = XTENSA_OP_NAME_ARRAY,
2819     }, {
2820         .name = (const char * const[]) {
2821             "bbc", "bbc.w15", "bbc.w18", NULL,
2822         },
2823         .translate = translate_bb,
2824         .par = (const uint32_t[]){TCG_COND_EQ},
2825         .op_flags = XTENSA_OP_NAME_ARRAY,
2826     }, {
2827         .name = (const char * const[]) {
2828             "bbci", "bbci.w15", "bbci.w18", NULL,
2829         },
2830         .translate = translate_bbi,
2831         .par = (const uint32_t[]){TCG_COND_EQ},
2832         .op_flags = XTENSA_OP_NAME_ARRAY,
2833     }, {
2834         .name = (const char * const[]) {
2835             "bbs", "bbs.w15", "bbs.w18", NULL,
2836         },
2837         .translate = translate_bb,
2838         .par = (const uint32_t[]){TCG_COND_NE},
2839         .op_flags = XTENSA_OP_NAME_ARRAY,
2840     }, {
2841         .name = (const char * const[]) {
2842             "bbsi", "bbsi.w15", "bbsi.w18", NULL,
2843         },
2844         .translate = translate_bbi,
2845         .par = (const uint32_t[]){TCG_COND_NE},
2846         .op_flags = XTENSA_OP_NAME_ARRAY,
2847     }, {
2848         .name = (const char * const[]) {
2849             "beq", "beq.w15", "beq.w18", NULL,
2850         },
2851         .translate = translate_b,
2852         .par = (const uint32_t[]){TCG_COND_EQ},
2853         .op_flags = XTENSA_OP_NAME_ARRAY,
2854     }, {
2855         .name = (const char * const[]) {
2856             "beqi", "beqi.w15", "beqi.w18", NULL,
2857         },
2858         .translate = translate_bi,
2859         .par = (const uint32_t[]){TCG_COND_EQ},
2860         .op_flags = XTENSA_OP_NAME_ARRAY,
2861     }, {
2862         .name = (const char * const[]) {
2863             "beqz", "beqz.n", "beqz.w15", "beqz.w18", NULL,
2864         },
2865         .translate = translate_bz,
2866         .par = (const uint32_t[]){TCG_COND_EQ},
2867         .op_flags = XTENSA_OP_NAME_ARRAY,
2868     }, {
2869         .name = "bf",
2870         .translate = translate_bp,
2871         .par = (const uint32_t[]){TCG_COND_EQ},
2872     }, {
2873         .name = (const char * const[]) {
2874             "bge", "bge.w15", "bge.w18", NULL,
2875         },
2876         .translate = translate_b,
2877         .par = (const uint32_t[]){TCG_COND_GE},
2878         .op_flags = XTENSA_OP_NAME_ARRAY,
2879     }, {
2880         .name = (const char * const[]) {
2881             "bgei", "bgei.w15", "bgei.w18", NULL,
2882         },
2883         .translate = translate_bi,
2884         .par = (const uint32_t[]){TCG_COND_GE},
2885         .op_flags = XTENSA_OP_NAME_ARRAY,
2886     }, {
2887         .name = (const char * const[]) {
2888             "bgeu", "bgeu.w15", "bgeu.w18", NULL,
2889         },
2890         .translate = translate_b,
2891         .par = (const uint32_t[]){TCG_COND_GEU},
2892         .op_flags = XTENSA_OP_NAME_ARRAY,
2893     }, {
2894         .name = (const char * const[]) {
2895             "bgeui", "bgeui.w15", "bgeui.w18", NULL,
2896         },
2897         .translate = translate_bi,
2898         .par = (const uint32_t[]){TCG_COND_GEU},
2899         .op_flags = XTENSA_OP_NAME_ARRAY,
2900     }, {
2901         .name = (const char * const[]) {
2902             "bgez", "bgez.w15", "bgez.w18", NULL,
2903         },
2904         .translate = translate_bz,
2905         .par = (const uint32_t[]){TCG_COND_GE},
2906         .op_flags = XTENSA_OP_NAME_ARRAY,
2907     }, {
2908         .name = (const char * const[]) {
2909             "blt", "blt.w15", "blt.w18", NULL,
2910         },
2911         .translate = translate_b,
2912         .par = (const uint32_t[]){TCG_COND_LT},
2913         .op_flags = XTENSA_OP_NAME_ARRAY,
2914     }, {
2915         .name = (const char * const[]) {
2916             "blti", "blti.w15", "blti.w18", NULL,
2917         },
2918         .translate = translate_bi,
2919         .par = (const uint32_t[]){TCG_COND_LT},
2920         .op_flags = XTENSA_OP_NAME_ARRAY,
2921     }, {
2922         .name = (const char * const[]) {
2923             "bltu", "bltu.w15", "bltu.w18", NULL,
2924         },
2925         .translate = translate_b,
2926         .par = (const uint32_t[]){TCG_COND_LTU},
2927         .op_flags = XTENSA_OP_NAME_ARRAY,
2928     }, {
2929         .name = (const char * const[]) {
2930             "bltui", "bltui.w15", "bltui.w18", NULL,
2931         },
2932         .translate = translate_bi,
2933         .par = (const uint32_t[]){TCG_COND_LTU},
2934         .op_flags = XTENSA_OP_NAME_ARRAY,
2935     }, {
2936         .name = (const char * const[]) {
2937             "bltz", "bltz.w15", "bltz.w18", NULL,
2938         },
2939         .translate = translate_bz,
2940         .par = (const uint32_t[]){TCG_COND_LT},
2941         .op_flags = XTENSA_OP_NAME_ARRAY,
2942     }, {
2943         .name = (const char * const[]) {
2944             "bnall", "bnall.w15", "bnall.w18", NULL,
2945         },
2946         .translate = translate_ball,
2947         .par = (const uint32_t[]){TCG_COND_NE},
2948         .op_flags = XTENSA_OP_NAME_ARRAY,
2949     }, {
2950         .name = (const char * const[]) {
2951             "bne", "bne.w15", "bne.w18", NULL,
2952         },
2953         .translate = translate_b,
2954         .par = (const uint32_t[]){TCG_COND_NE},
2955         .op_flags = XTENSA_OP_NAME_ARRAY,
2956     }, {
2957         .name = (const char * const[]) {
2958             "bnei", "bnei.w15", "bnei.w18", NULL,
2959         },
2960         .translate = translate_bi,
2961         .par = (const uint32_t[]){TCG_COND_NE},
2962         .op_flags = XTENSA_OP_NAME_ARRAY,
2963     }, {
2964         .name = (const char * const[]) {
2965             "bnez", "bnez.n", "bnez.w15", "bnez.w18", NULL,
2966         },
2967         .translate = translate_bz,
2968         .par = (const uint32_t[]){TCG_COND_NE},
2969         .op_flags = XTENSA_OP_NAME_ARRAY,
2970     }, {
2971         .name = (const char * const[]) {
2972             "bnone", "bnone.w15", "bnone.w18", NULL,
2973         },
2974         .translate = translate_bany,
2975         .par = (const uint32_t[]){TCG_COND_EQ},
2976         .op_flags = XTENSA_OP_NAME_ARRAY,
2977     }, {
2978         .name = "break",
2979         .translate = translate_nop,
2980         .par = (const uint32_t[]){DEBUGCAUSE_BI},
2981         .op_flags = XTENSA_OP_DEBUG_BREAK,
2982     }, {
2983         .name = "break.n",
2984         .translate = translate_nop,
2985         .par = (const uint32_t[]){DEBUGCAUSE_BN},
2986         .op_flags = XTENSA_OP_DEBUG_BREAK,
2987     }, {
2988         .name = "bt",
2989         .translate = translate_bp,
2990         .par = (const uint32_t[]){TCG_COND_NE},
2991     }, {
2992         .name = "call0",
2993         .translate = translate_call0,
2994     }, {
2995         .name = "call12",
2996         .translate = translate_callw,
2997         .par = (const uint32_t[]){3},
2998     }, {
2999         .name = "call4",
3000         .translate = translate_callw,
3001         .par = (const uint32_t[]){1},
3002     }, {
3003         .name = "call8",
3004         .translate = translate_callw,
3005         .par = (const uint32_t[]){2},
3006     }, {
3007         .name = "callx0",
3008         .translate = translate_callx0,
3009     }, {
3010         .name = "callx12",
3011         .translate = translate_callxw,
3012         .par = (const uint32_t[]){3},
3013     }, {
3014         .name = "callx4",
3015         .translate = translate_callxw,
3016         .par = (const uint32_t[]){1},
3017     }, {
3018         .name = "callx8",
3019         .translate = translate_callxw,
3020         .par = (const uint32_t[]){2},
3021     }, {
3022         .name = "clamps",
3023         .translate = translate_clamps,
3024     }, {
3025         .name = "clrb_expstate",
3026         .translate = translate_clrb_expstate,
3027     }, {
3028         .name = "clrex",
3029         .translate = translate_clrex,
3030     }, {
3031         .name = "const16",
3032         .translate = translate_const16,
3033     }, {
3034         .name = "depbits",
3035         .translate = translate_depbits,
3036     }, {
3037         .name = "dhi",
3038         .translate = translate_dcache,
3039         .op_flags = XTENSA_OP_PRIVILEGED,
3040     }, {
3041         .name = "dhi.b",
3042         .translate = translate_nop,
3043     }, {
3044         .name = "dhu",
3045         .translate = translate_dcache,
3046         .op_flags = XTENSA_OP_PRIVILEGED,
3047     }, {
3048         .name = "dhwb",
3049         .translate = translate_dcache,
3050     }, {
3051         .name = "dhwb.b",
3052         .translate = translate_nop,
3053     }, {
3054         .name = "dhwbi",
3055         .translate = translate_dcache,
3056     }, {
3057         .name = "dhwbi.b",
3058         .translate = translate_nop,
3059     }, {
3060         .name = "dii",
3061         .translate = translate_nop,
3062         .op_flags = XTENSA_OP_PRIVILEGED,
3063     }, {
3064         .name = "diu",
3065         .translate = translate_nop,
3066         .op_flags = XTENSA_OP_PRIVILEGED,
3067     }, {
3068         .name = "diwb",
3069         .translate = translate_nop,
3070         .op_flags = XTENSA_OP_PRIVILEGED,
3071     }, {
3072         .name = "diwbi",
3073         .translate = translate_nop,
3074         .op_flags = XTENSA_OP_PRIVILEGED,
3075     }, {
3076         .name = "diwbui.p",
3077         .translate = translate_diwbuip,
3078         .op_flags = XTENSA_OP_PRIVILEGED,
3079     }, {
3080         .name = "dpfl",
3081         .translate = translate_dcache,
3082         .op_flags = XTENSA_OP_PRIVILEGED,
3083     }, {
3084         .name = "dpfm.b",
3085         .translate = translate_nop,
3086     }, {
3087         .name = "dpfm.bf",
3088         .translate = translate_nop,
3089     }, {
3090         .name = "dpfr",
3091         .translate = translate_nop,
3092     }, {
3093         .name = "dpfr.b",
3094         .translate = translate_nop,
3095     }, {
3096         .name = "dpfr.bf",
3097         .translate = translate_nop,
3098     }, {
3099         .name = "dpfro",
3100         .translate = translate_nop,
3101     }, {
3102         .name = "dpfw",
3103         .translate = translate_nop,
3104     }, {
3105         .name = "dpfw.b",
3106         .translate = translate_nop,
3107     }, {
3108         .name = "dpfw.bf",
3109         .translate = translate_nop,
3110     }, {
3111         .name = "dpfwo",
3112         .translate = translate_nop,
3113     }, {
3114         .name = "dsync",
3115         .translate = translate_nop,
3116     }, {
3117         .name = "entry",
3118         .translate = translate_entry,
3119         .test_exceptions = test_exceptions_entry,
3120         .test_overflow = test_overflow_entry,
3121         .op_flags = XTENSA_OP_EXIT_TB_M1 |
3122             XTENSA_OP_SYNC_REGISTER_WINDOW,
3123     }, {
3124         .name = "esync",
3125         .translate = translate_nop,
3126     }, {
3127         .name = "excw",
3128         .translate = translate_nop,
3129     }, {
3130         .name = "extui",
3131         .translate = translate_extui,
3132     }, {
3133         .name = "extw",
3134         .translate = translate_memw,
3135     }, {
3136         .name = "getex",
3137         .translate = translate_getex,
3138     }, {
3139         .name = "hwwdtlba",
3140         .op_flags = XTENSA_OP_ILL,
3141     }, {
3142         .name = "hwwitlba",
3143         .op_flags = XTENSA_OP_ILL,
3144     }, {
3145         .name = "idtlb",
3146         .translate = translate_itlb,
3147         .par = (const uint32_t[]){true},
3148         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
3149     }, {
3150         .name = "ihi",
3151         .translate = translate_icache,
3152     }, {
3153         .name = "ihu",
3154         .translate = translate_icache,
3155         .op_flags = XTENSA_OP_PRIVILEGED,
3156     }, {
3157         .name = "iii",
3158         .translate = translate_nop,
3159         .op_flags = XTENSA_OP_PRIVILEGED,
3160     }, {
3161         .name = "iitlb",
3162         .translate = translate_itlb,
3163         .par = (const uint32_t[]){false},
3164         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
3165     }, {
3166         .name = "iiu",
3167         .translate = translate_nop,
3168         .op_flags = XTENSA_OP_PRIVILEGED,
3169     }, {
3170         .name = (const char * const[]) {
3171             "ill", "ill.n", NULL,
3172         },
3173         .op_flags = XTENSA_OP_ILL | XTENSA_OP_NAME_ARRAY,
3174     }, {
3175         .name = "ipf",
3176         .translate = translate_nop,
3177     }, {
3178         .name = "ipfl",
3179         .translate = translate_icache,
3180         .op_flags = XTENSA_OP_PRIVILEGED,
3181     }, {
3182         .name = "isync",
3183         .translate = translate_nop,
3184     }, {
3185         .name = "j",
3186         .translate = translate_j,
3187     }, {
3188         .name = "jx",
3189         .translate = translate_jx,
3190     }, {
3191         .name = "l16si",
3192         .translate = translate_ldst,
3193         .par = (const uint32_t[]){MO_TESW, false, false},
3194         .op_flags = XTENSA_OP_LOAD,
3195     }, {
3196         .name = "l16ui",
3197         .translate = translate_ldst,
3198         .par = (const uint32_t[]){MO_TEUW, false, false},
3199         .op_flags = XTENSA_OP_LOAD,
3200     }, {
3201         .name = "l32ai",
3202         .translate = translate_ldst,
3203         .par = (const uint32_t[]){MO_TEUL | MO_ALIGN, true, false},
3204         .op_flags = XTENSA_OP_LOAD,
3205     }, {
3206         .name = "l32e",
3207         .translate = translate_l32e,
3208         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_LOAD,
3209     }, {
3210         .name = "l32ex",
3211         .translate = translate_l32ex,
3212         .op_flags = XTENSA_OP_LOAD,
3213     }, {
3214         .name = (const char * const[]) {
3215             "l32i", "l32i.n", NULL,
3216         },
3217         .translate = translate_ldst,
3218         .par = (const uint32_t[]){MO_TEUL, false, false},
3219         .op_flags = XTENSA_OP_NAME_ARRAY | XTENSA_OP_LOAD,
3220     }, {
3221         .name = "l32r",
3222         .translate = translate_l32r,
3223         .op_flags = XTENSA_OP_LOAD,
3224     }, {
3225         .name = "l8ui",
3226         .translate = translate_ldst,
3227         .par = (const uint32_t[]){MO_UB, false, false},
3228         .op_flags = XTENSA_OP_LOAD,
3229     }, {
3230         .name = "ldct",
3231         .translate = translate_lct,
3232         .op_flags = XTENSA_OP_PRIVILEGED,
3233     }, {
3234         .name = "ldcw",
3235         .translate = translate_nop,
3236         .op_flags = XTENSA_OP_PRIVILEGED,
3237     }, {
3238         .name = "lddec",
3239         .translate = translate_mac16,
3240         .par = (const uint32_t[]){MAC16_NONE, 0, -4},
3241         .op_flags = XTENSA_OP_LOAD,
3242     }, {
3243         .name = "ldinc",
3244         .translate = translate_mac16,
3245         .par = (const uint32_t[]){MAC16_NONE, 0, 4},
3246         .op_flags = XTENSA_OP_LOAD,
3247     }, {
3248         .name = "ldpte",
3249         .op_flags = XTENSA_OP_ILL,
3250     }, {
3251         .name = "lict",
3252         .translate = translate_lct,
3253         .op_flags = XTENSA_OP_PRIVILEGED,
3254     }, {
3255         .name = "licw",
3256         .translate = translate_nop,
3257         .op_flags = XTENSA_OP_PRIVILEGED,
3258     }, {
3259         .name = (const char * const[]) {
3260             "loop", "loop.w15", NULL,
3261         },
3262         .translate = translate_loop,
3263         .par = (const uint32_t[]){TCG_COND_NEVER},
3264         .op_flags = XTENSA_OP_NAME_ARRAY,
3265     }, {
3266         .name = (const char * const[]) {
3267             "loopgtz", "loopgtz.w15", NULL,
3268         },
3269         .translate = translate_loop,
3270         .par = (const uint32_t[]){TCG_COND_GT},
3271         .op_flags = XTENSA_OP_NAME_ARRAY,
3272     }, {
3273         .name = (const char * const[]) {
3274             "loopnez", "loopnez.w15", NULL,
3275         },
3276         .translate = translate_loop,
3277         .par = (const uint32_t[]){TCG_COND_NE},
3278         .op_flags = XTENSA_OP_NAME_ARRAY,
3279     }, {
3280         .name = "max",
3281         .translate = translate_smax,
3282     }, {
3283         .name = "maxu",
3284         .translate = translate_umax,
3285     }, {
3286         .name = "memw",
3287         .translate = translate_memw,
3288     }, {
3289         .name = "min",
3290         .translate = translate_smin,
3291     }, {
3292         .name = "minu",
3293         .translate = translate_umin,
3294     }, {
3295         .name = (const char * const[]) {
3296             "mov", "mov.n", NULL,
3297         },
3298         .translate = translate_mov,
3299         .op_flags = XTENSA_OP_NAME_ARRAY,
3300     }, {
3301         .name = "moveqz",
3302         .translate = translate_movcond,
3303         .par = (const uint32_t[]){TCG_COND_EQ},
3304     }, {
3305         .name = "movf",
3306         .translate = translate_movp,
3307         .par = (const uint32_t[]){TCG_COND_EQ},
3308     }, {
3309         .name = "movgez",
3310         .translate = translate_movcond,
3311         .par = (const uint32_t[]){TCG_COND_GE},
3312     }, {
3313         .name = "movi",
3314         .translate = translate_movi,
3315     }, {
3316         .name = "movi.n",
3317         .translate = translate_movi,
3318     }, {
3319         .name = "movltz",
3320         .translate = translate_movcond,
3321         .par = (const uint32_t[]){TCG_COND_LT},
3322     }, {
3323         .name = "movnez",
3324         .translate = translate_movcond,
3325         .par = (const uint32_t[]){TCG_COND_NE},
3326     }, {
3327         .name = "movsp",
3328         .translate = translate_movsp,
3329         .op_flags = XTENSA_OP_ALLOCA,
3330     }, {
3331         .name = "movt",
3332         .translate = translate_movp,
3333         .par = (const uint32_t[]){TCG_COND_NE},
3334     }, {
3335         .name = "mul.aa.hh",
3336         .translate = translate_mac16,
3337         .par = (const uint32_t[]){MAC16_MUL, MAC16_HH, 0},
3338     }, {
3339         .name = "mul.aa.hl",
3340         .translate = translate_mac16,
3341         .par = (const uint32_t[]){MAC16_MUL, MAC16_HL, 0},
3342     }, {
3343         .name = "mul.aa.lh",
3344         .translate = translate_mac16,
3345         .par = (const uint32_t[]){MAC16_MUL, MAC16_LH, 0},
3346     }, {
3347         .name = "mul.aa.ll",
3348         .translate = translate_mac16,
3349         .par = (const uint32_t[]){MAC16_MUL, MAC16_LL, 0},
3350     }, {
3351         .name = "mul.ad.hh",
3352         .translate = translate_mac16,
3353         .par = (const uint32_t[]){MAC16_MUL, MAC16_HH, 0},
3354     }, {
3355         .name = "mul.ad.hl",
3356         .translate = translate_mac16,
3357         .par = (const uint32_t[]){MAC16_MUL, MAC16_HL, 0},
3358     }, {
3359         .name = "mul.ad.lh",
3360         .translate = translate_mac16,
3361         .par = (const uint32_t[]){MAC16_MUL, MAC16_LH, 0},
3362     }, {
3363         .name = "mul.ad.ll",
3364         .translate = translate_mac16,
3365         .par = (const uint32_t[]){MAC16_MUL, MAC16_LL, 0},
3366     }, {
3367         .name = "mul.da.hh",
3368         .translate = translate_mac16,
3369         .par = (const uint32_t[]){MAC16_MUL, MAC16_HH, 0},
3370     }, {
3371         .name = "mul.da.hl",
3372         .translate = translate_mac16,
3373         .par = (const uint32_t[]){MAC16_MUL, MAC16_HL, 0},
3374     }, {
3375         .name = "mul.da.lh",
3376         .translate = translate_mac16,
3377         .par = (const uint32_t[]){MAC16_MUL, MAC16_LH, 0},
3378     }, {
3379         .name = "mul.da.ll",
3380         .translate = translate_mac16,
3381         .par = (const uint32_t[]){MAC16_MUL, MAC16_LL, 0},
3382     }, {
3383         .name = "mul.dd.hh",
3384         .translate = translate_mac16,
3385         .par = (const uint32_t[]){MAC16_MUL, MAC16_HH, 0},
3386     }, {
3387         .name = "mul.dd.hl",
3388         .translate = translate_mac16,
3389         .par = (const uint32_t[]){MAC16_MUL, MAC16_HL, 0},
3390     }, {
3391         .name = "mul.dd.lh",
3392         .translate = translate_mac16,
3393         .par = (const uint32_t[]){MAC16_MUL, MAC16_LH, 0},
3394     }, {
3395         .name = "mul.dd.ll",
3396         .translate = translate_mac16,
3397         .par = (const uint32_t[]){MAC16_MUL, MAC16_LL, 0},
3398     }, {
3399         .name = "mul16s",
3400         .translate = translate_mul16,
3401         .par = (const uint32_t[]){true},
3402     }, {
3403         .name = "mul16u",
3404         .translate = translate_mul16,
3405         .par = (const uint32_t[]){false},
3406     }, {
3407         .name = "mula.aa.hh",
3408         .translate = translate_mac16,
3409         .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 0},
3410     }, {
3411         .name = "mula.aa.hl",
3412         .translate = translate_mac16,
3413         .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 0},
3414     }, {
3415         .name = "mula.aa.lh",
3416         .translate = translate_mac16,
3417         .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 0},
3418     }, {
3419         .name = "mula.aa.ll",
3420         .translate = translate_mac16,
3421         .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 0},
3422     }, {
3423         .name = "mula.ad.hh",
3424         .translate = translate_mac16,
3425         .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 0},
3426     }, {
3427         .name = "mula.ad.hl",
3428         .translate = translate_mac16,
3429         .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 0},
3430     }, {
3431         .name = "mula.ad.lh",
3432         .translate = translate_mac16,
3433         .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 0},
3434     }, {
3435         .name = "mula.ad.ll",
3436         .translate = translate_mac16,
3437         .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 0},
3438     }, {
3439         .name = "mula.da.hh",
3440         .translate = translate_mac16,
3441         .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 0},
3442     }, {
3443         .name = "mula.da.hh.lddec",
3444         .translate = translate_mac16,
3445         .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, -4},
3446     }, {
3447         .name = "mula.da.hh.ldinc",
3448         .translate = translate_mac16,
3449         .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 4},
3450     }, {
3451         .name = "mula.da.hl",
3452         .translate = translate_mac16,
3453         .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 0},
3454     }, {
3455         .name = "mula.da.hl.lddec",
3456         .translate = translate_mac16,
3457         .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, -4},
3458     }, {
3459         .name = "mula.da.hl.ldinc",
3460         .translate = translate_mac16,
3461         .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 4},
3462     }, {
3463         .name = "mula.da.lh",
3464         .translate = translate_mac16,
3465         .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 0},
3466     }, {
3467         .name = "mula.da.lh.lddec",
3468         .translate = translate_mac16,
3469         .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, -4},
3470     }, {
3471         .name = "mula.da.lh.ldinc",
3472         .translate = translate_mac16,
3473         .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 4},
3474     }, {
3475         .name = "mula.da.ll",
3476         .translate = translate_mac16,
3477         .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 0},
3478     }, {
3479         .name = "mula.da.ll.lddec",
3480         .translate = translate_mac16,
3481         .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, -4},
3482     }, {
3483         .name = "mula.da.ll.ldinc",
3484         .translate = translate_mac16,
3485         .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 4},
3486     }, {
3487         .name = "mula.dd.hh",
3488         .translate = translate_mac16,
3489         .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 0},
3490     }, {
3491         .name = "mula.dd.hh.lddec",
3492         .translate = translate_mac16,
3493         .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, -4},
3494     }, {
3495         .name = "mula.dd.hh.ldinc",
3496         .translate = translate_mac16,
3497         .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 4},
3498     }, {
3499         .name = "mula.dd.hl",
3500         .translate = translate_mac16,
3501         .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 0},
3502     }, {
3503         .name = "mula.dd.hl.lddec",
3504         .translate = translate_mac16,
3505         .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, -4},
3506     }, {
3507         .name = "mula.dd.hl.ldinc",
3508         .translate = translate_mac16,
3509         .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 4},
3510     }, {
3511         .name = "mula.dd.lh",
3512         .translate = translate_mac16,
3513         .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 0},
3514     }, {
3515         .name = "mula.dd.lh.lddec",
3516         .translate = translate_mac16,
3517         .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, -4},
3518     }, {
3519         .name = "mula.dd.lh.ldinc",
3520         .translate = translate_mac16,
3521         .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 4},
3522     }, {
3523         .name = "mula.dd.ll",
3524         .translate = translate_mac16,
3525         .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 0},
3526     }, {
3527         .name = "mula.dd.ll.lddec",
3528         .translate = translate_mac16,
3529         .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, -4},
3530     }, {
3531         .name = "mula.dd.ll.ldinc",
3532         .translate = translate_mac16,
3533         .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 4},
3534     }, {
3535         .name = "mull",
3536         .translate = translate_mull,
3537     }, {
3538         .name = "muls.aa.hh",
3539         .translate = translate_mac16,
3540         .par = (const uint32_t[]){MAC16_MULS, MAC16_HH, 0},
3541     }, {
3542         .name = "muls.aa.hl",
3543         .translate = translate_mac16,
3544         .par = (const uint32_t[]){MAC16_MULS, MAC16_HL, 0},
3545     }, {
3546         .name = "muls.aa.lh",
3547         .translate = translate_mac16,
3548         .par = (const uint32_t[]){MAC16_MULS, MAC16_LH, 0},
3549     }, {
3550         .name = "muls.aa.ll",
3551         .translate = translate_mac16,
3552         .par = (const uint32_t[]){MAC16_MULS, MAC16_LL, 0},
3553     }, {
3554         .name = "muls.ad.hh",
3555         .translate = translate_mac16,
3556         .par = (const uint32_t[]){MAC16_MULS, MAC16_HH, 0},
3557     }, {
3558         .name = "muls.ad.hl",
3559         .translate = translate_mac16,
3560         .par = (const uint32_t[]){MAC16_MULS, MAC16_HL, 0},
3561     }, {
3562         .name = "muls.ad.lh",
3563         .translate = translate_mac16,
3564         .par = (const uint32_t[]){MAC16_MULS, MAC16_LH, 0},
3565     }, {
3566         .name = "muls.ad.ll",
3567         .translate = translate_mac16,
3568         .par = (const uint32_t[]){MAC16_MULS, MAC16_LL, 0},
3569     }, {
3570         .name = "muls.da.hh",
3571         .translate = translate_mac16,
3572         .par = (const uint32_t[]){MAC16_MULS, MAC16_HH, 0},
3573     }, {
3574         .name = "muls.da.hl",
3575         .translate = translate_mac16,
3576         .par = (const uint32_t[]){MAC16_MULS, MAC16_HL, 0},
3577     }, {
3578         .name = "muls.da.lh",
3579         .translate = translate_mac16,
3580         .par = (const uint32_t[]){MAC16_MULS, MAC16_LH, 0},
3581     }, {
3582         .name = "muls.da.ll",
3583         .translate = translate_mac16,
3584         .par = (const uint32_t[]){MAC16_MULS, MAC16_LL, 0},
3585     }, {
3586         .name = "muls.dd.hh",
3587         .translate = translate_mac16,
3588         .par = (const uint32_t[]){MAC16_MULS, MAC16_HH, 0},
3589     }, {
3590         .name = "muls.dd.hl",
3591         .translate = translate_mac16,
3592         .par = (const uint32_t[]){MAC16_MULS, MAC16_HL, 0},
3593     }, {
3594         .name = "muls.dd.lh",
3595         .translate = translate_mac16,
3596         .par = (const uint32_t[]){MAC16_MULS, MAC16_LH, 0},
3597     }, {
3598         .name = "muls.dd.ll",
3599         .translate = translate_mac16,
3600         .par = (const uint32_t[]){MAC16_MULS, MAC16_LL, 0},
3601     }, {
3602         .name = "mulsh",
3603         .translate = translate_mulh,
3604         .par = (const uint32_t[]){true},
3605     }, {
3606         .name = "muluh",
3607         .translate = translate_mulh,
3608         .par = (const uint32_t[]){false},
3609     }, {
3610         .name = "neg",
3611         .translate = translate_neg,
3612     }, {
3613         .name = (const char * const[]) {
3614             "nop", "nop.n", NULL,
3615         },
3616         .translate = translate_nop,
3617         .op_flags = XTENSA_OP_NAME_ARRAY,
3618     }, {
3619         .name = "nsa",
3620         .translate = translate_nsa,
3621     }, {
3622         .name = "nsau",
3623         .translate = translate_nsau,
3624     }, {
3625         .name = "or",
3626         .translate = translate_or,
3627     }, {
3628         .name = "orb",
3629         .translate = translate_boolean,
3630         .par = (const uint32_t[]){BOOLEAN_OR},
3631     }, {
3632         .name = "orbc",
3633         .translate = translate_boolean,
3634         .par = (const uint32_t[]){BOOLEAN_ORC},
3635     }, {
3636         .name = "pdtlb",
3637         .translate = translate_ptlb,
3638         .par = (const uint32_t[]){true},
3639         .op_flags = XTENSA_OP_PRIVILEGED,
3640     }, {
3641         .name = "pfend.a",
3642         .translate = translate_nop,
3643     }, {
3644         .name = "pfend.o",
3645         .translate = translate_nop,
3646     }, {
3647         .name = "pfnxt.f",
3648         .translate = translate_nop,
3649     }, {
3650         .name = "pfwait.a",
3651         .translate = translate_nop,
3652     }, {
3653         .name = "pfwait.r",
3654         .translate = translate_nop,
3655     }, {
3656         .name = "pitlb",
3657         .translate = translate_ptlb,
3658         .par = (const uint32_t[]){false},
3659         .op_flags = XTENSA_OP_PRIVILEGED,
3660     }, {
3661         .name = "pptlb",
3662         .translate = translate_pptlb,
3663         .op_flags = XTENSA_OP_PRIVILEGED,
3664     }, {
3665         .name = "quos",
3666         .translate = translate_quos,
3667         .par = (const uint32_t[]){true},
3668         .op_flags = XTENSA_OP_DIVIDE_BY_ZERO,
3669     }, {
3670         .name = "quou",
3671         .translate = translate_quou,
3672         .op_flags = XTENSA_OP_DIVIDE_BY_ZERO,
3673     }, {
3674         .name = "rdtlb0",
3675         .translate = translate_rtlb,
3676         .par = (const uint32_t[]){true, 0},
3677         .op_flags = XTENSA_OP_PRIVILEGED,
3678     }, {
3679         .name = "rdtlb1",
3680         .translate = translate_rtlb,
3681         .par = (const uint32_t[]){true, 1},
3682         .op_flags = XTENSA_OP_PRIVILEGED,
3683     }, {
3684         .name = "read_impwire",
3685         .translate = translate_read_impwire,
3686     }, {
3687         .name = "rems",
3688         .translate = translate_quos,
3689         .par = (const uint32_t[]){false},
3690         .op_flags = XTENSA_OP_DIVIDE_BY_ZERO,
3691     }, {
3692         .name = "remu",
3693         .translate = translate_remu,
3694         .op_flags = XTENSA_OP_DIVIDE_BY_ZERO,
3695     }, {
3696         .name = "rer",
3697         .translate = translate_rer,
3698         .op_flags = XTENSA_OP_PRIVILEGED,
3699     }, {
3700         .name = (const char * const[]) {
3701             "ret", "ret.n", NULL,
3702         },
3703         .translate = translate_ret,
3704         .op_flags = XTENSA_OP_NAME_ARRAY,
3705     }, {
3706         .name = (const char * const[]) {
3707             "retw", "retw.n", NULL,
3708         },
3709         .translate = translate_retw,
3710         .test_exceptions = test_exceptions_retw,
3711         .op_flags = XTENSA_OP_UNDERFLOW | XTENSA_OP_NAME_ARRAY,
3712     }, {
3713         .name = "rfdd",
3714         .op_flags = XTENSA_OP_ILL,
3715     }, {
3716         .name = "rfde",
3717         .translate = translate_rfde,
3718         .op_flags = XTENSA_OP_PRIVILEGED,
3719     }, {
3720         .name = "rfdo",
3721         .op_flags = XTENSA_OP_ILL,
3722     }, {
3723         .name = "rfe",
3724         .translate = translate_rfe,
3725         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_CHECK_INTERRUPTS,
3726     }, {
3727         .name = "rfi",
3728         .translate = translate_rfi,
3729         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_CHECK_INTERRUPTS,
3730     }, {
3731         .name = "rfwo",
3732         .translate = translate_rfw,
3733         .par = (const uint32_t[]){true},
3734         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_CHECK_INTERRUPTS,
3735     }, {
3736         .name = "rfwu",
3737         .translate = translate_rfw,
3738         .par = (const uint32_t[]){false},
3739         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_CHECK_INTERRUPTS,
3740     }, {
3741         .name = "ritlb0",
3742         .translate = translate_rtlb,
3743         .par = (const uint32_t[]){false, 0},
3744         .op_flags = XTENSA_OP_PRIVILEGED,
3745     }, {
3746         .name = "ritlb1",
3747         .translate = translate_rtlb,
3748         .par = (const uint32_t[]){false, 1},
3749         .op_flags = XTENSA_OP_PRIVILEGED,
3750     }, {
3751         .name = "rptlb0",
3752         .translate = translate_rptlb0,
3753         .op_flags = XTENSA_OP_PRIVILEGED,
3754     }, {
3755         .name = "rptlb1",
3756         .translate = translate_rptlb1,
3757         .op_flags = XTENSA_OP_PRIVILEGED,
3758     }, {
3759         .name = "rotw",
3760         .translate = translate_rotw,
3761         .op_flags = XTENSA_OP_PRIVILEGED |
3762             XTENSA_OP_EXIT_TB_M1 |
3763             XTENSA_OP_SYNC_REGISTER_WINDOW,
3764     }, {
3765         .name = "rsil",
3766         .translate = translate_rsil,
3767         .op_flags =
3768             XTENSA_OP_PRIVILEGED |
3769             XTENSA_OP_EXIT_TB_0 |
3770             XTENSA_OP_CHECK_INTERRUPTS,
3771     }, {
3772         .name = "rsr.176",
3773         .translate = translate_rsr,
3774         .par = (const uint32_t[]){176},
3775         .op_flags = XTENSA_OP_PRIVILEGED,
3776     }, {
3777         .name = "rsr.208",
3778         .translate = translate_rsr,
3779         .par = (const uint32_t[]){208},
3780         .op_flags = XTENSA_OP_PRIVILEGED,
3781     }, {
3782         .name = "rsr.acchi",
3783         .translate = translate_rsr,
3784         .test_exceptions = test_exceptions_sr,
3785         .par = (const uint32_t[]){
3786             ACCHI,
3787             XTENSA_OPTION_MAC16,
3788         },
3789     }, {
3790         .name = "rsr.acclo",
3791         .translate = translate_rsr,
3792         .test_exceptions = test_exceptions_sr,
3793         .par = (const uint32_t[]){
3794             ACCLO,
3795             XTENSA_OPTION_MAC16,
3796         },
3797     }, {
3798         .name = "rsr.atomctl",
3799         .translate = translate_rsr,
3800         .test_exceptions = test_exceptions_sr,
3801         .par = (const uint32_t[]){
3802             ATOMCTL,
3803             XTENSA_OPTION_ATOMCTL,
3804         },
3805         .op_flags = XTENSA_OP_PRIVILEGED,
3806     }, {
3807         .name = "rsr.br",
3808         .translate = translate_rsr,
3809         .test_exceptions = test_exceptions_sr,
3810         .par = (const uint32_t[]){
3811             BR,
3812             XTENSA_OPTION_BOOLEAN,
3813         },
3814     }, {
3815         .name = "rsr.cacheadrdis",
3816         .translate = translate_rsr,
3817         .test_exceptions = test_exceptions_sr,
3818         .par = (const uint32_t[]){
3819             CACHEADRDIS,
3820             XTENSA_OPTION_MPU,
3821         },
3822         .op_flags = XTENSA_OP_PRIVILEGED,
3823     }, {
3824         .name = "rsr.cacheattr",
3825         .translate = translate_rsr,
3826         .test_exceptions = test_exceptions_sr,
3827         .par = (const uint32_t[]){
3828             CACHEATTR,
3829             XTENSA_OPTION_CACHEATTR,
3830         },
3831         .op_flags = XTENSA_OP_PRIVILEGED,
3832     }, {
3833         .name = "rsr.ccompare0",
3834         .translate = translate_rsr,
3835         .test_exceptions = test_exceptions_ccompare,
3836         .par = (const uint32_t[]){
3837             CCOMPARE,
3838             XTENSA_OPTION_TIMER_INTERRUPT,
3839         },
3840         .op_flags = XTENSA_OP_PRIVILEGED,
3841     }, {
3842         .name = "rsr.ccompare1",
3843         .translate = translate_rsr,
3844         .test_exceptions = test_exceptions_ccompare,
3845         .par = (const uint32_t[]){
3846             CCOMPARE + 1,
3847             XTENSA_OPTION_TIMER_INTERRUPT,
3848         },
3849         .op_flags = XTENSA_OP_PRIVILEGED,
3850     }, {
3851         .name = "rsr.ccompare2",
3852         .translate = translate_rsr,
3853         .test_exceptions = test_exceptions_ccompare,
3854         .par = (const uint32_t[]){
3855             CCOMPARE + 2,
3856             XTENSA_OPTION_TIMER_INTERRUPT,
3857         },
3858         .op_flags = XTENSA_OP_PRIVILEGED,
3859     }, {
3860         .name = "rsr.ccount",
3861         .translate = translate_rsr_ccount,
3862         .test_exceptions = test_exceptions_sr,
3863         .par = (const uint32_t[]){
3864             CCOUNT,
3865             XTENSA_OPTION_TIMER_INTERRUPT,
3866         },
3867         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
3868     }, {
3869         .name = "rsr.configid0",
3870         .translate = translate_rsr,
3871         .par = (const uint32_t[]){CONFIGID0},
3872         .op_flags = XTENSA_OP_PRIVILEGED,
3873     }, {
3874         .name = "rsr.configid1",
3875         .translate = translate_rsr,
3876         .par = (const uint32_t[]){CONFIGID1},
3877         .op_flags = XTENSA_OP_PRIVILEGED,
3878     }, {
3879         .name = "rsr.cpenable",
3880         .translate = translate_rsr,
3881         .test_exceptions = test_exceptions_sr,
3882         .par = (const uint32_t[]){
3883             CPENABLE,
3884             XTENSA_OPTION_COPROCESSOR,
3885         },
3886         .op_flags = XTENSA_OP_PRIVILEGED,
3887     }, {
3888         .name = "rsr.dbreaka0",
3889         .translate = translate_rsr,
3890         .test_exceptions = test_exceptions_dbreak,
3891         .par = (const uint32_t[]){
3892             DBREAKA,
3893             XTENSA_OPTION_DEBUG,
3894         },
3895         .op_flags = XTENSA_OP_PRIVILEGED,
3896     }, {
3897         .name = "rsr.dbreaka1",
3898         .translate = translate_rsr,
3899         .test_exceptions = test_exceptions_dbreak,
3900         .par = (const uint32_t[]){
3901             DBREAKA + 1,
3902             XTENSA_OPTION_DEBUG,
3903         },
3904         .op_flags = XTENSA_OP_PRIVILEGED,
3905     }, {
3906         .name = "rsr.dbreakc0",
3907         .translate = translate_rsr,
3908         .test_exceptions = test_exceptions_dbreak,
3909         .par = (const uint32_t[]){
3910             DBREAKC,
3911             XTENSA_OPTION_DEBUG,
3912         },
3913         .op_flags = XTENSA_OP_PRIVILEGED,
3914     }, {
3915         .name = "rsr.dbreakc1",
3916         .translate = translate_rsr,
3917         .test_exceptions = test_exceptions_dbreak,
3918         .par = (const uint32_t[]){
3919             DBREAKC + 1,
3920             XTENSA_OPTION_DEBUG,
3921         },
3922         .op_flags = XTENSA_OP_PRIVILEGED,
3923     }, {
3924         .name = "rsr.ddr",
3925         .translate = translate_rsr,
3926         .test_exceptions = test_exceptions_sr,
3927         .par = (const uint32_t[]){
3928             DDR,
3929             XTENSA_OPTION_DEBUG,
3930         },
3931         .op_flags = XTENSA_OP_PRIVILEGED,
3932     }, {
3933         .name = "rsr.debugcause",
3934         .translate = translate_rsr,
3935         .test_exceptions = test_exceptions_sr,
3936         .par = (const uint32_t[]){
3937             DEBUGCAUSE,
3938             XTENSA_OPTION_DEBUG,
3939         },
3940         .op_flags = XTENSA_OP_PRIVILEGED,
3941     }, {
3942         .name = "rsr.depc",
3943         .translate = translate_rsr,
3944         .test_exceptions = test_exceptions_sr,
3945         .par = (const uint32_t[]){
3946             DEPC,
3947             XTENSA_OPTION_EXCEPTION,
3948         },
3949         .op_flags = XTENSA_OP_PRIVILEGED,
3950     }, {
3951         .name = "rsr.dtlbcfg",
3952         .translate = translate_rsr,
3953         .test_exceptions = test_exceptions_sr,
3954         .par = (const uint32_t[]){
3955             DTLBCFG,
3956             XTENSA_OPTION_MMU,
3957         },
3958         .op_flags = XTENSA_OP_PRIVILEGED,
3959     }, {
3960         .name = "rsr.epc1",
3961         .translate = translate_rsr,
3962         .test_exceptions = test_exceptions_sr,
3963         .par = (const uint32_t[]){
3964             EPC1,
3965             XTENSA_OPTION_EXCEPTION,
3966         },
3967         .op_flags = XTENSA_OP_PRIVILEGED,
3968     }, {
3969         .name = "rsr.epc2",
3970         .translate = translate_rsr,
3971         .test_exceptions = test_exceptions_hpi,
3972         .par = (const uint32_t[]){
3973             EPC1 + 1,
3974             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
3975         },
3976         .op_flags = XTENSA_OP_PRIVILEGED,
3977     }, {
3978         .name = "rsr.epc3",
3979         .translate = translate_rsr,
3980         .test_exceptions = test_exceptions_hpi,
3981         .par = (const uint32_t[]){
3982             EPC1 + 2,
3983             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
3984         },
3985         .op_flags = XTENSA_OP_PRIVILEGED,
3986     }, {
3987         .name = "rsr.epc4",
3988         .translate = translate_rsr,
3989         .test_exceptions = test_exceptions_hpi,
3990         .par = (const uint32_t[]){
3991             EPC1 + 3,
3992             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
3993         },
3994         .op_flags = XTENSA_OP_PRIVILEGED,
3995     }, {
3996         .name = "rsr.epc5",
3997         .translate = translate_rsr,
3998         .test_exceptions = test_exceptions_hpi,
3999         .par = (const uint32_t[]){
4000             EPC1 + 4,
4001             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4002         },
4003         .op_flags = XTENSA_OP_PRIVILEGED,
4004     }, {
4005         .name = "rsr.epc6",
4006         .translate = translate_rsr,
4007         .test_exceptions = test_exceptions_hpi,
4008         .par = (const uint32_t[]){
4009             EPC1 + 5,
4010             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4011         },
4012         .op_flags = XTENSA_OP_PRIVILEGED,
4013     }, {
4014         .name = "rsr.epc7",
4015         .translate = translate_rsr,
4016         .test_exceptions = test_exceptions_hpi,
4017         .par = (const uint32_t[]){
4018             EPC1 + 6,
4019             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4020         },
4021         .op_flags = XTENSA_OP_PRIVILEGED,
4022     }, {
4023         .name = "rsr.eps2",
4024         .translate = translate_rsr,
4025         .test_exceptions = test_exceptions_hpi,
4026         .par = (const uint32_t[]){
4027             EPS2,
4028             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4029         },
4030         .op_flags = XTENSA_OP_PRIVILEGED,
4031     }, {
4032         .name = "rsr.eps3",
4033         .translate = translate_rsr,
4034         .test_exceptions = test_exceptions_hpi,
4035         .par = (const uint32_t[]){
4036             EPS2 + 1,
4037             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4038         },
4039         .op_flags = XTENSA_OP_PRIVILEGED,
4040     }, {
4041         .name = "rsr.eps4",
4042         .translate = translate_rsr,
4043         .test_exceptions = test_exceptions_hpi,
4044         .par = (const uint32_t[]){
4045             EPS2 + 2,
4046             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4047         },
4048         .op_flags = XTENSA_OP_PRIVILEGED,
4049     }, {
4050         .name = "rsr.eps5",
4051         .translate = translate_rsr,
4052         .test_exceptions = test_exceptions_hpi,
4053         .par = (const uint32_t[]){
4054             EPS2 + 3,
4055             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4056         },
4057         .op_flags = XTENSA_OP_PRIVILEGED,
4058     }, {
4059         .name = "rsr.eps6",
4060         .translate = translate_rsr,
4061         .test_exceptions = test_exceptions_hpi,
4062         .par = (const uint32_t[]){
4063             EPS2 + 4,
4064             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4065         },
4066         .op_flags = XTENSA_OP_PRIVILEGED,
4067     }, {
4068         .name = "rsr.eps7",
4069         .translate = translate_rsr,
4070         .test_exceptions = test_exceptions_hpi,
4071         .par = (const uint32_t[]){
4072             EPS2 + 5,
4073             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4074         },
4075         .op_flags = XTENSA_OP_PRIVILEGED,
4076     }, {
4077         .name = "rsr.eraccess",
4078         .translate = translate_rsr,
4079         .par = (const uint32_t[]){ERACCESS},
4080         .op_flags = XTENSA_OP_PRIVILEGED,
4081     }, {
4082         .name = "rsr.exccause",
4083         .translate = translate_rsr,
4084         .test_exceptions = test_exceptions_sr,
4085         .par = (const uint32_t[]){
4086             EXCCAUSE,
4087             XTENSA_OPTION_EXCEPTION,
4088         },
4089         .op_flags = XTENSA_OP_PRIVILEGED,
4090     }, {
4091         .name = "rsr.excsave1",
4092         .translate = translate_rsr,
4093         .test_exceptions = test_exceptions_sr,
4094         .par = (const uint32_t[]){
4095             EXCSAVE1,
4096             XTENSA_OPTION_EXCEPTION,
4097         },
4098         .op_flags = XTENSA_OP_PRIVILEGED,
4099     }, {
4100         .name = "rsr.excsave2",
4101         .translate = translate_rsr,
4102         .test_exceptions = test_exceptions_hpi,
4103         .par = (const uint32_t[]){
4104             EXCSAVE1 + 1,
4105             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4106         },
4107         .op_flags = XTENSA_OP_PRIVILEGED,
4108     }, {
4109         .name = "rsr.excsave3",
4110         .translate = translate_rsr,
4111         .test_exceptions = test_exceptions_hpi,
4112         .par = (const uint32_t[]){
4113             EXCSAVE1 + 2,
4114             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4115         },
4116         .op_flags = XTENSA_OP_PRIVILEGED,
4117     }, {
4118         .name = "rsr.excsave4",
4119         .translate = translate_rsr,
4120         .test_exceptions = test_exceptions_hpi,
4121         .par = (const uint32_t[]){
4122             EXCSAVE1 + 3,
4123             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4124         },
4125         .op_flags = XTENSA_OP_PRIVILEGED,
4126     }, {
4127         .name = "rsr.excsave5",
4128         .translate = translate_rsr,
4129         .test_exceptions = test_exceptions_hpi,
4130         .par = (const uint32_t[]){
4131             EXCSAVE1 + 4,
4132             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4133         },
4134         .op_flags = XTENSA_OP_PRIVILEGED,
4135     }, {
4136         .name = "rsr.excsave6",
4137         .translate = translate_rsr,
4138         .test_exceptions = test_exceptions_hpi,
4139         .par = (const uint32_t[]){
4140             EXCSAVE1 + 5,
4141             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4142         },
4143         .op_flags = XTENSA_OP_PRIVILEGED,
4144     }, {
4145         .name = "rsr.excsave7",
4146         .translate = translate_rsr,
4147         .test_exceptions = test_exceptions_hpi,
4148         .par = (const uint32_t[]){
4149             EXCSAVE1 + 6,
4150             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4151         },
4152         .op_flags = XTENSA_OP_PRIVILEGED,
4153     }, {
4154         .name = "rsr.excvaddr",
4155         .translate = translate_rsr,
4156         .test_exceptions = test_exceptions_sr,
4157         .par = (const uint32_t[]){
4158             EXCVADDR,
4159             XTENSA_OPTION_EXCEPTION,
4160         },
4161         .op_flags = XTENSA_OP_PRIVILEGED,
4162     }, {
4163         .name = "rsr.ibreaka0",
4164         .translate = translate_rsr,
4165         .test_exceptions = test_exceptions_ibreak,
4166         .par = (const uint32_t[]){
4167             IBREAKA,
4168             XTENSA_OPTION_DEBUG,
4169         },
4170         .op_flags = XTENSA_OP_PRIVILEGED,
4171     }, {
4172         .name = "rsr.ibreaka1",
4173         .translate = translate_rsr,
4174         .test_exceptions = test_exceptions_ibreak,
4175         .par = (const uint32_t[]){
4176             IBREAKA + 1,
4177             XTENSA_OPTION_DEBUG,
4178         },
4179         .op_flags = XTENSA_OP_PRIVILEGED,
4180     }, {
4181         .name = "rsr.ibreakenable",
4182         .translate = translate_rsr,
4183         .test_exceptions = test_exceptions_sr,
4184         .par = (const uint32_t[]){
4185             IBREAKENABLE,
4186             XTENSA_OPTION_DEBUG,
4187         },
4188         .op_flags = XTENSA_OP_PRIVILEGED,
4189     }, {
4190         .name = "rsr.icount",
4191         .translate = translate_rsr,
4192         .test_exceptions = test_exceptions_sr,
4193         .par = (const uint32_t[]){
4194             ICOUNT,
4195             XTENSA_OPTION_DEBUG,
4196         },
4197         .op_flags = XTENSA_OP_PRIVILEGED,
4198     }, {
4199         .name = "rsr.icountlevel",
4200         .translate = translate_rsr,
4201         .test_exceptions = test_exceptions_sr,
4202         .par = (const uint32_t[]){
4203             ICOUNTLEVEL,
4204             XTENSA_OPTION_DEBUG,
4205         },
4206         .op_flags = XTENSA_OP_PRIVILEGED,
4207     }, {
4208         .name = "rsr.intclear",
4209         .translate = translate_rsr,
4210         .test_exceptions = test_exceptions_sr,
4211         .par = (const uint32_t[]){
4212             INTCLEAR,
4213             XTENSA_OPTION_INTERRUPT,
4214         },
4215         .op_flags = XTENSA_OP_PRIVILEGED,
4216     }, {
4217         .name = "rsr.intenable",
4218         .translate = translate_rsr,
4219         .test_exceptions = test_exceptions_sr,
4220         .par = (const uint32_t[]){
4221             INTENABLE,
4222             XTENSA_OPTION_INTERRUPT,
4223         },
4224         .op_flags = XTENSA_OP_PRIVILEGED,
4225     }, {
4226         .name = "rsr.interrupt",
4227         .translate = translate_rsr_ccount,
4228         .test_exceptions = test_exceptions_sr,
4229         .par = (const uint32_t[]){
4230             INTSET,
4231             XTENSA_OPTION_INTERRUPT,
4232         },
4233         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
4234     }, {
4235         .name = "rsr.intset",
4236         .translate = translate_rsr_ccount,
4237         .test_exceptions = test_exceptions_sr,
4238         .par = (const uint32_t[]){
4239             INTSET,
4240             XTENSA_OPTION_INTERRUPT,
4241         },
4242         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
4243     }, {
4244         .name = "rsr.itlbcfg",
4245         .translate = translate_rsr,
4246         .test_exceptions = test_exceptions_sr,
4247         .par = (const uint32_t[]){
4248             ITLBCFG,
4249             XTENSA_OPTION_MMU,
4250         },
4251         .op_flags = XTENSA_OP_PRIVILEGED,
4252     }, {
4253         .name = "rsr.lbeg",
4254         .translate = translate_rsr,
4255         .test_exceptions = test_exceptions_sr,
4256         .par = (const uint32_t[]){
4257             LBEG,
4258             XTENSA_OPTION_LOOP,
4259         },
4260     }, {
4261         .name = "rsr.lcount",
4262         .translate = translate_rsr,
4263         .test_exceptions = test_exceptions_sr,
4264         .par = (const uint32_t[]){
4265             LCOUNT,
4266             XTENSA_OPTION_LOOP,
4267         },
4268     }, {
4269         .name = "rsr.lend",
4270         .translate = translate_rsr,
4271         .test_exceptions = test_exceptions_sr,
4272         .par = (const uint32_t[]){
4273             LEND,
4274             XTENSA_OPTION_LOOP,
4275         },
4276     }, {
4277         .name = "rsr.litbase",
4278         .translate = translate_rsr,
4279         .test_exceptions = test_exceptions_sr,
4280         .par = (const uint32_t[]){
4281             LITBASE,
4282             XTENSA_OPTION_EXTENDED_L32R,
4283         },
4284     }, {
4285         .name = "rsr.m0",
4286         .translate = translate_rsr,
4287         .test_exceptions = test_exceptions_sr,
4288         .par = (const uint32_t[]){
4289             MR,
4290             XTENSA_OPTION_MAC16,
4291         },
4292     }, {
4293         .name = "rsr.m1",
4294         .translate = translate_rsr,
4295         .test_exceptions = test_exceptions_sr,
4296         .par = (const uint32_t[]){
4297             MR + 1,
4298             XTENSA_OPTION_MAC16,
4299         },
4300     }, {
4301         .name = "rsr.m2",
4302         .translate = translate_rsr,
4303         .test_exceptions = test_exceptions_sr,
4304         .par = (const uint32_t[]){
4305             MR + 2,
4306             XTENSA_OPTION_MAC16,
4307         },
4308     }, {
4309         .name = "rsr.m3",
4310         .translate = translate_rsr,
4311         .test_exceptions = test_exceptions_sr,
4312         .par = (const uint32_t[]){
4313             MR + 3,
4314             XTENSA_OPTION_MAC16,
4315         },
4316     }, {
4317         .name = "rsr.memctl",
4318         .translate = translate_rsr,
4319         .par = (const uint32_t[]){MEMCTL},
4320         .op_flags = XTENSA_OP_PRIVILEGED,
4321     }, {
4322         .name = "rsr.mecr",
4323         .translate = translate_rsr,
4324         .test_exceptions = test_exceptions_sr,
4325         .par = (const uint32_t[]){
4326             MECR,
4327             XTENSA_OPTION_MEMORY_ECC_PARITY,
4328         },
4329         .op_flags = XTENSA_OP_PRIVILEGED,
4330     }, {
4331         .name = "rsr.mepc",
4332         .translate = translate_rsr,
4333         .test_exceptions = test_exceptions_sr,
4334         .par = (const uint32_t[]){
4335             MEPC,
4336             XTENSA_OPTION_MEMORY_ECC_PARITY,
4337         },
4338         .op_flags = XTENSA_OP_PRIVILEGED,
4339     }, {
4340         .name = "rsr.meps",
4341         .translate = translate_rsr,
4342         .test_exceptions = test_exceptions_sr,
4343         .par = (const uint32_t[]){
4344             MEPS,
4345             XTENSA_OPTION_MEMORY_ECC_PARITY,
4346         },
4347         .op_flags = XTENSA_OP_PRIVILEGED,
4348     }, {
4349         .name = "rsr.mesave",
4350         .translate = translate_rsr,
4351         .test_exceptions = test_exceptions_sr,
4352         .par = (const uint32_t[]){
4353             MESAVE,
4354             XTENSA_OPTION_MEMORY_ECC_PARITY,
4355         },
4356         .op_flags = XTENSA_OP_PRIVILEGED,
4357     }, {
4358         .name = "rsr.mesr",
4359         .translate = translate_rsr,
4360         .test_exceptions = test_exceptions_sr,
4361         .par = (const uint32_t[]){
4362             MESR,
4363             XTENSA_OPTION_MEMORY_ECC_PARITY,
4364         },
4365         .op_flags = XTENSA_OP_PRIVILEGED,
4366     }, {
4367         .name = "rsr.mevaddr",
4368         .translate = translate_rsr,
4369         .test_exceptions = test_exceptions_sr,
4370         .par = (const uint32_t[]){
4371             MESR,
4372             XTENSA_OPTION_MEMORY_ECC_PARITY,
4373         },
4374         .op_flags = XTENSA_OP_PRIVILEGED,
4375     }, {
4376         .name = "rsr.misc0",
4377         .translate = translate_rsr,
4378         .test_exceptions = test_exceptions_sr,
4379         .par = (const uint32_t[]){
4380             MISC,
4381             XTENSA_OPTION_MISC_SR,
4382         },
4383         .op_flags = XTENSA_OP_PRIVILEGED,
4384     }, {
4385         .name = "rsr.misc1",
4386         .translate = translate_rsr,
4387         .test_exceptions = test_exceptions_sr,
4388         .par = (const uint32_t[]){
4389             MISC + 1,
4390             XTENSA_OPTION_MISC_SR,
4391         },
4392         .op_flags = XTENSA_OP_PRIVILEGED,
4393     }, {
4394         .name = "rsr.misc2",
4395         .translate = translate_rsr,
4396         .test_exceptions = test_exceptions_sr,
4397         .par = (const uint32_t[]){
4398             MISC + 2,
4399             XTENSA_OPTION_MISC_SR,
4400         },
4401         .op_flags = XTENSA_OP_PRIVILEGED,
4402     }, {
4403         .name = "rsr.misc3",
4404         .translate = translate_rsr,
4405         .test_exceptions = test_exceptions_sr,
4406         .par = (const uint32_t[]){
4407             MISC + 3,
4408             XTENSA_OPTION_MISC_SR,
4409         },
4410         .op_flags = XTENSA_OP_PRIVILEGED,
4411     }, {
4412         .name = "rsr.mpucfg",
4413         .translate = translate_rsr,
4414         .test_exceptions = test_exceptions_sr,
4415         .par = (const uint32_t[]){
4416             MPUCFG,
4417             XTENSA_OPTION_MPU,
4418         },
4419         .op_flags = XTENSA_OP_PRIVILEGED,
4420     }, {
4421         .name = "rsr.mpuenb",
4422         .translate = translate_rsr,
4423         .test_exceptions = test_exceptions_sr,
4424         .par = (const uint32_t[]){
4425             MPUENB,
4426             XTENSA_OPTION_MPU,
4427         },
4428         .op_flags = XTENSA_OP_PRIVILEGED,
4429     }, {
4430         .name = "rsr.prefctl",
4431         .translate = translate_rsr,
4432         .par = (const uint32_t[]){PREFCTL},
4433     }, {
4434         .name = "rsr.prid",
4435         .translate = translate_rsr,
4436         .test_exceptions = test_exceptions_sr,
4437         .par = (const uint32_t[]){
4438             PRID,
4439             XTENSA_OPTION_PROCESSOR_ID,
4440         },
4441         .op_flags = XTENSA_OP_PRIVILEGED,
4442     }, {
4443         .name = "rsr.ps",
4444         .translate = translate_rsr,
4445         .test_exceptions = test_exceptions_sr,
4446         .par = (const uint32_t[]){
4447             PS,
4448             XTENSA_OPTION_EXCEPTION,
4449         },
4450         .op_flags = XTENSA_OP_PRIVILEGED,
4451     }, {
4452         .name = "rsr.ptevaddr",
4453         .translate = translate_rsr_ptevaddr,
4454         .test_exceptions = test_exceptions_sr,
4455         .par = (const uint32_t[]){
4456             PTEVADDR,
4457             XTENSA_OPTION_MMU,
4458         },
4459         .op_flags = XTENSA_OP_PRIVILEGED,
4460     }, {
4461         .name = "rsr.rasid",
4462         .translate = translate_rsr,
4463         .test_exceptions = test_exceptions_sr,
4464         .par = (const uint32_t[]){
4465             RASID,
4466             XTENSA_OPTION_MMU,
4467         },
4468         .op_flags = XTENSA_OP_PRIVILEGED,
4469     }, {
4470         .name = "rsr.sar",
4471         .translate = translate_rsr,
4472         .par = (const uint32_t[]){SAR},
4473     }, {
4474         .name = "rsr.scompare1",
4475         .translate = translate_rsr,
4476         .test_exceptions = test_exceptions_sr,
4477         .par = (const uint32_t[]){
4478             SCOMPARE1,
4479             XTENSA_OPTION_CONDITIONAL_STORE,
4480         },
4481     }, {
4482         .name = "rsr.vecbase",
4483         .translate = translate_rsr,
4484         .test_exceptions = test_exceptions_sr,
4485         .par = (const uint32_t[]){
4486             VECBASE,
4487             XTENSA_OPTION_RELOCATABLE_VECTOR,
4488         },
4489         .op_flags = XTENSA_OP_PRIVILEGED,
4490     }, {
4491         .name = "rsr.windowbase",
4492         .translate = translate_rsr,
4493         .test_exceptions = test_exceptions_sr,
4494         .par = (const uint32_t[]){
4495             WINDOW_BASE,
4496             XTENSA_OPTION_WINDOWED_REGISTER,
4497         },
4498         .op_flags = XTENSA_OP_PRIVILEGED,
4499     }, {
4500         .name = "rsr.windowstart",
4501         .translate = translate_rsr,
4502         .test_exceptions = test_exceptions_sr,
4503         .par = (const uint32_t[]){
4504             WINDOW_START,
4505             XTENSA_OPTION_WINDOWED_REGISTER,
4506         },
4507         .op_flags = XTENSA_OP_PRIVILEGED,
4508     }, {
4509         .name = "rsync",
4510         .translate = translate_nop,
4511     }, {
4512         .name = "rur.expstate",
4513         .translate = translate_rur,
4514         .par = (const uint32_t[]){EXPSTATE},
4515     }, {
4516         .name = "rur.threadptr",
4517         .translate = translate_rur,
4518         .par = (const uint32_t[]){THREADPTR},
4519     }, {
4520         .name = "s16i",
4521         .translate = translate_ldst,
4522         .par = (const uint32_t[]){MO_TEUW, false, true},
4523         .op_flags = XTENSA_OP_STORE,
4524     }, {
4525         .name = "s32c1i",
4526         .translate = translate_s32c1i,
4527         .op_flags = XTENSA_OP_LOAD | XTENSA_OP_STORE,
4528     }, {
4529         .name = "s32e",
4530         .translate = translate_s32e,
4531         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_STORE,
4532     }, {
4533         .name = "s32ex",
4534         .translate = translate_s32ex,
4535         .op_flags = XTENSA_OP_LOAD | XTENSA_OP_STORE,
4536     }, {
4537         .name = (const char * const[]) {
4538             "s32i", "s32i.n", "s32nb", NULL,
4539         },
4540         .translate = translate_ldst,
4541         .par = (const uint32_t[]){MO_TEUL, false, true},
4542         .op_flags = XTENSA_OP_NAME_ARRAY | XTENSA_OP_STORE,
4543     }, {
4544         .name = "s32ri",
4545         .translate = translate_ldst,
4546         .par = (const uint32_t[]){MO_TEUL | MO_ALIGN, true, true},
4547         .op_flags = XTENSA_OP_STORE,
4548     }, {
4549         .name = "s8i",
4550         .translate = translate_ldst,
4551         .par = (const uint32_t[]){MO_UB, false, true},
4552         .op_flags = XTENSA_OP_STORE,
4553     }, {
4554         .name = "salt",
4555         .translate = translate_salt,
4556         .par = (const uint32_t[]){TCG_COND_LT},
4557     }, {
4558         .name = "saltu",
4559         .translate = translate_salt,
4560         .par = (const uint32_t[]){TCG_COND_LTU},
4561     }, {
4562         .name = "sdct",
4563         .translate = translate_nop,
4564         .op_flags = XTENSA_OP_PRIVILEGED,
4565     }, {
4566         .name = "sdcw",
4567         .translate = translate_nop,
4568         .op_flags = XTENSA_OP_PRIVILEGED,
4569     }, {
4570         .name = "setb_expstate",
4571         .translate = translate_setb_expstate,
4572     }, {
4573         .name = "sext",
4574         .translate = translate_sext,
4575     }, {
4576         .name = "sict",
4577         .translate = translate_nop,
4578         .op_flags = XTENSA_OP_PRIVILEGED,
4579     }, {
4580         .name = "sicw",
4581         .translate = translate_nop,
4582         .op_flags = XTENSA_OP_PRIVILEGED,
4583     }, {
4584         .name = "simcall",
4585         .translate = translate_simcall,
4586         .test_exceptions = test_exceptions_simcall,
4587         .op_flags = XTENSA_OP_PRIVILEGED,
4588     }, {
4589         .name = "sll",
4590         .translate = translate_sll,
4591     }, {
4592         .name = "slli",
4593         .translate = translate_slli,
4594     }, {
4595         .name = "sra",
4596         .translate = translate_sra,
4597     }, {
4598         .name = "srai",
4599         .translate = translate_srai,
4600     }, {
4601         .name = "src",
4602         .translate = translate_src,
4603     }, {
4604         .name = "srl",
4605         .translate = translate_srl,
4606     }, {
4607         .name = "srli",
4608         .translate = translate_srli,
4609     }, {
4610         .name = "ssa8b",
4611         .translate = translate_ssa8b,
4612     }, {
4613         .name = "ssa8l",
4614         .translate = translate_ssa8l,
4615     }, {
4616         .name = "ssai",
4617         .translate = translate_ssai,
4618     }, {
4619         .name = "ssl",
4620         .translate = translate_ssl,
4621     }, {
4622         .name = "ssr",
4623         .translate = translate_ssr,
4624     }, {
4625         .name = "sub",
4626         .translate = translate_sub,
4627     }, {
4628         .name = "subx2",
4629         .translate = translate_subx,
4630         .par = (const uint32_t[]){1},
4631     }, {
4632         .name = "subx4",
4633         .translate = translate_subx,
4634         .par = (const uint32_t[]){2},
4635     }, {
4636         .name = "subx8",
4637         .translate = translate_subx,
4638         .par = (const uint32_t[]){3},
4639     }, {
4640         .name = "syscall",
4641         .op_flags = XTENSA_OP_SYSCALL,
4642     }, {
4643         .name = "umul.aa.hh",
4644         .translate = translate_mac16,
4645         .par = (const uint32_t[]){MAC16_UMUL, MAC16_HH, 0},
4646     }, {
4647         .name = "umul.aa.hl",
4648         .translate = translate_mac16,
4649         .par = (const uint32_t[]){MAC16_UMUL, MAC16_HL, 0},
4650     }, {
4651         .name = "umul.aa.lh",
4652         .translate = translate_mac16,
4653         .par = (const uint32_t[]){MAC16_UMUL, MAC16_LH, 0},
4654     }, {
4655         .name = "umul.aa.ll",
4656         .translate = translate_mac16,
4657         .par = (const uint32_t[]){MAC16_UMUL, MAC16_LL, 0},
4658     }, {
4659         .name = "waiti",
4660         .translate = translate_waiti,
4661         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
4662     }, {
4663         .name = "wdtlb",
4664         .translate = translate_wtlb,
4665         .par = (const uint32_t[]){true},
4666         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
4667     }, {
4668         .name = "wer",
4669         .translate = translate_wer,
4670         .op_flags = XTENSA_OP_PRIVILEGED,
4671     }, {
4672         .name = "witlb",
4673         .translate = translate_wtlb,
4674         .par = (const uint32_t[]){false},
4675         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
4676     }, {
4677         .name = "wptlb",
4678         .translate = translate_wptlb,
4679         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
4680     }, {
4681         .name = "wrmsk_expstate",
4682         .translate = translate_wrmsk_expstate,
4683     }, {
4684         .name = "wsr.176",
4685         .op_flags = XTENSA_OP_ILL,
4686     }, {
4687         .name = "wsr.208",
4688         .op_flags = XTENSA_OP_ILL,
4689     }, {
4690         .name = "wsr.acchi",
4691         .translate = translate_wsr_acchi,
4692         .test_exceptions = test_exceptions_sr,
4693         .par = (const uint32_t[]){
4694             ACCHI,
4695             XTENSA_OPTION_MAC16,
4696         },
4697     }, {
4698         .name = "wsr.acclo",
4699         .translate = translate_wsr,
4700         .test_exceptions = test_exceptions_sr,
4701         .par = (const uint32_t[]){
4702             ACCLO,
4703             XTENSA_OPTION_MAC16,
4704         },
4705     }, {
4706         .name = "wsr.atomctl",
4707         .translate = translate_wsr_mask,
4708         .test_exceptions = test_exceptions_sr,
4709         .par = (const uint32_t[]){
4710             ATOMCTL,
4711             XTENSA_OPTION_ATOMCTL,
4712             0x3f,
4713         },
4714         .op_flags = XTENSA_OP_PRIVILEGED,
4715     }, {
4716         .name = "wsr.br",
4717         .translate = translate_wsr_mask,
4718         .test_exceptions = test_exceptions_sr,
4719         .par = (const uint32_t[]){
4720             BR,
4721             XTENSA_OPTION_BOOLEAN,
4722             0xffff,
4723         },
4724     }, {
4725         .name = "wsr.cacheadrdis",
4726         .translate = translate_wsr_mask,
4727         .test_exceptions = test_exceptions_sr,
4728         .par = (const uint32_t[]){
4729             CACHEADRDIS,
4730             XTENSA_OPTION_MPU,
4731             0xff,
4732         },
4733         .op_flags = XTENSA_OP_PRIVILEGED,
4734     }, {
4735         .name = "wsr.cacheattr",
4736         .translate = translate_wsr,
4737         .test_exceptions = test_exceptions_sr,
4738         .par = (const uint32_t[]){
4739             CACHEATTR,
4740             XTENSA_OPTION_CACHEATTR,
4741         },
4742         .op_flags = XTENSA_OP_PRIVILEGED,
4743     }, {
4744         .name = "wsr.ccompare0",
4745         .translate = translate_wsr_ccompare,
4746         .test_exceptions = test_exceptions_ccompare,
4747         .par = (const uint32_t[]){
4748             CCOMPARE,
4749             XTENSA_OPTION_TIMER_INTERRUPT,
4750         },
4751         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
4752     }, {
4753         .name = "wsr.ccompare1",
4754         .translate = translate_wsr_ccompare,
4755         .test_exceptions = test_exceptions_ccompare,
4756         .par = (const uint32_t[]){
4757             CCOMPARE + 1,
4758             XTENSA_OPTION_TIMER_INTERRUPT,
4759         },
4760         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
4761     }, {
4762         .name = "wsr.ccompare2",
4763         .translate = translate_wsr_ccompare,
4764         .test_exceptions = test_exceptions_ccompare,
4765         .par = (const uint32_t[]){
4766             CCOMPARE + 2,
4767             XTENSA_OPTION_TIMER_INTERRUPT,
4768         },
4769         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
4770     }, {
4771         .name = "wsr.ccount",
4772         .translate = translate_wsr_ccount,
4773         .test_exceptions = test_exceptions_sr,
4774         .par = (const uint32_t[]){
4775             CCOUNT,
4776             XTENSA_OPTION_TIMER_INTERRUPT,
4777         },
4778         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
4779     }, {
4780         .name = "wsr.configid0",
4781         .op_flags = XTENSA_OP_ILL,
4782     }, {
4783         .name = "wsr.configid1",
4784         .op_flags = XTENSA_OP_ILL,
4785     }, {
4786         .name = "wsr.cpenable",
4787         .translate = translate_wsr_mask,
4788         .test_exceptions = test_exceptions_sr,
4789         .par = (const uint32_t[]){
4790             CPENABLE,
4791             XTENSA_OPTION_COPROCESSOR,
4792             0xff,
4793         },
4794         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
4795     }, {
4796         .name = "wsr.dbreaka0",
4797         .translate = translate_wsr_dbreaka,
4798         .test_exceptions = test_exceptions_dbreak,
4799         .par = (const uint32_t[]){
4800             DBREAKA,
4801             XTENSA_OPTION_DEBUG,
4802         },
4803         .op_flags = XTENSA_OP_PRIVILEGED,
4804     }, {
4805         .name = "wsr.dbreaka1",
4806         .translate = translate_wsr_dbreaka,
4807         .test_exceptions = test_exceptions_dbreak,
4808         .par = (const uint32_t[]){
4809             DBREAKA + 1,
4810             XTENSA_OPTION_DEBUG,
4811         },
4812         .op_flags = XTENSA_OP_PRIVILEGED,
4813     }, {
4814         .name = "wsr.dbreakc0",
4815         .translate = translate_wsr_dbreakc,
4816         .test_exceptions = test_exceptions_dbreak,
4817         .par = (const uint32_t[]){
4818             DBREAKC,
4819             XTENSA_OPTION_DEBUG,
4820         },
4821         .op_flags = XTENSA_OP_PRIVILEGED,
4822     }, {
4823         .name = "wsr.dbreakc1",
4824         .translate = translate_wsr_dbreakc,
4825         .test_exceptions = test_exceptions_dbreak,
4826         .par = (const uint32_t[]){
4827             DBREAKC + 1,
4828             XTENSA_OPTION_DEBUG,
4829         },
4830         .op_flags = XTENSA_OP_PRIVILEGED,
4831     }, {
4832         .name = "wsr.ddr",
4833         .translate = translate_wsr,
4834         .test_exceptions = test_exceptions_sr,
4835         .par = (const uint32_t[]){
4836             DDR,
4837             XTENSA_OPTION_DEBUG,
4838         },
4839         .op_flags = XTENSA_OP_PRIVILEGED,
4840     }, {
4841         .name = "wsr.debugcause",
4842         .op_flags = XTENSA_OP_ILL,
4843     }, {
4844         .name = "wsr.depc",
4845         .translate = translate_wsr,
4846         .test_exceptions = test_exceptions_sr,
4847         .par = (const uint32_t[]){
4848             DEPC,
4849             XTENSA_OPTION_EXCEPTION,
4850         },
4851         .op_flags = XTENSA_OP_PRIVILEGED,
4852     }, {
4853         .name = "wsr.dtlbcfg",
4854         .translate = translate_wsr_mask,
4855         .test_exceptions = test_exceptions_sr,
4856         .par = (const uint32_t[]){
4857             DTLBCFG,
4858             XTENSA_OPTION_MMU,
4859             0x01130000,
4860         },
4861         .op_flags = XTENSA_OP_PRIVILEGED,
4862     }, {
4863         .name = "wsr.epc1",
4864         .translate = translate_wsr,
4865         .test_exceptions = test_exceptions_sr,
4866         .par = (const uint32_t[]){
4867             EPC1,
4868             XTENSA_OPTION_EXCEPTION,
4869         },
4870         .op_flags = XTENSA_OP_PRIVILEGED,
4871     }, {
4872         .name = "wsr.epc2",
4873         .translate = translate_wsr,
4874         .test_exceptions = test_exceptions_hpi,
4875         .par = (const uint32_t[]){
4876             EPC1 + 1,
4877             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4878         },
4879         .op_flags = XTENSA_OP_PRIVILEGED,
4880     }, {
4881         .name = "wsr.epc3",
4882         .translate = translate_wsr,
4883         .test_exceptions = test_exceptions_hpi,
4884         .par = (const uint32_t[]){
4885             EPC1 + 2,
4886             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4887         },
4888         .op_flags = XTENSA_OP_PRIVILEGED,
4889     }, {
4890         .name = "wsr.epc4",
4891         .translate = translate_wsr,
4892         .test_exceptions = test_exceptions_hpi,
4893         .par = (const uint32_t[]){
4894             EPC1 + 3,
4895             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4896         },
4897         .op_flags = XTENSA_OP_PRIVILEGED,
4898     }, {
4899         .name = "wsr.epc5",
4900         .translate = translate_wsr,
4901         .test_exceptions = test_exceptions_hpi,
4902         .par = (const uint32_t[]){
4903             EPC1 + 4,
4904             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4905         },
4906         .op_flags = XTENSA_OP_PRIVILEGED,
4907     }, {
4908         .name = "wsr.epc6",
4909         .translate = translate_wsr,
4910         .test_exceptions = test_exceptions_hpi,
4911         .par = (const uint32_t[]){
4912             EPC1 + 5,
4913             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4914         },
4915         .op_flags = XTENSA_OP_PRIVILEGED,
4916     }, {
4917         .name = "wsr.epc7",
4918         .translate = translate_wsr,
4919         .test_exceptions = test_exceptions_hpi,
4920         .par = (const uint32_t[]){
4921             EPC1 + 6,
4922             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4923         },
4924         .op_flags = XTENSA_OP_PRIVILEGED,
4925     }, {
4926         .name = "wsr.eps2",
4927         .translate = translate_wsr,
4928         .test_exceptions = test_exceptions_hpi,
4929         .par = (const uint32_t[]){
4930             EPS2,
4931             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4932         },
4933         .op_flags = XTENSA_OP_PRIVILEGED,
4934     }, {
4935         .name = "wsr.eps3",
4936         .translate = translate_wsr,
4937         .test_exceptions = test_exceptions_hpi,
4938         .par = (const uint32_t[]){
4939             EPS2 + 1,
4940             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4941         },
4942         .op_flags = XTENSA_OP_PRIVILEGED,
4943     }, {
4944         .name = "wsr.eps4",
4945         .translate = translate_wsr,
4946         .test_exceptions = test_exceptions_hpi,
4947         .par = (const uint32_t[]){
4948             EPS2 + 2,
4949             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4950         },
4951         .op_flags = XTENSA_OP_PRIVILEGED,
4952     }, {
4953         .name = "wsr.eps5",
4954         .translate = translate_wsr,
4955         .test_exceptions = test_exceptions_hpi,
4956         .par = (const uint32_t[]){
4957             EPS2 + 3,
4958             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4959         },
4960         .op_flags = XTENSA_OP_PRIVILEGED,
4961     }, {
4962         .name = "wsr.eps6",
4963         .translate = translate_wsr,
4964         .test_exceptions = test_exceptions_hpi,
4965         .par = (const uint32_t[]){
4966             EPS2 + 4,
4967             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4968         },
4969         .op_flags = XTENSA_OP_PRIVILEGED,
4970     }, {
4971         .name = "wsr.eps7",
4972         .translate = translate_wsr,
4973         .test_exceptions = test_exceptions_hpi,
4974         .par = (const uint32_t[]){
4975             EPS2 + 5,
4976             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4977         },
4978         .op_flags = XTENSA_OP_PRIVILEGED,
4979     }, {
4980         .name = "wsr.eraccess",
4981         .translate = translate_wsr_mask,
4982         .par = (const uint32_t[]){
4983             ERACCESS,
4984             0,
4985             0xffff,
4986         },
4987         .op_flags = XTENSA_OP_PRIVILEGED,
4988     }, {
4989         .name = "wsr.exccause",
4990         .translate = translate_wsr,
4991         .test_exceptions = test_exceptions_sr,
4992         .par = (const uint32_t[]){
4993             EXCCAUSE,
4994             XTENSA_OPTION_EXCEPTION,
4995         },
4996         .op_flags = XTENSA_OP_PRIVILEGED,
4997     }, {
4998         .name = "wsr.excsave1",
4999         .translate = translate_wsr,
5000         .test_exceptions = test_exceptions_sr,
5001         .par = (const uint32_t[]){
5002             EXCSAVE1,
5003             XTENSA_OPTION_EXCEPTION,
5004         },
5005         .op_flags = XTENSA_OP_PRIVILEGED,
5006     }, {
5007         .name = "wsr.excsave2",
5008         .translate = translate_wsr,
5009         .test_exceptions = test_exceptions_hpi,
5010         .par = (const uint32_t[]){
5011             EXCSAVE1 + 1,
5012             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5013         },
5014         .op_flags = XTENSA_OP_PRIVILEGED,
5015     }, {
5016         .name = "wsr.excsave3",
5017         .translate = translate_wsr,
5018         .test_exceptions = test_exceptions_hpi,
5019         .par = (const uint32_t[]){
5020             EXCSAVE1 + 2,
5021             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5022         },
5023         .op_flags = XTENSA_OP_PRIVILEGED,
5024     }, {
5025         .name = "wsr.excsave4",
5026         .translate = translate_wsr,
5027         .test_exceptions = test_exceptions_hpi,
5028         .par = (const uint32_t[]){
5029             EXCSAVE1 + 3,
5030             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5031         },
5032         .op_flags = XTENSA_OP_PRIVILEGED,
5033     }, {
5034         .name = "wsr.excsave5",
5035         .translate = translate_wsr,
5036         .test_exceptions = test_exceptions_hpi,
5037         .par = (const uint32_t[]){
5038             EXCSAVE1 + 4,
5039             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5040         },
5041         .op_flags = XTENSA_OP_PRIVILEGED,
5042     }, {
5043         .name = "wsr.excsave6",
5044         .translate = translate_wsr,
5045         .test_exceptions = test_exceptions_hpi,
5046         .par = (const uint32_t[]){
5047             EXCSAVE1 + 5,
5048             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5049         },
5050         .op_flags = XTENSA_OP_PRIVILEGED,
5051     }, {
5052         .name = "wsr.excsave7",
5053         .translate = translate_wsr,
5054         .test_exceptions = test_exceptions_hpi,
5055         .par = (const uint32_t[]){
5056             EXCSAVE1 + 6,
5057             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5058         },
5059         .op_flags = XTENSA_OP_PRIVILEGED,
5060     }, {
5061         .name = "wsr.excvaddr",
5062         .translate = translate_wsr,
5063         .test_exceptions = test_exceptions_sr,
5064         .par = (const uint32_t[]){
5065             EXCVADDR,
5066             XTENSA_OPTION_EXCEPTION,
5067         },
5068         .op_flags = XTENSA_OP_PRIVILEGED,
5069     }, {
5070         .name = "wsr.ibreaka0",
5071         .translate = translate_wsr_ibreaka,
5072         .test_exceptions = test_exceptions_ibreak,
5073         .par = (const uint32_t[]){
5074             IBREAKA,
5075             XTENSA_OPTION_DEBUG,
5076         },
5077         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5078     }, {
5079         .name = "wsr.ibreaka1",
5080         .translate = translate_wsr_ibreaka,
5081         .test_exceptions = test_exceptions_ibreak,
5082         .par = (const uint32_t[]){
5083             IBREAKA + 1,
5084             XTENSA_OPTION_DEBUG,
5085         },
5086         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5087     }, {
5088         .name = "wsr.ibreakenable",
5089         .translate = translate_wsr_ibreakenable,
5090         .test_exceptions = test_exceptions_sr,
5091         .par = (const uint32_t[]){
5092             IBREAKENABLE,
5093             XTENSA_OPTION_DEBUG,
5094         },
5095         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5096     }, {
5097         .name = "wsr.icount",
5098         .translate = translate_wsr_icount,
5099         .test_exceptions = test_exceptions_sr,
5100         .par = (const uint32_t[]){
5101             ICOUNT,
5102             XTENSA_OPTION_DEBUG,
5103         },
5104         .op_flags = XTENSA_OP_PRIVILEGED,
5105     }, {
5106         .name = "wsr.icountlevel",
5107         .translate = translate_wsr_mask,
5108         .test_exceptions = test_exceptions_sr,
5109         .par = (const uint32_t[]){
5110             ICOUNTLEVEL,
5111             XTENSA_OPTION_DEBUG,
5112             0xf,
5113         },
5114         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
5115     }, {
5116         .name = "wsr.intclear",
5117         .translate = translate_wsr_intclear,
5118         .test_exceptions = test_exceptions_sr,
5119         .par = (const uint32_t[]){
5120             INTCLEAR,
5121             XTENSA_OPTION_INTERRUPT,
5122         },
5123         .op_flags =
5124             XTENSA_OP_PRIVILEGED |
5125             XTENSA_OP_EXIT_TB_0 |
5126             XTENSA_OP_CHECK_INTERRUPTS,
5127     }, {
5128         .name = "wsr.intenable",
5129         .translate = translate_wsr,
5130         .test_exceptions = test_exceptions_sr,
5131         .par = (const uint32_t[]){
5132             INTENABLE,
5133             XTENSA_OPTION_INTERRUPT,
5134         },
5135         .op_flags =
5136             XTENSA_OP_PRIVILEGED |
5137             XTENSA_OP_EXIT_TB_0 |
5138             XTENSA_OP_CHECK_INTERRUPTS,
5139     }, {
5140         .name = "wsr.interrupt",
5141         .translate = translate_wsr,
5142         .test_exceptions = test_exceptions_sr,
5143         .par = (const uint32_t[]){
5144             INTSET,
5145             XTENSA_OPTION_INTERRUPT,
5146         },
5147         .op_flags =
5148             XTENSA_OP_PRIVILEGED |
5149             XTENSA_OP_EXIT_TB_0 |
5150             XTENSA_OP_CHECK_INTERRUPTS,
5151     }, {
5152         .name = "wsr.intset",
5153         .translate = translate_wsr_intset,
5154         .test_exceptions = test_exceptions_sr,
5155         .par = (const uint32_t[]){
5156             INTSET,
5157             XTENSA_OPTION_INTERRUPT,
5158         },
5159         .op_flags =
5160             XTENSA_OP_PRIVILEGED |
5161             XTENSA_OP_EXIT_TB_0 |
5162             XTENSA_OP_CHECK_INTERRUPTS,
5163     }, {
5164         .name = "wsr.itlbcfg",
5165         .translate = translate_wsr_mask,
5166         .test_exceptions = test_exceptions_sr,
5167         .par = (const uint32_t[]){
5168             ITLBCFG,
5169             XTENSA_OPTION_MMU,
5170             0x01130000,
5171         },
5172         .op_flags = XTENSA_OP_PRIVILEGED,
5173     }, {
5174         .name = "wsr.lbeg",
5175         .translate = translate_wsr,
5176         .test_exceptions = test_exceptions_sr,
5177         .par = (const uint32_t[]){
5178             LBEG,
5179             XTENSA_OPTION_LOOP,
5180         },
5181         .op_flags = XTENSA_OP_EXIT_TB_M1,
5182     }, {
5183         .name = "wsr.lcount",
5184         .translate = translate_wsr,
5185         .test_exceptions = test_exceptions_sr,
5186         .par = (const uint32_t[]){
5187             LCOUNT,
5188             XTENSA_OPTION_LOOP,
5189         },
5190     }, {
5191         .name = "wsr.lend",
5192         .translate = translate_wsr,
5193         .test_exceptions = test_exceptions_sr,
5194         .par = (const uint32_t[]){
5195             LEND,
5196             XTENSA_OPTION_LOOP,
5197         },
5198         .op_flags = XTENSA_OP_EXIT_TB_M1,
5199     }, {
5200         .name = "wsr.litbase",
5201         .translate = translate_wsr_mask,
5202         .test_exceptions = test_exceptions_sr,
5203         .par = (const uint32_t[]){
5204             LITBASE,
5205             XTENSA_OPTION_EXTENDED_L32R,
5206             0xfffff001,
5207         },
5208         .op_flags = XTENSA_OP_EXIT_TB_M1,
5209     }, {
5210         .name = "wsr.m0",
5211         .translate = translate_wsr,
5212         .test_exceptions = test_exceptions_sr,
5213         .par = (const uint32_t[]){
5214             MR,
5215             XTENSA_OPTION_MAC16,
5216         },
5217     }, {
5218         .name = "wsr.m1",
5219         .translate = translate_wsr,
5220         .test_exceptions = test_exceptions_sr,
5221         .par = (const uint32_t[]){
5222             MR + 1,
5223             XTENSA_OPTION_MAC16,
5224         },
5225     }, {
5226         .name = "wsr.m2",
5227         .translate = translate_wsr,
5228         .test_exceptions = test_exceptions_sr,
5229         .par = (const uint32_t[]){
5230             MR + 2,
5231             XTENSA_OPTION_MAC16,
5232         },
5233     }, {
5234         .name = "wsr.m3",
5235         .translate = translate_wsr,
5236         .test_exceptions = test_exceptions_sr,
5237         .par = (const uint32_t[]){
5238             MR + 3,
5239             XTENSA_OPTION_MAC16,
5240         },
5241     }, {
5242         .name = "wsr.memctl",
5243         .translate = translate_wsr_memctl,
5244         .par = (const uint32_t[]){MEMCTL},
5245         .op_flags = XTENSA_OP_PRIVILEGED,
5246     }, {
5247         .name = "wsr.mecr",
5248         .translate = translate_wsr,
5249         .test_exceptions = test_exceptions_sr,
5250         .par = (const uint32_t[]){
5251             MECR,
5252             XTENSA_OPTION_MEMORY_ECC_PARITY,
5253         },
5254         .op_flags = XTENSA_OP_PRIVILEGED,
5255     }, {
5256         .name = "wsr.mepc",
5257         .translate = translate_wsr,
5258         .test_exceptions = test_exceptions_sr,
5259         .par = (const uint32_t[]){
5260             MEPC,
5261             XTENSA_OPTION_MEMORY_ECC_PARITY,
5262         },
5263         .op_flags = XTENSA_OP_PRIVILEGED,
5264     }, {
5265         .name = "wsr.meps",
5266         .translate = translate_wsr,
5267         .test_exceptions = test_exceptions_sr,
5268         .par = (const uint32_t[]){
5269             MEPS,
5270             XTENSA_OPTION_MEMORY_ECC_PARITY,
5271         },
5272         .op_flags = XTENSA_OP_PRIVILEGED,
5273     }, {
5274         .name = "wsr.mesave",
5275         .translate = translate_wsr,
5276         .test_exceptions = test_exceptions_sr,
5277         .par = (const uint32_t[]){
5278             MESAVE,
5279             XTENSA_OPTION_MEMORY_ECC_PARITY,
5280         },
5281         .op_flags = XTENSA_OP_PRIVILEGED,
5282     }, {
5283         .name = "wsr.mesr",
5284         .translate = translate_wsr,
5285         .test_exceptions = test_exceptions_sr,
5286         .par = (const uint32_t[]){
5287             MESR,
5288             XTENSA_OPTION_MEMORY_ECC_PARITY,
5289         },
5290         .op_flags = XTENSA_OP_PRIVILEGED,
5291     }, {
5292         .name = "wsr.mevaddr",
5293         .translate = translate_wsr,
5294         .test_exceptions = test_exceptions_sr,
5295         .par = (const uint32_t[]){
5296             MESR,
5297             XTENSA_OPTION_MEMORY_ECC_PARITY,
5298         },
5299         .op_flags = XTENSA_OP_PRIVILEGED,
5300     }, {
5301         .name = "wsr.misc0",
5302         .translate = translate_wsr,
5303         .test_exceptions = test_exceptions_sr,
5304         .par = (const uint32_t[]){
5305             MISC,
5306             XTENSA_OPTION_MISC_SR,
5307         },
5308         .op_flags = XTENSA_OP_PRIVILEGED,
5309     }, {
5310         .name = "wsr.misc1",
5311         .translate = translate_wsr,
5312         .test_exceptions = test_exceptions_sr,
5313         .par = (const uint32_t[]){
5314             MISC + 1,
5315             XTENSA_OPTION_MISC_SR,
5316         },
5317         .op_flags = XTENSA_OP_PRIVILEGED,
5318     }, {
5319         .name = "wsr.misc2",
5320         .translate = translate_wsr,
5321         .test_exceptions = test_exceptions_sr,
5322         .par = (const uint32_t[]){
5323             MISC + 2,
5324             XTENSA_OPTION_MISC_SR,
5325         },
5326         .op_flags = XTENSA_OP_PRIVILEGED,
5327     }, {
5328         .name = "wsr.misc3",
5329         .translate = translate_wsr,
5330         .test_exceptions = test_exceptions_sr,
5331         .par = (const uint32_t[]){
5332             MISC + 3,
5333             XTENSA_OPTION_MISC_SR,
5334         },
5335         .op_flags = XTENSA_OP_PRIVILEGED,
5336     }, {
5337         .name = "wsr.mmid",
5338         .translate = translate_wsr,
5339         .test_exceptions = test_exceptions_sr,
5340         .par = (const uint32_t[]){
5341             MMID,
5342             XTENSA_OPTION_TRACE_PORT,
5343         },
5344         .op_flags = XTENSA_OP_PRIVILEGED,
5345     }, {
5346         .name = "wsr.mpuenb",
5347         .translate = translate_wsr_mpuenb,
5348         .test_exceptions = test_exceptions_sr,
5349         .par = (const uint32_t[]){
5350             MPUENB,
5351             XTENSA_OPTION_MPU,
5352         },
5353         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
5354     }, {
5355         .name = "wsr.prefctl",
5356         .translate = translate_wsr,
5357         .par = (const uint32_t[]){PREFCTL},
5358     }, {
5359         .name = "wsr.prid",
5360         .op_flags = XTENSA_OP_ILL,
5361     }, {
5362         .name = "wsr.ps",
5363         .translate = translate_wsr_ps,
5364         .test_exceptions = test_exceptions_sr,
5365         .par = (const uint32_t[]){
5366             PS,
5367             XTENSA_OPTION_EXCEPTION,
5368         },
5369         .op_flags =
5370             XTENSA_OP_PRIVILEGED |
5371             XTENSA_OP_EXIT_TB_M1 |
5372             XTENSA_OP_CHECK_INTERRUPTS,
5373     }, {
5374         .name = "wsr.ptevaddr",
5375         .translate = translate_wsr_mask,
5376         .test_exceptions = test_exceptions_sr,
5377         .par = (const uint32_t[]){
5378             PTEVADDR,
5379             XTENSA_OPTION_MMU,
5380             0xffc00000,
5381         },
5382         .op_flags = XTENSA_OP_PRIVILEGED,
5383     }, {
5384         .name = "wsr.rasid",
5385         .translate = translate_wsr_rasid,
5386         .test_exceptions = test_exceptions_sr,
5387         .par = (const uint32_t[]){
5388             RASID,
5389             XTENSA_OPTION_MMU,
5390         },
5391         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
5392     }, {
5393         .name = "wsr.sar",
5394         .translate = translate_wsr_sar,
5395         .par = (const uint32_t[]){SAR},
5396     }, {
5397         .name = "wsr.scompare1",
5398         .translate = translate_wsr,
5399         .test_exceptions = test_exceptions_sr,
5400         .par = (const uint32_t[]){
5401             SCOMPARE1,
5402             XTENSA_OPTION_CONDITIONAL_STORE,
5403         },
5404     }, {
5405         .name = "wsr.vecbase",
5406         .translate = translate_wsr,
5407         .test_exceptions = test_exceptions_sr,
5408         .par = (const uint32_t[]){
5409             VECBASE,
5410             XTENSA_OPTION_RELOCATABLE_VECTOR,
5411         },
5412         .op_flags = XTENSA_OP_PRIVILEGED,
5413     }, {
5414         .name = "wsr.windowbase",
5415         .translate = translate_wsr_windowbase,
5416         .test_exceptions = test_exceptions_sr,
5417         .par = (const uint32_t[]){
5418             WINDOW_BASE,
5419             XTENSA_OPTION_WINDOWED_REGISTER,
5420         },
5421         .op_flags = XTENSA_OP_PRIVILEGED |
5422             XTENSA_OP_EXIT_TB_M1 |
5423             XTENSA_OP_SYNC_REGISTER_WINDOW,
5424     }, {
5425         .name = "wsr.windowstart",
5426         .translate = translate_wsr_windowstart,
5427         .test_exceptions = test_exceptions_sr,
5428         .par = (const uint32_t[]){
5429             WINDOW_START,
5430             XTENSA_OPTION_WINDOWED_REGISTER,
5431         },
5432         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
5433     }, {
5434         .name = "wur.expstate",
5435         .translate = translate_wur,
5436         .par = (const uint32_t[]){EXPSTATE},
5437     }, {
5438         .name = "wur.threadptr",
5439         .translate = translate_wur,
5440         .par = (const uint32_t[]){THREADPTR},
5441     }, {
5442         .name = "xor",
5443         .translate = translate_xor,
5444     }, {
5445         .name = "xorb",
5446         .translate = translate_boolean,
5447         .par = (const uint32_t[]){BOOLEAN_XOR},
5448     }, {
5449         .name = "xsr.176",
5450         .op_flags = XTENSA_OP_ILL,
5451     }, {
5452         .name = "xsr.208",
5453         .op_flags = XTENSA_OP_ILL,
5454     }, {
5455         .name = "xsr.acchi",
5456         .translate = translate_xsr_acchi,
5457         .test_exceptions = test_exceptions_sr,
5458         .par = (const uint32_t[]){
5459             ACCHI,
5460             XTENSA_OPTION_MAC16,
5461         },
5462     }, {
5463         .name = "xsr.acclo",
5464         .translate = translate_xsr,
5465         .test_exceptions = test_exceptions_sr,
5466         .par = (const uint32_t[]){
5467             ACCLO,
5468             XTENSA_OPTION_MAC16,
5469         },
5470     }, {
5471         .name = "xsr.atomctl",
5472         .translate = translate_xsr_mask,
5473         .test_exceptions = test_exceptions_sr,
5474         .par = (const uint32_t[]){
5475             ATOMCTL,
5476             XTENSA_OPTION_ATOMCTL,
5477             0x3f,
5478         },
5479         .op_flags = XTENSA_OP_PRIVILEGED,
5480     }, {
5481         .name = "xsr.br",
5482         .translate = translate_xsr_mask,
5483         .test_exceptions = test_exceptions_sr,
5484         .par = (const uint32_t[]){
5485             BR,
5486             XTENSA_OPTION_BOOLEAN,
5487             0xffff,
5488         },
5489     }, {
5490         .name = "xsr.cacheadrdis",
5491         .translate = translate_xsr_mask,
5492         .test_exceptions = test_exceptions_sr,
5493         .par = (const uint32_t[]){
5494             CACHEADRDIS,
5495             XTENSA_OPTION_MPU,
5496             0xff,
5497         },
5498         .op_flags = XTENSA_OP_PRIVILEGED,
5499     }, {
5500         .name = "xsr.cacheattr",
5501         .translate = translate_xsr,
5502         .test_exceptions = test_exceptions_sr,
5503         .par = (const uint32_t[]){
5504             CACHEATTR,
5505             XTENSA_OPTION_CACHEATTR,
5506         },
5507         .op_flags = XTENSA_OP_PRIVILEGED,
5508     }, {
5509         .name = "xsr.ccompare0",
5510         .translate = translate_xsr_ccompare,
5511         .test_exceptions = test_exceptions_ccompare,
5512         .par = (const uint32_t[]){
5513             CCOMPARE,
5514             XTENSA_OPTION_TIMER_INTERRUPT,
5515         },
5516         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5517     }, {
5518         .name = "xsr.ccompare1",
5519         .translate = translate_xsr_ccompare,
5520         .test_exceptions = test_exceptions_ccompare,
5521         .par = (const uint32_t[]){
5522             CCOMPARE + 1,
5523             XTENSA_OPTION_TIMER_INTERRUPT,
5524         },
5525         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5526     }, {
5527         .name = "xsr.ccompare2",
5528         .translate = translate_xsr_ccompare,
5529         .test_exceptions = test_exceptions_ccompare,
5530         .par = (const uint32_t[]){
5531             CCOMPARE + 2,
5532             XTENSA_OPTION_TIMER_INTERRUPT,
5533         },
5534         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5535     }, {
5536         .name = "xsr.ccount",
5537         .translate = translate_xsr_ccount,
5538         .test_exceptions = test_exceptions_sr,
5539         .par = (const uint32_t[]){
5540             CCOUNT,
5541             XTENSA_OPTION_TIMER_INTERRUPT,
5542         },
5543         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5544     }, {
5545         .name = "xsr.configid0",
5546         .op_flags = XTENSA_OP_ILL,
5547     }, {
5548         .name = "xsr.configid1",
5549         .op_flags = XTENSA_OP_ILL,
5550     }, {
5551         .name = "xsr.cpenable",
5552         .translate = translate_xsr_mask,
5553         .test_exceptions = test_exceptions_sr,
5554         .par = (const uint32_t[]){
5555             CPENABLE,
5556             XTENSA_OPTION_COPROCESSOR,
5557             0xff,
5558         },
5559         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
5560     }, {
5561         .name = "xsr.dbreaka0",
5562         .translate = translate_xsr_dbreaka,
5563         .test_exceptions = test_exceptions_dbreak,
5564         .par = (const uint32_t[]){
5565             DBREAKA,
5566             XTENSA_OPTION_DEBUG,
5567         },
5568         .op_flags = XTENSA_OP_PRIVILEGED,
5569     }, {
5570         .name = "xsr.dbreaka1",
5571         .translate = translate_xsr_dbreaka,
5572         .test_exceptions = test_exceptions_dbreak,
5573         .par = (const uint32_t[]){
5574             DBREAKA + 1,
5575             XTENSA_OPTION_DEBUG,
5576         },
5577         .op_flags = XTENSA_OP_PRIVILEGED,
5578     }, {
5579         .name = "xsr.dbreakc0",
5580         .translate = translate_xsr_dbreakc,
5581         .test_exceptions = test_exceptions_dbreak,
5582         .par = (const uint32_t[]){
5583             DBREAKC,
5584             XTENSA_OPTION_DEBUG,
5585         },
5586         .op_flags = XTENSA_OP_PRIVILEGED,
5587     }, {
5588         .name = "xsr.dbreakc1",
5589         .translate = translate_xsr_dbreakc,
5590         .test_exceptions = test_exceptions_dbreak,
5591         .par = (const uint32_t[]){
5592             DBREAKC + 1,
5593             XTENSA_OPTION_DEBUG,
5594         },
5595         .op_flags = XTENSA_OP_PRIVILEGED,
5596     }, {
5597         .name = "xsr.ddr",
5598         .translate = translate_xsr,
5599         .test_exceptions = test_exceptions_sr,
5600         .par = (const uint32_t[]){
5601             DDR,
5602             XTENSA_OPTION_DEBUG,
5603         },
5604         .op_flags = XTENSA_OP_PRIVILEGED,
5605     }, {
5606         .name = "xsr.debugcause",
5607         .op_flags = XTENSA_OP_ILL,
5608     }, {
5609         .name = "xsr.depc",
5610         .translate = translate_xsr,
5611         .test_exceptions = test_exceptions_sr,
5612         .par = (const uint32_t[]){
5613             DEPC,
5614             XTENSA_OPTION_EXCEPTION,
5615         },
5616         .op_flags = XTENSA_OP_PRIVILEGED,
5617     }, {
5618         .name = "xsr.dtlbcfg",
5619         .translate = translate_xsr_mask,
5620         .test_exceptions = test_exceptions_sr,
5621         .par = (const uint32_t[]){
5622             DTLBCFG,
5623             XTENSA_OPTION_MMU,
5624             0x01130000,
5625         },
5626         .op_flags = XTENSA_OP_PRIVILEGED,
5627     }, {
5628         .name = "xsr.epc1",
5629         .translate = translate_xsr,
5630         .test_exceptions = test_exceptions_sr,
5631         .par = (const uint32_t[]){
5632             EPC1,
5633             XTENSA_OPTION_EXCEPTION,
5634         },
5635         .op_flags = XTENSA_OP_PRIVILEGED,
5636     }, {
5637         .name = "xsr.epc2",
5638         .translate = translate_xsr,
5639         .test_exceptions = test_exceptions_hpi,
5640         .par = (const uint32_t[]){
5641             EPC1 + 1,
5642             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5643         },
5644         .op_flags = XTENSA_OP_PRIVILEGED,
5645     }, {
5646         .name = "xsr.epc3",
5647         .translate = translate_xsr,
5648         .test_exceptions = test_exceptions_hpi,
5649         .par = (const uint32_t[]){
5650             EPC1 + 2,
5651             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5652         },
5653         .op_flags = XTENSA_OP_PRIVILEGED,
5654     }, {
5655         .name = "xsr.epc4",
5656         .translate = translate_xsr,
5657         .test_exceptions = test_exceptions_hpi,
5658         .par = (const uint32_t[]){
5659             EPC1 + 3,
5660             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5661         },
5662         .op_flags = XTENSA_OP_PRIVILEGED,
5663     }, {
5664         .name = "xsr.epc5",
5665         .translate = translate_xsr,
5666         .test_exceptions = test_exceptions_hpi,
5667         .par = (const uint32_t[]){
5668             EPC1 + 4,
5669             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5670         },
5671         .op_flags = XTENSA_OP_PRIVILEGED,
5672     }, {
5673         .name = "xsr.epc6",
5674         .translate = translate_xsr,
5675         .test_exceptions = test_exceptions_hpi,
5676         .par = (const uint32_t[]){
5677             EPC1 + 5,
5678             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5679         },
5680         .op_flags = XTENSA_OP_PRIVILEGED,
5681     }, {
5682         .name = "xsr.epc7",
5683         .translate = translate_xsr,
5684         .test_exceptions = test_exceptions_hpi,
5685         .par = (const uint32_t[]){
5686             EPC1 + 6,
5687             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5688         },
5689         .op_flags = XTENSA_OP_PRIVILEGED,
5690     }, {
5691         .name = "xsr.eps2",
5692         .translate = translate_xsr,
5693         .test_exceptions = test_exceptions_hpi,
5694         .par = (const uint32_t[]){
5695             EPS2,
5696             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5697         },
5698         .op_flags = XTENSA_OP_PRIVILEGED,
5699     }, {
5700         .name = "xsr.eps3",
5701         .translate = translate_xsr,
5702         .test_exceptions = test_exceptions_hpi,
5703         .par = (const uint32_t[]){
5704             EPS2 + 1,
5705             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5706         },
5707         .op_flags = XTENSA_OP_PRIVILEGED,
5708     }, {
5709         .name = "xsr.eps4",
5710         .translate = translate_xsr,
5711         .test_exceptions = test_exceptions_hpi,
5712         .par = (const uint32_t[]){
5713             EPS2 + 2,
5714             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5715         },
5716         .op_flags = XTENSA_OP_PRIVILEGED,
5717     }, {
5718         .name = "xsr.eps5",
5719         .translate = translate_xsr,
5720         .test_exceptions = test_exceptions_hpi,
5721         .par = (const uint32_t[]){
5722             EPS2 + 3,
5723             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5724         },
5725         .op_flags = XTENSA_OP_PRIVILEGED,
5726     }, {
5727         .name = "xsr.eps6",
5728         .translate = translate_xsr,
5729         .test_exceptions = test_exceptions_hpi,
5730         .par = (const uint32_t[]){
5731             EPS2 + 4,
5732             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5733         },
5734         .op_flags = XTENSA_OP_PRIVILEGED,
5735     }, {
5736         .name = "xsr.eps7",
5737         .translate = translate_xsr,
5738         .test_exceptions = test_exceptions_hpi,
5739         .par = (const uint32_t[]){
5740             EPS2 + 5,
5741             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5742         },
5743         .op_flags = XTENSA_OP_PRIVILEGED,
5744     }, {
5745         .name = "xsr.eraccess",
5746         .translate = translate_xsr_mask,
5747         .par = (const uint32_t[]){
5748             ERACCESS,
5749             0,
5750             0xffff,
5751         },
5752         .op_flags = XTENSA_OP_PRIVILEGED,
5753     }, {
5754         .name = "xsr.exccause",
5755         .translate = translate_xsr,
5756         .test_exceptions = test_exceptions_sr,
5757         .par = (const uint32_t[]){
5758             EXCCAUSE,
5759             XTENSA_OPTION_EXCEPTION,
5760         },
5761         .op_flags = XTENSA_OP_PRIVILEGED,
5762     }, {
5763         .name = "xsr.excsave1",
5764         .translate = translate_xsr,
5765         .test_exceptions = test_exceptions_sr,
5766         .par = (const uint32_t[]){
5767             EXCSAVE1,
5768             XTENSA_OPTION_EXCEPTION,
5769         },
5770         .op_flags = XTENSA_OP_PRIVILEGED,
5771     }, {
5772         .name = "xsr.excsave2",
5773         .translate = translate_xsr,
5774         .test_exceptions = test_exceptions_hpi,
5775         .par = (const uint32_t[]){
5776             EXCSAVE1 + 1,
5777             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5778         },
5779         .op_flags = XTENSA_OP_PRIVILEGED,
5780     }, {
5781         .name = "xsr.excsave3",
5782         .translate = translate_xsr,
5783         .test_exceptions = test_exceptions_hpi,
5784         .par = (const uint32_t[]){
5785             EXCSAVE1 + 2,
5786             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5787         },
5788         .op_flags = XTENSA_OP_PRIVILEGED,
5789     }, {
5790         .name = "xsr.excsave4",
5791         .translate = translate_xsr,
5792         .test_exceptions = test_exceptions_hpi,
5793         .par = (const uint32_t[]){
5794             EXCSAVE1 + 3,
5795             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5796         },
5797         .op_flags = XTENSA_OP_PRIVILEGED,
5798     }, {
5799         .name = "xsr.excsave5",
5800         .translate = translate_xsr,
5801         .test_exceptions = test_exceptions_hpi,
5802         .par = (const uint32_t[]){
5803             EXCSAVE1 + 4,
5804             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5805         },
5806         .op_flags = XTENSA_OP_PRIVILEGED,
5807     }, {
5808         .name = "xsr.excsave6",
5809         .translate = translate_xsr,
5810         .test_exceptions = test_exceptions_hpi,
5811         .par = (const uint32_t[]){
5812             EXCSAVE1 + 5,
5813             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5814         },
5815         .op_flags = XTENSA_OP_PRIVILEGED,
5816     }, {
5817         .name = "xsr.excsave7",
5818         .translate = translate_xsr,
5819         .test_exceptions = test_exceptions_hpi,
5820         .par = (const uint32_t[]){
5821             EXCSAVE1 + 6,
5822             XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5823         },
5824         .op_flags = XTENSA_OP_PRIVILEGED,
5825     }, {
5826         .name = "xsr.excvaddr",
5827         .translate = translate_xsr,
5828         .test_exceptions = test_exceptions_sr,
5829         .par = (const uint32_t[]){
5830             EXCVADDR,
5831             XTENSA_OPTION_EXCEPTION,
5832         },
5833         .op_flags = XTENSA_OP_PRIVILEGED,
5834     }, {
5835         .name = "xsr.ibreaka0",
5836         .translate = translate_xsr_ibreaka,
5837         .test_exceptions = test_exceptions_ibreak,
5838         .par = (const uint32_t[]){
5839             IBREAKA,
5840             XTENSA_OPTION_DEBUG,
5841         },
5842         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5843     }, {
5844         .name = "xsr.ibreaka1",
5845         .translate = translate_xsr_ibreaka,
5846         .test_exceptions = test_exceptions_ibreak,
5847         .par = (const uint32_t[]){
5848             IBREAKA + 1,
5849             XTENSA_OPTION_DEBUG,
5850         },
5851         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5852     }, {
5853         .name = "xsr.ibreakenable",
5854         .translate = translate_xsr_ibreakenable,
5855         .test_exceptions = test_exceptions_sr,
5856         .par = (const uint32_t[]){
5857             IBREAKENABLE,
5858             XTENSA_OPTION_DEBUG,
5859         },
5860         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5861     }, {
5862         .name = "xsr.icount",
5863         .translate = translate_xsr_icount,
5864         .test_exceptions = test_exceptions_sr,
5865         .par = (const uint32_t[]){
5866             ICOUNT,
5867             XTENSA_OPTION_DEBUG,
5868         },
5869         .op_flags = XTENSA_OP_PRIVILEGED,
5870     }, {
5871         .name = "xsr.icountlevel",
5872         .translate = translate_xsr_mask,
5873         .test_exceptions = test_exceptions_sr,
5874         .par = (const uint32_t[]){
5875             ICOUNTLEVEL,
5876             XTENSA_OPTION_DEBUG,
5877             0xf,
5878         },
5879         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
5880     }, {
5881         .name = "xsr.intclear",
5882         .op_flags = XTENSA_OP_ILL,
5883     }, {
5884         .name = "xsr.intenable",
5885         .translate = translate_xsr,
5886         .test_exceptions = test_exceptions_sr,
5887         .par = (const uint32_t[]){
5888             INTENABLE,
5889             XTENSA_OPTION_INTERRUPT,
5890         },
5891         .op_flags =
5892             XTENSA_OP_PRIVILEGED |
5893             XTENSA_OP_EXIT_TB_0 |
5894             XTENSA_OP_CHECK_INTERRUPTS,
5895     }, {
5896         .name = "xsr.interrupt",
5897         .op_flags = XTENSA_OP_ILL,
5898     }, {
5899         .name = "xsr.intset",
5900         .op_flags = XTENSA_OP_ILL,
5901     }, {
5902         .name = "xsr.itlbcfg",
5903         .translate = translate_xsr_mask,
5904         .test_exceptions = test_exceptions_sr,
5905         .par = (const uint32_t[]){
5906             ITLBCFG,
5907             XTENSA_OPTION_MMU,
5908             0x01130000,
5909         },
5910         .op_flags = XTENSA_OP_PRIVILEGED,
5911     }, {
5912         .name = "xsr.lbeg",
5913         .translate = translate_xsr,
5914         .test_exceptions = test_exceptions_sr,
5915         .par = (const uint32_t[]){
5916             LBEG,
5917             XTENSA_OPTION_LOOP,
5918         },
5919         .op_flags = XTENSA_OP_EXIT_TB_M1,
5920     }, {
5921         .name = "xsr.lcount",
5922         .translate = translate_xsr,
5923         .test_exceptions = test_exceptions_sr,
5924         .par = (const uint32_t[]){
5925             LCOUNT,
5926             XTENSA_OPTION_LOOP,
5927         },
5928     }, {
5929         .name = "xsr.lend",
5930         .translate = translate_xsr,
5931         .test_exceptions = test_exceptions_sr,
5932         .par = (const uint32_t[]){
5933             LEND,
5934             XTENSA_OPTION_LOOP,
5935         },
5936         .op_flags = XTENSA_OP_EXIT_TB_M1,
5937     }, {
5938         .name = "xsr.litbase",
5939         .translate = translate_xsr_mask,
5940         .test_exceptions = test_exceptions_sr,
5941         .par = (const uint32_t[]){
5942             LITBASE,
5943             XTENSA_OPTION_EXTENDED_L32R,
5944             0xfffff001,
5945         },
5946         .op_flags = XTENSA_OP_EXIT_TB_M1,
5947     }, {
5948         .name = "xsr.m0",
5949         .translate = translate_xsr,
5950         .test_exceptions = test_exceptions_sr,
5951         .par = (const uint32_t[]){
5952             MR,
5953             XTENSA_OPTION_MAC16,
5954         },
5955     }, {
5956         .name = "xsr.m1",
5957         .translate = translate_xsr,
5958         .test_exceptions = test_exceptions_sr,
5959         .par = (const uint32_t[]){
5960             MR + 1,
5961             XTENSA_OPTION_MAC16,
5962         },
5963     }, {
5964         .name = "xsr.m2",
5965         .translate = translate_xsr,
5966         .test_exceptions = test_exceptions_sr,
5967         .par = (const uint32_t[]){
5968             MR + 2,
5969             XTENSA_OPTION_MAC16,
5970         },
5971     }, {
5972         .name = "xsr.m3",
5973         .translate = translate_xsr,
5974         .test_exceptions = test_exceptions_sr,
5975         .par = (const uint32_t[]){
5976             MR + 3,
5977             XTENSA_OPTION_MAC16,
5978         },
5979     }, {
5980         .name = "xsr.memctl",
5981         .translate = translate_xsr_memctl,
5982         .par = (const uint32_t[]){MEMCTL},
5983         .op_flags = XTENSA_OP_PRIVILEGED,
5984     }, {
5985         .name = "xsr.mecr",
5986         .translate = translate_xsr,
5987         .test_exceptions = test_exceptions_sr,
5988         .par = (const uint32_t[]){
5989             MECR,
5990             XTENSA_OPTION_MEMORY_ECC_PARITY,
5991         },
5992         .op_flags = XTENSA_OP_PRIVILEGED,
5993     }, {
5994         .name = "xsr.mepc",
5995         .translate = translate_xsr,
5996         .test_exceptions = test_exceptions_sr,
5997         .par = (const uint32_t[]){
5998             MEPC,
5999             XTENSA_OPTION_MEMORY_ECC_PARITY,
6000         },
6001         .op_flags = XTENSA_OP_PRIVILEGED,
6002     }, {
6003         .name = "xsr.meps",
6004         .translate = translate_xsr,
6005         .test_exceptions = test_exceptions_sr,
6006         .par = (const uint32_t[]){
6007             MEPS,
6008             XTENSA_OPTION_MEMORY_ECC_PARITY,
6009         },
6010         .op_flags = XTENSA_OP_PRIVILEGED,
6011     }, {
6012         .name = "xsr.mesave",
6013         .translate = translate_xsr,
6014         .test_exceptions = test_exceptions_sr,
6015         .par = (const uint32_t[]){
6016             MESAVE,
6017             XTENSA_OPTION_MEMORY_ECC_PARITY,
6018         },
6019         .op_flags = XTENSA_OP_PRIVILEGED,
6020     }, {
6021         .name = "xsr.mesr",
6022         .translate = translate_xsr,
6023         .test_exceptions = test_exceptions_sr,
6024         .par = (const uint32_t[]){
6025             MESR,
6026             XTENSA_OPTION_MEMORY_ECC_PARITY,
6027         },
6028         .op_flags = XTENSA_OP_PRIVILEGED,
6029     }, {
6030         .name = "xsr.mevaddr",
6031         .translate = translate_xsr,
6032         .test_exceptions = test_exceptions_sr,
6033         .par = (const uint32_t[]){
6034             MESR,
6035             XTENSA_OPTION_MEMORY_ECC_PARITY,
6036         },
6037         .op_flags = XTENSA_OP_PRIVILEGED,
6038     }, {
6039         .name = "xsr.misc0",
6040         .translate = translate_xsr,
6041         .test_exceptions = test_exceptions_sr,
6042         .par = (const uint32_t[]){
6043             MISC,
6044             XTENSA_OPTION_MISC_SR,
6045         },
6046         .op_flags = XTENSA_OP_PRIVILEGED,
6047     }, {
6048         .name = "xsr.misc1",
6049         .translate = translate_xsr,
6050         .test_exceptions = test_exceptions_sr,
6051         .par = (const uint32_t[]){
6052             MISC + 1,
6053             XTENSA_OPTION_MISC_SR,
6054         },
6055         .op_flags = XTENSA_OP_PRIVILEGED,
6056     }, {
6057         .name = "xsr.misc2",
6058         .translate = translate_xsr,
6059         .test_exceptions = test_exceptions_sr,
6060         .par = (const uint32_t[]){
6061             MISC + 2,
6062             XTENSA_OPTION_MISC_SR,
6063         },
6064         .op_flags = XTENSA_OP_PRIVILEGED,
6065     }, {
6066         .name = "xsr.misc3",
6067         .translate = translate_xsr,
6068         .test_exceptions = test_exceptions_sr,
6069         .par = (const uint32_t[]){
6070             MISC + 3,
6071             XTENSA_OPTION_MISC_SR,
6072         },
6073         .op_flags = XTENSA_OP_PRIVILEGED,
6074     }, {
6075         .name = "xsr.mpuenb",
6076         .translate = translate_xsr_mpuenb,
6077         .test_exceptions = test_exceptions_sr,
6078         .par = (const uint32_t[]){
6079             MPUENB,
6080             XTENSA_OPTION_MPU,
6081         },
6082         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
6083     }, {
6084         .name = "xsr.prefctl",
6085         .translate = translate_xsr,
6086         .par = (const uint32_t[]){PREFCTL},
6087     }, {
6088         .name = "xsr.prid",
6089         .op_flags = XTENSA_OP_ILL,
6090     }, {
6091         .name = "xsr.ps",
6092         .translate = translate_xsr_ps,
6093         .test_exceptions = test_exceptions_sr,
6094         .par = (const uint32_t[]){
6095             PS,
6096             XTENSA_OPTION_EXCEPTION,
6097         },
6098         .op_flags =
6099             XTENSA_OP_PRIVILEGED |
6100             XTENSA_OP_EXIT_TB_M1 |
6101             XTENSA_OP_CHECK_INTERRUPTS,
6102     }, {
6103         .name = "xsr.ptevaddr",
6104         .translate = translate_xsr_mask,
6105         .test_exceptions = test_exceptions_sr,
6106         .par = (const uint32_t[]){
6107             PTEVADDR,
6108             XTENSA_OPTION_MMU,
6109             0xffc00000,
6110         },
6111         .op_flags = XTENSA_OP_PRIVILEGED,
6112     }, {
6113         .name = "xsr.rasid",
6114         .translate = translate_xsr_rasid,
6115         .test_exceptions = test_exceptions_sr,
6116         .par = (const uint32_t[]){
6117             RASID,
6118             XTENSA_OPTION_MMU,
6119         },
6120         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
6121     }, {
6122         .name = "xsr.sar",
6123         .translate = translate_xsr_sar,
6124         .par = (const uint32_t[]){SAR},
6125     }, {
6126         .name = "xsr.scompare1",
6127         .translate = translate_xsr,
6128         .test_exceptions = test_exceptions_sr,
6129         .par = (const uint32_t[]){
6130             SCOMPARE1,
6131             XTENSA_OPTION_CONDITIONAL_STORE,
6132         },
6133     }, {
6134         .name = "xsr.vecbase",
6135         .translate = translate_xsr,
6136         .test_exceptions = test_exceptions_sr,
6137         .par = (const uint32_t[]){
6138             VECBASE,
6139             XTENSA_OPTION_RELOCATABLE_VECTOR,
6140         },
6141         .op_flags = XTENSA_OP_PRIVILEGED,
6142     }, {
6143         .name = "xsr.windowbase",
6144         .translate = translate_xsr_windowbase,
6145         .test_exceptions = test_exceptions_sr,
6146         .par = (const uint32_t[]){
6147             WINDOW_BASE,
6148             XTENSA_OPTION_WINDOWED_REGISTER,
6149         },
6150         .op_flags = XTENSA_OP_PRIVILEGED |
6151             XTENSA_OP_EXIT_TB_M1 |
6152             XTENSA_OP_SYNC_REGISTER_WINDOW,
6153     }, {
6154         .name = "xsr.windowstart",
6155         .translate = translate_xsr_windowstart,
6156         .test_exceptions = test_exceptions_sr,
6157         .par = (const uint32_t[]){
6158             WINDOW_START,
6159             XTENSA_OPTION_WINDOWED_REGISTER,
6160         },
6161         .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
6162     },
6163 };
6164 
6165 const XtensaOpcodeTranslators xtensa_core_opcodes = {
6166     .num_opcodes = ARRAY_SIZE(core_ops),
6167     .opcode = core_ops,
6168 };
6169 
6170 
6171 static inline void get_f32_o1_i3(const OpcodeArg *arg, OpcodeArg *arg32,
6172                                  int o0, int i0, int i1, int i2)
6173 {
6174     if ((i0 >= 0 && arg[i0].num_bits == 64) ||
6175         (o0 >= 0 && arg[o0].num_bits == 64)) {
6176         if (o0 >= 0) {
6177             arg32[o0].out = tcg_temp_new_i32();
6178         }
6179         if (i0 >= 0) {
6180             arg32[i0].in = tcg_temp_new_i32();
6181             tcg_gen_extrl_i64_i32(arg32[i0].in, arg[i0].in);
6182         }
6183         if (i1 >= 0) {
6184             arg32[i1].in = tcg_temp_new_i32();
6185             tcg_gen_extrl_i64_i32(arg32[i1].in, arg[i1].in);
6186         }
6187         if (i2 >= 0) {
6188             arg32[i2].in = tcg_temp_new_i32();
6189             tcg_gen_extrl_i64_i32(arg32[i2].in, arg[i2].in);
6190         }
6191     } else {
6192         if (o0 >= 0) {
6193             arg32[o0].out = arg[o0].out;
6194         }
6195         if (i0 >= 0) {
6196             arg32[i0].in = arg[i0].in;
6197         }
6198         if (i1 >= 0) {
6199             arg32[i1].in = arg[i1].in;
6200         }
6201         if (i2 >= 0) {
6202             arg32[i2].in = arg[i2].in;
6203         }
6204     }
6205 }
6206 
6207 static inline void put_f32_o1_i3(const OpcodeArg *arg, const OpcodeArg *arg32,
6208                                  int o0, int i0, int i1, int i2)
6209 {
6210     if ((i0 >= 0 && arg[i0].num_bits == 64) ||
6211         (o0 >= 0 && arg[o0].num_bits == 64)) {
6212         if (o0 >= 0) {
6213             tcg_gen_extu_i32_i64(arg[o0].out, arg32[o0].out);
6214         }
6215     }
6216 }
6217 
6218 static inline void get_f32_o1_i2(const OpcodeArg *arg, OpcodeArg *arg32,
6219                                  int o0, int i0, int i1)
6220 {
6221     get_f32_o1_i3(arg, arg32, o0, i0, i1, -1);
6222 }
6223 
6224 static inline void put_f32_o1_i2(const OpcodeArg *arg, const OpcodeArg *arg32,
6225                                  int o0, int i0, int i1)
6226 {
6227     put_f32_o1_i3(arg, arg32, o0, i0, i1, -1);
6228 }
6229 
6230 static inline void get_f32_o1_i1(const OpcodeArg *arg, OpcodeArg *arg32,
6231                                  int o0, int i0)
6232 {
6233     get_f32_o1_i2(arg, arg32, o0, i0, -1);
6234 }
6235 
6236 static inline void put_f32_o1_i1(const OpcodeArg *arg, const OpcodeArg *arg32,
6237                                  int o0, int i0)
6238 {
6239     put_f32_o1_i2(arg, arg32, o0, i0, -1);
6240 }
6241 
6242 static inline void get_f32_o1(const OpcodeArg *arg, OpcodeArg *arg32,
6243                               int o0)
6244 {
6245     get_f32_o1_i1(arg, arg32, o0, -1);
6246 }
6247 
6248 static inline void put_f32_o1(const OpcodeArg *arg, const OpcodeArg *arg32,
6249                               int o0)
6250 {
6251     put_f32_o1_i1(arg, arg32, o0, -1);
6252 }
6253 
6254 static inline void get_f32_i2(const OpcodeArg *arg, OpcodeArg *arg32,
6255                               int i0, int i1)
6256 {
6257     get_f32_o1_i2(arg, arg32, -1, i0, i1);
6258 }
6259 
6260 static inline void put_f32_i2(const OpcodeArg *arg, const OpcodeArg *arg32,
6261                               int i0, int i1)
6262 {
6263     put_f32_o1_i2(arg, arg32, -1, i0, i1);
6264 }
6265 
6266 static inline void get_f32_i1(const OpcodeArg *arg, OpcodeArg *arg32,
6267                               int i0)
6268 {
6269     get_f32_i2(arg, arg32, i0, -1);
6270 }
6271 
6272 static inline void put_f32_i1(const OpcodeArg *arg, const OpcodeArg *arg32,
6273                               int i0)
6274 {
6275     put_f32_i2(arg, arg32, i0, -1);
6276 }
6277 
6278 
6279 static void translate_abs_d(DisasContext *dc, const OpcodeArg arg[],
6280                             const uint32_t par[])
6281 {
6282     gen_helper_abs_d(arg[0].out, arg[1].in);
6283 }
6284 
6285 static void translate_abs_s(DisasContext *dc, const OpcodeArg arg[],
6286                             const uint32_t par[])
6287 {
6288     OpcodeArg arg32[2];
6289 
6290     get_f32_o1_i1(arg, arg32, 0, 1);
6291     gen_helper_abs_s(arg32[0].out, arg32[1].in);
6292     put_f32_o1_i1(arg, arg32, 0, 1);
6293 }
6294 
6295 static void translate_fpu2k_add_s(DisasContext *dc, const OpcodeArg arg[],
6296                                   const uint32_t par[])
6297 {
6298     gen_helper_fpu2k_add_s(arg[0].out, cpu_env,
6299                            arg[1].in, arg[2].in);
6300 }
6301 
6302 enum {
6303     COMPARE_UN,
6304     COMPARE_OEQ,
6305     COMPARE_UEQ,
6306     COMPARE_OLT,
6307     COMPARE_ULT,
6308     COMPARE_OLE,
6309     COMPARE_ULE,
6310 };
6311 
6312 static void translate_compare_d(DisasContext *dc, const OpcodeArg arg[],
6313                                 const uint32_t par[])
6314 {
6315     static void (* const helper[])(TCGv_i32 res, TCGv_env env,
6316                                    TCGv_i64 s, TCGv_i64 t) = {
6317         [COMPARE_UN] = gen_helper_un_d,
6318         [COMPARE_OEQ] = gen_helper_oeq_d,
6319         [COMPARE_UEQ] = gen_helper_ueq_d,
6320         [COMPARE_OLT] = gen_helper_olt_d,
6321         [COMPARE_ULT] = gen_helper_ult_d,
6322         [COMPARE_OLE] = gen_helper_ole_d,
6323         [COMPARE_ULE] = gen_helper_ule_d,
6324     };
6325     TCGv_i32 zero = tcg_constant_i32(0);
6326     TCGv_i32 res = tcg_temp_new_i32();
6327     TCGv_i32 set_br = tcg_temp_new_i32();
6328     TCGv_i32 clr_br = tcg_temp_new_i32();
6329 
6330     tcg_gen_ori_i32(set_br, arg[0].in, 1 << arg[0].imm);
6331     tcg_gen_andi_i32(clr_br, arg[0].in, ~(1 << arg[0].imm));
6332 
6333     helper[par[0]](res, cpu_env, arg[1].in, arg[2].in);
6334     tcg_gen_movcond_i32(TCG_COND_NE,
6335                         arg[0].out, res, zero,
6336                         set_br, clr_br);
6337 }
6338 
6339 static void translate_compare_s(DisasContext *dc, const OpcodeArg arg[],
6340                                 const uint32_t par[])
6341 {
6342     static void (* const helper[])(TCGv_i32 res, TCGv_env env,
6343                                    TCGv_i32 s, TCGv_i32 t) = {
6344         [COMPARE_UN] = gen_helper_un_s,
6345         [COMPARE_OEQ] = gen_helper_oeq_s,
6346         [COMPARE_UEQ] = gen_helper_ueq_s,
6347         [COMPARE_OLT] = gen_helper_olt_s,
6348         [COMPARE_ULT] = gen_helper_ult_s,
6349         [COMPARE_OLE] = gen_helper_ole_s,
6350         [COMPARE_ULE] = gen_helper_ule_s,
6351     };
6352     OpcodeArg arg32[3];
6353     TCGv_i32 zero = tcg_constant_i32(0);
6354     TCGv_i32 res = tcg_temp_new_i32();
6355     TCGv_i32 set_br = tcg_temp_new_i32();
6356     TCGv_i32 clr_br = tcg_temp_new_i32();
6357 
6358     tcg_gen_ori_i32(set_br, arg[0].in, 1 << arg[0].imm);
6359     tcg_gen_andi_i32(clr_br, arg[0].in, ~(1 << arg[0].imm));
6360 
6361     get_f32_i2(arg, arg32, 1, 2);
6362     helper[par[0]](res, cpu_env, arg32[1].in, arg32[2].in);
6363     tcg_gen_movcond_i32(TCG_COND_NE,
6364                         arg[0].out, res, zero,
6365                         set_br, clr_br);
6366     put_f32_i2(arg, arg32, 1, 2);
6367 }
6368 
6369 static void translate_const_d(DisasContext *dc, const OpcodeArg arg[],
6370                               const uint32_t par[])
6371 {
6372     static const uint64_t v[] = {
6373         UINT64_C(0x0000000000000000),
6374         UINT64_C(0x3ff0000000000000),
6375         UINT64_C(0x4000000000000000),
6376         UINT64_C(0x3fe0000000000000),
6377     };
6378 
6379     tcg_gen_movi_i64(arg[0].out, v[arg[1].imm % ARRAY_SIZE(v)]);
6380     if (arg[1].imm >= ARRAY_SIZE(v)) {
6381         qemu_log_mask(LOG_GUEST_ERROR,
6382                       "const.d f%d, #%d, immediate value is reserved\n",
6383                       arg[0].imm, arg[1].imm);
6384     }
6385 }
6386 
6387 static void translate_const_s(DisasContext *dc, const OpcodeArg arg[],
6388                               const uint32_t par[])
6389 {
6390     static const uint32_t v[] = {
6391         0x00000000,
6392         0x3f800000,
6393         0x40000000,
6394         0x3f000000,
6395     };
6396 
6397     if (arg[0].num_bits == 32) {
6398         tcg_gen_movi_i32(arg[0].out, v[arg[1].imm % ARRAY_SIZE(v)]);
6399     } else {
6400         tcg_gen_movi_i64(arg[0].out, v[arg[1].imm % ARRAY_SIZE(v)]);
6401     }
6402     if (arg[1].imm >= ARRAY_SIZE(v)) {
6403         qemu_log_mask(LOG_GUEST_ERROR,
6404                       "const.s f%d, #%d, immediate value is reserved\n",
6405                       arg[0].imm, arg[1].imm);
6406     }
6407 }
6408 
6409 static void translate_float_d(DisasContext *dc, const OpcodeArg arg[],
6410                               const uint32_t par[])
6411 {
6412     TCGv_i32 scale = tcg_constant_i32(-arg[2].imm);
6413 
6414     if (par[0]) {
6415         gen_helper_uitof_d(arg[0].out, cpu_env, arg[1].in, scale);
6416     } else {
6417         gen_helper_itof_d(arg[0].out, cpu_env, arg[1].in, scale);
6418     }
6419 }
6420 
6421 static void translate_float_s(DisasContext *dc, const OpcodeArg arg[],
6422                               const uint32_t par[])
6423 {
6424     TCGv_i32 scale = tcg_constant_i32(-arg[2].imm);
6425     OpcodeArg arg32[1];
6426 
6427     get_f32_o1(arg, arg32, 0);
6428     if (par[0]) {
6429         gen_helper_uitof_s(arg32[0].out, cpu_env, arg[1].in, scale);
6430     } else {
6431         gen_helper_itof_s(arg32[0].out, cpu_env, arg[1].in, scale);
6432     }
6433     put_f32_o1(arg, arg32, 0);
6434 }
6435 
6436 static void translate_ftoi_d(DisasContext *dc, const OpcodeArg arg[],
6437                              const uint32_t par[])
6438 {
6439     TCGv_i32 rounding_mode = tcg_constant_i32(par[0]);
6440     TCGv_i32 scale = tcg_constant_i32(arg[2].imm);
6441 
6442     if (par[1]) {
6443         gen_helper_ftoui_d(arg[0].out, cpu_env, arg[1].in,
6444                            rounding_mode, scale);
6445     } else {
6446         gen_helper_ftoi_d(arg[0].out, cpu_env, arg[1].in,
6447                           rounding_mode, scale);
6448     }
6449 }
6450 
6451 static void translate_ftoi_s(DisasContext *dc, const OpcodeArg arg[],
6452                              const uint32_t par[])
6453 {
6454     TCGv_i32 rounding_mode = tcg_constant_i32(par[0]);
6455     TCGv_i32 scale = tcg_constant_i32(arg[2].imm);
6456     OpcodeArg arg32[2];
6457 
6458     get_f32_i1(arg, arg32, 1);
6459     if (par[1]) {
6460         gen_helper_ftoui_s(arg[0].out, cpu_env, arg32[1].in,
6461                            rounding_mode, scale);
6462     } else {
6463         gen_helper_ftoi_s(arg[0].out, cpu_env, arg32[1].in,
6464                           rounding_mode, scale);
6465     }
6466     put_f32_i1(arg, arg32, 1);
6467 }
6468 
6469 static void translate_ldsti(DisasContext *dc, const OpcodeArg arg[],
6470                             const uint32_t par[])
6471 {
6472     TCGv_i32 addr = tcg_temp_new_i32();
6473     MemOp mop;
6474 
6475     tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm);
6476     mop = gen_load_store_alignment(dc, MO_TEUL, addr);
6477     if (par[0]) {
6478         tcg_gen_qemu_st_tl(arg[0].in, addr, dc->cring, mop);
6479     } else {
6480         tcg_gen_qemu_ld_tl(arg[0].out, addr, dc->cring, mop);
6481     }
6482     if (par[1]) {
6483         tcg_gen_mov_i32(arg[1].out, addr);
6484     }
6485 }
6486 
6487 static void translate_ldstx(DisasContext *dc, const OpcodeArg arg[],
6488                             const uint32_t par[])
6489 {
6490     TCGv_i32 addr = tcg_temp_new_i32();
6491     MemOp mop;
6492 
6493     tcg_gen_add_i32(addr, arg[1].in, arg[2].in);
6494     mop = gen_load_store_alignment(dc, MO_TEUL, addr);
6495     if (par[0]) {
6496         tcg_gen_qemu_st_tl(arg[0].in, addr, dc->cring, mop);
6497     } else {
6498         tcg_gen_qemu_ld_tl(arg[0].out, addr, dc->cring, mop);
6499     }
6500     if (par[1]) {
6501         tcg_gen_mov_i32(arg[1].out, addr);
6502     }
6503 }
6504 
6505 static void translate_fpu2k_madd_s(DisasContext *dc, const OpcodeArg arg[],
6506                                    const uint32_t par[])
6507 {
6508     gen_helper_fpu2k_madd_s(arg[0].out, cpu_env,
6509                             arg[0].in, arg[1].in, arg[2].in);
6510 }
6511 
6512 static void translate_mov_d(DisasContext *dc, const OpcodeArg arg[],
6513                                 const uint32_t par[])
6514 {
6515     tcg_gen_mov_i64(arg[0].out, arg[1].in);
6516 }
6517 
6518 static void translate_mov_s(DisasContext *dc, const OpcodeArg arg[],
6519                             const uint32_t par[])
6520 {
6521     if (arg[0].num_bits == 32) {
6522         tcg_gen_mov_i32(arg[0].out, arg[1].in);
6523     } else {
6524         tcg_gen_mov_i64(arg[0].out, arg[1].in);
6525     }
6526 }
6527 
6528 static void translate_movcond_d(DisasContext *dc, const OpcodeArg arg[],
6529                                 const uint32_t par[])
6530 {
6531     TCGv_i64 zero = tcg_constant_i64(0);
6532     TCGv_i64 arg2 = tcg_temp_new_i64();
6533 
6534     tcg_gen_ext_i32_i64(arg2, arg[2].in);
6535     tcg_gen_movcond_i64(par[0], arg[0].out,
6536                         arg2, zero,
6537                         arg[1].in, arg[0].in);
6538 }
6539 
6540 static void translate_movcond_s(DisasContext *dc, const OpcodeArg arg[],
6541                                 const uint32_t par[])
6542 {
6543     if (arg[0].num_bits == 32) {
6544         TCGv_i32 zero = tcg_constant_i32(0);
6545 
6546         tcg_gen_movcond_i32(par[0], arg[0].out,
6547                             arg[2].in, zero,
6548                             arg[1].in, arg[0].in);
6549     } else {
6550         translate_movcond_d(dc, arg, par);
6551     }
6552 }
6553 
6554 static void translate_movp_d(DisasContext *dc, const OpcodeArg arg[],
6555                              const uint32_t par[])
6556 {
6557     TCGv_i64 zero = tcg_constant_i64(0);
6558     TCGv_i32 tmp1 = tcg_temp_new_i32();
6559     TCGv_i64 tmp2 = tcg_temp_new_i64();
6560 
6561     tcg_gen_andi_i32(tmp1, arg[2].in, 1 << arg[2].imm);
6562     tcg_gen_extu_i32_i64(tmp2, tmp1);
6563     tcg_gen_movcond_i64(par[0],
6564                         arg[0].out, tmp2, zero,
6565                         arg[1].in, arg[0].in);
6566 }
6567 
6568 static void translate_movp_s(DisasContext *dc, const OpcodeArg arg[],
6569                              const uint32_t par[])
6570 {
6571     if (arg[0].num_bits == 32) {
6572         TCGv_i32 zero = tcg_constant_i32(0);
6573         TCGv_i32 tmp = tcg_temp_new_i32();
6574 
6575         tcg_gen_andi_i32(tmp, arg[2].in, 1 << arg[2].imm);
6576         tcg_gen_movcond_i32(par[0],
6577                             arg[0].out, tmp, zero,
6578                             arg[1].in, arg[0].in);
6579     } else {
6580         translate_movp_d(dc, arg, par);
6581     }
6582 }
6583 
6584 static void translate_fpu2k_mul_s(DisasContext *dc, const OpcodeArg arg[],
6585                                   const uint32_t par[])
6586 {
6587     gen_helper_fpu2k_mul_s(arg[0].out, cpu_env,
6588                            arg[1].in, arg[2].in);
6589 }
6590 
6591 static void translate_fpu2k_msub_s(DisasContext *dc, const OpcodeArg arg[],
6592                                    const uint32_t par[])
6593 {
6594     gen_helper_fpu2k_msub_s(arg[0].out, cpu_env,
6595                             arg[0].in, arg[1].in, arg[2].in);
6596 }
6597 
6598 static void translate_neg_d(DisasContext *dc, const OpcodeArg arg[],
6599                             const uint32_t par[])
6600 {
6601     gen_helper_neg_d(arg[0].out, arg[1].in);
6602 }
6603 
6604 static void translate_neg_s(DisasContext *dc, const OpcodeArg arg[],
6605                             const uint32_t par[])
6606 {
6607     OpcodeArg arg32[2];
6608 
6609     get_f32_o1_i1(arg, arg32, 0, 1);
6610     gen_helper_neg_s(arg32[0].out, arg32[1].in);
6611     put_f32_o1_i1(arg, arg32, 0, 1);
6612 }
6613 
6614 static void translate_rfr_d(DisasContext *dc, const OpcodeArg arg[],
6615                             const uint32_t par[])
6616 {
6617     tcg_gen_extrh_i64_i32(arg[0].out, arg[1].in);
6618 }
6619 
6620 static void translate_rfr_s(DisasContext *dc, const OpcodeArg arg[],
6621                             const uint32_t par[])
6622 {
6623     if (arg[1].num_bits == 32) {
6624         tcg_gen_mov_i32(arg[0].out, arg[1].in);
6625     } else {
6626         tcg_gen_extrl_i64_i32(arg[0].out, arg[1].in);
6627     }
6628 }
6629 
6630 static void translate_fpu2k_sub_s(DisasContext *dc, const OpcodeArg arg[],
6631                                   const uint32_t par[])
6632 {
6633     gen_helper_fpu2k_sub_s(arg[0].out, cpu_env,
6634                            arg[1].in, arg[2].in);
6635 }
6636 
6637 static void translate_wfr_d(DisasContext *dc, const OpcodeArg arg[],
6638                             const uint32_t par[])
6639 {
6640     tcg_gen_concat_i32_i64(arg[0].out, arg[2].in, arg[1].in);
6641 }
6642 
6643 static void translate_wfr_s(DisasContext *dc, const OpcodeArg arg[],
6644                             const uint32_t par[])
6645 {
6646     if (arg[0].num_bits == 32) {
6647         tcg_gen_mov_i32(arg[0].out, arg[1].in);
6648     } else {
6649         tcg_gen_ext_i32_i64(arg[0].out, arg[1].in);
6650     }
6651 }
6652 
6653 static void translate_wur_fpu2k_fcr(DisasContext *dc, const OpcodeArg arg[],
6654                                     const uint32_t par[])
6655 {
6656     gen_helper_wur_fpu2k_fcr(cpu_env, arg[0].in);
6657 }
6658 
6659 static void translate_wur_fpu2k_fsr(DisasContext *dc, const OpcodeArg arg[],
6660                                     const uint32_t par[])
6661 {
6662     tcg_gen_andi_i32(cpu_UR[par[0]], arg[0].in, 0xffffff80);
6663 }
6664 
6665 static const XtensaOpcodeOps fpu2000_ops[] = {
6666     {
6667         .name = "abs.s",
6668         .translate = translate_abs_s,
6669         .coprocessor = 0x1,
6670     }, {
6671         .name = "add.s",
6672         .translate = translate_fpu2k_add_s,
6673         .coprocessor = 0x1,
6674     }, {
6675         .name = "ceil.s",
6676         .translate = translate_ftoi_s,
6677         .par = (const uint32_t[]){float_round_up, false},
6678         .coprocessor = 0x1,
6679     }, {
6680         .name = "float.s",
6681         .translate = translate_float_s,
6682         .par = (const uint32_t[]){false},
6683         .coprocessor = 0x1,
6684     }, {
6685         .name = "floor.s",
6686         .translate = translate_ftoi_s,
6687         .par = (const uint32_t[]){float_round_down, false},
6688         .coprocessor = 0x1,
6689     }, {
6690         .name = "lsi",
6691         .translate = translate_ldsti,
6692         .par = (const uint32_t[]){false, false},
6693         .op_flags = XTENSA_OP_LOAD,
6694         .coprocessor = 0x1,
6695     }, {
6696         .name = "lsiu",
6697         .translate = translate_ldsti,
6698         .par = (const uint32_t[]){false, true},
6699         .op_flags = XTENSA_OP_LOAD,
6700         .coprocessor = 0x1,
6701     }, {
6702         .name = "lsx",
6703         .translate = translate_ldstx,
6704         .par = (const uint32_t[]){false, false},
6705         .op_flags = XTENSA_OP_LOAD,
6706         .coprocessor = 0x1,
6707     }, {
6708         .name = "lsxu",
6709         .translate = translate_ldstx,
6710         .par = (const uint32_t[]){false, true},
6711         .op_flags = XTENSA_OP_LOAD,
6712         .coprocessor = 0x1,
6713     }, {
6714         .name = "madd.s",
6715         .translate = translate_fpu2k_madd_s,
6716         .coprocessor = 0x1,
6717     }, {
6718         .name = "mov.s",
6719         .translate = translate_mov_s,
6720         .coprocessor = 0x1,
6721     }, {
6722         .name = "moveqz.s",
6723         .translate = translate_movcond_s,
6724         .par = (const uint32_t[]){TCG_COND_EQ},
6725         .coprocessor = 0x1,
6726     }, {
6727         .name = "movf.s",
6728         .translate = translate_movp_s,
6729         .par = (const uint32_t[]){TCG_COND_EQ},
6730         .coprocessor = 0x1,
6731     }, {
6732         .name = "movgez.s",
6733         .translate = translate_movcond_s,
6734         .par = (const uint32_t[]){TCG_COND_GE},
6735         .coprocessor = 0x1,
6736     }, {
6737         .name = "movltz.s",
6738         .translate = translate_movcond_s,
6739         .par = (const uint32_t[]){TCG_COND_LT},
6740         .coprocessor = 0x1,
6741     }, {
6742         .name = "movnez.s",
6743         .translate = translate_movcond_s,
6744         .par = (const uint32_t[]){TCG_COND_NE},
6745         .coprocessor = 0x1,
6746     }, {
6747         .name = "movt.s",
6748         .translate = translate_movp_s,
6749         .par = (const uint32_t[]){TCG_COND_NE},
6750         .coprocessor = 0x1,
6751     }, {
6752         .name = "msub.s",
6753         .translate = translate_fpu2k_msub_s,
6754         .coprocessor = 0x1,
6755     }, {
6756         .name = "mul.s",
6757         .translate = translate_fpu2k_mul_s,
6758         .coprocessor = 0x1,
6759     }, {
6760         .name = "neg.s",
6761         .translate = translate_neg_s,
6762         .coprocessor = 0x1,
6763     }, {
6764         .name = "oeq.s",
6765         .translate = translate_compare_s,
6766         .par = (const uint32_t[]){COMPARE_OEQ},
6767         .coprocessor = 0x1,
6768     }, {
6769         .name = "ole.s",
6770         .translate = translate_compare_s,
6771         .par = (const uint32_t[]){COMPARE_OLE},
6772         .coprocessor = 0x1,
6773     }, {
6774         .name = "olt.s",
6775         .translate = translate_compare_s,
6776         .par = (const uint32_t[]){COMPARE_OLT},
6777         .coprocessor = 0x1,
6778     }, {
6779         .name = "rfr",
6780         .translate = translate_rfr_s,
6781         .coprocessor = 0x1,
6782     }, {
6783         .name = "round.s",
6784         .translate = translate_ftoi_s,
6785         .par = (const uint32_t[]){float_round_nearest_even, false},
6786         .coprocessor = 0x1,
6787     }, {
6788         .name = "rur.fcr",
6789         .translate = translate_rur,
6790         .par = (const uint32_t[]){FCR},
6791         .coprocessor = 0x1,
6792     }, {
6793         .name = "rur.fsr",
6794         .translate = translate_rur,
6795         .par = (const uint32_t[]){FSR},
6796         .coprocessor = 0x1,
6797     }, {
6798         .name = "ssi",
6799         .translate = translate_ldsti,
6800         .par = (const uint32_t[]){true, false},
6801         .op_flags = XTENSA_OP_STORE,
6802         .coprocessor = 0x1,
6803     }, {
6804         .name = "ssiu",
6805         .translate = translate_ldsti,
6806         .par = (const uint32_t[]){true, true},
6807         .op_flags = XTENSA_OP_STORE,
6808         .coprocessor = 0x1,
6809     }, {
6810         .name = "ssx",
6811         .translate = translate_ldstx,
6812         .par = (const uint32_t[]){true, false},
6813         .op_flags = XTENSA_OP_STORE,
6814         .coprocessor = 0x1,
6815     }, {
6816         .name = "ssxu",
6817         .translate = translate_ldstx,
6818         .par = (const uint32_t[]){true, true},
6819         .op_flags = XTENSA_OP_STORE,
6820         .coprocessor = 0x1,
6821     }, {
6822         .name = "sub.s",
6823         .translate = translate_fpu2k_sub_s,
6824         .coprocessor = 0x1,
6825     }, {
6826         .name = "trunc.s",
6827         .translate = translate_ftoi_s,
6828         .par = (const uint32_t[]){float_round_to_zero, false},
6829         .coprocessor = 0x1,
6830     }, {
6831         .name = "ueq.s",
6832         .translate = translate_compare_s,
6833         .par = (const uint32_t[]){COMPARE_UEQ},
6834         .coprocessor = 0x1,
6835     }, {
6836         .name = "ufloat.s",
6837         .translate = translate_float_s,
6838         .par = (const uint32_t[]){true},
6839         .coprocessor = 0x1,
6840     }, {
6841         .name = "ule.s",
6842         .translate = translate_compare_s,
6843         .par = (const uint32_t[]){COMPARE_ULE},
6844         .coprocessor = 0x1,
6845     }, {
6846         .name = "ult.s",
6847         .translate = translate_compare_s,
6848         .par = (const uint32_t[]){COMPARE_ULT},
6849         .coprocessor = 0x1,
6850     }, {
6851         .name = "un.s",
6852         .translate = translate_compare_s,
6853         .par = (const uint32_t[]){COMPARE_UN},
6854         .coprocessor = 0x1,
6855     }, {
6856         .name = "utrunc.s",
6857         .translate = translate_ftoi_s,
6858         .par = (const uint32_t[]){float_round_to_zero, true},
6859         .coprocessor = 0x1,
6860     }, {
6861         .name = "wfr",
6862         .translate = translate_wfr_s,
6863         .coprocessor = 0x1,
6864     }, {
6865         .name = "wur.fcr",
6866         .translate = translate_wur_fpu2k_fcr,
6867         .par = (const uint32_t[]){FCR},
6868         .coprocessor = 0x1,
6869     }, {
6870         .name = "wur.fsr",
6871         .translate = translate_wur_fpu2k_fsr,
6872         .par = (const uint32_t[]){FSR},
6873         .coprocessor = 0x1,
6874     },
6875 };
6876 
6877 const XtensaOpcodeTranslators xtensa_fpu2000_opcodes = {
6878     .num_opcodes = ARRAY_SIZE(fpu2000_ops),
6879     .opcode = fpu2000_ops,
6880 };
6881 
6882 static void translate_add_d(DisasContext *dc, const OpcodeArg arg[],
6883                             const uint32_t par[])
6884 {
6885     gen_helper_add_d(arg[0].out, cpu_env, arg[1].in, arg[2].in);
6886 }
6887 
6888 static void translate_add_s(DisasContext *dc, const OpcodeArg arg[],
6889                                 const uint32_t par[])
6890 {
6891     if (option_enabled(dc, XTENSA_OPTION_DFPU_SINGLE_ONLY)) {
6892         gen_helper_fpu2k_add_s(arg[0].out, cpu_env,
6893                                arg[1].in, arg[2].in);
6894     } else {
6895         OpcodeArg arg32[3];
6896 
6897         get_f32_o1_i2(arg, arg32, 0, 1, 2);
6898         gen_helper_add_s(arg32[0].out, cpu_env, arg32[1].in, arg32[2].in);
6899         put_f32_o1_i2(arg, arg32, 0, 1, 2);
6900     }
6901 }
6902 
6903 static void translate_cvtd_s(DisasContext *dc, const OpcodeArg arg[],
6904                              const uint32_t par[])
6905 {
6906     TCGv_i32 v = tcg_temp_new_i32();
6907 
6908     tcg_gen_extrl_i64_i32(v, arg[1].in);
6909     gen_helper_cvtd_s(arg[0].out, cpu_env, v);
6910 }
6911 
6912 static void translate_cvts_d(DisasContext *dc, const OpcodeArg arg[],
6913                              const uint32_t par[])
6914 {
6915     TCGv_i32 v = tcg_temp_new_i32();
6916 
6917     gen_helper_cvts_d(v, cpu_env, arg[1].in);
6918     tcg_gen_extu_i32_i64(arg[0].out, v);
6919 }
6920 
6921 static void translate_ldsti_d(DisasContext *dc, const OpcodeArg arg[],
6922                               const uint32_t par[])
6923 {
6924     TCGv_i32 addr;
6925     MemOp mop;
6926 
6927     if (par[1]) {
6928         addr = tcg_temp_new_i32();
6929         tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm);
6930     } else {
6931         addr = arg[1].in;
6932     }
6933     mop = gen_load_store_alignment(dc, MO_TEUQ, addr);
6934     if (par[0]) {
6935         tcg_gen_qemu_st_i64(arg[0].in, addr, dc->cring, mop);
6936     } else {
6937         tcg_gen_qemu_ld_i64(arg[0].out, addr, dc->cring, mop);
6938     }
6939     if (par[2]) {
6940         if (par[1]) {
6941             tcg_gen_mov_i32(arg[1].out, addr);
6942         } else {
6943             tcg_gen_addi_i32(arg[1].out, arg[1].in, arg[2].imm);
6944         }
6945     }
6946 }
6947 
6948 static void translate_ldsti_s(DisasContext *dc, const OpcodeArg arg[],
6949                               const uint32_t par[])
6950 {
6951     TCGv_i32 addr;
6952     OpcodeArg arg32[1];
6953     MemOp mop;
6954 
6955     if (par[1]) {
6956         addr = tcg_temp_new_i32();
6957         tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm);
6958     } else {
6959         addr = arg[1].in;
6960     }
6961     mop = gen_load_store_alignment(dc, MO_TEUL, addr);
6962     if (par[0]) {
6963         get_f32_i1(arg, arg32, 0);
6964         tcg_gen_qemu_st_tl(arg32[0].in, addr, dc->cring, mop);
6965         put_f32_i1(arg, arg32, 0);
6966     } else {
6967         get_f32_o1(arg, arg32, 0);
6968         tcg_gen_qemu_ld_tl(arg32[0].out, addr, dc->cring, mop);
6969         put_f32_o1(arg, arg32, 0);
6970     }
6971     if (par[2]) {
6972         if (par[1]) {
6973             tcg_gen_mov_i32(arg[1].out, addr);
6974         } else {
6975             tcg_gen_addi_i32(arg[1].out, arg[1].in, arg[2].imm);
6976         }
6977     }
6978 }
6979 
6980 static void translate_ldstx_d(DisasContext *dc, const OpcodeArg arg[],
6981                               const uint32_t par[])
6982 {
6983     TCGv_i32 addr;
6984     MemOp mop;
6985 
6986     if (par[1]) {
6987         addr = tcg_temp_new_i32();
6988         tcg_gen_add_i32(addr, arg[1].in, arg[2].in);
6989     } else {
6990         addr = arg[1].in;
6991     }
6992     mop = gen_load_store_alignment(dc, MO_TEUQ, addr);
6993     if (par[0]) {
6994         tcg_gen_qemu_st_i64(arg[0].in, addr, dc->cring, mop);
6995     } else {
6996         tcg_gen_qemu_ld_i64(arg[0].out, addr, dc->cring, mop);
6997     }
6998     if (par[2]) {
6999         if (par[1]) {
7000             tcg_gen_mov_i32(arg[1].out, addr);
7001         } else {
7002             tcg_gen_add_i32(arg[1].out, arg[1].in, arg[2].in);
7003         }
7004     }
7005 }
7006 
7007 static void translate_ldstx_s(DisasContext *dc, const OpcodeArg arg[],
7008                               const uint32_t par[])
7009 {
7010     TCGv_i32 addr;
7011     OpcodeArg arg32[1];
7012     MemOp mop;
7013 
7014     if (par[1]) {
7015         addr = tcg_temp_new_i32();
7016         tcg_gen_add_i32(addr, arg[1].in, arg[2].in);
7017     } else {
7018         addr = arg[1].in;
7019     }
7020     mop = gen_load_store_alignment(dc, MO_TEUL, addr);
7021     if (par[0]) {
7022         get_f32_i1(arg, arg32, 0);
7023         tcg_gen_qemu_st_tl(arg32[0].in, addr, dc->cring, mop);
7024         put_f32_i1(arg, arg32, 0);
7025     } else {
7026         get_f32_o1(arg, arg32, 0);
7027         tcg_gen_qemu_ld_tl(arg32[0].out, addr, dc->cring, mop);
7028         put_f32_o1(arg, arg32, 0);
7029     }
7030     if (par[2]) {
7031         if (par[1]) {
7032             tcg_gen_mov_i32(arg[1].out, addr);
7033         } else {
7034             tcg_gen_add_i32(arg[1].out, arg[1].in, arg[2].in);
7035         }
7036     }
7037 }
7038 
7039 static void translate_madd_d(DisasContext *dc, const OpcodeArg arg[],
7040                              const uint32_t par[])
7041 {
7042     gen_helper_madd_d(arg[0].out, cpu_env,
7043                       arg[0].in, arg[1].in, arg[2].in);
7044 }
7045 
7046 static void translate_madd_s(DisasContext *dc, const OpcodeArg arg[],
7047                              const uint32_t par[])
7048 {
7049     if (option_enabled(dc, XTENSA_OPTION_DFPU_SINGLE_ONLY)) {
7050         gen_helper_fpu2k_madd_s(arg[0].out, cpu_env,
7051                                 arg[0].in, arg[1].in, arg[2].in);
7052     } else {
7053         OpcodeArg arg32[3];
7054 
7055         get_f32_o1_i3(arg, arg32, 0, 0, 1, 2);
7056         gen_helper_madd_s(arg32[0].out, cpu_env,
7057                           arg32[0].in, arg32[1].in, arg32[2].in);
7058         put_f32_o1_i3(arg, arg32, 0, 0, 1, 2);
7059     }
7060 }
7061 
7062 static void translate_mul_d(DisasContext *dc, const OpcodeArg arg[],
7063                             const uint32_t par[])
7064 {
7065     gen_helper_mul_d(arg[0].out, cpu_env, arg[1].in, arg[2].in);
7066 }
7067 
7068 static void translate_mul_s(DisasContext *dc, const OpcodeArg arg[],
7069                             const uint32_t par[])
7070 {
7071     if (option_enabled(dc, XTENSA_OPTION_DFPU_SINGLE_ONLY)) {
7072         gen_helper_fpu2k_mul_s(arg[0].out, cpu_env,
7073                                arg[1].in, arg[2].in);
7074     } else {
7075         OpcodeArg arg32[3];
7076 
7077         get_f32_o1_i2(arg, arg32, 0, 1, 2);
7078         gen_helper_mul_s(arg32[0].out, cpu_env, arg32[1].in, arg32[2].in);
7079         put_f32_o1_i2(arg, arg32, 0, 1, 2);
7080     }
7081 }
7082 
7083 static void translate_msub_d(DisasContext *dc, const OpcodeArg arg[],
7084                              const uint32_t par[])
7085 {
7086     gen_helper_msub_d(arg[0].out, cpu_env,
7087                       arg[0].in, arg[1].in, arg[2].in);
7088 }
7089 
7090 static void translate_msub_s(DisasContext *dc, const OpcodeArg arg[],
7091                              const uint32_t par[])
7092 {
7093     if (option_enabled(dc, XTENSA_OPTION_DFPU_SINGLE_ONLY)) {
7094         gen_helper_fpu2k_msub_s(arg[0].out, cpu_env,
7095                                 arg[0].in, arg[1].in, arg[2].in);
7096     } else {
7097         OpcodeArg arg32[3];
7098 
7099         get_f32_o1_i3(arg, arg32, 0, 0, 1, 2);
7100         gen_helper_msub_s(arg32[0].out, cpu_env,
7101                           arg32[0].in, arg32[1].in, arg32[2].in);
7102         put_f32_o1_i3(arg, arg32, 0, 0, 1, 2);
7103     }
7104 }
7105 
7106 static void translate_sub_d(DisasContext *dc, const OpcodeArg arg[],
7107                             const uint32_t par[])
7108 {
7109     gen_helper_sub_d(arg[0].out, cpu_env, arg[1].in, arg[2].in);
7110 }
7111 
7112 static void translate_sub_s(DisasContext *dc, const OpcodeArg arg[],
7113                             const uint32_t par[])
7114 {
7115     if (option_enabled(dc, XTENSA_OPTION_DFPU_SINGLE_ONLY)) {
7116         gen_helper_fpu2k_sub_s(arg[0].out, cpu_env,
7117                                arg[1].in, arg[2].in);
7118     } else {
7119         OpcodeArg arg32[3];
7120 
7121         get_f32_o1_i2(arg, arg32, 0, 1, 2);
7122         gen_helper_sub_s(arg32[0].out, cpu_env, arg32[1].in, arg32[2].in);
7123         put_f32_o1_i2(arg, arg32, 0, 1, 2);
7124     }
7125 }
7126 
7127 static void translate_mkdadj_d(DisasContext *dc, const OpcodeArg arg[],
7128                                const uint32_t par[])
7129 {
7130     gen_helper_mkdadj_d(arg[0].out, cpu_env, arg[0].in, arg[1].in);
7131 }
7132 
7133 static void translate_mkdadj_s(DisasContext *dc, const OpcodeArg arg[],
7134                                const uint32_t par[])
7135 {
7136     OpcodeArg arg32[2];
7137 
7138     get_f32_o1_i2(arg, arg32, 0, 0, 1);
7139     gen_helper_mkdadj_s(arg32[0].out, cpu_env, arg32[0].in, arg32[1].in);
7140     put_f32_o1_i2(arg, arg32, 0, 0, 1);
7141 }
7142 
7143 static void translate_mksadj_d(DisasContext *dc, const OpcodeArg arg[],
7144                                const uint32_t par[])
7145 {
7146     gen_helper_mksadj_d(arg[0].out, cpu_env, arg[1].in);
7147 }
7148 
7149 static void translate_mksadj_s(DisasContext *dc, const OpcodeArg arg[],
7150                                const uint32_t par[])
7151 {
7152     OpcodeArg arg32[2];
7153 
7154     get_f32_o1_i1(arg, arg32, 0, 1);
7155     gen_helper_mksadj_s(arg32[0].out, cpu_env, arg32[1].in);
7156     put_f32_o1_i1(arg, arg32, 0, 1);
7157 }
7158 
7159 static void translate_wur_fpu_fcr(DisasContext *dc, const OpcodeArg arg[],
7160                                   const uint32_t par[])
7161 {
7162     gen_helper_wur_fpu_fcr(cpu_env, arg[0].in);
7163 }
7164 
7165 static void translate_rur_fpu_fsr(DisasContext *dc, const OpcodeArg arg[],
7166                                   const uint32_t par[])
7167 {
7168     gen_helper_rur_fpu_fsr(arg[0].out, cpu_env);
7169 }
7170 
7171 static void translate_wur_fpu_fsr(DisasContext *dc, const OpcodeArg arg[],
7172                                   const uint32_t par[])
7173 {
7174     gen_helper_wur_fpu_fsr(cpu_env, arg[0].in);
7175 }
7176 
7177 static const XtensaOpcodeOps fpu_ops[] = {
7178     {
7179         .name = "abs.d",
7180         .translate = translate_abs_d,
7181         .coprocessor = 0x1,
7182     }, {
7183         .name = "abs.s",
7184         .translate = translate_abs_s,
7185         .coprocessor = 0x1,
7186     }, {
7187         .name = "add.d",
7188         .translate = translate_add_d,
7189         .coprocessor = 0x1,
7190     }, {
7191         .name = "add.s",
7192         .translate = translate_add_s,
7193         .coprocessor = 0x1,
7194     }, {
7195         .name = "addexp.d",
7196         .translate = translate_nop,
7197         .coprocessor = 0x1,
7198     }, {
7199         .name = "addexp.s",
7200         .translate = translate_nop,
7201         .coprocessor = 0x1,
7202     }, {
7203         .name = "addexpm.d",
7204         .translate = translate_mov_s,
7205         .coprocessor = 0x1,
7206     }, {
7207         .name = "addexpm.s",
7208         .translate = translate_mov_s,
7209         .coprocessor = 0x1,
7210     }, {
7211         .name = "ceil.d",
7212         .translate = translate_ftoi_d,
7213         .par = (const uint32_t[]){float_round_up, false},
7214         .coprocessor = 0x1,
7215     }, {
7216         .name = "ceil.s",
7217         .translate = translate_ftoi_s,
7218         .par = (const uint32_t[]){float_round_up, false},
7219         .coprocessor = 0x1,
7220     }, {
7221         .name = "const.d",
7222         .translate = translate_const_d,
7223         .coprocessor = 0x1,
7224     }, {
7225         .name = "const.s",
7226         .translate = translate_const_s,
7227         .coprocessor = 0x1,
7228     }, {
7229         .name = "cvtd.s",
7230         .translate = translate_cvtd_s,
7231         .coprocessor = 0x1,
7232     }, {
7233         .name = "cvts.d",
7234         .translate = translate_cvts_d,
7235         .coprocessor = 0x1,
7236     }, {
7237         .name = "div0.d",
7238         .translate = translate_nop,
7239         .coprocessor = 0x1,
7240     }, {
7241         .name = "div0.s",
7242         .translate = translate_nop,
7243         .coprocessor = 0x1,
7244     }, {
7245         .name = "divn.d",
7246         .translate = translate_nop,
7247         .coprocessor = 0x1,
7248     }, {
7249         .name = "divn.s",
7250         .translate = translate_nop,
7251         .coprocessor = 0x1,
7252     }, {
7253         .name = "float.d",
7254         .translate = translate_float_d,
7255         .par = (const uint32_t[]){false},
7256         .coprocessor = 0x1,
7257     }, {
7258         .name = "float.s",
7259         .translate = translate_float_s,
7260         .par = (const uint32_t[]){false},
7261         .coprocessor = 0x1,
7262     }, {
7263         .name = "floor.d",
7264         .translate = translate_ftoi_d,
7265         .par = (const uint32_t[]){float_round_down, false},
7266         .coprocessor = 0x1,
7267     }, {
7268         .name = "floor.s",
7269         .translate = translate_ftoi_s,
7270         .par = (const uint32_t[]){float_round_down, false},
7271         .coprocessor = 0x1,
7272     }, {
7273         .name = "ldi",
7274         .translate = translate_ldsti_d,
7275         .par = (const uint32_t[]){false, true, false},
7276         .op_flags = XTENSA_OP_LOAD,
7277         .coprocessor = 0x1,
7278     }, {
7279         .name = "ldip",
7280         .translate = translate_ldsti_d,
7281         .par = (const uint32_t[]){false, false, true},
7282         .op_flags = XTENSA_OP_LOAD,
7283         .coprocessor = 0x1,
7284     }, {
7285         .name = "ldiu",
7286         .translate = translate_ldsti_d,
7287         .par = (const uint32_t[]){false, true, true},
7288         .op_flags = XTENSA_OP_LOAD,
7289         .coprocessor = 0x1,
7290     }, {
7291         .name = "ldx",
7292         .translate = translate_ldstx_d,
7293         .par = (const uint32_t[]){false, true, false},
7294         .op_flags = XTENSA_OP_LOAD,
7295         .coprocessor = 0x1,
7296     }, {
7297         .name = "ldxp",
7298         .translate = translate_ldstx_d,
7299         .par = (const uint32_t[]){false, false, true},
7300         .op_flags = XTENSA_OP_LOAD,
7301         .coprocessor = 0x1,
7302     }, {
7303         .name = "ldxu",
7304         .translate = translate_ldstx_d,
7305         .par = (const uint32_t[]){false, true, true},
7306         .op_flags = XTENSA_OP_LOAD,
7307         .coprocessor = 0x1,
7308     }, {
7309         .name = "lsi",
7310         .translate = translate_ldsti_s,
7311         .par = (const uint32_t[]){false, true, false},
7312         .op_flags = XTENSA_OP_LOAD,
7313         .coprocessor = 0x1,
7314     }, {
7315         .name = "lsip",
7316         .translate = translate_ldsti_s,
7317         .par = (const uint32_t[]){false, false, true},
7318         .op_flags = XTENSA_OP_LOAD,
7319         .coprocessor = 0x1,
7320     }, {
7321         .name = "lsiu",
7322         .translate = translate_ldsti_s,
7323         .par = (const uint32_t[]){false, true, true},
7324         .op_flags = XTENSA_OP_LOAD,
7325         .coprocessor = 0x1,
7326     }, {
7327         .name = "lsx",
7328         .translate = translate_ldstx_s,
7329         .par = (const uint32_t[]){false, true, false},
7330         .op_flags = XTENSA_OP_LOAD,
7331         .coprocessor = 0x1,
7332     }, {
7333         .name = "lsxp",
7334         .translate = translate_ldstx_s,
7335         .par = (const uint32_t[]){false, false, true},
7336         .op_flags = XTENSA_OP_LOAD,
7337         .coprocessor = 0x1,
7338     }, {
7339         .name = "lsxu",
7340         .translate = translate_ldstx_s,
7341         .par = (const uint32_t[]){false, true, true},
7342         .op_flags = XTENSA_OP_LOAD,
7343         .coprocessor = 0x1,
7344     }, {
7345         .name = "madd.d",
7346         .translate = translate_madd_d,
7347         .coprocessor = 0x1,
7348     }, {
7349         .name = "madd.s",
7350         .translate = translate_madd_s,
7351         .coprocessor = 0x1,
7352     }, {
7353         .name = "maddn.d",
7354         .translate = translate_nop,
7355         .coprocessor = 0x1,
7356     }, {
7357         .name = "maddn.s",
7358         .translate = translate_nop,
7359         .coprocessor = 0x1,
7360     }, {
7361         .name = "mkdadj.d",
7362         .translate = translate_mkdadj_d,
7363         .coprocessor = 0x1,
7364     }, {
7365         .name = "mkdadj.s",
7366         .translate = translate_mkdadj_s,
7367         .coprocessor = 0x1,
7368     }, {
7369         .name = "mksadj.d",
7370         .translate = translate_mksadj_d,
7371         .coprocessor = 0x1,
7372     }, {
7373         .name = "mksadj.s",
7374         .translate = translate_mksadj_s,
7375         .coprocessor = 0x1,
7376     }, {
7377         .name = "mov.d",
7378         .translate = translate_mov_d,
7379         .coprocessor = 0x1,
7380     }, {
7381         .name = "mov.s",
7382         .translate = translate_mov_s,
7383         .coprocessor = 0x1,
7384     }, {
7385         .name = "moveqz.d",
7386         .translate = translate_movcond_d,
7387         .par = (const uint32_t[]){TCG_COND_EQ},
7388         .coprocessor = 0x1,
7389     }, {
7390         .name = "moveqz.s",
7391         .translate = translate_movcond_s,
7392         .par = (const uint32_t[]){TCG_COND_EQ},
7393         .coprocessor = 0x1,
7394     }, {
7395         .name = "movf.d",
7396         .translate = translate_movp_d,
7397         .par = (const uint32_t[]){TCG_COND_EQ},
7398         .coprocessor = 0x1,
7399     }, {
7400         .name = "movf.s",
7401         .translate = translate_movp_s,
7402         .par = (const uint32_t[]){TCG_COND_EQ},
7403         .coprocessor = 0x1,
7404     }, {
7405         .name = "movgez.d",
7406         .translate = translate_movcond_d,
7407         .par = (const uint32_t[]){TCG_COND_GE},
7408         .coprocessor = 0x1,
7409     }, {
7410         .name = "movgez.s",
7411         .translate = translate_movcond_s,
7412         .par = (const uint32_t[]){TCG_COND_GE},
7413         .coprocessor = 0x1,
7414     }, {
7415         .name = "movltz.d",
7416         .translate = translate_movcond_d,
7417         .par = (const uint32_t[]){TCG_COND_LT},
7418         .coprocessor = 0x1,
7419     }, {
7420         .name = "movltz.s",
7421         .translate = translate_movcond_s,
7422         .par = (const uint32_t[]){TCG_COND_LT},
7423         .coprocessor = 0x1,
7424     }, {
7425         .name = "movnez.d",
7426         .translate = translate_movcond_d,
7427         .par = (const uint32_t[]){TCG_COND_NE},
7428         .coprocessor = 0x1,
7429     }, {
7430         .name = "movnez.s",
7431         .translate = translate_movcond_s,
7432         .par = (const uint32_t[]){TCG_COND_NE},
7433         .coprocessor = 0x1,
7434     }, {
7435         .name = "movt.d",
7436         .translate = translate_movp_d,
7437         .par = (const uint32_t[]){TCG_COND_NE},
7438         .coprocessor = 0x1,
7439     }, {
7440         .name = "movt.s",
7441         .translate = translate_movp_s,
7442         .par = (const uint32_t[]){TCG_COND_NE},
7443         .coprocessor = 0x1,
7444     }, {
7445         .name = "msub.d",
7446         .translate = translate_msub_d,
7447         .coprocessor = 0x1,
7448     }, {
7449         .name = "msub.s",
7450         .translate = translate_msub_s,
7451         .coprocessor = 0x1,
7452     }, {
7453         .name = "mul.d",
7454         .translate = translate_mul_d,
7455         .coprocessor = 0x1,
7456     }, {
7457         .name = "mul.s",
7458         .translate = translate_mul_s,
7459         .coprocessor = 0x1,
7460     }, {
7461         .name = "neg.d",
7462         .translate = translate_neg_d,
7463         .coprocessor = 0x1,
7464     }, {
7465         .name = "neg.s",
7466         .translate = translate_neg_s,
7467         .coprocessor = 0x1,
7468     }, {
7469         .name = "nexp01.d",
7470         .translate = translate_nop,
7471         .coprocessor = 0x1,
7472     }, {
7473         .name = "nexp01.s",
7474         .translate = translate_nop,
7475         .coprocessor = 0x1,
7476     }, {
7477         .name = "oeq.d",
7478         .translate = translate_compare_d,
7479         .par = (const uint32_t[]){COMPARE_OEQ},
7480         .coprocessor = 0x1,
7481     }, {
7482         .name = "oeq.s",
7483         .translate = translate_compare_s,
7484         .par = (const uint32_t[]){COMPARE_OEQ},
7485         .coprocessor = 0x1,
7486     }, {
7487         .name = "ole.d",
7488         .translate = translate_compare_d,
7489         .par = (const uint32_t[]){COMPARE_OLE},
7490         .coprocessor = 0x1,
7491     }, {
7492         .name = "ole.s",
7493         .translate = translate_compare_s,
7494         .par = (const uint32_t[]){COMPARE_OLE},
7495         .coprocessor = 0x1,
7496     }, {
7497         .name = "olt.d",
7498         .translate = translate_compare_d,
7499         .par = (const uint32_t[]){COMPARE_OLT},
7500         .coprocessor = 0x1,
7501     }, {
7502         .name = "olt.s",
7503         .translate = translate_compare_s,
7504         .par = (const uint32_t[]){COMPARE_OLT},
7505         .coprocessor = 0x1,
7506     }, {
7507         .name = "rfr",
7508         .translate = translate_rfr_s,
7509         .coprocessor = 0x1,
7510     }, {
7511         .name = "rfrd",
7512         .translate = translate_rfr_d,
7513         .coprocessor = 0x1,
7514     }, {
7515         .name = "round.d",
7516         .translate = translate_ftoi_d,
7517         .par = (const uint32_t[]){float_round_nearest_even, false},
7518         .coprocessor = 0x1,
7519     }, {
7520         .name = "round.s",
7521         .translate = translate_ftoi_s,
7522         .par = (const uint32_t[]){float_round_nearest_even, false},
7523         .coprocessor = 0x1,
7524     }, {
7525         .name = "rur.fcr",
7526         .translate = translate_rur,
7527         .par = (const uint32_t[]){FCR},
7528         .coprocessor = 0x1,
7529     }, {
7530         .name = "rur.fsr",
7531         .translate = translate_rur_fpu_fsr,
7532         .coprocessor = 0x1,
7533     }, {
7534         .name = "sdi",
7535         .translate = translate_ldsti_d,
7536         .par = (const uint32_t[]){true, true, false},
7537         .op_flags = XTENSA_OP_STORE,
7538         .coprocessor = 0x1,
7539     }, {
7540         .name = "sdip",
7541         .translate = translate_ldsti_d,
7542         .par = (const uint32_t[]){true, false, true},
7543         .op_flags = XTENSA_OP_STORE,
7544         .coprocessor = 0x1,
7545     }, {
7546         .name = "sdiu",
7547         .translate = translate_ldsti_d,
7548         .par = (const uint32_t[]){true, true, true},
7549         .op_flags = XTENSA_OP_STORE,
7550         .coprocessor = 0x1,
7551     }, {
7552         .name = "sdx",
7553         .translate = translate_ldstx_d,
7554         .par = (const uint32_t[]){true, true, false},
7555         .op_flags = XTENSA_OP_STORE,
7556         .coprocessor = 0x1,
7557     }, {
7558         .name = "sdxp",
7559         .translate = translate_ldstx_d,
7560         .par = (const uint32_t[]){true, false, true},
7561         .op_flags = XTENSA_OP_STORE,
7562         .coprocessor = 0x1,
7563     }, {
7564         .name = "sdxu",
7565         .translate = translate_ldstx_d,
7566         .par = (const uint32_t[]){true, true, true},
7567         .op_flags = XTENSA_OP_STORE,
7568         .coprocessor = 0x1,
7569     }, {
7570         .name = "sqrt0.d",
7571         .translate = translate_nop,
7572         .coprocessor = 0x1,
7573     }, {
7574         .name = "sqrt0.s",
7575         .translate = translate_nop,
7576         .coprocessor = 0x1,
7577     }, {
7578         .name = "ssi",
7579         .translate = translate_ldsti_s,
7580         .par = (const uint32_t[]){true, true, false},
7581         .op_flags = XTENSA_OP_STORE,
7582         .coprocessor = 0x1,
7583     }, {
7584         .name = "ssip",
7585         .translate = translate_ldsti_s,
7586         .par = (const uint32_t[]){true, false, true},
7587         .op_flags = XTENSA_OP_STORE,
7588         .coprocessor = 0x1,
7589     }, {
7590         .name = "ssiu",
7591         .translate = translate_ldsti_s,
7592         .par = (const uint32_t[]){true, true, true},
7593         .op_flags = XTENSA_OP_STORE,
7594         .coprocessor = 0x1,
7595     }, {
7596         .name = "ssx",
7597         .translate = translate_ldstx_s,
7598         .par = (const uint32_t[]){true, true, false},
7599         .op_flags = XTENSA_OP_STORE,
7600         .coprocessor = 0x1,
7601     }, {
7602         .name = "ssxp",
7603         .translate = translate_ldstx_s,
7604         .par = (const uint32_t[]){true, false, true},
7605         .op_flags = XTENSA_OP_STORE,
7606         .coprocessor = 0x1,
7607     }, {
7608         .name = "ssxu",
7609         .translate = translate_ldstx_s,
7610         .par = (const uint32_t[]){true, true, true},
7611         .op_flags = XTENSA_OP_STORE,
7612         .coprocessor = 0x1,
7613     }, {
7614         .name = "sub.d",
7615         .translate = translate_sub_d,
7616         .coprocessor = 0x1,
7617     }, {
7618         .name = "sub.s",
7619         .translate = translate_sub_s,
7620         .coprocessor = 0x1,
7621     }, {
7622         .name = "trunc.d",
7623         .translate = translate_ftoi_d,
7624         .par = (const uint32_t[]){float_round_to_zero, false},
7625         .coprocessor = 0x1,
7626     }, {
7627         .name = "trunc.s",
7628         .translate = translate_ftoi_s,
7629         .par = (const uint32_t[]){float_round_to_zero, false},
7630         .coprocessor = 0x1,
7631     }, {
7632         .name = "ueq.d",
7633         .translate = translate_compare_d,
7634         .par = (const uint32_t[]){COMPARE_UEQ},
7635         .coprocessor = 0x1,
7636     }, {
7637         .name = "ueq.s",
7638         .translate = translate_compare_s,
7639         .par = (const uint32_t[]){COMPARE_UEQ},
7640         .coprocessor = 0x1,
7641     }, {
7642         .name = "ufloat.d",
7643         .translate = translate_float_d,
7644         .par = (const uint32_t[]){true},
7645         .coprocessor = 0x1,
7646     }, {
7647         .name = "ufloat.s",
7648         .translate = translate_float_s,
7649         .par = (const uint32_t[]){true},
7650         .coprocessor = 0x1,
7651     }, {
7652         .name = "ule.d",
7653         .translate = translate_compare_d,
7654         .par = (const uint32_t[]){COMPARE_ULE},
7655         .coprocessor = 0x1,
7656     }, {
7657         .name = "ule.s",
7658         .translate = translate_compare_s,
7659         .par = (const uint32_t[]){COMPARE_ULE},
7660         .coprocessor = 0x1,
7661     }, {
7662         .name = "ult.d",
7663         .translate = translate_compare_d,
7664         .par = (const uint32_t[]){COMPARE_ULT},
7665         .coprocessor = 0x1,
7666     }, {
7667         .name = "ult.s",
7668         .translate = translate_compare_s,
7669         .par = (const uint32_t[]){COMPARE_ULT},
7670         .coprocessor = 0x1,
7671     }, {
7672         .name = "un.d",
7673         .translate = translate_compare_d,
7674         .par = (const uint32_t[]){COMPARE_UN},
7675         .coprocessor = 0x1,
7676     }, {
7677         .name = "un.s",
7678         .translate = translate_compare_s,
7679         .par = (const uint32_t[]){COMPARE_UN},
7680         .coprocessor = 0x1,
7681     }, {
7682         .name = "utrunc.d",
7683         .translate = translate_ftoi_d,
7684         .par = (const uint32_t[]){float_round_to_zero, true},
7685         .coprocessor = 0x1,
7686     }, {
7687         .name = "utrunc.s",
7688         .translate = translate_ftoi_s,
7689         .par = (const uint32_t[]){float_round_to_zero, true},
7690         .coprocessor = 0x1,
7691     }, {
7692         .name = "wfr",
7693         .translate = translate_wfr_s,
7694         .coprocessor = 0x1,
7695     }, {
7696         .name = "wfrd",
7697         .translate = translate_wfr_d,
7698         .coprocessor = 0x1,
7699     }, {
7700         .name = "wur.fcr",
7701         .translate = translate_wur_fpu_fcr,
7702         .par = (const uint32_t[]){FCR},
7703         .coprocessor = 0x1,
7704     }, {
7705         .name = "wur.fsr",
7706         .translate = translate_wur_fpu_fsr,
7707         .coprocessor = 0x1,
7708     },
7709 };
7710 
7711 const XtensaOpcodeTranslators xtensa_fpu_opcodes = {
7712     .num_opcodes = ARRAY_SIZE(fpu_ops),
7713     .opcode = fpu_ops,
7714 };
7715