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