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