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