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