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