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