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