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