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