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