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