filemon: fix watch IDs to avoid potential wraparound issues
[qemu/ar7.git] / target / xtensa / translate.c
blob65561d2c49729e7997243023880e8861d7adae64
1 /*
2 * Xtensa ISA:
3 * http://www.tensilica.com/products/literature-docs/documentation/xtensa-isa-databook.htm
5 * Copyright (c) 2011, Max Filippov, Open Source and Linux Lab.
6 * All rights reserved.
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.
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.
31 #include "qemu/osdep.h"
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"
43 #include "exec/helper-proto.h"
44 #include "exec/helper-gen.h"
46 #include "trace-tcg.h"
47 #include "exec/log.h"
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;
59 bool sar_5bit;
60 bool sar_m32_5bit;
61 bool sar_m32_allocated;
62 TCGv_i32 sar_m32;
64 unsigned window;
65 unsigned callinc;
66 bool cwoe;
68 bool debug;
69 bool icount;
70 TCGv_i32 next_icount;
72 unsigned cpenable;
74 uint32_t op_flags;
75 xtensa_insnbuf insnbuf;
76 xtensa_insnbuf slotbuf;
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;
90 static GHashTable *xtensa_regfile_table;
92 #include "exec/gen-icount.h"
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;
106 #define XTENSA_REG_ACCESS(regname, opt, acc) { \
107 .name = (regname), \
108 .opt_bits = XTENSA_OPTION_BIT(opt), \
109 .access = (acc), \
112 #define XTENSA_REG(regname, opt) XTENSA_REG_ACCESS(regname, opt, SR_RWX)
114 #define XTENSA_REG_BITS_ACCESS(regname, opt, acc) { \
115 .name = (regname), \
116 .opt_bits = (opt), \
117 .access = (acc), \
120 #define XTENSA_REG_BITS(regname, opt) \
121 XTENSA_REG_BITS_ACCESS(regname, opt, SR_RWX)
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),
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),
217 void xtensa_translate_init(void)
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",
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",
231 static const char * const mregnames[] = {
232 "m0", "m1", "m2", "m3",
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",
240 int i;
242 cpu_pc = tcg_global_mem_new_i32(cpu_env,
243 offsetof(CPUXtensaState, pc), "pc");
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]);
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]);
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]);
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]);
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]);
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);
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);
300 cpu_windowbase_next =
301 tcg_global_mem_new_i32(cpu_env,
302 offsetof(CPUXtensaState, windowbase_next),
303 "windowbase_next");
306 void **xtensa_get_regfile_by_name(const char *name)
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);
323 return (void **)g_hash_table_lookup(xtensa_regfile_table, (void *)name);
326 static inline bool option_enabled(DisasContext *dc, int opt)
328 return xtensa_option_enabled(dc->config, opt);
331 static void init_sar_tracker(DisasContext *dc)
333 dc->sar_5bit = false;
334 dc->sar_m32_5bit = false;
335 dc->sar_m32_allocated = false;
338 static void reset_sar_tracker(DisasContext *dc)
340 if (dc->sar_m32_allocated) {
341 tcg_temp_free(dc->sar_m32);
345 static void gen_right_shift_sar(DisasContext *dc, TCGv_i32 sa)
347 tcg_gen_andi_i32(cpu_SR[SAR], sa, 0x1f);
348 if (dc->sar_m32_5bit) {
349 tcg_gen_discard_i32(dc->sar_m32);
351 dc->sar_5bit = true;
352 dc->sar_m32_5bit = false;
355 static void gen_left_shift_sar(DisasContext *dc, TCGv_i32 sa)
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;
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);
369 static void gen_exception(DisasContext *dc, int excp)
371 TCGv_i32 tmp = tcg_const_i32(excp);
372 gen_helper_exception(cpu_env, tmp);
373 tcg_temp_free(tmp);
376 static void gen_exception_cause(DisasContext *dc, uint32_t cause)
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;
389 static void gen_exception_cause_vaddr(DisasContext *dc, uint32_t cause,
390 TCGv_i32 vaddr)
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);
399 static void gen_debug_exception(DisasContext *dc, uint32_t cause)
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;
411 static bool gen_check_privilege(DisasContext *dc)
413 #ifndef CONFIG_USER_ONLY
414 if (!dc->cring) {
415 return true;
417 #endif
418 gen_exception_cause(dc, PRIVILEGED_CAUSE);
419 dc->base.is_jmp = DISAS_NORETURN;
420 return false;
423 static bool gen_check_cpenable(DisasContext *dc, uint32_t cp_mask)
425 cp_mask &= ~dc->cpenable;
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;
432 return true;
435 static int gen_postprocess(DisasContext *dc, int slot);
437 static void gen_jump_slot(DisasContext *dc, TCGv dest, int slot)
439 tcg_gen_mov_i32(cpu_pc, dest);
440 if (dc->icount) {
441 tcg_gen_mov_i32(cpu_SR[ICOUNT], dc->next_icount);
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);
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);
456 dc->base.is_jmp = DISAS_NORETURN;
459 static void gen_jump(DisasContext *dc, TCGv dest)
461 gen_jump_slot(dc, dest, -1);
464 static int adjust_jump_slot(DisasContext *dc, uint32_t dest, int slot)
466 if (((dc->base.pc_first ^ dest) & TARGET_PAGE_MASK) != 0) {
467 return -1;
468 } else {
469 return slot;
473 static void gen_jumpi(DisasContext *dc, uint32_t dest, int slot)
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);
480 static void gen_callw_slot(DisasContext *dc, int callinc, TCGv_i32 dest,
481 int slot)
483 TCGv_i32 tcallinc = tcg_const_i32(callinc);
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);
493 static bool gen_check_loop_end(DisasContext *dc, int slot)
495 if (dc->base.pc_next == dc->lend) {
496 TCGLabel *label = gen_new_label();
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]);
505 gen_set_label(label);
506 gen_jumpi(dc, dc->base.pc_next, -1);
507 return true;
509 return false;
512 static void gen_jumpi_check_loop_end(DisasContext *dc, int slot)
514 if (!gen_check_loop_end(dc, slot)) {
515 gen_jumpi(dc, dc->base.pc_next, slot);
519 static void gen_brcond(DisasContext *dc, TCGCond cond,
520 TCGv_i32 t0, TCGv_i32 t1, uint32_t addr)
522 TCGLabel *label = gen_new_label();
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);
530 static void gen_brcondi(DisasContext *dc, TCGCond cond,
531 TCGv_i32 t0, uint32_t t1, uint32_t addr)
533 TCGv_i32 tmp = tcg_const_i32(t1);
534 gen_brcond(dc, cond, t0, tmp, addr);
535 tcg_temp_free(tmp);
538 static bool check_sr(DisasContext *dc, uint32_t sr, unsigned access)
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);
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",
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;
558 return true;
561 #ifndef CONFIG_USER_ONLY
562 static void gen_rsr_ccount(DisasContext *dc, TCGv_i32 d, uint32_t sr)
564 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
565 gen_io_start();
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();
574 static void gen_rsr_ptevaddr(DisasContext *dc, TCGv_i32 d, uint32_t sr)
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);
580 #endif
582 static void gen_rsr(DisasContext *dc, TCGv_i32 d, uint32_t sr)
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
593 if (rsr_handler[sr]) {
594 rsr_handler[sr](dc, d, sr);
595 } else {
596 tcg_gen_mov_i32(d, cpu_SR[sr]);
600 static void gen_wsr_sar(DisasContext *dc, uint32_t sr, TCGv_i32 s)
602 tcg_gen_andi_i32(cpu_SR[sr], s, 0x3f);
603 if (dc->sar_m32_5bit) {
604 tcg_gen_discard_i32(dc->sar_m32);
606 dc->sar_5bit = false;
607 dc->sar_m32_5bit = false;
610 static void gen_wsr_br(DisasContext *dc, uint32_t sr, TCGv_i32 s)
612 tcg_gen_andi_i32(cpu_SR[sr], s, 0xffff);
615 static void gen_wsr_litbase(DisasContext *dc, uint32_t sr, TCGv_i32 s)
617 tcg_gen_andi_i32(cpu_SR[sr], s, 0xfffff001);
620 static void gen_wsr_acchi(DisasContext *dc, uint32_t sr, TCGv_i32 s)
622 tcg_gen_ext8s_i32(cpu_SR[sr], s);
625 #ifndef CONFIG_USER_ONLY
626 static void gen_wsr_windowbase(DisasContext *dc, uint32_t sr, TCGv_i32 v)
628 tcg_gen_mov_i32(cpu_windowbase_next, v);
631 static void gen_wsr_windowstart(DisasContext *dc, uint32_t sr, TCGv_i32 v)
633 tcg_gen_andi_i32(cpu_SR[sr], v, (1 << dc->config->nareg / 4) - 1);
636 static void gen_wsr_ptevaddr(DisasContext *dc, uint32_t sr, TCGv_i32 v)
638 tcg_gen_andi_i32(cpu_SR[sr], v, 0xffc00000);
641 static void gen_wsr_rasid(DisasContext *dc, uint32_t sr, TCGv_i32 v)
643 gen_helper_wsr_rasid(cpu_env, v);
646 static void gen_wsr_tlbcfg(DisasContext *dc, uint32_t sr, TCGv_i32 v)
648 tcg_gen_andi_i32(cpu_SR[sr], v, 0x01130000);
651 static void gen_wsr_ibreakenable(DisasContext *dc, uint32_t sr, TCGv_i32 v)
653 gen_helper_wsr_ibreakenable(cpu_env, v);
656 static void gen_wsr_memctl(DisasContext *dc, uint32_t sr, TCGv_i32 v)
658 gen_helper_wsr_memctl(cpu_env, v);
661 static void gen_wsr_atomctl(DisasContext *dc, uint32_t sr, TCGv_i32 v)
663 tcg_gen_andi_i32(cpu_SR[sr], v, 0x3f);
666 static void gen_wsr_ibreaka(DisasContext *dc, uint32_t sr, TCGv_i32 v)
668 unsigned id = sr - IBREAKA;
669 TCGv_i32 tmp = tcg_const_i32(id);
671 assert(id < dc->config->nibreak);
672 gen_helper_wsr_ibreaka(cpu_env, tmp, v);
673 tcg_temp_free(tmp);
676 static void gen_wsr_dbreaka(DisasContext *dc, uint32_t sr, TCGv_i32 v)
678 unsigned id = sr - DBREAKA;
679 TCGv_i32 tmp = tcg_const_i32(id);
681 assert(id < dc->config->ndbreak);
682 gen_helper_wsr_dbreaka(cpu_env, tmp, v);
683 tcg_temp_free(tmp);
686 static void gen_wsr_dbreakc(DisasContext *dc, uint32_t sr, TCGv_i32 v)
688 unsigned id = sr - DBREAKC;
689 TCGv_i32 tmp = tcg_const_i32(id);
691 assert(id < dc->config->ndbreak);
692 gen_helper_wsr_dbreakc(cpu_env, tmp, v);
693 tcg_temp_free(tmp);
696 static void gen_wsr_cpenable(DisasContext *dc, uint32_t sr, TCGv_i32 v)
698 tcg_gen_andi_i32(cpu_SR[sr], v, 0xff);
701 static void gen_check_interrupts(DisasContext *dc)
703 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
704 gen_io_start();
706 gen_helper_check_interrupts(cpu_env);
707 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
708 gen_io_end();
712 static void gen_wsr_intset(DisasContext *dc, uint32_t sr, TCGv_i32 v)
714 gen_helper_intset(cpu_env, v);
717 static void gen_wsr_intclear(DisasContext *dc, uint32_t sr, TCGv_i32 v)
719 gen_helper_intclear(cpu_env, v);
722 static void gen_wsr_intenable(DisasContext *dc, uint32_t sr, TCGv_i32 v)
724 tcg_gen_mov_i32(cpu_SR[sr], v);
727 static void gen_wsr_ps(DisasContext *dc, uint32_t sr, TCGv_i32 v)
729 uint32_t mask = PS_WOE | PS_CALLINC | PS_OWB |
730 PS_UM | PS_EXCM | PS_INTLEVEL;
732 if (option_enabled(dc, XTENSA_OPTION_MMU)) {
733 mask |= PS_RING;
735 tcg_gen_andi_i32(cpu_SR[sr], v, mask);
738 static void gen_wsr_ccount(DisasContext *dc, uint32_t sr, TCGv_i32 v)
740 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
741 gen_io_start();
743 gen_helper_wsr_ccount(cpu_env, v);
744 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
745 gen_io_end();
749 static void gen_wsr_icount(DisasContext *dc, uint32_t sr, TCGv_i32 v)
751 if (dc->icount) {
752 tcg_gen_mov_i32(dc->next_icount, v);
753 } else {
754 tcg_gen_mov_i32(cpu_SR[sr], v);
758 static void gen_wsr_icountlevel(DisasContext *dc, uint32_t sr, TCGv_i32 v)
760 tcg_gen_andi_i32(cpu_SR[sr], v, 0xf);
763 static void gen_wsr_ccompare(DisasContext *dc, uint32_t sr, TCGv_i32 v)
765 uint32_t id = sr - CCOMPARE;
766 TCGv_i32 tmp = tcg_const_i32(id);
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();
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();
779 #else
780 static void gen_check_interrupts(DisasContext *dc)
783 #endif
785 static void gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s)
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
823 if (wsr_handler[sr]) {
824 wsr_handler[sr](dc, sr, s);
825 } else {
826 tcg_gen_mov_i32(cpu_SR[sr], s);
830 static void gen_wur(uint32_t ur, TCGv_i32 s)
832 switch (ur) {
833 case FCR:
834 gen_helper_wur_fcr(cpu_env, s);
835 break;
837 case FSR:
838 tcg_gen_andi_i32(cpu_UR[ur], s, 0xffffff80);
839 break;
841 default:
842 tcg_gen_mov_i32(cpu_UR[ur], s);
843 break;
847 static void gen_load_store_alignment(DisasContext *dc, int shift,
848 TCGv_i32 addr, bool no_hw_alignment)
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);
864 #ifndef CONFIG_USER_ONLY
865 static void gen_waiti(DisasContext *dc, uint32_t imm4)
867 TCGv_i32 pc = tcg_const_i32(dc->base.pc_next);
868 TCGv_i32 intlevel = tcg_const_i32(imm4);
870 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
871 gen_io_start();
873 gen_helper_waiti(cpu_env, pc, intlevel);
874 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
875 gen_io_end();
877 tcg_temp_free(pc);
878 tcg_temp_free(intlevel);
880 #endif
882 static bool gen_window_check(DisasContext *dc, uint32_t mask)
884 unsigned r = 31 - clz32(mask);
886 if (r / 4 > dc->window) {
887 TCGv_i32 pc = tcg_const_i32(dc->pc);
888 TCGv_i32 w = tcg_const_i32(r / 4);
890 gen_helper_window_check(cpu_env, pc, w);
891 dc->base.is_jmp = DISAS_NORETURN;
892 return false;
894 return true;
897 static TCGv_i32 gen_mac16_m(TCGv_i32 v, bool hi, bool is_unsigned)
899 TCGv_i32 m = tcg_temp_new_i32();
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);
906 return m;
909 static void gen_zero_check(DisasContext *dc, const OpcodeArg arg[])
911 TCGLabel *label = gen_new_label();
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);
918 static inline unsigned xtensa_op0_insn_len(DisasContext *dc, uint8_t op0)
920 return xtensa_isa_length_from_chars(dc->config->isa, &op0);
923 static int gen_postprocess(DisasContext *dc, int slot)
925 uint32_t op_flags = dc->op_flags;
927 if (op_flags & XTENSA_OP_CHECK_INTERRUPTS) {
928 gen_check_interrupts(dc);
930 if (op_flags & XTENSA_OP_SYNC_REGISTER_WINDOW) {
931 gen_helper_sync_windowbase(cpu_env);
933 if (op_flags & XTENSA_OP_EXIT_TB_M1) {
934 slot = -1;
936 return slot;
939 struct opcode_arg_copy {
940 uint32_t resource;
941 void *temp;
942 OpcodeArg *arg;
945 struct opcode_arg_info {
946 uint32_t resource;
947 int index;
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;
960 enum resource_type {
961 RES_REGFILE,
962 RES_STATE,
963 RES_MAX,
966 static uint32_t encode_resource(enum resource_type r, unsigned g, unsigned n)
968 assert(r < RES_MAX && g < 256 && n < 65536);
969 return (r << 24) | (g << 16) | n;
972 static enum resource_type get_resource_type(uint32_t resource)
974 return resource >> 24;
978 * a depends on b if b must be executed before a,
979 * because a's side effects will destroy b's inputs.
981 static bool op_depends_on(const struct slot_prop *a,
982 const struct slot_prop *b)
984 unsigned i = 0;
985 unsigned j = 0;
987 if (a->op_flags & XTENSA_OP_CONTROL_FLOW) {
988 return true;
990 if ((a->op_flags & XTENSA_OP_LOAD_STORE) <
991 (b->op_flags & XTENSA_OP_LOAD_STORE)) {
992 return true;
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;
1003 return false;
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.
1012 static bool break_dependency(struct slot_prop *a,
1013 struct slot_prop *b,
1014 struct opcode_arg_copy *copy,
1015 unsigned *n_copy)
1017 unsigned i = 0;
1018 unsigned j = 0;
1019 unsigned n = *n_copy;
1020 bool rv = false;
1022 if (a->op_flags & XTENSA_OP_CONTROL_FLOW) {
1023 return false;
1025 if ((a->op_flags & XTENSA_OP_LOAD_STORE) <
1026 (b->op_flags & XTENSA_OP_LOAD_STORE)) {
1027 return false;
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;
1037 if (get_resource_type(a->out[i].resource) != RES_REGFILE ||
1038 index < 0) {
1039 return false;
1041 copy[n].resource = b->in[j].resource;
1042 copy[n].arg = b->arg + index;
1043 ++n;
1044 ++j;
1045 rv = true;
1048 *n_copy = n;
1049 return rv;
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.
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)
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];
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;
1078 for (i = 0; i < n; ++i) {
1079 node[i].n_in_edge = 0;
1080 node[i].n_out_edge = 0;
1083 for (i = 0; i < n; ++i) {
1084 unsigned n_out_edge = 0;
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;
1094 node[i].n_out_edge = n_out_edge;
1097 for (i = 0; i < n; ++i) {
1098 if (!node[i].n_in_edge) {
1099 in[n_in] = i;
1100 ++n_in;
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;
1117 if (n_edge) {
1118 for (; node_idx < n; ++node_idx) {
1119 struct tsnode *cnode = node + node_idx;
1121 if (cnode->n_in_edge) {
1122 for (j = 0; j < cnode->n_out_edge; ++j) {
1123 unsigned k = cnode->out_edge[j];
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;
1140 return n_edge == 0;
1143 static void opcode_add_resource(struct slot_prop *op,
1144 uint32_t resource, char direction,
1145 int index)
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;
1162 break;
1163 default:
1164 g_assert_not_reached();
1168 static int resource_compare(const void *a, const void *b)
1170 const struct opcode_arg_info *pa = a;
1171 const struct opcode_arg_info *pb = b;
1173 return pa->resource < pb->resource ?
1174 -1 : (pa->resource > pb->resource ? 1 : 0);
1177 static int arg_copy_compare(const void *a, const void *b)
1179 const struct opcode_arg_copy *pa = a;
1180 const struct opcode_arg_copy *pb = b;
1182 return pa->resource < pb->resource ?
1183 -1 : (pa->resource > pb->resource ? 1 : 0);
1186 static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
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;
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;
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);
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;
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;
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;
1240 opnds = xtensa_opcode_num_operands(isa, opc);
1242 for (opnd = vopnd = 0; opnd < opnds; ++opnd) {
1243 void **register_file = NULL;
1245 if (xtensa_operand_is_register(isa, opc, opnd)) {
1246 xtensa_regfile rf = xtensa_operand_regfile(isa, opc, opnd);
1248 register_file = dc->config->regfile[rf];
1250 if (rf == dc->config->a_regfile) {
1251 uint32_t v;
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;
1259 if (xtensa_operand_is_visible(isa, opc, opnd)) {
1260 uint32_t v;
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);
1269 arg[vopnd].imm = v;
1270 if (register_file) {
1271 arg[vopnd].in = register_file[v];
1272 arg[vopnd].out = register_file[v];
1274 ++vopnd;
1277 ops = dc->config->opcode_ops[opc];
1278 slot_prop[slot].ops = ops;
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;
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;
1293 if (ops->op_flags & XTENSA_OP_DEBUG_BREAK) {
1294 debug_cause |= ops->par[0];
1296 if (ops->test_overflow) {
1297 windowed_register |= ops->test_overflow(dc, arg, ops->par);
1299 coprocessor |= ops->coprocessor;
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;
1306 opnds = xtensa_opcode_num_operands(isa, opc);
1308 for (opnd = vopnd = 0; opnd < opnds; ++opnd) {
1309 bool visible = xtensa_operand_is_visible(isa, opc, opnd);
1311 if (xtensa_operand_is_register(isa, opc, opnd)) {
1312 xtensa_regfile rf = xtensa_operand_regfile(isa, opc, opnd);
1313 uint32_t v = 0;
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);
1323 if (visible) {
1324 ++vopnd;
1328 opnds = xtensa_opcode_num_stateOperands(isa, opc);
1330 for (opnd = 0; opnd < opnds; ++opnd) {
1331 xtensa_state state = xtensa_stateOperand_state(isa, opc, opnd);
1333 opcode_add_resource(slot_prop + slot,
1334 encode_resource(RES_STATE, 0, state),
1335 xtensa_stateOperand_inout(isa, opc, opnd),
1336 -1);
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;
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);
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;
1360 } else {
1361 ordered[0] = slot_prop + 0;
1364 if ((op_flags & XTENSA_OP_PRIVILEGED) &&
1365 !gen_check_privilege(dc)) {
1366 return;
1369 if (op_flags & XTENSA_OP_SYSCALL) {
1370 gen_exception_cause(dc, SYSCALL_CAUSE);
1371 return;
1374 if ((op_flags & XTENSA_OP_DEBUG_BREAK) && dc->debug) {
1375 gen_debug_exception(dc, debug_cause);
1376 return;
1379 if (windowed_register && !gen_window_check(dc, windowed_register)) {
1380 return;
1383 if (op_flags & XTENSA_OP_UNDERFLOW) {
1384 TCGv_i32 tmp = tcg_const_i32(dc->pc);
1386 gen_helper_test_underflow_retw(cpu_env, tmp);
1387 tcg_temp_free(tmp);
1390 if (op_flags & XTENSA_OP_ALLOCA) {
1391 TCGv_i32 tmp = tcg_const_i32(dc->pc);
1393 gen_helper_movsp(cpu_env, tmp);
1394 tcg_temp_free(tmp);
1397 if (coprocessor && !gen_check_cpenable(dc, coprocessor)) {
1398 return;
1401 if (n_arg_copy) {
1402 uint32_t resource;
1403 void *temp;
1404 unsigned j;
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;
1414 if (i != j) {
1415 arg_copy[j] = arg_copy[i];
1417 ++j;
1419 arg_copy[i].arg->in = temp;
1421 n_arg_copy = j;
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);
1432 dc->op_flags = op_flags;
1434 for (slot = 0; slot < slots; ++slot) {
1435 struct slot_prop *pslot = ordered[slot];
1436 XtensaOpcodeOps *ops = pslot->ops;
1438 ops->translate(dc, pslot->arg, ops->par);
1441 for (i = 0; i < n_arg_copy; ++i) {
1442 tcg_temp_free(arg_copy[i].temp);
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);
1457 dc->pc = dc->base.pc_next;
1460 static inline unsigned xtensa_insn_len(CPUXtensaState *env, DisasContext *dc)
1462 uint8_t b0 = cpu_ldub_code(env, dc->pc);
1463 return xtensa_op0_insn_len(dc, b0);
1466 static void gen_ibreak_check(CPUXtensaState *env, DisasContext *dc)
1468 unsigned i;
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;
1479 static void xtensa_tr_init_disas_context(DisasContextBase *dcbase,
1480 CPUState *cpu)
1482 DisasContext *dc = container_of(dcbase, DisasContext, base);
1483 CPUXtensaState *env = cpu->env_ptr;
1484 uint32_t tb_flags = dc->base.tb->flags;
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);
1504 if (dc->config->isa) {
1505 dc->insnbuf = xtensa_insnbuf_alloc(dc->config->isa);
1506 dc->slotbuf = xtensa_insnbuf_alloc(dc->config->isa);
1508 init_sar_tracker(dc);
1511 static void xtensa_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
1513 DisasContext *dc = container_of(dcbase, DisasContext, base);
1515 if (dc->icount) {
1516 dc->next_icount = tcg_temp_local_new_i32();
1520 static void xtensa_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
1522 tcg_gen_insn_start(dcbase->pc_next);
1525 static bool xtensa_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
1526 const CPUBreakpoint *bp)
1528 DisasContext *dc = container_of(dcbase, DisasContext, base);
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;
1541 static void xtensa_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
1543 DisasContext *dc = container_of(dcbase, DisasContext, base);
1544 CPUXtensaState *env = cpu->env_ptr;
1545 target_ulong page_start;
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;
1555 if (dc->base.tb->flags & XTENSA_TBFLAG_EXCEPTION) {
1556 gen_exception(dc, EXCP_DEBUG);
1557 dc->base.is_jmp = DISAS_NORETURN;
1558 return;
1561 if (dc->icount) {
1562 TCGLabel *label = gen_new_label();
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);
1570 gen_set_label(label);
1573 if (dc->debug) {
1574 gen_ibreak_check(env, dc);
1577 disas_xtensa_insn(env, dc);
1579 if (dc->icount) {
1580 tcg_gen_mov_i32(cpu_SR[ICOUNT], dc->next_icount);
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;
1592 static void xtensa_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
1594 DisasContext *dc = container_of(dcbase, DisasContext, base);
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);
1601 if (dc->icount) {
1602 tcg_temp_free(dc->next_icount);
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);
1615 break;
1616 default:
1617 g_assert_not_reached();
1621 static void xtensa_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
1623 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
1624 log_target_disas(cpu, dcbase->pc_first, dcbase->tb->size);
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,
1637 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
1639 DisasContext dc = {};
1640 translator_loop(&xtensa_translator_ops, &dc.base, cpu, tb);
1643 void xtensa_cpu_dump_state(CPUState *cs, FILE *f,
1644 fprintf_function cpu_fprintf, int flags)
1646 XtensaCPU *cpu = XTENSA_CPU(cs);
1647 CPUXtensaState *env = &cpu->env;
1648 int i, j;
1650 cpu_fprintf(f, "PC=%08x\n\n", env->pc);
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' : ' ');
1659 cpu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n");
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' : ' ');
1668 cpu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n");
1670 for (i = 0; i < 16; ++i) {
1671 cpu_fprintf(f, " A%02d=%08x%c", i, env->regs[i],
1672 (i % 4) == 3 ? '\n' : ' ');
1675 xtensa_sync_phys_from_window(env);
1676 cpu_fprintf(f, "\n");
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;
1684 cpu_fprintf(f, "%c%c\n", ws ? '<' : ' ', cw ? '=' : ' ');
1688 if ((flags & CPU_DUMP_FPU) &&
1689 xtensa_option_enabled(env->config, XTENSA_OPTION_FP_COPROCESSOR)) {
1690 cpu_fprintf(f, "\n");
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' : ' ');
1701 void restore_state_to_opc(CPUXtensaState *env, TranslationBlock *tb,
1702 target_ulong *data)
1704 env->pc = data[0];
1707 static void translate_abs(DisasContext *dc, const OpcodeArg arg[],
1708 const uint32_t par[])
1710 TCGv_i32 zero = tcg_const_i32(0);
1711 TCGv_i32 neg = tcg_temp_new_i32();
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);
1720 static void translate_add(DisasContext *dc, const OpcodeArg arg[],
1721 const uint32_t par[])
1723 tcg_gen_add_i32(arg[0].out, arg[1].in, arg[2].in);
1726 static void translate_addi(DisasContext *dc, const OpcodeArg arg[],
1727 const uint32_t par[])
1729 tcg_gen_addi_i32(arg[0].out, arg[1].in, arg[2].imm);
1732 static void translate_addx(DisasContext *dc, const OpcodeArg arg[],
1733 const uint32_t par[])
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);
1741 static void translate_all(DisasContext *dc, const OpcodeArg arg[],
1742 const uint32_t par[])
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();
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);
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);
1761 static void translate_and(DisasContext *dc, const OpcodeArg arg[],
1762 const uint32_t par[])
1764 tcg_gen_and_i32(arg[0].out, arg[1].in, arg[2].in);
1767 static void translate_ball(DisasContext *dc, const OpcodeArg arg[],
1768 const uint32_t par[])
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);
1776 static void translate_bany(DisasContext *dc, const OpcodeArg arg[],
1777 const uint32_t par[])
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);
1785 static void translate_b(DisasContext *dc, const OpcodeArg arg[],
1786 const uint32_t par[])
1788 gen_brcond(dc, par[0], arg[0].in, arg[1].in, arg[2].imm);
1791 static void translate_bb(DisasContext *dc, const OpcodeArg arg[],
1792 const uint32_t par[])
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);
1812 static void translate_bbi(DisasContext *dc, const OpcodeArg arg[],
1813 const uint32_t par[])
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);
1825 static void translate_bi(DisasContext *dc, const OpcodeArg arg[],
1826 const uint32_t par[])
1828 gen_brcondi(dc, par[0], arg[0].in, arg[1].imm, arg[2].imm);
1831 static void translate_bz(DisasContext *dc, const OpcodeArg arg[],
1832 const uint32_t par[])
1834 gen_brcondi(dc, par[0], arg[0].in, 0, arg[1].imm);
1837 enum {
1838 BOOLEAN_AND,
1839 BOOLEAN_ANDC,
1840 BOOLEAN_OR,
1841 BOOLEAN_ORC,
1842 BOOLEAN_XOR,
1845 static void translate_boolean(DisasContext *dc, const OpcodeArg arg[],
1846 const uint32_t par[])
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,
1856 TCGv_i32 tmp1 = tcg_temp_new_i32();
1857 TCGv_i32 tmp2 = tcg_temp_new_i32();
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);
1867 static void translate_bp(DisasContext *dc, const OpcodeArg arg[],
1868 const uint32_t par[])
1870 TCGv_i32 tmp = tcg_temp_new_i32();
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);
1877 static void translate_call0(DisasContext *dc, const OpcodeArg arg[],
1878 const uint32_t par[])
1880 tcg_gen_movi_i32(cpu_R[0], dc->base.pc_next);
1881 gen_jumpi(dc, arg[0].imm, 0);
1884 static void translate_callw(DisasContext *dc, const OpcodeArg arg[],
1885 const uint32_t par[])
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);
1892 static void translate_callx0(DisasContext *dc, const OpcodeArg arg[],
1893 const uint32_t par[])
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);
1902 static void translate_callxw(DisasContext *dc, const OpcodeArg arg[],
1903 const uint32_t par[])
1905 TCGv_i32 tmp = tcg_temp_new_i32();
1907 tcg_gen_mov_i32(tmp, arg[0].in);
1908 gen_callw_slot(dc, par[0], tmp, -1);
1909 tcg_temp_free(tmp);
1912 static void translate_clamps(DisasContext *dc, const OpcodeArg arg[],
1913 const uint32_t par[])
1915 TCGv_i32 tmp1 = tcg_const_i32(-1u << arg[2].imm);
1916 TCGv_i32 tmp2 = tcg_const_i32((1 << arg[2].imm) - 1);
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);
1924 static void translate_clrb_expstate(DisasContext *dc, const OpcodeArg arg[],
1925 const uint32_t par[])
1927 /* TODO: GPIO32 may be a part of coprocessor */
1928 tcg_gen_andi_i32(cpu_UR[EXPSTATE], cpu_UR[EXPSTATE], ~(1u << arg[0].imm));
1931 static void translate_const16(DisasContext *dc, const OpcodeArg arg[],
1932 const uint32_t par[])
1934 TCGv_i32 c = tcg_const_i32(arg[1].imm);
1936 tcg_gen_deposit_i32(arg[0].out, c, arg[0].in, 16, 16);
1937 tcg_temp_free(c);
1940 static void translate_dcache(DisasContext *dc, const OpcodeArg arg[],
1941 const uint32_t par[])
1943 TCGv_i32 addr = tcg_temp_new_i32();
1944 TCGv_i32 res = tcg_temp_new_i32();
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);
1952 static void translate_depbits(DisasContext *dc, const OpcodeArg arg[],
1953 const uint32_t par[])
1955 tcg_gen_deposit_i32(arg[1].out, arg[1].in, arg[0].in,
1956 arg[2].imm, arg[3].imm);
1959 static bool test_ill_entry(DisasContext *dc, const OpcodeArg arg[],
1960 const uint32_t par[])
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;
1971 static uint32_t test_overflow_entry(DisasContext *dc, const OpcodeArg arg[],
1972 const uint32_t par[])
1974 return 1 << (dc->callinc * 4);
1977 static void translate_entry(DisasContext *dc, const OpcodeArg arg[],
1978 const uint32_t par[])
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);
1989 static void translate_extui(DisasContext *dc, const OpcodeArg arg[],
1990 const uint32_t par[])
1992 int maskimm = (1 << arg[3].imm) - 1;
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);
2000 static void translate_icache(DisasContext *dc, const OpcodeArg arg[],
2001 const uint32_t par[])
2003 #ifndef CONFIG_USER_ONLY
2004 TCGv_i32 addr = tcg_temp_new_i32();
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
2013 static void translate_itlb(DisasContext *dc, const OpcodeArg arg[],
2014 const uint32_t par[])
2016 #ifndef CONFIG_USER_ONLY
2017 TCGv_i32 dtlb = tcg_const_i32(par[0]);
2019 gen_helper_itlb(cpu_env, arg[0].in, dtlb);
2020 tcg_temp_free(dtlb);
2021 #endif
2024 static void translate_j(DisasContext *dc, const OpcodeArg arg[],
2025 const uint32_t par[])
2027 gen_jumpi(dc, arg[0].imm, 0);
2030 static void translate_jx(DisasContext *dc, const OpcodeArg arg[],
2031 const uint32_t par[])
2033 gen_jump(dc, arg[0].in);
2036 static void translate_l32e(DisasContext *dc, const OpcodeArg arg[],
2037 const uint32_t par[])
2039 TCGv_i32 addr = tcg_temp_new_i32();
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);
2047 static void translate_ldst(DisasContext *dc, const OpcodeArg arg[],
2048 const uint32_t par[])
2050 TCGv_i32 addr = tcg_temp_new_i32();
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]);
2056 if (par[2]) {
2057 if (par[1]) {
2058 tcg_gen_mb(TCG_BAR_STRL | TCG_MO_ALL);
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);
2067 tcg_temp_free(addr);
2070 static void translate_l32r(DisasContext *dc, const OpcodeArg arg[],
2071 const uint32_t par[])
2073 TCGv_i32 tmp;
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);
2081 tcg_gen_qemu_ld32u(arg[0].out, tmp, dc->cring);
2082 tcg_temp_free(tmp);
2085 static void translate_loop(DisasContext *dc, const OpcodeArg arg[],
2086 const uint32_t par[])
2088 uint32_t lend = arg[1].imm;
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);
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);
2101 gen_jumpi(dc, dc->base.pc_next, 0);
2104 enum {
2105 MAC16_UMUL,
2106 MAC16_MUL,
2107 MAC16_MULA,
2108 MAC16_MULS,
2109 MAC16_NONE,
2112 enum {
2113 MAC16_LL,
2114 MAC16_HL,
2115 MAC16_LH,
2116 MAC16_HH,
2118 MAC16_HX = 0x1,
2119 MAC16_XH = 0x2,
2122 static void translate_mac16(DisasContext *dc, const OpcodeArg arg[],
2123 const uint32_t par[])
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();
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);
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);
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);
2150 } else {
2151 TCGv_i32 lo = tcg_temp_new_i32();
2152 TCGv_i32 hi = tcg_temp_new_i32();
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);
2165 tcg_gen_ext8s_i32(cpu_SR[ACCHI], cpu_SR[ACCHI]);
2167 tcg_temp_free_i32(lo);
2168 tcg_temp_free_i32(hi);
2170 tcg_temp_free(m1);
2171 tcg_temp_free(m2);
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);
2177 tcg_temp_free(vaddr);
2178 tcg_temp_free(mem32);
2181 static void translate_memw(DisasContext *dc, const OpcodeArg arg[],
2182 const uint32_t par[])
2184 tcg_gen_mb(TCG_BAR_SC | TCG_MO_ALL);
2187 static void translate_smin(DisasContext *dc, const OpcodeArg arg[],
2188 const uint32_t par[])
2190 tcg_gen_smin_i32(arg[0].out, arg[1].in, arg[2].in);
2193 static void translate_umin(DisasContext *dc, const OpcodeArg arg[],
2194 const uint32_t par[])
2196 tcg_gen_umin_i32(arg[0].out, arg[1].in, arg[2].in);
2199 static void translate_smax(DisasContext *dc, const OpcodeArg arg[],
2200 const uint32_t par[])
2202 tcg_gen_smax_i32(arg[0].out, arg[1].in, arg[2].in);
2205 static void translate_umax(DisasContext *dc, const OpcodeArg arg[],
2206 const uint32_t par[])
2208 tcg_gen_umax_i32(arg[0].out, arg[1].in, arg[2].in);
2211 static void translate_mov(DisasContext *dc, const OpcodeArg arg[],
2212 const uint32_t par[])
2214 tcg_gen_mov_i32(arg[0].out, arg[1].in);
2217 static void translate_movcond(DisasContext *dc, const OpcodeArg arg[],
2218 const uint32_t par[])
2220 TCGv_i32 zero = tcg_const_i32(0);
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);
2227 static void translate_movi(DisasContext *dc, const OpcodeArg arg[],
2228 const uint32_t par[])
2230 tcg_gen_movi_i32(arg[0].out, arg[1].imm);
2233 static void translate_movp(DisasContext *dc, const OpcodeArg arg[],
2234 const uint32_t par[])
2236 TCGv_i32 zero = tcg_const_i32(0);
2237 TCGv_i32 tmp = tcg_temp_new_i32();
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);
2247 static void translate_movsp(DisasContext *dc, const OpcodeArg arg[],
2248 const uint32_t par[])
2250 tcg_gen_mov_i32(arg[0].out, arg[1].in);
2253 static void translate_mul16(DisasContext *dc, const OpcodeArg arg[],
2254 const uint32_t par[])
2256 TCGv_i32 v1 = tcg_temp_new_i32();
2257 TCGv_i32 v2 = tcg_temp_new_i32();
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);
2266 tcg_gen_mul_i32(arg[0].out, v1, v2);
2267 tcg_temp_free(v2);
2268 tcg_temp_free(v1);
2271 static void translate_mull(DisasContext *dc, const OpcodeArg arg[],
2272 const uint32_t par[])
2274 tcg_gen_mul_i32(arg[0].out, arg[1].in, arg[2].in);
2277 static void translate_mulh(DisasContext *dc, const OpcodeArg arg[],
2278 const uint32_t par[])
2280 TCGv_i32 lo = tcg_temp_new();
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);
2287 tcg_temp_free(lo);
2290 static void translate_neg(DisasContext *dc, const OpcodeArg arg[],
2291 const uint32_t par[])
2293 tcg_gen_neg_i32(arg[0].out, arg[1].in);
2296 static void translate_nop(DisasContext *dc, const OpcodeArg arg[],
2297 const uint32_t par[])
2301 static void translate_nsa(DisasContext *dc, const OpcodeArg arg[],
2302 const uint32_t par[])
2304 tcg_gen_clrsb_i32(arg[0].out, arg[1].in);
2307 static void translate_nsau(DisasContext *dc, const OpcodeArg arg[],
2308 const uint32_t par[])
2310 tcg_gen_clzi_i32(arg[0].out, arg[1].in, 32);
2313 static void translate_or(DisasContext *dc, const OpcodeArg arg[],
2314 const uint32_t par[])
2316 tcg_gen_or_i32(arg[0].out, arg[1].in, arg[2].in);
2319 static void translate_ptlb(DisasContext *dc, const OpcodeArg arg[],
2320 const uint32_t par[])
2322 #ifndef CONFIG_USER_ONLY
2323 TCGv_i32 dtlb = tcg_const_i32(par[0]);
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
2331 static void translate_quos(DisasContext *dc, const OpcodeArg arg[],
2332 const uint32_t par[])
2334 TCGLabel *label1 = gen_new_label();
2335 TCGLabel *label2 = gen_new_label();
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);
2352 gen_set_label(label2);
2355 static void translate_quou(DisasContext *dc, const OpcodeArg arg[],
2356 const uint32_t par[])
2358 tcg_gen_divu_i32(arg[0].out,
2359 arg[1].in, arg[2].in);
2362 static void translate_read_impwire(DisasContext *dc, const OpcodeArg arg[],
2363 const uint32_t par[])
2365 /* TODO: GPIO32 may be a part of coprocessor */
2366 tcg_gen_movi_i32(arg[0].out, 0);
2369 static void translate_remu(DisasContext *dc, const OpcodeArg arg[],
2370 const uint32_t par[])
2372 tcg_gen_remu_i32(arg[0].out,
2373 arg[1].in, arg[2].in);
2376 static void translate_rer(DisasContext *dc, const OpcodeArg arg[],
2377 const uint32_t par[])
2379 gen_helper_rer(arg[0].out, cpu_env, arg[1].in);
2382 static void translate_ret(DisasContext *dc, const OpcodeArg arg[],
2383 const uint32_t par[])
2385 gen_jump(dc, cpu_R[0]);
2388 static bool test_ill_retw(DisasContext *dc, const OpcodeArg arg[],
2389 const uint32_t par[])
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);
2398 gen_helper_test_ill_retw(cpu_env, tmp);
2399 tcg_temp_free(tmp);
2400 return false;
2404 static void translate_retw(DisasContext *dc, const OpcodeArg arg[],
2405 const uint32_t par[])
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);
2418 static void translate_rfde(DisasContext *dc, const OpcodeArg arg[],
2419 const uint32_t par[])
2421 gen_jump(dc, cpu_SR[dc->config->ndepc ? DEPC : EPC1]);
2424 static void translate_rfe(DisasContext *dc, const OpcodeArg arg[],
2425 const uint32_t par[])
2427 tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_EXCM);
2428 gen_jump(dc, cpu_SR[EPC1]);
2431 static void translate_rfi(DisasContext *dc, const OpcodeArg arg[],
2432 const uint32_t par[])
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]);
2438 static void translate_rfw(DisasContext *dc, const OpcodeArg arg[],
2439 const uint32_t par[])
2441 TCGv_i32 tmp = tcg_const_i32(1);
2443 tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_EXCM);
2444 tcg_gen_shl_i32(tmp, tmp, cpu_SR[WINDOW_BASE]);
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);
2454 tcg_temp_free(tmp);
2455 gen_helper_restore_owb(cpu_env);
2456 gen_jump(dc, cpu_SR[EPC1]);
2459 static void translate_rotw(DisasContext *dc, const OpcodeArg arg[],
2460 const uint32_t par[])
2462 tcg_gen_addi_i32(cpu_windowbase_next, cpu_SR[WINDOW_BASE], arg[0].imm);
2465 static void translate_rsil(DisasContext *dc, const OpcodeArg arg[],
2466 const uint32_t par[])
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);
2473 static bool test_ill_rsr(DisasContext *dc, const OpcodeArg arg[],
2474 const uint32_t par[])
2476 return !check_sr(dc, par[0], SR_R);
2479 static void translate_rsr(DisasContext *dc, const OpcodeArg arg[],
2480 const uint32_t par[])
2482 gen_rsr(dc, arg[0].out, par[0]);
2485 static void translate_rtlb(DisasContext *dc, const OpcodeArg arg[],
2486 const uint32_t par[])
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,
2494 TCGv_i32 dtlb = tcg_const_i32(par[0]);
2496 helper[par[1]](arg[0].out, cpu_env, arg[1].in, dtlb);
2497 tcg_temp_free(dtlb);
2498 #endif
2501 static void translate_rur(DisasContext *dc, const OpcodeArg arg[],
2502 const uint32_t par[])
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]);
2511 static void translate_setb_expstate(DisasContext *dc, const OpcodeArg arg[],
2512 const uint32_t par[])
2514 /* TODO: GPIO32 may be a part of coprocessor */
2515 tcg_gen_ori_i32(cpu_UR[EXPSTATE], cpu_UR[EXPSTATE], 1u << arg[0].imm);
2518 #ifdef CONFIG_USER_ONLY
2519 static void gen_check_atomctl(DisasContext *dc, TCGv_i32 addr)
2522 #else
2523 static void gen_check_atomctl(DisasContext *dc, TCGv_i32 addr)
2525 TCGv_i32 tpc = tcg_const_i32(dc->pc);
2527 gen_helper_check_atomctl(cpu_env, tpc, addr);
2528 tcg_temp_free(tpc);
2530 #endif
2532 static void translate_s32c1i(DisasContext *dc, const OpcodeArg arg[],
2533 const uint32_t par[])
2535 TCGv_i32 tmp = tcg_temp_local_new_i32();
2536 TCGv_i32 addr = tcg_temp_local_new_i32();
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);
2548 static void translate_s32e(DisasContext *dc, const OpcodeArg arg[],
2549 const uint32_t par[])
2551 TCGv_i32 addr = tcg_temp_new_i32();
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);
2559 static void translate_salt(DisasContext *dc, const OpcodeArg arg[],
2560 const uint32_t par[])
2562 tcg_gen_setcond_i32(par[0],
2563 arg[0].out,
2564 arg[1].in, arg[2].in);
2567 static void translate_sext(DisasContext *dc, const OpcodeArg arg[],
2568 const uint32_t par[])
2570 int shift = 31 - arg[2].imm;
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);
2584 static bool test_ill_simcall(DisasContext *dc, const OpcodeArg arg[],
2585 const uint32_t par[])
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");
2595 return ill;
2598 static void translate_simcall(DisasContext *dc, const OpcodeArg arg[],
2599 const uint32_t par[])
2601 #ifndef CONFIG_USER_ONLY
2602 gen_helper_simcall(cpu_env);
2603 #endif
2607 * Note: 64 bit ops are used here solely because SAR values
2608 * have range 0..63
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)
2619 #define gen_shift(cmd) gen_shift_reg(cmd, cpu_SR[SAR])
2621 static void translate_sll(DisasContext *dc, const OpcodeArg arg[],
2622 const uint32_t par[])
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);
2637 static void translate_slli(DisasContext *dc, const OpcodeArg arg[],
2638 const uint32_t par[])
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);
2644 tcg_gen_shli_i32(arg[0].out, arg[1].in, arg[2].imm & 0x1f);
2647 static void translate_sra(DisasContext *dc, const OpcodeArg arg[],
2648 const uint32_t par[])
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);
2659 static void translate_srai(DisasContext *dc, const OpcodeArg arg[],
2660 const uint32_t par[])
2662 tcg_gen_sari_i32(arg[0].out, arg[1].in, arg[2].imm);
2665 static void translate_src(DisasContext *dc, const OpcodeArg arg[],
2666 const uint32_t par[])
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);
2673 static void translate_srl(DisasContext *dc, const OpcodeArg arg[],
2674 const uint32_t par[])
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);
2685 #undef gen_shift
2686 #undef gen_shift_reg
2688 static void translate_srli(DisasContext *dc, const OpcodeArg arg[],
2689 const uint32_t par[])
2691 tcg_gen_shri_i32(arg[0].out, arg[1].in, arg[2].imm);
2694 static void translate_ssa8b(DisasContext *dc, const OpcodeArg arg[],
2695 const uint32_t par[])
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);
2703 static void translate_ssa8l(DisasContext *dc, const OpcodeArg arg[],
2704 const uint32_t par[])
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);
2712 static void translate_ssai(DisasContext *dc, const OpcodeArg arg[],
2713 const uint32_t par[])
2715 TCGv_i32 tmp = tcg_const_i32(arg[0].imm);
2716 gen_right_shift_sar(dc, tmp);
2717 tcg_temp_free(tmp);
2720 static void translate_ssl(DisasContext *dc, const OpcodeArg arg[],
2721 const uint32_t par[])
2723 gen_left_shift_sar(dc, arg[0].in);
2726 static void translate_ssr(DisasContext *dc, const OpcodeArg arg[],
2727 const uint32_t par[])
2729 gen_right_shift_sar(dc, arg[0].in);
2732 static void translate_sub(DisasContext *dc, const OpcodeArg arg[],
2733 const uint32_t par[])
2735 tcg_gen_sub_i32(arg[0].out, arg[1].in, arg[2].in);
2738 static void translate_subx(DisasContext *dc, const OpcodeArg arg[],
2739 const uint32_t par[])
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);
2747 static void translate_waiti(DisasContext *dc, const OpcodeArg arg[],
2748 const uint32_t par[])
2750 #ifndef CONFIG_USER_ONLY
2751 gen_waiti(dc, arg[0].imm);
2752 #endif
2755 static void translate_wtlb(DisasContext *dc, const OpcodeArg arg[],
2756 const uint32_t par[])
2758 #ifndef CONFIG_USER_ONLY
2759 TCGv_i32 dtlb = tcg_const_i32(par[0]);
2761 gen_helper_wtlb(cpu_env, arg[0].in, arg[1].in, dtlb);
2762 tcg_temp_free(dtlb);
2763 #endif
2766 static void translate_wer(DisasContext *dc, const OpcodeArg arg[],
2767 const uint32_t par[])
2769 gen_helper_wer(cpu_env, arg[0].in, arg[1].in);
2772 static void translate_wrmsk_expstate(DisasContext *dc, const OpcodeArg arg[],
2773 const uint32_t par[])
2775 /* TODO: GPIO32 may be a part of coprocessor */
2776 tcg_gen_and_i32(cpu_UR[EXPSTATE], arg[0].in, arg[1].in);
2779 static bool test_ill_wsr(DisasContext *dc, const OpcodeArg arg[],
2780 const uint32_t par[])
2782 return !check_sr(dc, par[0], SR_W);
2785 static void translate_wsr(DisasContext *dc, const OpcodeArg arg[],
2786 const uint32_t par[])
2788 gen_wsr(dc, par[0], arg[0].in);
2791 static void translate_wur(DisasContext *dc, const OpcodeArg arg[],
2792 const uint32_t par[])
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]);
2801 static void translate_xor(DisasContext *dc, const OpcodeArg arg[],
2802 const uint32_t par[])
2804 tcg_gen_xor_i32(arg[0].out, arg[1].in, arg[2].in);
2807 static bool test_ill_xsr(DisasContext *dc, const OpcodeArg arg[],
2808 const uint32_t par[])
2810 return !check_sr(dc, par[0], SR_X);
2813 static void translate_xsr(DisasContext *dc, const OpcodeArg arg[],
2814 const uint32_t par[])
2816 TCGv_i32 tmp = tcg_temp_new_i32();
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);
2824 static const XtensaOpcodeOps core_ops[] = {
2826 .name = "abs",
2827 .translate = translate_abs,
2828 }, {
2829 .name = (const char * const[]) {
2830 "add", "add.n", NULL,
2832 .translate = translate_add,
2833 .op_flags = XTENSA_OP_NAME_ARRAY,
2834 }, {
2835 .name = (const char * const[]) {
2836 "addi", "addi.n", NULL,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
3704 .translate = translate_ret,
3705 .op_flags = XTENSA_OP_NAME_ARRAY,
3706 }, {
3707 .name = (const char * const[]) {
3708 "retw", "retw.n", NULL,
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,
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,
5343 const XtensaOpcodeTranslators xtensa_core_opcodes = {
5344 .num_opcodes = ARRAY_SIZE(core_ops),
5345 .opcode = core_ops,
5349 static void translate_abs_s(DisasContext *dc, const OpcodeArg arg[],
5350 const uint32_t par[])
5352 gen_helper_abs_s(arg[0].out, arg[1].in);
5355 static void translate_add_s(DisasContext *dc, const OpcodeArg arg[],
5356 const uint32_t par[])
5358 gen_helper_add_s(arg[0].out, cpu_env,
5359 arg[1].in, arg[2].in);
5362 enum {
5363 COMPARE_UN,
5364 COMPARE_OEQ,
5365 COMPARE_UEQ,
5366 COMPARE_OLT,
5367 COMPARE_ULT,
5368 COMPARE_OLE,
5369 COMPARE_ULE,
5372 static void translate_compare_s(DisasContext *dc, const OpcodeArg arg[],
5373 const uint32_t par[])
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,
5385 TCGv_i32 bit = tcg_const_i32(1 << arg[0].imm);
5387 helper[par[0]](cpu_env, bit, arg[1].in, arg[2].in);
5388 tcg_temp_free(bit);
5391 static void translate_float_s(DisasContext *dc, const OpcodeArg arg[],
5392 const uint32_t par[])
5394 TCGv_i32 scale = tcg_const_i32(-arg[2].imm);
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);
5401 tcg_temp_free(scale);
5404 static void translate_ftoi_s(DisasContext *dc, const OpcodeArg arg[],
5405 const uint32_t par[])
5407 TCGv_i32 rounding_mode = tcg_const_i32(par[0]);
5408 TCGv_i32 scale = tcg_const_i32(arg[2].imm);
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);
5417 tcg_temp_free(rounding_mode);
5418 tcg_temp_free(scale);
5421 static void translate_ldsti(DisasContext *dc, const OpcodeArg arg[],
5422 const uint32_t par[])
5424 TCGv_i32 addr = tcg_temp_new_i32();
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);
5433 if (par[1]) {
5434 tcg_gen_mov_i32(arg[1].out, addr);
5436 tcg_temp_free(addr);
5439 static void translate_ldstx(DisasContext *dc, const OpcodeArg arg[],
5440 const uint32_t par[])
5442 TCGv_i32 addr = tcg_temp_new_i32();
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);
5451 if (par[1]) {
5452 tcg_gen_mov_i32(arg[1].out, addr);
5454 tcg_temp_free(addr);
5457 static void translate_madd_s(DisasContext *dc, const OpcodeArg arg[],
5458 const uint32_t par[])
5460 gen_helper_madd_s(arg[0].out, cpu_env,
5461 arg[0].in, arg[1].in, arg[2].in);
5464 static void translate_mov_s(DisasContext *dc, const OpcodeArg arg[],
5465 const uint32_t par[])
5467 tcg_gen_mov_i32(arg[0].out, arg[1].in);
5470 static void translate_movcond_s(DisasContext *dc, const OpcodeArg arg[],
5471 const uint32_t par[])
5473 TCGv_i32 zero = tcg_const_i32(0);
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);
5481 static void translate_movp_s(DisasContext *dc, const OpcodeArg arg[],
5482 const uint32_t par[])
5484 TCGv_i32 zero = tcg_const_i32(0);
5485 TCGv_i32 tmp = tcg_temp_new_i32();
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);
5495 static void translate_mul_s(DisasContext *dc, const OpcodeArg arg[],
5496 const uint32_t par[])
5498 gen_helper_mul_s(arg[0].out, cpu_env,
5499 arg[1].in, arg[2].in);
5502 static void translate_msub_s(DisasContext *dc, const OpcodeArg arg[],
5503 const uint32_t par[])
5505 gen_helper_msub_s(arg[0].out, cpu_env,
5506 arg[0].in, arg[1].in, arg[2].in);
5509 static void translate_neg_s(DisasContext *dc, const OpcodeArg arg[],
5510 const uint32_t par[])
5512 gen_helper_neg_s(arg[0].out, arg[1].in);
5515 static void translate_rfr_s(DisasContext *dc, const OpcodeArg arg[],
5516 const uint32_t par[])
5518 tcg_gen_mov_i32(arg[0].out, arg[1].in);
5521 static void translate_sub_s(DisasContext *dc, const OpcodeArg arg[],
5522 const uint32_t par[])
5524 gen_helper_sub_s(arg[0].out, cpu_env,
5525 arg[1].in, arg[2].in);
5528 static void translate_wfr_s(DisasContext *dc, const OpcodeArg arg[],
5529 const uint32_t par[])
5531 tcg_gen_mov_i32(arg[0].out, arg[1].in);
5534 static const XtensaOpcodeOps fpu2000_ops[] = {
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,
5726 const XtensaOpcodeTranslators xtensa_fpu2000_opcodes = {
5727 .num_opcodes = ARRAY_SIZE(fpu2000_ops),
5728 .opcode = fpu2000_ops,