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