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