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