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