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