3 * http://www.tensilica.com/products/literature-docs/documentation/xtensa-isa-databook.htm
5 * Copyright (c) 2011, Max Filippov, Open Source and Linux Lab.
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"
34 #include "exec/exec-all.h"
35 #include "disas/disas.h"
38 #include "qemu/qemu-print.h"
39 #include "sysemu/sysemu.h"
40 #include "exec/cpu_ldst.h"
41 #include "exec/semihost.h"
42 #include "exec/translator.h"
44 #include "exec/helper-proto.h"
45 #include "exec/helper-gen.h"
47 #include "trace-tcg.h"
52 DisasContextBase base;
53 const XtensaConfig *config;
62 bool sar_m32_allocated;
76 xtensa_insnbuf insnbuf;
77 xtensa_insnbuf slotbuf;
80 static TCGv_i32 cpu_pc;
81 static TCGv_i32 cpu_R[16];
82 static TCGv_i32 cpu_FR[16];
83 static TCGv_i32 cpu_MR[4];
84 static TCGv_i32 cpu_BR[16];
85 static TCGv_i32 cpu_BR4[4];
86 static TCGv_i32 cpu_BR8[2];
87 static TCGv_i32 cpu_SR[256];
88 static TCGv_i32 cpu_UR[256];
89 static TCGv_i32 cpu_windowbase_next;
91 static GHashTable *xtensa_regfile_table;
93 #include "exec/gen-icount.h"
95 static char *sr_name[256];
96 static char *ur_name[256];
98 void xtensa_collect_sr_names(const XtensaConfig *config)
100 xtensa_isa isa = config->isa;
101 int n = xtensa_isa_num_sysregs(isa);
104 for (i = 0; i < n; ++i) {
105 int sr = xtensa_sysreg_number(isa, i);
107 if (sr >= 0 && sr < 256) {
108 const char *name = xtensa_sysreg_name(isa, i);
110 (xtensa_sysreg_is_user(isa, i) ? ur_name : sr_name) + sr;
113 if (strstr(*pname, name) == NULL) {
115 malloc(strlen(*pname) + strlen(name) + 2);
117 strcpy(new_name, *pname);
118 strcat(new_name, "/");
119 strcat(new_name, name);
124 *pname = strdup(name);
130 void xtensa_translate_init(void)
132 static const char * const regnames[] = {
133 "ar0", "ar1", "ar2", "ar3",
134 "ar4", "ar5", "ar6", "ar7",
135 "ar8", "ar9", "ar10", "ar11",
136 "ar12", "ar13", "ar14", "ar15",
138 static const char * const fregnames[] = {
139 "f0", "f1", "f2", "f3",
140 "f4", "f5", "f6", "f7",
141 "f8", "f9", "f10", "f11",
142 "f12", "f13", "f14", "f15",
144 static const char * const mregnames[] = {
145 "m0", "m1", "m2", "m3",
147 static const char * const bregnames[] = {
148 "b0", "b1", "b2", "b3",
149 "b4", "b5", "b6", "b7",
150 "b8", "b9", "b10", "b11",
151 "b12", "b13", "b14", "b15",
155 cpu_pc = tcg_global_mem_new_i32(cpu_env,
156 offsetof(CPUXtensaState, pc), "pc");
158 for (i = 0; i < 16; i++) {
159 cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
160 offsetof(CPUXtensaState, regs[i]),
164 for (i = 0; i < 16; i++) {
165 cpu_FR[i] = tcg_global_mem_new_i32(cpu_env,
166 offsetof(CPUXtensaState,
167 fregs[i].f32[FP_F32_LOW]),
171 for (i = 0; i < 4; i++) {
172 cpu_MR[i] = tcg_global_mem_new_i32(cpu_env,
173 offsetof(CPUXtensaState,
178 for (i = 0; i < 16; i++) {
179 cpu_BR[i] = tcg_global_mem_new_i32(cpu_env,
180 offsetof(CPUXtensaState,
184 cpu_BR4[i / 4] = tcg_global_mem_new_i32(cpu_env,
185 offsetof(CPUXtensaState,
190 cpu_BR8[i / 8] = tcg_global_mem_new_i32(cpu_env,
191 offsetof(CPUXtensaState,
197 for (i = 0; i < 256; ++i) {
199 cpu_SR[i] = tcg_global_mem_new_i32(cpu_env,
200 offsetof(CPUXtensaState,
206 for (i = 0; i < 256; ++i) {
208 cpu_UR[i] = tcg_global_mem_new_i32(cpu_env,
209 offsetof(CPUXtensaState,
215 cpu_windowbase_next =
216 tcg_global_mem_new_i32(cpu_env,
217 offsetof(CPUXtensaState, windowbase_next),
221 void **xtensa_get_regfile_by_name(const char *name)
223 if (xtensa_regfile_table == NULL) {
224 xtensa_regfile_table = g_hash_table_new(g_str_hash, g_str_equal);
225 g_hash_table_insert(xtensa_regfile_table,
226 (void *)"AR", (void *)cpu_R);
227 g_hash_table_insert(xtensa_regfile_table,
228 (void *)"MR", (void *)cpu_MR);
229 g_hash_table_insert(xtensa_regfile_table,
230 (void *)"FR", (void *)cpu_FR);
231 g_hash_table_insert(xtensa_regfile_table,
232 (void *)"BR", (void *)cpu_BR);
233 g_hash_table_insert(xtensa_regfile_table,
234 (void *)"BR4", (void *)cpu_BR4);
235 g_hash_table_insert(xtensa_regfile_table,
236 (void *)"BR8", (void *)cpu_BR8);
238 return (void **)g_hash_table_lookup(xtensa_regfile_table, (void *)name);
241 static inline bool option_enabled(DisasContext *dc, int opt)
243 return xtensa_option_enabled(dc->config, opt);
246 static void init_sar_tracker(DisasContext *dc)
248 dc->sar_5bit = false;
249 dc->sar_m32_5bit = false;
250 dc->sar_m32_allocated = false;
253 static void reset_sar_tracker(DisasContext *dc)
255 if (dc->sar_m32_allocated) {
256 tcg_temp_free(dc->sar_m32);
260 static void gen_right_shift_sar(DisasContext *dc, TCGv_i32 sa)
262 tcg_gen_andi_i32(cpu_SR[SAR], sa, 0x1f);
263 if (dc->sar_m32_5bit) {
264 tcg_gen_discard_i32(dc->sar_m32);
267 dc->sar_m32_5bit = false;
270 static void gen_left_shift_sar(DisasContext *dc, TCGv_i32 sa)
272 TCGv_i32 tmp = tcg_const_i32(32);
273 if (!dc->sar_m32_allocated) {
274 dc->sar_m32 = tcg_temp_local_new_i32();
275 dc->sar_m32_allocated = true;
277 tcg_gen_andi_i32(dc->sar_m32, sa, 0x1f);
278 tcg_gen_sub_i32(cpu_SR[SAR], tmp, dc->sar_m32);
279 dc->sar_5bit = false;
280 dc->sar_m32_5bit = true;
284 static void gen_exception(DisasContext *dc, int excp)
286 TCGv_i32 tmp = tcg_const_i32(excp);
287 gen_helper_exception(cpu_env, tmp);
291 static void gen_exception_cause(DisasContext *dc, uint32_t cause)
293 TCGv_i32 tpc = tcg_const_i32(dc->pc);
294 TCGv_i32 tcause = tcg_const_i32(cause);
295 gen_helper_exception_cause(cpu_env, tpc, tcause);
297 tcg_temp_free(tcause);
298 if (cause == ILLEGAL_INSTRUCTION_CAUSE ||
299 cause == SYSCALL_CAUSE) {
300 dc->base.is_jmp = DISAS_NORETURN;
304 static void gen_exception_cause_vaddr(DisasContext *dc, uint32_t cause,
307 TCGv_i32 tpc = tcg_const_i32(dc->pc);
308 TCGv_i32 tcause = tcg_const_i32(cause);
309 gen_helper_exception_cause_vaddr(cpu_env, tpc, tcause, vaddr);
311 tcg_temp_free(tcause);
314 static void gen_debug_exception(DisasContext *dc, uint32_t cause)
316 TCGv_i32 tpc = tcg_const_i32(dc->pc);
317 TCGv_i32 tcause = tcg_const_i32(cause);
318 gen_helper_debug_exception(cpu_env, tpc, tcause);
320 tcg_temp_free(tcause);
321 if (cause & (DEBUGCAUSE_IB | DEBUGCAUSE_BI | DEBUGCAUSE_BN)) {
322 dc->base.is_jmp = DISAS_NORETURN;
326 static bool gen_check_privilege(DisasContext *dc)
328 #ifndef CONFIG_USER_ONLY
333 gen_exception_cause(dc, PRIVILEGED_CAUSE);
334 dc->base.is_jmp = DISAS_NORETURN;
338 static bool gen_check_cpenable(DisasContext *dc, uint32_t cp_mask)
340 cp_mask &= ~dc->cpenable;
342 if (option_enabled(dc, XTENSA_OPTION_COPROCESSOR) && cp_mask) {
343 gen_exception_cause(dc, COPROCESSOR0_DISABLED + ctz32(cp_mask));
344 dc->base.is_jmp = DISAS_NORETURN;
350 static int gen_postprocess(DisasContext *dc, int slot);
352 static void gen_jump_slot(DisasContext *dc, TCGv dest, int slot)
354 tcg_gen_mov_i32(cpu_pc, dest);
356 tcg_gen_mov_i32(cpu_SR[ICOUNT], dc->next_icount);
358 if (dc->base.singlestep_enabled) {
359 gen_exception(dc, EXCP_DEBUG);
361 if (dc->op_flags & XTENSA_OP_POSTPROCESS) {
362 slot = gen_postprocess(dc, slot);
365 tcg_gen_goto_tb(slot);
366 tcg_gen_exit_tb(dc->base.tb, slot);
368 tcg_gen_exit_tb(NULL, 0);
371 dc->base.is_jmp = DISAS_NORETURN;
374 static void gen_jump(DisasContext *dc, TCGv dest)
376 gen_jump_slot(dc, dest, -1);
379 static int adjust_jump_slot(DisasContext *dc, uint32_t dest, int slot)
381 if (((dc->base.pc_first ^ dest) & TARGET_PAGE_MASK) != 0) {
388 static void gen_jumpi(DisasContext *dc, uint32_t dest, int slot)
390 TCGv_i32 tmp = tcg_const_i32(dest);
391 gen_jump_slot(dc, tmp, adjust_jump_slot(dc, dest, slot));
395 static void gen_callw_slot(DisasContext *dc, int callinc, TCGv_i32 dest,
398 TCGv_i32 tcallinc = tcg_const_i32(callinc);
400 tcg_gen_deposit_i32(cpu_SR[PS], cpu_SR[PS],
401 tcallinc, PS_CALLINC_SHIFT, PS_CALLINC_LEN);
402 tcg_temp_free(tcallinc);
403 tcg_gen_movi_i32(cpu_R[callinc << 2],
404 (callinc << 30) | (dc->base.pc_next & 0x3fffffff));
405 gen_jump_slot(dc, dest, slot);
408 static bool gen_check_loop_end(DisasContext *dc, int slot)
410 if (dc->base.pc_next == dc->lend) {
411 TCGLabel *label = gen_new_label();
413 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_SR[LCOUNT], 0, label);
414 tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_SR[LCOUNT], 1);
416 gen_jumpi(dc, dc->base.pc_next - dc->lbeg_off, slot);
418 gen_jump(dc, cpu_SR[LBEG]);
420 gen_set_label(label);
421 gen_jumpi(dc, dc->base.pc_next, -1);
427 static void gen_jumpi_check_loop_end(DisasContext *dc, int slot)
429 if (!gen_check_loop_end(dc, slot)) {
430 gen_jumpi(dc, dc->base.pc_next, slot);
434 static void gen_brcond(DisasContext *dc, TCGCond cond,
435 TCGv_i32 t0, TCGv_i32 t1, uint32_t addr)
437 TCGLabel *label = gen_new_label();
439 tcg_gen_brcond_i32(cond, t0, t1, label);
440 gen_jumpi_check_loop_end(dc, 0);
441 gen_set_label(label);
442 gen_jumpi(dc, addr, 1);
445 static void gen_brcondi(DisasContext *dc, TCGCond cond,
446 TCGv_i32 t0, uint32_t t1, uint32_t addr)
448 TCGv_i32 tmp = tcg_const_i32(t1);
449 gen_brcond(dc, cond, t0, tmp, addr);
453 static bool test_ill_sr(DisasContext *dc, const OpcodeArg arg[],
454 const uint32_t par[])
456 return !xtensa_option_enabled(dc->config, par[1]);
459 static bool test_ill_ccompare(DisasContext *dc, const OpcodeArg arg[],
460 const uint32_t par[])
462 unsigned n = par[0] - CCOMPARE;
464 return test_ill_sr(dc, arg, par) || n >= dc->config->nccompare;
467 static bool test_ill_dbreak(DisasContext *dc, const OpcodeArg arg[],
468 const uint32_t par[])
470 unsigned n = MAX_NDBREAK;
472 if (par[0] >= DBREAKA && par[0] < DBREAKA + MAX_NDBREAK) {
473 n = par[0] - DBREAKA;
475 if (par[0] >= DBREAKC && par[0] < DBREAKC + MAX_NDBREAK) {
476 n = par[0] - DBREAKC;
478 return test_ill_sr(dc, arg, par) || n >= dc->config->ndbreak;
481 static bool test_ill_ibreak(DisasContext *dc, const OpcodeArg arg[],
482 const uint32_t par[])
484 unsigned n = par[0] - IBREAKA;
486 return test_ill_sr(dc, arg, par) || n >= dc->config->nibreak;
489 static bool test_ill_hpi(DisasContext *dc, const OpcodeArg arg[],
490 const uint32_t par[])
492 unsigned n = MAX_NLEVEL + 1;
494 if (par[0] >= EXCSAVE1 && par[0] < EXCSAVE1 + MAX_NLEVEL) {
495 n = par[0] - EXCSAVE1 + 1;
497 if (par[0] >= EPC1 && par[0] < EPC1 + MAX_NLEVEL) {
498 n = par[0] - EPC1 + 1;
500 if (par[0] >= EPS2 && par[0] < EPS2 + MAX_NLEVEL - 1) {
501 n = par[0] - EPS2 + 2;
503 return test_ill_sr(dc, arg, par) || n > dc->config->nlevel;
506 static void gen_load_store_alignment(DisasContext *dc, int shift,
507 TCGv_i32 addr, bool no_hw_alignment)
509 if (!option_enabled(dc, XTENSA_OPTION_UNALIGNED_EXCEPTION)) {
510 tcg_gen_andi_i32(addr, addr, ~0 << shift);
511 } else if (option_enabled(dc, XTENSA_OPTION_HW_ALIGNMENT) &&
513 TCGLabel *label = gen_new_label();
514 TCGv_i32 tmp = tcg_temp_new_i32();
515 tcg_gen_andi_i32(tmp, addr, ~(~0 << shift));
516 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
517 gen_exception_cause_vaddr(dc, LOAD_STORE_ALIGNMENT_CAUSE, addr);
518 gen_set_label(label);
523 #ifndef CONFIG_USER_ONLY
524 static void gen_waiti(DisasContext *dc, uint32_t imm4)
526 TCGv_i32 pc = tcg_const_i32(dc->base.pc_next);
527 TCGv_i32 intlevel = tcg_const_i32(imm4);
529 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
532 gen_helper_waiti(cpu_env, pc, intlevel);
533 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
537 tcg_temp_free(intlevel);
541 static bool gen_window_check(DisasContext *dc, uint32_t mask)
543 unsigned r = 31 - clz32(mask);
545 if (r / 4 > dc->window) {
546 TCGv_i32 pc = tcg_const_i32(dc->pc);
547 TCGv_i32 w = tcg_const_i32(r / 4);
549 gen_helper_window_check(cpu_env, pc, w);
550 dc->base.is_jmp = DISAS_NORETURN;
556 static TCGv_i32 gen_mac16_m(TCGv_i32 v, bool hi, bool is_unsigned)
558 TCGv_i32 m = tcg_temp_new_i32();
561 (is_unsigned ? tcg_gen_shri_i32 : tcg_gen_sari_i32)(m, v, 16);
563 (is_unsigned ? tcg_gen_ext16u_i32 : tcg_gen_ext16s_i32)(m, v);
568 static void gen_zero_check(DisasContext *dc, const OpcodeArg arg[])
570 TCGLabel *label = gen_new_label();
572 tcg_gen_brcondi_i32(TCG_COND_NE, arg[2].in, 0, label);
573 gen_exception_cause(dc, INTEGER_DIVIDE_BY_ZERO_CAUSE);
574 gen_set_label(label);
577 static inline unsigned xtensa_op0_insn_len(DisasContext *dc, uint8_t op0)
579 return xtensa_isa_length_from_chars(dc->config->isa, &op0);
582 static int gen_postprocess(DisasContext *dc, int slot)
584 uint32_t op_flags = dc->op_flags;
586 #ifndef CONFIG_USER_ONLY
587 if (op_flags & XTENSA_OP_CHECK_INTERRUPTS) {
588 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
591 gen_helper_check_interrupts(cpu_env);
592 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
597 if (op_flags & XTENSA_OP_SYNC_REGISTER_WINDOW) {
598 gen_helper_sync_windowbase(cpu_env);
600 if (op_flags & XTENSA_OP_EXIT_TB_M1) {
606 struct opcode_arg_copy {
612 struct opcode_arg_info {
618 XtensaOpcodeOps *ops;
619 OpcodeArg arg[MAX_OPCODE_ARGS];
620 struct opcode_arg_info in[MAX_OPCODE_ARGS];
621 struct opcode_arg_info out[MAX_OPCODE_ARGS];
633 static uint32_t encode_resource(enum resource_type r, unsigned g, unsigned n)
635 assert(r < RES_MAX && g < 256 && n < 65536);
636 return (r << 24) | (g << 16) | n;
639 static enum resource_type get_resource_type(uint32_t resource)
641 return resource >> 24;
645 * a depends on b if b must be executed before a,
646 * because a's side effects will destroy b's inputs.
648 static bool op_depends_on(const struct slot_prop *a,
649 const struct slot_prop *b)
654 if (a->op_flags & XTENSA_OP_CONTROL_FLOW) {
657 if ((a->op_flags & XTENSA_OP_LOAD_STORE) <
658 (b->op_flags & XTENSA_OP_LOAD_STORE)) {
661 while (i < a->n_out && j < b->n_in) {
662 if (a->out[i].resource < b->in[j].resource) {
664 } else if (a->out[i].resource > b->in[j].resource) {
674 * Try to break a dependency on b, append temporary register copy records
675 * to the end of copy and update n_copy in case of success.
676 * This is not always possible: e.g. control flow must always be the last,
677 * load/store must be first and state dependencies are not supported yet.
679 static bool break_dependency(struct slot_prop *a,
681 struct opcode_arg_copy *copy,
686 unsigned n = *n_copy;
689 if (a->op_flags & XTENSA_OP_CONTROL_FLOW) {
692 if ((a->op_flags & XTENSA_OP_LOAD_STORE) <
693 (b->op_flags & XTENSA_OP_LOAD_STORE)) {
696 while (i < a->n_out && j < b->n_in) {
697 if (a->out[i].resource < b->in[j].resource) {
699 } else if (a->out[i].resource > b->in[j].resource) {
702 int index = b->in[j].index;
704 if (get_resource_type(a->out[i].resource) != RES_REGFILE ||
708 copy[n].resource = b->in[j].resource;
709 copy[n].arg = b->arg + index;
720 * Calculate evaluation order for slot opcodes.
721 * Build opcode order graph and output its nodes in topological sort order.
722 * An edge a -> b in the graph means that opcode a must be followed by
725 static bool tsort(struct slot_prop *slot,
726 struct slot_prop *sorted[],
728 struct opcode_arg_copy *copy,
734 unsigned out_edge[MAX_INSN_SLOTS];
735 } node[MAX_INSN_SLOTS];
737 unsigned in[MAX_INSN_SLOTS];
743 unsigned node_idx = 0;
745 for (i = 0; i < n; ++i) {
746 node[i].n_in_edge = 0;
747 node[i].n_out_edge = 0;
750 for (i = 0; i < n; ++i) {
751 unsigned n_out_edge = 0;
753 for (j = 0; j < n; ++j) {
754 if (i != j && op_depends_on(slot + j, slot + i)) {
755 node[i].out_edge[n_out_edge] = j;
761 node[i].n_out_edge = n_out_edge;
764 for (i = 0; i < n; ++i) {
765 if (!node[i].n_in_edge) {
772 for (; in_idx < n_in; ++in_idx) {
774 sorted[n_out] = slot + i;
776 for (j = 0; j < node[i].n_out_edge; ++j) {
778 if (--node[node[i].out_edge[j]].n_in_edge == 0) {
779 in[n_in] = node[i].out_edge[j];
785 for (; node_idx < n; ++node_idx) {
786 struct tsnode *cnode = node + node_idx;
788 if (cnode->n_in_edge) {
789 for (j = 0; j < cnode->n_out_edge; ++j) {
790 unsigned k = cnode->out_edge[j];
792 if (break_dependency(slot + k, slot + node_idx,
794 --node[k].n_in_edge == 0) {
799 cnode->out_edge[cnode->n_out_edge - 1];
810 static void opcode_add_resource(struct slot_prop *op,
811 uint32_t resource, char direction,
817 assert(op->n_in < ARRAY_SIZE(op->in));
818 op->in[op->n_in].resource = resource;
819 op->in[op->n_in].index = index;
823 if (direction == 'm' || direction == 'o') {
824 assert(op->n_out < ARRAY_SIZE(op->out));
825 op->out[op->n_out].resource = resource;
826 op->out[op->n_out].index = index;
831 g_assert_not_reached();
835 static int resource_compare(const void *a, const void *b)
837 const struct opcode_arg_info *pa = a;
838 const struct opcode_arg_info *pb = b;
840 return pa->resource < pb->resource ?
841 -1 : (pa->resource > pb->resource ? 1 : 0);
844 static int arg_copy_compare(const void *a, const void *b)
846 const struct opcode_arg_copy *pa = a;
847 const struct opcode_arg_copy *pb = b;
849 return pa->resource < pb->resource ?
850 -1 : (pa->resource > pb->resource ? 1 : 0);
853 static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
855 xtensa_isa isa = dc->config->isa;
856 unsigned char b[MAX_INSN_LENGTH] = {cpu_ldub_code(env, dc->pc)};
857 unsigned len = xtensa_op0_insn_len(dc, b[0]);
861 uint32_t op_flags = 0;
862 struct slot_prop slot_prop[MAX_INSN_SLOTS];
863 struct slot_prop *ordered[MAX_INSN_SLOTS];
864 struct opcode_arg_copy arg_copy[MAX_INSN_SLOTS * MAX_OPCODE_ARGS];
865 unsigned n_arg_copy = 0;
866 uint32_t debug_cause = 0;
867 uint32_t windowed_register = 0;
868 uint32_t coprocessor = 0;
870 if (len == XTENSA_UNDEFINED) {
871 qemu_log_mask(LOG_GUEST_ERROR,
872 "unknown instruction length (pc = %08x)\n",
874 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
878 dc->base.pc_next = dc->pc + len;
879 for (i = 1; i < len; ++i) {
880 b[i] = cpu_ldub_code(env, dc->pc + i);
882 xtensa_insnbuf_from_chars(isa, dc->insnbuf, b, len);
883 fmt = xtensa_format_decode(isa, dc->insnbuf);
884 if (fmt == XTENSA_UNDEFINED) {
885 qemu_log_mask(LOG_GUEST_ERROR,
886 "unrecognized instruction format (pc = %08x)\n",
888 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
891 slots = xtensa_format_num_slots(isa, fmt);
892 for (slot = 0; slot < slots; ++slot) {
894 int opnd, vopnd, opnds;
895 OpcodeArg *arg = slot_prop[slot].arg;
896 XtensaOpcodeOps *ops;
898 xtensa_format_get_slot(isa, fmt, slot, dc->insnbuf, dc->slotbuf);
899 opc = xtensa_opcode_decode(isa, fmt, slot, dc->slotbuf);
900 if (opc == XTENSA_UNDEFINED) {
901 qemu_log_mask(LOG_GUEST_ERROR,
902 "unrecognized opcode in slot %d (pc = %08x)\n",
904 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
907 opnds = xtensa_opcode_num_operands(isa, opc);
909 for (opnd = vopnd = 0; opnd < opnds; ++opnd) {
910 void **register_file = NULL;
912 if (xtensa_operand_is_register(isa, opc, opnd)) {
913 xtensa_regfile rf = xtensa_operand_regfile(isa, opc, opnd);
915 register_file = dc->config->regfile[rf];
917 if (rf == dc->config->a_regfile) {
920 xtensa_operand_get_field(isa, opc, opnd, fmt, slot,
922 xtensa_operand_decode(isa, opc, opnd, &v);
923 windowed_register |= 1u << v;
926 if (xtensa_operand_is_visible(isa, opc, opnd)) {
929 xtensa_operand_get_field(isa, opc, opnd, fmt, slot,
931 xtensa_operand_decode(isa, opc, opnd, &v);
932 arg[vopnd].raw_imm = v;
933 if (xtensa_operand_is_PCrelative(isa, opc, opnd)) {
934 xtensa_operand_undo_reloc(isa, opc, opnd, &v, dc->pc);
938 arg[vopnd].in = register_file[v];
939 arg[vopnd].out = register_file[v];
944 ops = dc->config->opcode_ops[opc];
945 slot_prop[slot].ops = ops;
948 op_flags |= ops->op_flags;
950 qemu_log_mask(LOG_UNIMP,
951 "unimplemented opcode '%s' in slot %d (pc = %08x)\n",
952 xtensa_opcode_name(isa, opc), slot, dc->pc);
953 op_flags |= XTENSA_OP_ILL;
955 if ((op_flags & XTENSA_OP_ILL) ||
956 (ops && ops->test_ill && ops->test_ill(dc, arg, ops->par))) {
957 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
960 if (ops->op_flags & XTENSA_OP_DEBUG_BREAK) {
961 debug_cause |= ops->par[0];
963 if (ops->test_overflow) {
964 windowed_register |= ops->test_overflow(dc, arg, ops->par);
966 coprocessor |= ops->coprocessor;
969 slot_prop[slot].n_in = 0;
970 slot_prop[slot].n_out = 0;
971 slot_prop[slot].op_flags = ops->op_flags & XTENSA_OP_LOAD_STORE;
973 opnds = xtensa_opcode_num_operands(isa, opc);
975 for (opnd = vopnd = 0; opnd < opnds; ++opnd) {
976 bool visible = xtensa_operand_is_visible(isa, opc, opnd);
978 if (xtensa_operand_is_register(isa, opc, opnd)) {
979 xtensa_regfile rf = xtensa_operand_regfile(isa, opc, opnd);
982 xtensa_operand_get_field(isa, opc, opnd, fmt, slot,
984 xtensa_operand_decode(isa, opc, opnd, &v);
985 opcode_add_resource(slot_prop + slot,
986 encode_resource(RES_REGFILE, rf, v),
987 xtensa_operand_inout(isa, opc, opnd),
988 visible ? vopnd : -1);
995 opnds = xtensa_opcode_num_stateOperands(isa, opc);
997 for (opnd = 0; opnd < opnds; ++opnd) {
998 xtensa_state state = xtensa_stateOperand_state(isa, opc, opnd);
1000 opcode_add_resource(slot_prop + slot,
1001 encode_resource(RES_STATE, 0, state),
1002 xtensa_stateOperand_inout(isa, opc, opnd),
1005 if (xtensa_opcode_is_branch(isa, opc) ||
1006 xtensa_opcode_is_jump(isa, opc) ||
1007 xtensa_opcode_is_loop(isa, opc) ||
1008 xtensa_opcode_is_call(isa, opc)) {
1009 slot_prop[slot].op_flags |= XTENSA_OP_CONTROL_FLOW;
1012 qsort(slot_prop[slot].in, slot_prop[slot].n_in,
1013 sizeof(slot_prop[slot].in[0]), resource_compare);
1014 qsort(slot_prop[slot].out, slot_prop[slot].n_out,
1015 sizeof(slot_prop[slot].out[0]), resource_compare);
1020 if (!tsort(slot_prop, ordered, slots, arg_copy, &n_arg_copy)) {
1021 qemu_log_mask(LOG_UNIMP,
1022 "Circular resource dependencies (pc = %08x)\n",
1024 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
1028 ordered[0] = slot_prop + 0;
1031 if ((op_flags & XTENSA_OP_PRIVILEGED) &&
1032 !gen_check_privilege(dc)) {
1036 if (op_flags & XTENSA_OP_SYSCALL) {
1037 gen_exception_cause(dc, SYSCALL_CAUSE);
1041 if ((op_flags & XTENSA_OP_DEBUG_BREAK) && dc->debug) {
1042 gen_debug_exception(dc, debug_cause);
1046 if (windowed_register && !gen_window_check(dc, windowed_register)) {
1050 if (op_flags & XTENSA_OP_UNDERFLOW) {
1051 TCGv_i32 tmp = tcg_const_i32(dc->pc);
1053 gen_helper_test_underflow_retw(cpu_env, tmp);
1057 if (op_flags & XTENSA_OP_ALLOCA) {
1058 TCGv_i32 tmp = tcg_const_i32(dc->pc);
1060 gen_helper_movsp(cpu_env, tmp);
1064 if (coprocessor && !gen_check_cpenable(dc, coprocessor)) {
1073 qsort(arg_copy, n_arg_copy, sizeof(*arg_copy), arg_copy_compare);
1074 for (i = j = 0; i < n_arg_copy; ++i) {
1075 if (i == 0 || arg_copy[i].resource != resource) {
1076 resource = arg_copy[i].resource;
1077 temp = tcg_temp_local_new();
1078 tcg_gen_mov_i32(temp, arg_copy[i].arg->in);
1079 arg_copy[i].temp = temp;
1082 arg_copy[j] = arg_copy[i];
1086 arg_copy[i].arg->in = temp;
1091 if (op_flags & XTENSA_OP_DIVIDE_BY_ZERO) {
1092 for (slot = 0; slot < slots; ++slot) {
1093 if (slot_prop[slot].ops->op_flags & XTENSA_OP_DIVIDE_BY_ZERO) {
1094 gen_zero_check(dc, slot_prop[slot].arg);
1099 dc->op_flags = op_flags;
1101 for (slot = 0; slot < slots; ++slot) {
1102 struct slot_prop *pslot = ordered[slot];
1103 XtensaOpcodeOps *ops = pslot->ops;
1105 ops->translate(dc, pslot->arg, ops->par);
1108 for (i = 0; i < n_arg_copy; ++i) {
1109 tcg_temp_free(arg_copy[i].temp);
1112 if (dc->base.is_jmp == DISAS_NEXT) {
1113 gen_postprocess(dc, 0);
1115 if (op_flags & XTENSA_OP_EXIT_TB_M1) {
1116 /* Change in mmu index, memory mapping or tb->flags; exit tb */
1117 gen_jumpi_check_loop_end(dc, -1);
1118 } else if (op_flags & XTENSA_OP_EXIT_TB_0) {
1119 gen_jumpi_check_loop_end(dc, 0);
1121 gen_check_loop_end(dc, 0);
1124 dc->pc = dc->base.pc_next;
1127 static inline unsigned xtensa_insn_len(CPUXtensaState *env, DisasContext *dc)
1129 uint8_t b0 = cpu_ldub_code(env, dc->pc);
1130 return xtensa_op0_insn_len(dc, b0);
1133 static void gen_ibreak_check(CPUXtensaState *env, DisasContext *dc)
1137 for (i = 0; i < dc->config->nibreak; ++i) {
1138 if ((env->sregs[IBREAKENABLE] & (1 << i)) &&
1139 env->sregs[IBREAKA + i] == dc->pc) {
1140 gen_debug_exception(dc, DEBUGCAUSE_IB);
1146 static void xtensa_tr_init_disas_context(DisasContextBase *dcbase,
1149 DisasContext *dc = container_of(dcbase, DisasContext, base);
1150 CPUXtensaState *env = cpu->env_ptr;
1151 uint32_t tb_flags = dc->base.tb->flags;
1153 dc->config = env->config;
1154 dc->pc = dc->base.pc_first;
1155 dc->ring = tb_flags & XTENSA_TBFLAG_RING_MASK;
1156 dc->cring = (tb_flags & XTENSA_TBFLAG_EXCM) ? 0 : dc->ring;
1157 dc->lbeg_off = (dc->base.tb->cs_base & XTENSA_CSBASE_LBEG_OFF_MASK) >>
1158 XTENSA_CSBASE_LBEG_OFF_SHIFT;
1159 dc->lend = (dc->base.tb->cs_base & XTENSA_CSBASE_LEND_MASK) +
1160 (dc->base.pc_first & TARGET_PAGE_MASK);
1161 dc->debug = tb_flags & XTENSA_TBFLAG_DEBUG;
1162 dc->icount = tb_flags & XTENSA_TBFLAG_ICOUNT;
1163 dc->cpenable = (tb_flags & XTENSA_TBFLAG_CPENABLE_MASK) >>
1164 XTENSA_TBFLAG_CPENABLE_SHIFT;
1165 dc->window = ((tb_flags & XTENSA_TBFLAG_WINDOW_MASK) >>
1166 XTENSA_TBFLAG_WINDOW_SHIFT);
1167 dc->cwoe = tb_flags & XTENSA_TBFLAG_CWOE;
1168 dc->callinc = ((tb_flags & XTENSA_TBFLAG_CALLINC_MASK) >>
1169 XTENSA_TBFLAG_CALLINC_SHIFT);
1171 if (dc->config->isa) {
1172 dc->insnbuf = xtensa_insnbuf_alloc(dc->config->isa);
1173 dc->slotbuf = xtensa_insnbuf_alloc(dc->config->isa);
1175 init_sar_tracker(dc);
1178 static void xtensa_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
1180 DisasContext *dc = container_of(dcbase, DisasContext, base);
1183 dc->next_icount = tcg_temp_local_new_i32();
1187 static void xtensa_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
1189 tcg_gen_insn_start(dcbase->pc_next);
1192 static bool xtensa_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
1193 const CPUBreakpoint *bp)
1195 DisasContext *dc = container_of(dcbase, DisasContext, base);
1197 tcg_gen_movi_i32(cpu_pc, dc->base.pc_next);
1198 gen_exception(dc, EXCP_DEBUG);
1199 dc->base.is_jmp = DISAS_NORETURN;
1200 /* The address covered by the breakpoint must be included in
1201 [tb->pc, tb->pc + tb->size) in order to for it to be
1202 properly cleared -- thus we increment the PC here so that
1203 the logic setting tb->size below does the right thing. */
1204 dc->base.pc_next += 2;
1208 static void xtensa_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
1210 DisasContext *dc = container_of(dcbase, DisasContext, base);
1211 CPUXtensaState *env = cpu->env_ptr;
1212 target_ulong page_start;
1214 /* These two conditions only apply to the first insn in the TB,
1215 but this is the first TranslateOps hook that allows exiting. */
1216 if ((tb_cflags(dc->base.tb) & CF_USE_ICOUNT)
1217 && (dc->base.tb->flags & XTENSA_TBFLAG_YIELD)) {
1218 gen_exception(dc, EXCP_YIELD);
1219 dc->base.is_jmp = DISAS_NORETURN;
1222 if (dc->base.tb->flags & XTENSA_TBFLAG_EXCEPTION) {
1223 gen_exception(dc, EXCP_DEBUG);
1224 dc->base.is_jmp = DISAS_NORETURN;
1229 TCGLabel *label = gen_new_label();
1231 tcg_gen_addi_i32(dc->next_icount, cpu_SR[ICOUNT], 1);
1232 tcg_gen_brcondi_i32(TCG_COND_NE, dc->next_icount, 0, label);
1233 tcg_gen_mov_i32(dc->next_icount, cpu_SR[ICOUNT]);
1235 gen_debug_exception(dc, DEBUGCAUSE_IC);
1237 gen_set_label(label);
1241 gen_ibreak_check(env, dc);
1244 disas_xtensa_insn(env, dc);
1247 tcg_gen_mov_i32(cpu_SR[ICOUNT], dc->next_icount);
1250 /* End the TB if the next insn will cross into the next page. */
1251 page_start = dc->base.pc_first & TARGET_PAGE_MASK;
1252 if (dc->base.is_jmp == DISAS_NEXT &&
1253 (dc->pc - page_start >= TARGET_PAGE_SIZE ||
1254 dc->pc - page_start + xtensa_insn_len(env, dc) > TARGET_PAGE_SIZE)) {
1255 dc->base.is_jmp = DISAS_TOO_MANY;
1259 static void xtensa_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
1261 DisasContext *dc = container_of(dcbase, DisasContext, base);
1263 reset_sar_tracker(dc);
1264 if (dc->config->isa) {
1265 xtensa_insnbuf_free(dc->config->isa, dc->insnbuf);
1266 xtensa_insnbuf_free(dc->config->isa, dc->slotbuf);
1269 tcg_temp_free(dc->next_icount);
1272 switch (dc->base.is_jmp) {
1273 case DISAS_NORETURN:
1275 case DISAS_TOO_MANY:
1276 if (dc->base.singlestep_enabled) {
1277 tcg_gen_movi_i32(cpu_pc, dc->pc);
1278 gen_exception(dc, EXCP_DEBUG);
1280 gen_jumpi(dc, dc->pc, 0);
1284 g_assert_not_reached();
1288 static void xtensa_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
1290 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
1291 log_target_disas(cpu, dcbase->pc_first, dcbase->tb->size);
1294 static const TranslatorOps xtensa_translator_ops = {
1295 .init_disas_context = xtensa_tr_init_disas_context,
1296 .tb_start = xtensa_tr_tb_start,
1297 .insn_start = xtensa_tr_insn_start,
1298 .breakpoint_check = xtensa_tr_breakpoint_check,
1299 .translate_insn = xtensa_tr_translate_insn,
1300 .tb_stop = xtensa_tr_tb_stop,
1301 .disas_log = xtensa_tr_disas_log,
1304 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
1306 DisasContext dc = {};
1307 translator_loop(&xtensa_translator_ops, &dc.base, cpu, tb, max_insns);
1310 void xtensa_cpu_dump_state(CPUState *cs, FILE *f, int flags)
1312 XtensaCPU *cpu = XTENSA_CPU(cs);
1313 CPUXtensaState *env = &cpu->env;
1314 xtensa_isa isa = env->config->isa;
1317 qemu_fprintf(f, "PC=%08x\n\n", env->pc);
1319 for (i = j = 0; i < xtensa_isa_num_sysregs(isa); ++i) {
1320 const uint32_t *reg =
1321 xtensa_sysreg_is_user(isa, i) ? env->uregs : env->sregs;
1322 int regno = xtensa_sysreg_number(isa, i);
1325 qemu_fprintf(f, "%12s=%08x%c",
1326 xtensa_sysreg_name(isa, i),
1328 (j++ % 4) == 3 ? '\n' : ' ');
1332 qemu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n");
1334 for (i = 0; i < 16; ++i) {
1335 qemu_fprintf(f, " A%02d=%08x%c",
1336 i, env->regs[i], (i % 4) == 3 ? '\n' : ' ');
1339 xtensa_sync_phys_from_window(env);
1340 qemu_fprintf(f, "\n");
1342 for (i = 0; i < env->config->nareg; ++i) {
1343 qemu_fprintf(f, "AR%02d=%08x ", i, env->phys_regs[i]);
1345 bool ws = (env->sregs[WINDOW_START] & (1 << (i / 4))) != 0;
1346 bool cw = env->sregs[WINDOW_BASE] == i / 4;
1348 qemu_fprintf(f, "%c%c\n", ws ? '<' : ' ', cw ? '=' : ' ');
1352 if ((flags & CPU_DUMP_FPU) &&
1353 xtensa_option_enabled(env->config, XTENSA_OPTION_FP_COPROCESSOR)) {
1354 qemu_fprintf(f, "\n");
1356 for (i = 0; i < 16; ++i) {
1357 qemu_fprintf(f, "F%02d=%08x (%+10.8e)%c", i,
1358 float32_val(env->fregs[i].f32[FP_F32_LOW]),
1359 *(float *)(env->fregs[i].f32 + FP_F32_LOW),
1360 (i % 2) == 1 ? '\n' : ' ');
1365 void restore_state_to_opc(CPUXtensaState *env, TranslationBlock *tb,
1371 static void translate_abs(DisasContext *dc, const OpcodeArg arg[],
1372 const uint32_t par[])
1374 TCGv_i32 zero = tcg_const_i32(0);
1375 TCGv_i32 neg = tcg_temp_new_i32();
1377 tcg_gen_neg_i32(neg, arg[1].in);
1378 tcg_gen_movcond_i32(TCG_COND_GE, arg[0].out,
1379 arg[1].in, zero, arg[1].in, neg);
1381 tcg_temp_free(zero);
1384 static void translate_add(DisasContext *dc, const OpcodeArg arg[],
1385 const uint32_t par[])
1387 tcg_gen_add_i32(arg[0].out, arg[1].in, arg[2].in);
1390 static void translate_addi(DisasContext *dc, const OpcodeArg arg[],
1391 const uint32_t par[])
1393 tcg_gen_addi_i32(arg[0].out, arg[1].in, arg[2].imm);
1396 static void translate_addx(DisasContext *dc, const OpcodeArg arg[],
1397 const uint32_t par[])
1399 TCGv_i32 tmp = tcg_temp_new_i32();
1400 tcg_gen_shli_i32(tmp, arg[1].in, par[0]);
1401 tcg_gen_add_i32(arg[0].out, tmp, arg[2].in);
1405 static void translate_all(DisasContext *dc, const OpcodeArg arg[],
1406 const uint32_t par[])
1408 uint32_t shift = par[1];
1409 TCGv_i32 mask = tcg_const_i32(((1 << shift) - 1) << arg[1].imm);
1410 TCGv_i32 tmp = tcg_temp_new_i32();
1412 tcg_gen_and_i32(tmp, arg[1].in, mask);
1414 tcg_gen_addi_i32(tmp, tmp, 1 << arg[1].imm);
1416 tcg_gen_add_i32(tmp, tmp, mask);
1418 tcg_gen_shri_i32(tmp, tmp, arg[1].imm + shift);
1419 tcg_gen_deposit_i32(arg[0].out, arg[0].out,
1420 tmp, arg[0].imm, 1);
1421 tcg_temp_free(mask);
1425 static void translate_and(DisasContext *dc, const OpcodeArg arg[],
1426 const uint32_t par[])
1428 tcg_gen_and_i32(arg[0].out, arg[1].in, arg[2].in);
1431 static void translate_ball(DisasContext *dc, const OpcodeArg arg[],
1432 const uint32_t par[])
1434 TCGv_i32 tmp = tcg_temp_new_i32();
1435 tcg_gen_and_i32(tmp, arg[0].in, arg[1].in);
1436 gen_brcond(dc, par[0], tmp, arg[1].in, arg[2].imm);
1440 static void translate_bany(DisasContext *dc, const OpcodeArg arg[],
1441 const uint32_t par[])
1443 TCGv_i32 tmp = tcg_temp_new_i32();
1444 tcg_gen_and_i32(tmp, arg[0].in, arg[1].in);
1445 gen_brcondi(dc, par[0], tmp, 0, arg[2].imm);
1449 static void translate_b(DisasContext *dc, const OpcodeArg arg[],
1450 const uint32_t par[])
1452 gen_brcond(dc, par[0], arg[0].in, arg[1].in, arg[2].imm);
1455 static void translate_bb(DisasContext *dc, const OpcodeArg arg[],
1456 const uint32_t par[])
1458 #ifdef TARGET_WORDS_BIGENDIAN
1459 TCGv_i32 bit = tcg_const_i32(0x80000000u);
1461 TCGv_i32 bit = tcg_const_i32(0x00000001u);
1463 TCGv_i32 tmp = tcg_temp_new_i32();
1464 tcg_gen_andi_i32(tmp, arg[1].in, 0x1f);
1465 #ifdef TARGET_WORDS_BIGENDIAN
1466 tcg_gen_shr_i32(bit, bit, tmp);
1468 tcg_gen_shl_i32(bit, bit, tmp);
1470 tcg_gen_and_i32(tmp, arg[0].in, bit);
1471 gen_brcondi(dc, par[0], tmp, 0, arg[2].imm);
1476 static void translate_bbi(DisasContext *dc, const OpcodeArg arg[],
1477 const uint32_t par[])
1479 TCGv_i32 tmp = tcg_temp_new_i32();
1480 #ifdef TARGET_WORDS_BIGENDIAN
1481 tcg_gen_andi_i32(tmp, arg[0].in, 0x80000000u >> arg[1].imm);
1483 tcg_gen_andi_i32(tmp, arg[0].in, 0x00000001u << arg[1].imm);
1485 gen_brcondi(dc, par[0], tmp, 0, arg[2].imm);
1489 static void translate_bi(DisasContext *dc, const OpcodeArg arg[],
1490 const uint32_t par[])
1492 gen_brcondi(dc, par[0], arg[0].in, arg[1].imm, arg[2].imm);
1495 static void translate_bz(DisasContext *dc, const OpcodeArg arg[],
1496 const uint32_t par[])
1498 gen_brcondi(dc, par[0], arg[0].in, 0, arg[1].imm);
1509 static void translate_boolean(DisasContext *dc, const OpcodeArg arg[],
1510 const uint32_t par[])
1512 static void (* const op[])(TCGv_i32, TCGv_i32, TCGv_i32) = {
1513 [BOOLEAN_AND] = tcg_gen_and_i32,
1514 [BOOLEAN_ANDC] = tcg_gen_andc_i32,
1515 [BOOLEAN_OR] = tcg_gen_or_i32,
1516 [BOOLEAN_ORC] = tcg_gen_orc_i32,
1517 [BOOLEAN_XOR] = tcg_gen_xor_i32,
1520 TCGv_i32 tmp1 = tcg_temp_new_i32();
1521 TCGv_i32 tmp2 = tcg_temp_new_i32();
1523 tcg_gen_shri_i32(tmp1, arg[1].in, arg[1].imm);
1524 tcg_gen_shri_i32(tmp2, arg[2].in, arg[2].imm);
1525 op[par[0]](tmp1, tmp1, tmp2);
1526 tcg_gen_deposit_i32(arg[0].out, arg[0].out, tmp1, arg[0].imm, 1);
1527 tcg_temp_free(tmp1);
1528 tcg_temp_free(tmp2);
1531 static void translate_bp(DisasContext *dc, const OpcodeArg arg[],
1532 const uint32_t par[])
1534 TCGv_i32 tmp = tcg_temp_new_i32();
1536 tcg_gen_andi_i32(tmp, arg[0].in, 1 << arg[0].imm);
1537 gen_brcondi(dc, par[0], tmp, 0, arg[1].imm);
1541 static void translate_call0(DisasContext *dc, const OpcodeArg arg[],
1542 const uint32_t par[])
1544 tcg_gen_movi_i32(cpu_R[0], dc->base.pc_next);
1545 gen_jumpi(dc, arg[0].imm, 0);
1548 static void translate_callw(DisasContext *dc, const OpcodeArg arg[],
1549 const uint32_t par[])
1551 TCGv_i32 tmp = tcg_const_i32(arg[0].imm);
1552 gen_callw_slot(dc, par[0], tmp, adjust_jump_slot(dc, arg[0].imm, 0));
1556 static void translate_callx0(DisasContext *dc, const OpcodeArg arg[],
1557 const uint32_t par[])
1559 TCGv_i32 tmp = tcg_temp_new_i32();
1560 tcg_gen_mov_i32(tmp, arg[0].in);
1561 tcg_gen_movi_i32(cpu_R[0], dc->base.pc_next);
1566 static void translate_callxw(DisasContext *dc, const OpcodeArg arg[],
1567 const uint32_t par[])
1569 TCGv_i32 tmp = tcg_temp_new_i32();
1571 tcg_gen_mov_i32(tmp, arg[0].in);
1572 gen_callw_slot(dc, par[0], tmp, -1);
1576 static void translate_clamps(DisasContext *dc, const OpcodeArg arg[],
1577 const uint32_t par[])
1579 TCGv_i32 tmp1 = tcg_const_i32(-1u << arg[2].imm);
1580 TCGv_i32 tmp2 = tcg_const_i32((1 << arg[2].imm) - 1);
1582 tcg_gen_smax_i32(tmp1, tmp1, arg[1].in);
1583 tcg_gen_smin_i32(arg[0].out, tmp1, tmp2);
1584 tcg_temp_free(tmp1);
1585 tcg_temp_free(tmp2);
1588 static void translate_clrb_expstate(DisasContext *dc, const OpcodeArg arg[],
1589 const uint32_t par[])
1591 /* TODO: GPIO32 may be a part of coprocessor */
1592 tcg_gen_andi_i32(cpu_UR[EXPSTATE], cpu_UR[EXPSTATE], ~(1u << arg[0].imm));
1595 static void translate_const16(DisasContext *dc, const OpcodeArg arg[],
1596 const uint32_t par[])
1598 TCGv_i32 c = tcg_const_i32(arg[1].imm);
1600 tcg_gen_deposit_i32(arg[0].out, c, arg[0].in, 16, 16);
1604 static void translate_dcache(DisasContext *dc, const OpcodeArg arg[],
1605 const uint32_t par[])
1607 TCGv_i32 addr = tcg_temp_new_i32();
1608 TCGv_i32 res = tcg_temp_new_i32();
1610 tcg_gen_addi_i32(addr, arg[0].in, arg[1].imm);
1611 tcg_gen_qemu_ld8u(res, addr, dc->cring);
1612 tcg_temp_free(addr);
1616 static void translate_depbits(DisasContext *dc, const OpcodeArg arg[],
1617 const uint32_t par[])
1619 tcg_gen_deposit_i32(arg[1].out, arg[1].in, arg[0].in,
1620 arg[2].imm, arg[3].imm);
1623 static bool test_ill_entry(DisasContext *dc, const OpcodeArg arg[],
1624 const uint32_t par[])
1626 if (arg[0].imm > 3 || !dc->cwoe) {
1627 qemu_log_mask(LOG_GUEST_ERROR,
1628 "Illegal entry instruction(pc = %08x)\n", dc->pc);
1635 static uint32_t test_overflow_entry(DisasContext *dc, const OpcodeArg arg[],
1636 const uint32_t par[])
1638 return 1 << (dc->callinc * 4);
1641 static void translate_entry(DisasContext *dc, const OpcodeArg arg[],
1642 const uint32_t par[])
1644 TCGv_i32 pc = tcg_const_i32(dc->pc);
1645 TCGv_i32 s = tcg_const_i32(arg[0].imm);
1646 TCGv_i32 imm = tcg_const_i32(arg[1].imm);
1647 gen_helper_entry(cpu_env, pc, s, imm);
1653 static void translate_extui(DisasContext *dc, const OpcodeArg arg[],
1654 const uint32_t par[])
1656 int maskimm = (1 << arg[3].imm) - 1;
1658 TCGv_i32 tmp = tcg_temp_new_i32();
1659 tcg_gen_shri_i32(tmp, arg[1].in, arg[2].imm);
1660 tcg_gen_andi_i32(arg[0].out, tmp, maskimm);
1664 static void translate_icache(DisasContext *dc, const OpcodeArg arg[],
1665 const uint32_t par[])
1667 #ifndef CONFIG_USER_ONLY
1668 TCGv_i32 addr = tcg_temp_new_i32();
1670 tcg_gen_movi_i32(cpu_pc, dc->pc);
1671 tcg_gen_addi_i32(addr, arg[0].in, arg[1].imm);
1672 gen_helper_itlb_hit_test(cpu_env, addr);
1673 tcg_temp_free(addr);
1677 static void translate_itlb(DisasContext *dc, const OpcodeArg arg[],
1678 const uint32_t par[])
1680 #ifndef CONFIG_USER_ONLY
1681 TCGv_i32 dtlb = tcg_const_i32(par[0]);
1683 gen_helper_itlb(cpu_env, arg[0].in, dtlb);
1684 tcg_temp_free(dtlb);
1688 static void translate_j(DisasContext *dc, const OpcodeArg arg[],
1689 const uint32_t par[])
1691 gen_jumpi(dc, arg[0].imm, 0);
1694 static void translate_jx(DisasContext *dc, const OpcodeArg arg[],
1695 const uint32_t par[])
1697 gen_jump(dc, arg[0].in);
1700 static void translate_l32e(DisasContext *dc, const OpcodeArg arg[],
1701 const uint32_t par[])
1703 TCGv_i32 addr = tcg_temp_new_i32();
1705 tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm);
1706 gen_load_store_alignment(dc, 2, addr, false);
1707 tcg_gen_qemu_ld_tl(arg[0].out, addr, dc->ring, MO_TEUL);
1708 tcg_temp_free(addr);
1711 static void translate_ldst(DisasContext *dc, const OpcodeArg arg[],
1712 const uint32_t par[])
1714 TCGv_i32 addr = tcg_temp_new_i32();
1716 tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm);
1717 if (par[0] & MO_SIZE) {
1718 gen_load_store_alignment(dc, par[0] & MO_SIZE, addr, par[1]);
1722 tcg_gen_mb(TCG_BAR_STRL | TCG_MO_ALL);
1724 tcg_gen_qemu_st_tl(arg[0].in, addr, dc->cring, par[0]);
1726 tcg_gen_qemu_ld_tl(arg[0].out, addr, dc->cring, par[0]);
1728 tcg_gen_mb(TCG_BAR_LDAQ | TCG_MO_ALL);
1731 tcg_temp_free(addr);
1734 static void translate_l32r(DisasContext *dc, const OpcodeArg arg[],
1735 const uint32_t par[])
1739 if (dc->base.tb->flags & XTENSA_TBFLAG_LITBASE) {
1740 tmp = tcg_const_i32(arg[1].raw_imm - 1);
1741 tcg_gen_add_i32(tmp, cpu_SR[LITBASE], tmp);
1743 tmp = tcg_const_i32(arg[1].imm);
1745 tcg_gen_qemu_ld32u(arg[0].out, tmp, dc->cring);
1749 static void translate_loop(DisasContext *dc, const OpcodeArg arg[],
1750 const uint32_t par[])
1752 uint32_t lend = arg[1].imm;
1754 tcg_gen_subi_i32(cpu_SR[LCOUNT], arg[0].in, 1);
1755 tcg_gen_movi_i32(cpu_SR[LBEG], dc->base.pc_next);
1756 tcg_gen_movi_i32(cpu_SR[LEND], lend);
1758 if (par[0] != TCG_COND_NEVER) {
1759 TCGLabel *label = gen_new_label();
1760 tcg_gen_brcondi_i32(par[0], arg[0].in, 0, label);
1761 gen_jumpi(dc, lend, 1);
1762 gen_set_label(label);
1765 gen_jumpi(dc, dc->base.pc_next, 0);
1786 static void translate_mac16(DisasContext *dc, const OpcodeArg arg[],
1787 const uint32_t par[])
1790 unsigned half = par[1];
1791 uint32_t ld_offset = par[2];
1792 unsigned off = ld_offset ? 2 : 0;
1793 TCGv_i32 vaddr = tcg_temp_new_i32();
1794 TCGv_i32 mem32 = tcg_temp_new_i32();
1797 tcg_gen_addi_i32(vaddr, arg[1].in, ld_offset);
1798 gen_load_store_alignment(dc, 2, vaddr, false);
1799 tcg_gen_qemu_ld32u(mem32, vaddr, dc->cring);
1801 if (op != MAC16_NONE) {
1802 TCGv_i32 m1 = gen_mac16_m(arg[off].in,
1803 half & MAC16_HX, op == MAC16_UMUL);
1804 TCGv_i32 m2 = gen_mac16_m(arg[off + 1].in,
1805 half & MAC16_XH, op == MAC16_UMUL);
1807 if (op == MAC16_MUL || op == MAC16_UMUL) {
1808 tcg_gen_mul_i32(cpu_SR[ACCLO], m1, m2);
1809 if (op == MAC16_UMUL) {
1810 tcg_gen_movi_i32(cpu_SR[ACCHI], 0);
1812 tcg_gen_sari_i32(cpu_SR[ACCHI], cpu_SR[ACCLO], 31);
1815 TCGv_i32 lo = tcg_temp_new_i32();
1816 TCGv_i32 hi = tcg_temp_new_i32();
1818 tcg_gen_mul_i32(lo, m1, m2);
1819 tcg_gen_sari_i32(hi, lo, 31);
1820 if (op == MAC16_MULA) {
1821 tcg_gen_add2_i32(cpu_SR[ACCLO], cpu_SR[ACCHI],
1822 cpu_SR[ACCLO], cpu_SR[ACCHI],
1825 tcg_gen_sub2_i32(cpu_SR[ACCLO], cpu_SR[ACCHI],
1826 cpu_SR[ACCLO], cpu_SR[ACCHI],
1829 tcg_gen_ext8s_i32(cpu_SR[ACCHI], cpu_SR[ACCHI]);
1831 tcg_temp_free_i32(lo);
1832 tcg_temp_free_i32(hi);
1838 tcg_gen_mov_i32(arg[1].out, vaddr);
1839 tcg_gen_mov_i32(cpu_SR[MR + arg[0].imm], mem32);
1841 tcg_temp_free(vaddr);
1842 tcg_temp_free(mem32);
1845 static void translate_memw(DisasContext *dc, const OpcodeArg arg[],
1846 const uint32_t par[])
1848 tcg_gen_mb(TCG_BAR_SC | TCG_MO_ALL);
1851 static void translate_smin(DisasContext *dc, const OpcodeArg arg[],
1852 const uint32_t par[])
1854 tcg_gen_smin_i32(arg[0].out, arg[1].in, arg[2].in);
1857 static void translate_umin(DisasContext *dc, const OpcodeArg arg[],
1858 const uint32_t par[])
1860 tcg_gen_umin_i32(arg[0].out, arg[1].in, arg[2].in);
1863 static void translate_smax(DisasContext *dc, const OpcodeArg arg[],
1864 const uint32_t par[])
1866 tcg_gen_smax_i32(arg[0].out, arg[1].in, arg[2].in);
1869 static void translate_umax(DisasContext *dc, const OpcodeArg arg[],
1870 const uint32_t par[])
1872 tcg_gen_umax_i32(arg[0].out, arg[1].in, arg[2].in);
1875 static void translate_mov(DisasContext *dc, const OpcodeArg arg[],
1876 const uint32_t par[])
1878 tcg_gen_mov_i32(arg[0].out, arg[1].in);
1881 static void translate_movcond(DisasContext *dc, const OpcodeArg arg[],
1882 const uint32_t par[])
1884 TCGv_i32 zero = tcg_const_i32(0);
1886 tcg_gen_movcond_i32(par[0], arg[0].out,
1887 arg[2].in, zero, arg[1].in, arg[0].in);
1888 tcg_temp_free(zero);
1891 static void translate_movi(DisasContext *dc, const OpcodeArg arg[],
1892 const uint32_t par[])
1894 tcg_gen_movi_i32(arg[0].out, arg[1].imm);
1897 static void translate_movp(DisasContext *dc, const OpcodeArg arg[],
1898 const uint32_t par[])
1900 TCGv_i32 zero = tcg_const_i32(0);
1901 TCGv_i32 tmp = tcg_temp_new_i32();
1903 tcg_gen_andi_i32(tmp, arg[2].in, 1 << arg[2].imm);
1904 tcg_gen_movcond_i32(par[0],
1905 arg[0].out, tmp, zero,
1906 arg[1].in, arg[0].in);
1908 tcg_temp_free(zero);
1911 static void translate_movsp(DisasContext *dc, const OpcodeArg arg[],
1912 const uint32_t par[])
1914 tcg_gen_mov_i32(arg[0].out, arg[1].in);
1917 static void translate_mul16(DisasContext *dc, const OpcodeArg arg[],
1918 const uint32_t par[])
1920 TCGv_i32 v1 = tcg_temp_new_i32();
1921 TCGv_i32 v2 = tcg_temp_new_i32();
1924 tcg_gen_ext16s_i32(v1, arg[1].in);
1925 tcg_gen_ext16s_i32(v2, arg[2].in);
1927 tcg_gen_ext16u_i32(v1, arg[1].in);
1928 tcg_gen_ext16u_i32(v2, arg[2].in);
1930 tcg_gen_mul_i32(arg[0].out, v1, v2);
1935 static void translate_mull(DisasContext *dc, const OpcodeArg arg[],
1936 const uint32_t par[])
1938 tcg_gen_mul_i32(arg[0].out, arg[1].in, arg[2].in);
1941 static void translate_mulh(DisasContext *dc, const OpcodeArg arg[],
1942 const uint32_t par[])
1944 TCGv_i32 lo = tcg_temp_new();
1947 tcg_gen_muls2_i32(lo, arg[0].out, arg[1].in, arg[2].in);
1949 tcg_gen_mulu2_i32(lo, arg[0].out, arg[1].in, arg[2].in);
1954 static void translate_neg(DisasContext *dc, const OpcodeArg arg[],
1955 const uint32_t par[])
1957 tcg_gen_neg_i32(arg[0].out, arg[1].in);
1960 static void translate_nop(DisasContext *dc, const OpcodeArg arg[],
1961 const uint32_t par[])
1965 static void translate_nsa(DisasContext *dc, const OpcodeArg arg[],
1966 const uint32_t par[])
1968 tcg_gen_clrsb_i32(arg[0].out, arg[1].in);
1971 static void translate_nsau(DisasContext *dc, const OpcodeArg arg[],
1972 const uint32_t par[])
1974 tcg_gen_clzi_i32(arg[0].out, arg[1].in, 32);
1977 static void translate_or(DisasContext *dc, const OpcodeArg arg[],
1978 const uint32_t par[])
1980 tcg_gen_or_i32(arg[0].out, arg[1].in, arg[2].in);
1983 static void translate_ptlb(DisasContext *dc, const OpcodeArg arg[],
1984 const uint32_t par[])
1986 #ifndef CONFIG_USER_ONLY
1987 TCGv_i32 dtlb = tcg_const_i32(par[0]);
1989 tcg_gen_movi_i32(cpu_pc, dc->pc);
1990 gen_helper_ptlb(arg[0].out, cpu_env, arg[1].in, dtlb);
1991 tcg_temp_free(dtlb);
1995 static void translate_quos(DisasContext *dc, const OpcodeArg arg[],
1996 const uint32_t par[])
1998 TCGLabel *label1 = gen_new_label();
1999 TCGLabel *label2 = gen_new_label();
2001 tcg_gen_brcondi_i32(TCG_COND_NE, arg[1].in, 0x80000000,
2003 tcg_gen_brcondi_i32(TCG_COND_NE, arg[2].in, 0xffffffff,
2005 tcg_gen_movi_i32(arg[0].out,
2006 par[0] ? 0x80000000 : 0);
2008 gen_set_label(label1);
2010 tcg_gen_div_i32(arg[0].out,
2011 arg[1].in, arg[2].in);
2013 tcg_gen_rem_i32(arg[0].out,
2014 arg[1].in, arg[2].in);
2016 gen_set_label(label2);
2019 static void translate_quou(DisasContext *dc, const OpcodeArg arg[],
2020 const uint32_t par[])
2022 tcg_gen_divu_i32(arg[0].out,
2023 arg[1].in, arg[2].in);
2026 static void translate_read_impwire(DisasContext *dc, const OpcodeArg arg[],
2027 const uint32_t par[])
2029 /* TODO: GPIO32 may be a part of coprocessor */
2030 tcg_gen_movi_i32(arg[0].out, 0);
2033 static void translate_remu(DisasContext *dc, const OpcodeArg arg[],
2034 const uint32_t par[])
2036 tcg_gen_remu_i32(arg[0].out,
2037 arg[1].in, arg[2].in);
2040 static void translate_rer(DisasContext *dc, const OpcodeArg arg[],
2041 const uint32_t par[])
2043 gen_helper_rer(arg[0].out, cpu_env, arg[1].in);
2046 static void translate_ret(DisasContext *dc, const OpcodeArg arg[],
2047 const uint32_t par[])
2049 gen_jump(dc, cpu_R[0]);
2052 static bool test_ill_retw(DisasContext *dc, const OpcodeArg arg[],
2053 const uint32_t par[])
2056 qemu_log_mask(LOG_GUEST_ERROR,
2057 "Illegal retw instruction(pc = %08x)\n", dc->pc);
2060 TCGv_i32 tmp = tcg_const_i32(dc->pc);
2062 gen_helper_test_ill_retw(cpu_env, tmp);
2068 static void translate_retw(DisasContext *dc, const OpcodeArg arg[],
2069 const uint32_t par[])
2071 TCGv_i32 tmp = tcg_const_i32(1);
2072 tcg_gen_shl_i32(tmp, tmp, cpu_SR[WINDOW_BASE]);
2073 tcg_gen_andc_i32(cpu_SR[WINDOW_START],
2074 cpu_SR[WINDOW_START], tmp);
2075 tcg_gen_movi_i32(tmp, dc->pc);
2076 tcg_gen_deposit_i32(tmp, tmp, cpu_R[0], 0, 30);
2077 gen_helper_retw(cpu_env, cpu_R[0]);
2082 static void translate_rfde(DisasContext *dc, const OpcodeArg arg[],
2083 const uint32_t par[])
2085 gen_jump(dc, cpu_SR[dc->config->ndepc ? DEPC : EPC1]);
2088 static void translate_rfe(DisasContext *dc, const OpcodeArg arg[],
2089 const uint32_t par[])
2091 tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_EXCM);
2092 gen_jump(dc, cpu_SR[EPC1]);
2095 static void translate_rfi(DisasContext *dc, const OpcodeArg arg[],
2096 const uint32_t par[])
2098 tcg_gen_mov_i32(cpu_SR[PS], cpu_SR[EPS2 + arg[0].imm - 2]);
2099 gen_jump(dc, cpu_SR[EPC1 + arg[0].imm - 1]);
2102 static void translate_rfw(DisasContext *dc, const OpcodeArg arg[],
2103 const uint32_t par[])
2105 TCGv_i32 tmp = tcg_const_i32(1);
2107 tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_EXCM);
2108 tcg_gen_shl_i32(tmp, tmp, cpu_SR[WINDOW_BASE]);
2111 tcg_gen_andc_i32(cpu_SR[WINDOW_START],
2112 cpu_SR[WINDOW_START], tmp);
2114 tcg_gen_or_i32(cpu_SR[WINDOW_START],
2115 cpu_SR[WINDOW_START], tmp);
2119 gen_helper_restore_owb(cpu_env);
2120 gen_jump(dc, cpu_SR[EPC1]);
2123 static void translate_rotw(DisasContext *dc, const OpcodeArg arg[],
2124 const uint32_t par[])
2126 tcg_gen_addi_i32(cpu_windowbase_next, cpu_SR[WINDOW_BASE], arg[0].imm);
2129 static void translate_rsil(DisasContext *dc, const OpcodeArg arg[],
2130 const uint32_t par[])
2132 tcg_gen_mov_i32(arg[0].out, cpu_SR[PS]);
2133 tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_INTLEVEL);
2134 tcg_gen_ori_i32(cpu_SR[PS], cpu_SR[PS], arg[1].imm);
2137 static void translate_rsr(DisasContext *dc, const OpcodeArg arg[],
2138 const uint32_t par[])
2140 tcg_gen_mov_i32(arg[0].out, cpu_SR[par[0]]);
2143 static void translate_rsr_ccount(DisasContext *dc, const OpcodeArg arg[],
2144 const uint32_t par[])
2146 #ifndef CONFIG_USER_ONLY
2147 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
2150 gen_helper_update_ccount(cpu_env);
2151 tcg_gen_mov_i32(arg[0].out, cpu_SR[par[0]]);
2152 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
2158 static void translate_rsr_ptevaddr(DisasContext *dc, const OpcodeArg arg[],
2159 const uint32_t par[])
2161 #ifndef CONFIG_USER_ONLY
2162 TCGv_i32 tmp = tcg_temp_new_i32();
2164 tcg_gen_shri_i32(tmp, cpu_SR[EXCVADDR], 10);
2165 tcg_gen_or_i32(tmp, tmp, cpu_SR[PTEVADDR]);
2166 tcg_gen_andi_i32(arg[0].out, tmp, 0xfffffffc);
2171 static void translate_rtlb(DisasContext *dc, const OpcodeArg arg[],
2172 const uint32_t par[])
2174 #ifndef CONFIG_USER_ONLY
2175 static void (* const helper[])(TCGv_i32 r, TCGv_env env, TCGv_i32 a1,
2180 TCGv_i32 dtlb = tcg_const_i32(par[0]);
2182 helper[par[1]](arg[0].out, cpu_env, arg[1].in, dtlb);
2183 tcg_temp_free(dtlb);
2187 static void translate_rur(DisasContext *dc, const OpcodeArg arg[],
2188 const uint32_t par[])
2190 tcg_gen_mov_i32(arg[0].out, cpu_UR[par[0]]);
2193 static void translate_setb_expstate(DisasContext *dc, const OpcodeArg arg[],
2194 const uint32_t par[])
2196 /* TODO: GPIO32 may be a part of coprocessor */
2197 tcg_gen_ori_i32(cpu_UR[EXPSTATE], cpu_UR[EXPSTATE], 1u << arg[0].imm);
2200 #ifdef CONFIG_USER_ONLY
2201 static void gen_check_atomctl(DisasContext *dc, TCGv_i32 addr)
2205 static void gen_check_atomctl(DisasContext *dc, TCGv_i32 addr)
2207 TCGv_i32 tpc = tcg_const_i32(dc->pc);
2209 gen_helper_check_atomctl(cpu_env, tpc, addr);
2214 static void translate_s32c1i(DisasContext *dc, const OpcodeArg arg[],
2215 const uint32_t par[])
2217 TCGv_i32 tmp = tcg_temp_local_new_i32();
2218 TCGv_i32 addr = tcg_temp_local_new_i32();
2220 tcg_gen_mov_i32(tmp, arg[0].in);
2221 tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm);
2222 gen_load_store_alignment(dc, 2, addr, true);
2223 gen_check_atomctl(dc, addr);
2224 tcg_gen_atomic_cmpxchg_i32(arg[0].out, addr, cpu_SR[SCOMPARE1],
2225 tmp, dc->cring, MO_TEUL);
2226 tcg_temp_free(addr);
2230 static void translate_s32e(DisasContext *dc, const OpcodeArg arg[],
2231 const uint32_t par[])
2233 TCGv_i32 addr = tcg_temp_new_i32();
2235 tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm);
2236 gen_load_store_alignment(dc, 2, addr, false);
2237 tcg_gen_qemu_st_tl(arg[0].in, addr, dc->ring, MO_TEUL);
2238 tcg_temp_free(addr);
2241 static void translate_salt(DisasContext *dc, const OpcodeArg arg[],
2242 const uint32_t par[])
2244 tcg_gen_setcond_i32(par[0],
2246 arg[1].in, arg[2].in);
2249 static void translate_sext(DisasContext *dc, const OpcodeArg arg[],
2250 const uint32_t par[])
2252 int shift = 31 - arg[2].imm;
2255 tcg_gen_ext8s_i32(arg[0].out, arg[1].in);
2256 } else if (shift == 16) {
2257 tcg_gen_ext16s_i32(arg[0].out, arg[1].in);
2259 TCGv_i32 tmp = tcg_temp_new_i32();
2260 tcg_gen_shli_i32(tmp, arg[1].in, shift);
2261 tcg_gen_sari_i32(arg[0].out, tmp, shift);
2266 static bool test_ill_simcall(DisasContext *dc, const OpcodeArg arg[],
2267 const uint32_t par[])
2269 #ifdef CONFIG_USER_ONLY
2272 bool ill = !semihosting_enabled();
2275 qemu_log_mask(LOG_GUEST_ERROR, "SIMCALL but semihosting is disabled\n");
2280 static void translate_simcall(DisasContext *dc, const OpcodeArg arg[],
2281 const uint32_t par[])
2283 #ifndef CONFIG_USER_ONLY
2284 gen_helper_simcall(cpu_env);
2289 * Note: 64 bit ops are used here solely because SAR values
2292 #define gen_shift_reg(cmd, reg) do { \
2293 TCGv_i64 tmp = tcg_temp_new_i64(); \
2294 tcg_gen_extu_i32_i64(tmp, reg); \
2295 tcg_gen_##cmd##_i64(v, v, tmp); \
2296 tcg_gen_extrl_i64_i32(arg[0].out, v); \
2297 tcg_temp_free_i64(v); \
2298 tcg_temp_free_i64(tmp); \
2301 #define gen_shift(cmd) gen_shift_reg(cmd, cpu_SR[SAR])
2303 static void translate_sll(DisasContext *dc, const OpcodeArg arg[],
2304 const uint32_t par[])
2306 if (dc->sar_m32_5bit) {
2307 tcg_gen_shl_i32(arg[0].out, arg[1].in, dc->sar_m32);
2309 TCGv_i64 v = tcg_temp_new_i64();
2310 TCGv_i32 s = tcg_const_i32(32);
2311 tcg_gen_sub_i32(s, s, cpu_SR[SAR]);
2312 tcg_gen_andi_i32(s, s, 0x3f);
2313 tcg_gen_extu_i32_i64(v, arg[1].in);
2314 gen_shift_reg(shl, s);
2319 static void translate_slli(DisasContext *dc, const OpcodeArg arg[],
2320 const uint32_t par[])
2322 if (arg[2].imm == 32) {
2323 qemu_log_mask(LOG_GUEST_ERROR, "slli a%d, a%d, 32 is undefined\n",
2324 arg[0].imm, arg[1].imm);
2326 tcg_gen_shli_i32(arg[0].out, arg[1].in, arg[2].imm & 0x1f);
2329 static void translate_sra(DisasContext *dc, const OpcodeArg arg[],
2330 const uint32_t par[])
2332 if (dc->sar_m32_5bit) {
2333 tcg_gen_sar_i32(arg[0].out, arg[1].in, cpu_SR[SAR]);
2335 TCGv_i64 v = tcg_temp_new_i64();
2336 tcg_gen_ext_i32_i64(v, arg[1].in);
2341 static void translate_srai(DisasContext *dc, const OpcodeArg arg[],
2342 const uint32_t par[])
2344 tcg_gen_sari_i32(arg[0].out, arg[1].in, arg[2].imm);
2347 static void translate_src(DisasContext *dc, const OpcodeArg arg[],
2348 const uint32_t par[])
2350 TCGv_i64 v = tcg_temp_new_i64();
2351 tcg_gen_concat_i32_i64(v, arg[2].in, arg[1].in);
2355 static void translate_srl(DisasContext *dc, const OpcodeArg arg[],
2356 const uint32_t par[])
2358 if (dc->sar_m32_5bit) {
2359 tcg_gen_shr_i32(arg[0].out, arg[1].in, cpu_SR[SAR]);
2361 TCGv_i64 v = tcg_temp_new_i64();
2362 tcg_gen_extu_i32_i64(v, arg[1].in);
2368 #undef gen_shift_reg
2370 static void translate_srli(DisasContext *dc, const OpcodeArg arg[],
2371 const uint32_t par[])
2373 tcg_gen_shri_i32(arg[0].out, arg[1].in, arg[2].imm);
2376 static void translate_ssa8b(DisasContext *dc, const OpcodeArg arg[],
2377 const uint32_t par[])
2379 TCGv_i32 tmp = tcg_temp_new_i32();
2380 tcg_gen_shli_i32(tmp, arg[0].in, 3);
2381 gen_left_shift_sar(dc, tmp);
2385 static void translate_ssa8l(DisasContext *dc, const OpcodeArg arg[],
2386 const uint32_t par[])
2388 TCGv_i32 tmp = tcg_temp_new_i32();
2389 tcg_gen_shli_i32(tmp, arg[0].in, 3);
2390 gen_right_shift_sar(dc, tmp);
2394 static void translate_ssai(DisasContext *dc, const OpcodeArg arg[],
2395 const uint32_t par[])
2397 TCGv_i32 tmp = tcg_const_i32(arg[0].imm);
2398 gen_right_shift_sar(dc, tmp);
2402 static void translate_ssl(DisasContext *dc, const OpcodeArg arg[],
2403 const uint32_t par[])
2405 gen_left_shift_sar(dc, arg[0].in);
2408 static void translate_ssr(DisasContext *dc, const OpcodeArg arg[],
2409 const uint32_t par[])
2411 gen_right_shift_sar(dc, arg[0].in);
2414 static void translate_sub(DisasContext *dc, const OpcodeArg arg[],
2415 const uint32_t par[])
2417 tcg_gen_sub_i32(arg[0].out, arg[1].in, arg[2].in);
2420 static void translate_subx(DisasContext *dc, const OpcodeArg arg[],
2421 const uint32_t par[])
2423 TCGv_i32 tmp = tcg_temp_new_i32();
2424 tcg_gen_shli_i32(tmp, arg[1].in, par[0]);
2425 tcg_gen_sub_i32(arg[0].out, tmp, arg[2].in);
2429 static void translate_waiti(DisasContext *dc, const OpcodeArg arg[],
2430 const uint32_t par[])
2432 #ifndef CONFIG_USER_ONLY
2433 gen_waiti(dc, arg[0].imm);
2437 static void translate_wtlb(DisasContext *dc, const OpcodeArg arg[],
2438 const uint32_t par[])
2440 #ifndef CONFIG_USER_ONLY
2441 TCGv_i32 dtlb = tcg_const_i32(par[0]);
2443 gen_helper_wtlb(cpu_env, arg[0].in, arg[1].in, dtlb);
2444 tcg_temp_free(dtlb);
2448 static void translate_wer(DisasContext *dc, const OpcodeArg arg[],
2449 const uint32_t par[])
2451 gen_helper_wer(cpu_env, arg[0].in, arg[1].in);
2454 static void translate_wrmsk_expstate(DisasContext *dc, const OpcodeArg arg[],
2455 const uint32_t par[])
2457 /* TODO: GPIO32 may be a part of coprocessor */
2458 tcg_gen_and_i32(cpu_UR[EXPSTATE], arg[0].in, arg[1].in);
2461 static void translate_wsr(DisasContext *dc, const OpcodeArg arg[],
2462 const uint32_t par[])
2464 tcg_gen_mov_i32(cpu_SR[par[0]], arg[0].in);
2467 static void translate_wsr_mask(DisasContext *dc, const OpcodeArg arg[],
2468 const uint32_t par[])
2470 tcg_gen_andi_i32(cpu_SR[par[0]], arg[0].in, par[2]);
2473 static void translate_wsr_acchi(DisasContext *dc, const OpcodeArg arg[],
2474 const uint32_t par[])
2476 tcg_gen_ext8s_i32(cpu_SR[par[0]], arg[0].in);
2479 static void translate_wsr_ccompare(DisasContext *dc, const OpcodeArg arg[],
2480 const uint32_t par[])
2482 #ifndef CONFIG_USER_ONLY
2483 uint32_t id = par[0] - CCOMPARE;
2484 TCGv_i32 tmp = tcg_const_i32(id);
2486 assert(id < dc->config->nccompare);
2487 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
2490 tcg_gen_mov_i32(cpu_SR[par[0]], arg[0].in);
2491 gen_helper_update_ccompare(cpu_env, tmp);
2493 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
2499 static void translate_wsr_ccount(DisasContext *dc, const OpcodeArg arg[],
2500 const uint32_t par[])
2502 #ifndef CONFIG_USER_ONLY
2503 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
2506 gen_helper_wsr_ccount(cpu_env, arg[0].in);
2507 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
2513 static void translate_wsr_dbreaka(DisasContext *dc, const OpcodeArg arg[],
2514 const uint32_t par[])
2516 #ifndef CONFIG_USER_ONLY
2517 unsigned id = par[0] - DBREAKA;
2518 TCGv_i32 tmp = tcg_const_i32(id);
2520 assert(id < dc->config->ndbreak);
2521 gen_helper_wsr_dbreaka(cpu_env, tmp, arg[0].in);
2526 static void translate_wsr_dbreakc(DisasContext *dc, const OpcodeArg arg[],
2527 const uint32_t par[])
2529 #ifndef CONFIG_USER_ONLY
2530 unsigned id = par[0] - DBREAKC;
2531 TCGv_i32 tmp = tcg_const_i32(id);
2533 assert(id < dc->config->ndbreak);
2534 gen_helper_wsr_dbreakc(cpu_env, tmp, arg[0].in);
2539 static void translate_wsr_ibreaka(DisasContext *dc, const OpcodeArg arg[],
2540 const uint32_t par[])
2542 #ifndef CONFIG_USER_ONLY
2543 unsigned id = par[0] - IBREAKA;
2544 TCGv_i32 tmp = tcg_const_i32(id);
2546 assert(id < dc->config->nibreak);
2547 gen_helper_wsr_ibreaka(cpu_env, tmp, arg[0].in);
2552 static void translate_wsr_ibreakenable(DisasContext *dc, const OpcodeArg arg[],
2553 const uint32_t par[])
2555 #ifndef CONFIG_USER_ONLY
2556 gen_helper_wsr_ibreakenable(cpu_env, arg[0].in);
2560 static void translate_wsr_icount(DisasContext *dc, const OpcodeArg arg[],
2561 const uint32_t par[])
2563 #ifndef CONFIG_USER_ONLY
2565 tcg_gen_mov_i32(dc->next_icount, arg[0].in);
2567 tcg_gen_mov_i32(cpu_SR[par[0]], arg[0].in);
2572 static void translate_wsr_intclear(DisasContext *dc, const OpcodeArg arg[],
2573 const uint32_t par[])
2575 #ifndef CONFIG_USER_ONLY
2576 gen_helper_intclear(cpu_env, arg[0].in);
2580 static void translate_wsr_intset(DisasContext *dc, const OpcodeArg arg[],
2581 const uint32_t par[])
2583 #ifndef CONFIG_USER_ONLY
2584 gen_helper_intset(cpu_env, arg[0].in);
2588 static void translate_wsr_memctl(DisasContext *dc, const OpcodeArg arg[],
2589 const uint32_t par[])
2591 #ifndef CONFIG_USER_ONLY
2592 gen_helper_wsr_memctl(cpu_env, arg[0].in);
2596 static void translate_wsr_ps(DisasContext *dc, const OpcodeArg arg[],
2597 const uint32_t par[])
2599 #ifndef CONFIG_USER_ONLY
2600 uint32_t mask = PS_WOE | PS_CALLINC | PS_OWB |
2601 PS_UM | PS_EXCM | PS_INTLEVEL;
2603 if (option_enabled(dc, XTENSA_OPTION_MMU)) {
2606 tcg_gen_andi_i32(cpu_SR[par[0]], arg[0].in, mask);
2610 static void translate_wsr_rasid(DisasContext *dc, const OpcodeArg arg[],
2611 const uint32_t par[])
2613 #ifndef CONFIG_USER_ONLY
2614 gen_helper_wsr_rasid(cpu_env, arg[0].in);
2618 static void translate_wsr_sar(DisasContext *dc, const OpcodeArg arg[],
2619 const uint32_t par[])
2621 tcg_gen_andi_i32(cpu_SR[par[0]], arg[0].in, 0x3f);
2622 if (dc->sar_m32_5bit) {
2623 tcg_gen_discard_i32(dc->sar_m32);
2625 dc->sar_5bit = false;
2626 dc->sar_m32_5bit = false;
2629 static void translate_wsr_windowbase(DisasContext *dc, const OpcodeArg arg[],
2630 const uint32_t par[])
2632 #ifndef CONFIG_USER_ONLY
2633 tcg_gen_mov_i32(cpu_windowbase_next, arg[0].in);
2637 static void translate_wsr_windowstart(DisasContext *dc, const OpcodeArg arg[],
2638 const uint32_t par[])
2640 #ifndef CONFIG_USER_ONLY
2641 tcg_gen_andi_i32(cpu_SR[par[0]], arg[0].in,
2642 (1 << dc->config->nareg / 4) - 1);
2646 static void translate_wur(DisasContext *dc, const OpcodeArg arg[],
2647 const uint32_t par[])
2649 tcg_gen_mov_i32(cpu_UR[par[0]], arg[0].in);
2652 static void translate_wur_fcr(DisasContext *dc, const OpcodeArg arg[],
2653 const uint32_t par[])
2655 gen_helper_wur_fcr(cpu_env, arg[0].in);
2658 static void translate_wur_fsr(DisasContext *dc, const OpcodeArg arg[],
2659 const uint32_t par[])
2661 tcg_gen_andi_i32(cpu_UR[par[0]], arg[0].in, 0xffffff80);
2664 static void translate_xor(DisasContext *dc, const OpcodeArg arg[],
2665 const uint32_t par[])
2667 tcg_gen_xor_i32(arg[0].out, arg[1].in, arg[2].in);
2670 static void translate_xsr(DisasContext *dc, const OpcodeArg arg[],
2671 const uint32_t par[])
2673 TCGv_i32 tmp = tcg_temp_new_i32();
2675 tcg_gen_mov_i32(tmp, arg[0].in);
2676 tcg_gen_mov_i32(arg[0].out, cpu_SR[par[0]]);
2677 tcg_gen_mov_i32(cpu_SR[par[0]], tmp);
2681 static void translate_xsr_mask(DisasContext *dc, const OpcodeArg arg[],
2682 const uint32_t par[])
2684 TCGv_i32 tmp = tcg_temp_new_i32();
2686 tcg_gen_mov_i32(tmp, arg[0].in);
2687 tcg_gen_mov_i32(arg[0].out, cpu_SR[par[0]]);
2688 tcg_gen_andi_i32(cpu_SR[par[0]], tmp, par[2]);
2692 static void translate_xsr_ccount(DisasContext *dc, const OpcodeArg arg[],
2693 const uint32_t par[])
2695 #ifndef CONFIG_USER_ONLY
2696 TCGv_i32 tmp = tcg_temp_new_i32();
2698 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
2702 gen_helper_update_ccount(cpu_env);
2703 tcg_gen_mov_i32(tmp, cpu_SR[par[0]]);
2704 gen_helper_wsr_ccount(cpu_env, arg[0].in);
2705 tcg_gen_mov_i32(arg[0].out, tmp);
2708 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
2714 #define gen_translate_xsr(name) \
2715 static void translate_xsr_##name(DisasContext *dc, const OpcodeArg arg[], \
2716 const uint32_t par[]) \
2718 TCGv_i32 tmp = tcg_temp_new_i32(); \
2720 tcg_gen_mov_i32(tmp, cpu_SR[par[0]]); \
2721 translate_wsr_##name(dc, arg, par); \
2722 tcg_gen_mov_i32(arg[0].out, tmp); \
2723 tcg_temp_free(tmp); \
2726 gen_translate_xsr(acchi)
2727 gen_translate_xsr(ccompare)
2728 gen_translate_xsr(dbreaka)
2729 gen_translate_xsr(dbreakc)
2730 gen_translate_xsr(ibreaka)
2731 gen_translate_xsr(ibreakenable)
2732 gen_translate_xsr(icount)
2733 gen_translate_xsr(memctl)
2734 gen_translate_xsr(ps)
2735 gen_translate_xsr(rasid)
2736 gen_translate_xsr(sar)
2737 gen_translate_xsr(windowbase)
2738 gen_translate_xsr(windowstart)
2740 #undef gen_translate_xsr
2742 static const XtensaOpcodeOps core_ops[] = {
2745 .translate = translate_abs,
2747 .name = (const char * const[]) {
2748 "add", "add.n", NULL,
2750 .translate = translate_add,
2751 .op_flags = XTENSA_OP_NAME_ARRAY,
2753 .name = (const char * const[]) {
2754 "addi", "addi.n", NULL,
2756 .translate = translate_addi,
2757 .op_flags = XTENSA_OP_NAME_ARRAY,
2760 .translate = translate_addi,
2763 .translate = translate_addx,
2764 .par = (const uint32_t[]){1},
2767 .translate = translate_addx,
2768 .par = (const uint32_t[]){2},
2771 .translate = translate_addx,
2772 .par = (const uint32_t[]){3},
2775 .translate = translate_all,
2776 .par = (const uint32_t[]){true, 4},
2779 .translate = translate_all,
2780 .par = (const uint32_t[]){true, 8},
2783 .translate = translate_and,
2786 .translate = translate_boolean,
2787 .par = (const uint32_t[]){BOOLEAN_AND},
2790 .translate = translate_boolean,
2791 .par = (const uint32_t[]){BOOLEAN_ANDC},
2794 .translate = translate_all,
2795 .par = (const uint32_t[]){false, 4},
2798 .translate = translate_all,
2799 .par = (const uint32_t[]){false, 8},
2801 .name = (const char * const[]) {
2802 "ball", "ball.w15", "ball.w18", NULL,
2804 .translate = translate_ball,
2805 .par = (const uint32_t[]){TCG_COND_EQ},
2806 .op_flags = XTENSA_OP_NAME_ARRAY,
2808 .name = (const char * const[]) {
2809 "bany", "bany.w15", "bany.w18", NULL,
2811 .translate = translate_bany,
2812 .par = (const uint32_t[]){TCG_COND_NE},
2813 .op_flags = XTENSA_OP_NAME_ARRAY,
2815 .name = (const char * const[]) {
2816 "bbc", "bbc.w15", "bbc.w18", NULL,
2818 .translate = translate_bb,
2819 .par = (const uint32_t[]){TCG_COND_EQ},
2820 .op_flags = XTENSA_OP_NAME_ARRAY,
2822 .name = (const char * const[]) {
2823 "bbci", "bbci.w15", "bbci.w18", NULL,
2825 .translate = translate_bbi,
2826 .par = (const uint32_t[]){TCG_COND_EQ},
2827 .op_flags = XTENSA_OP_NAME_ARRAY,
2829 .name = (const char * const[]) {
2830 "bbs", "bbs.w15", "bbs.w18", NULL,
2832 .translate = translate_bb,
2833 .par = (const uint32_t[]){TCG_COND_NE},
2834 .op_flags = XTENSA_OP_NAME_ARRAY,
2836 .name = (const char * const[]) {
2837 "bbsi", "bbsi.w15", "bbsi.w18", NULL,
2839 .translate = translate_bbi,
2840 .par = (const uint32_t[]){TCG_COND_NE},
2841 .op_flags = XTENSA_OP_NAME_ARRAY,
2843 .name = (const char * const[]) {
2844 "beq", "beq.w15", "beq.w18", NULL,
2846 .translate = translate_b,
2847 .par = (const uint32_t[]){TCG_COND_EQ},
2848 .op_flags = XTENSA_OP_NAME_ARRAY,
2850 .name = (const char * const[]) {
2851 "beqi", "beqi.w15", "beqi.w18", NULL,
2853 .translate = translate_bi,
2854 .par = (const uint32_t[]){TCG_COND_EQ},
2855 .op_flags = XTENSA_OP_NAME_ARRAY,
2857 .name = (const char * const[]) {
2858 "beqz", "beqz.n", "beqz.w15", "beqz.w18", NULL,
2860 .translate = translate_bz,
2861 .par = (const uint32_t[]){TCG_COND_EQ},
2862 .op_flags = XTENSA_OP_NAME_ARRAY,
2865 .translate = translate_bp,
2866 .par = (const uint32_t[]){TCG_COND_EQ},
2868 .name = (const char * const[]) {
2869 "bge", "bge.w15", "bge.w18", NULL,
2871 .translate = translate_b,
2872 .par = (const uint32_t[]){TCG_COND_GE},
2873 .op_flags = XTENSA_OP_NAME_ARRAY,
2875 .name = (const char * const[]) {
2876 "bgei", "bgei.w15", "bgei.w18", NULL,
2878 .translate = translate_bi,
2879 .par = (const uint32_t[]){TCG_COND_GE},
2880 .op_flags = XTENSA_OP_NAME_ARRAY,
2882 .name = (const char * const[]) {
2883 "bgeu", "bgeu.w15", "bgeu.w18", NULL,
2885 .translate = translate_b,
2886 .par = (const uint32_t[]){TCG_COND_GEU},
2887 .op_flags = XTENSA_OP_NAME_ARRAY,
2889 .name = (const char * const[]) {
2890 "bgeui", "bgeui.w15", "bgeui.w18", NULL,
2892 .translate = translate_bi,
2893 .par = (const uint32_t[]){TCG_COND_GEU},
2894 .op_flags = XTENSA_OP_NAME_ARRAY,
2896 .name = (const char * const[]) {
2897 "bgez", "bgez.w15", "bgez.w18", NULL,
2899 .translate = translate_bz,
2900 .par = (const uint32_t[]){TCG_COND_GE},
2901 .op_flags = XTENSA_OP_NAME_ARRAY,
2903 .name = (const char * const[]) {
2904 "blt", "blt.w15", "blt.w18", NULL,
2906 .translate = translate_b,
2907 .par = (const uint32_t[]){TCG_COND_LT},
2908 .op_flags = XTENSA_OP_NAME_ARRAY,
2910 .name = (const char * const[]) {
2911 "blti", "blti.w15", "blti.w18", NULL,
2913 .translate = translate_bi,
2914 .par = (const uint32_t[]){TCG_COND_LT},
2915 .op_flags = XTENSA_OP_NAME_ARRAY,
2917 .name = (const char * const[]) {
2918 "bltu", "bltu.w15", "bltu.w18", NULL,
2920 .translate = translate_b,
2921 .par = (const uint32_t[]){TCG_COND_LTU},
2922 .op_flags = XTENSA_OP_NAME_ARRAY,
2924 .name = (const char * const[]) {
2925 "bltui", "bltui.w15", "bltui.w18", NULL,
2927 .translate = translate_bi,
2928 .par = (const uint32_t[]){TCG_COND_LTU},
2929 .op_flags = XTENSA_OP_NAME_ARRAY,
2931 .name = (const char * const[]) {
2932 "bltz", "bltz.w15", "bltz.w18", NULL,
2934 .translate = translate_bz,
2935 .par = (const uint32_t[]){TCG_COND_LT},
2936 .op_flags = XTENSA_OP_NAME_ARRAY,
2938 .name = (const char * const[]) {
2939 "bnall", "bnall.w15", "bnall.w18", NULL,
2941 .translate = translate_ball,
2942 .par = (const uint32_t[]){TCG_COND_NE},
2943 .op_flags = XTENSA_OP_NAME_ARRAY,
2945 .name = (const char * const[]) {
2946 "bne", "bne.w15", "bne.w18", NULL,
2948 .translate = translate_b,
2949 .par = (const uint32_t[]){TCG_COND_NE},
2950 .op_flags = XTENSA_OP_NAME_ARRAY,
2952 .name = (const char * const[]) {
2953 "bnei", "bnei.w15", "bnei.w18", NULL,
2955 .translate = translate_bi,
2956 .par = (const uint32_t[]){TCG_COND_NE},
2957 .op_flags = XTENSA_OP_NAME_ARRAY,
2959 .name = (const char * const[]) {
2960 "bnez", "bnez.n", "bnez.w15", "bnez.w18", NULL,
2962 .translate = translate_bz,
2963 .par = (const uint32_t[]){TCG_COND_NE},
2964 .op_flags = XTENSA_OP_NAME_ARRAY,
2966 .name = (const char * const[]) {
2967 "bnone", "bnone.w15", "bnone.w18", NULL,
2969 .translate = translate_bany,
2970 .par = (const uint32_t[]){TCG_COND_EQ},
2971 .op_flags = XTENSA_OP_NAME_ARRAY,
2974 .translate = translate_nop,
2975 .par = (const uint32_t[]){DEBUGCAUSE_BI},
2976 .op_flags = XTENSA_OP_DEBUG_BREAK,
2979 .translate = translate_nop,
2980 .par = (const uint32_t[]){DEBUGCAUSE_BN},
2981 .op_flags = XTENSA_OP_DEBUG_BREAK,
2984 .translate = translate_bp,
2985 .par = (const uint32_t[]){TCG_COND_NE},
2988 .translate = translate_call0,
2991 .translate = translate_callw,
2992 .par = (const uint32_t[]){3},
2995 .translate = translate_callw,
2996 .par = (const uint32_t[]){1},
2999 .translate = translate_callw,
3000 .par = (const uint32_t[]){2},
3003 .translate = translate_callx0,
3006 .translate = translate_callxw,
3007 .par = (const uint32_t[]){3},
3010 .translate = translate_callxw,
3011 .par = (const uint32_t[]){1},
3014 .translate = translate_callxw,
3015 .par = (const uint32_t[]){2},
3018 .translate = translate_clamps,
3020 .name = "clrb_expstate",
3021 .translate = translate_clrb_expstate,
3024 .translate = translate_const16,
3027 .translate = translate_depbits,
3030 .translate = translate_dcache,
3031 .op_flags = XTENSA_OP_PRIVILEGED,
3034 .translate = translate_dcache,
3035 .op_flags = XTENSA_OP_PRIVILEGED,
3038 .translate = translate_dcache,
3041 .translate = translate_dcache,
3044 .translate = translate_nop,
3045 .op_flags = XTENSA_OP_PRIVILEGED,
3048 .translate = translate_nop,
3049 .op_flags = XTENSA_OP_PRIVILEGED,
3052 .translate = translate_nop,
3053 .op_flags = XTENSA_OP_PRIVILEGED,
3056 .translate = translate_nop,
3057 .op_flags = XTENSA_OP_PRIVILEGED,
3060 .translate = translate_dcache,
3061 .op_flags = XTENSA_OP_PRIVILEGED,
3064 .translate = translate_nop,
3067 .translate = translate_nop,
3070 .translate = translate_nop,
3073 .translate = translate_nop,
3076 .translate = translate_nop,
3079 .translate = translate_entry,
3080 .test_ill = test_ill_entry,
3081 .test_overflow = test_overflow_entry,
3082 .op_flags = XTENSA_OP_EXIT_TB_M1 |
3083 XTENSA_OP_SYNC_REGISTER_WINDOW,
3086 .translate = translate_nop,
3089 .translate = translate_nop,
3092 .translate = translate_extui,
3095 .translate = translate_memw,
3098 .op_flags = XTENSA_OP_ILL,
3101 .op_flags = XTENSA_OP_ILL,
3104 .translate = translate_itlb,
3105 .par = (const uint32_t[]){true},
3106 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
3109 .translate = translate_icache,
3112 .translate = translate_icache,
3113 .op_flags = XTENSA_OP_PRIVILEGED,
3116 .translate = translate_nop,
3117 .op_flags = XTENSA_OP_PRIVILEGED,
3120 .translate = translate_itlb,
3121 .par = (const uint32_t[]){false},
3122 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
3125 .translate = translate_nop,
3126 .op_flags = XTENSA_OP_PRIVILEGED,
3128 .name = (const char * const[]) {
3129 "ill", "ill.n", NULL,
3131 .op_flags = XTENSA_OP_ILL | XTENSA_OP_NAME_ARRAY,
3134 .translate = translate_nop,
3137 .translate = translate_icache,
3138 .op_flags = XTENSA_OP_PRIVILEGED,
3141 .translate = translate_nop,
3144 .translate = translate_j,
3147 .translate = translate_jx,
3150 .translate = translate_ldst,
3151 .par = (const uint32_t[]){MO_TESW, false, false},
3152 .op_flags = XTENSA_OP_LOAD,
3155 .translate = translate_ldst,
3156 .par = (const uint32_t[]){MO_TEUW, false, false},
3157 .op_flags = XTENSA_OP_LOAD,
3160 .translate = translate_ldst,
3161 .par = (const uint32_t[]){MO_TEUL, true, false},
3162 .op_flags = XTENSA_OP_LOAD,
3165 .translate = translate_l32e,
3166 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_LOAD,
3168 .name = (const char * const[]) {
3169 "l32i", "l32i.n", NULL,
3171 .translate = translate_ldst,
3172 .par = (const uint32_t[]){MO_TEUL, false, false},
3173 .op_flags = XTENSA_OP_NAME_ARRAY | XTENSA_OP_LOAD,
3176 .translate = translate_l32r,
3177 .op_flags = XTENSA_OP_LOAD,
3180 .translate = translate_ldst,
3181 .par = (const uint32_t[]){MO_UB, false, false},
3182 .op_flags = XTENSA_OP_LOAD,
3185 .translate = translate_mac16,
3186 .par = (const uint32_t[]){MAC16_NONE, 0, -4},
3187 .op_flags = XTENSA_OP_LOAD,
3190 .translate = translate_mac16,
3191 .par = (const uint32_t[]){MAC16_NONE, 0, 4},
3192 .op_flags = XTENSA_OP_LOAD,
3195 .op_flags = XTENSA_OP_ILL,
3197 .name = (const char * const[]) {
3198 "loop", "loop.w15", NULL,
3200 .translate = translate_loop,
3201 .par = (const uint32_t[]){TCG_COND_NEVER},
3202 .op_flags = XTENSA_OP_NAME_ARRAY,
3204 .name = (const char * const[]) {
3205 "loopgtz", "loopgtz.w15", NULL,
3207 .translate = translate_loop,
3208 .par = (const uint32_t[]){TCG_COND_GT},
3209 .op_flags = XTENSA_OP_NAME_ARRAY,
3211 .name = (const char * const[]) {
3212 "loopnez", "loopnez.w15", NULL,
3214 .translate = translate_loop,
3215 .par = (const uint32_t[]){TCG_COND_NE},
3216 .op_flags = XTENSA_OP_NAME_ARRAY,
3219 .translate = translate_smax,
3222 .translate = translate_umax,
3225 .translate = translate_memw,
3228 .translate = translate_smin,
3231 .translate = translate_umin,
3233 .name = (const char * const[]) {
3234 "mov", "mov.n", NULL,
3236 .translate = translate_mov,
3237 .op_flags = XTENSA_OP_NAME_ARRAY,
3240 .translate = translate_movcond,
3241 .par = (const uint32_t[]){TCG_COND_EQ},
3244 .translate = translate_movp,
3245 .par = (const uint32_t[]){TCG_COND_EQ},
3248 .translate = translate_movcond,
3249 .par = (const uint32_t[]){TCG_COND_GE},
3252 .translate = translate_movi,
3255 .translate = translate_movi,
3258 .translate = translate_movcond,
3259 .par = (const uint32_t[]){TCG_COND_LT},
3262 .translate = translate_movcond,
3263 .par = (const uint32_t[]){TCG_COND_NE},
3266 .translate = translate_movsp,
3267 .op_flags = XTENSA_OP_ALLOCA,
3270 .translate = translate_movp,
3271 .par = (const uint32_t[]){TCG_COND_NE},
3273 .name = "mul.aa.hh",
3274 .translate = translate_mac16,
3275 .par = (const uint32_t[]){MAC16_MUL, MAC16_HH, 0},
3277 .name = "mul.aa.hl",
3278 .translate = translate_mac16,
3279 .par = (const uint32_t[]){MAC16_MUL, MAC16_HL, 0},
3281 .name = "mul.aa.lh",
3282 .translate = translate_mac16,
3283 .par = (const uint32_t[]){MAC16_MUL, MAC16_LH, 0},
3285 .name = "mul.aa.ll",
3286 .translate = translate_mac16,
3287 .par = (const uint32_t[]){MAC16_MUL, MAC16_LL, 0},
3289 .name = "mul.ad.hh",
3290 .translate = translate_mac16,
3291 .par = (const uint32_t[]){MAC16_MUL, MAC16_HH, 0},
3293 .name = "mul.ad.hl",
3294 .translate = translate_mac16,
3295 .par = (const uint32_t[]){MAC16_MUL, MAC16_HL, 0},
3297 .name = "mul.ad.lh",
3298 .translate = translate_mac16,
3299 .par = (const uint32_t[]){MAC16_MUL, MAC16_LH, 0},
3301 .name = "mul.ad.ll",
3302 .translate = translate_mac16,
3303 .par = (const uint32_t[]){MAC16_MUL, MAC16_LL, 0},
3305 .name = "mul.da.hh",
3306 .translate = translate_mac16,
3307 .par = (const uint32_t[]){MAC16_MUL, MAC16_HH, 0},
3309 .name = "mul.da.hl",
3310 .translate = translate_mac16,
3311 .par = (const uint32_t[]){MAC16_MUL, MAC16_HL, 0},
3313 .name = "mul.da.lh",
3314 .translate = translate_mac16,
3315 .par = (const uint32_t[]){MAC16_MUL, MAC16_LH, 0},
3317 .name = "mul.da.ll",
3318 .translate = translate_mac16,
3319 .par = (const uint32_t[]){MAC16_MUL, MAC16_LL, 0},
3321 .name = "mul.dd.hh",
3322 .translate = translate_mac16,
3323 .par = (const uint32_t[]){MAC16_MUL, MAC16_HH, 0},
3325 .name = "mul.dd.hl",
3326 .translate = translate_mac16,
3327 .par = (const uint32_t[]){MAC16_MUL, MAC16_HL, 0},
3329 .name = "mul.dd.lh",
3330 .translate = translate_mac16,
3331 .par = (const uint32_t[]){MAC16_MUL, MAC16_LH, 0},
3333 .name = "mul.dd.ll",
3334 .translate = translate_mac16,
3335 .par = (const uint32_t[]){MAC16_MUL, MAC16_LL, 0},
3338 .translate = translate_mul16,
3339 .par = (const uint32_t[]){true},
3342 .translate = translate_mul16,
3343 .par = (const uint32_t[]){false},
3345 .name = "mula.aa.hh",
3346 .translate = translate_mac16,
3347 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 0},
3349 .name = "mula.aa.hl",
3350 .translate = translate_mac16,
3351 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 0},
3353 .name = "mula.aa.lh",
3354 .translate = translate_mac16,
3355 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 0},
3357 .name = "mula.aa.ll",
3358 .translate = translate_mac16,
3359 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 0},
3361 .name = "mula.ad.hh",
3362 .translate = translate_mac16,
3363 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 0},
3365 .name = "mula.ad.hl",
3366 .translate = translate_mac16,
3367 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 0},
3369 .name = "mula.ad.lh",
3370 .translate = translate_mac16,
3371 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 0},
3373 .name = "mula.ad.ll",
3374 .translate = translate_mac16,
3375 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 0},
3377 .name = "mula.da.hh",
3378 .translate = translate_mac16,
3379 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 0},
3381 .name = "mula.da.hh.lddec",
3382 .translate = translate_mac16,
3383 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, -4},
3385 .name = "mula.da.hh.ldinc",
3386 .translate = translate_mac16,
3387 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 4},
3389 .name = "mula.da.hl",
3390 .translate = translate_mac16,
3391 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 0},
3393 .name = "mula.da.hl.lddec",
3394 .translate = translate_mac16,
3395 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, -4},
3397 .name = "mula.da.hl.ldinc",
3398 .translate = translate_mac16,
3399 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 4},
3401 .name = "mula.da.lh",
3402 .translate = translate_mac16,
3403 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 0},
3405 .name = "mula.da.lh.lddec",
3406 .translate = translate_mac16,
3407 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, -4},
3409 .name = "mula.da.lh.ldinc",
3410 .translate = translate_mac16,
3411 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 4},
3413 .name = "mula.da.ll",
3414 .translate = translate_mac16,
3415 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 0},
3417 .name = "mula.da.ll.lddec",
3418 .translate = translate_mac16,
3419 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, -4},
3421 .name = "mula.da.ll.ldinc",
3422 .translate = translate_mac16,
3423 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 4},
3425 .name = "mula.dd.hh",
3426 .translate = translate_mac16,
3427 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 0},
3429 .name = "mula.dd.hh.lddec",
3430 .translate = translate_mac16,
3431 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, -4},
3433 .name = "mula.dd.hh.ldinc",
3434 .translate = translate_mac16,
3435 .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 4},
3437 .name = "mula.dd.hl",
3438 .translate = translate_mac16,
3439 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 0},
3441 .name = "mula.dd.hl.lddec",
3442 .translate = translate_mac16,
3443 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, -4},
3445 .name = "mula.dd.hl.ldinc",
3446 .translate = translate_mac16,
3447 .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 4},
3449 .name = "mula.dd.lh",
3450 .translate = translate_mac16,
3451 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 0},
3453 .name = "mula.dd.lh.lddec",
3454 .translate = translate_mac16,
3455 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, -4},
3457 .name = "mula.dd.lh.ldinc",
3458 .translate = translate_mac16,
3459 .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 4},
3461 .name = "mula.dd.ll",
3462 .translate = translate_mac16,
3463 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 0},
3465 .name = "mula.dd.ll.lddec",
3466 .translate = translate_mac16,
3467 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, -4},
3469 .name = "mula.dd.ll.ldinc",
3470 .translate = translate_mac16,
3471 .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 4},
3474 .translate = translate_mull,
3476 .name = "muls.aa.hh",
3477 .translate = translate_mac16,
3478 .par = (const uint32_t[]){MAC16_MULS, MAC16_HH, 0},
3480 .name = "muls.aa.hl",
3481 .translate = translate_mac16,
3482 .par = (const uint32_t[]){MAC16_MULS, MAC16_HL, 0},
3484 .name = "muls.aa.lh",
3485 .translate = translate_mac16,
3486 .par = (const uint32_t[]){MAC16_MULS, MAC16_LH, 0},
3488 .name = "muls.aa.ll",
3489 .translate = translate_mac16,
3490 .par = (const uint32_t[]){MAC16_MULS, MAC16_LL, 0},
3492 .name = "muls.ad.hh",
3493 .translate = translate_mac16,
3494 .par = (const uint32_t[]){MAC16_MULS, MAC16_HH, 0},
3496 .name = "muls.ad.hl",
3497 .translate = translate_mac16,
3498 .par = (const uint32_t[]){MAC16_MULS, MAC16_HL, 0},
3500 .name = "muls.ad.lh",
3501 .translate = translate_mac16,
3502 .par = (const uint32_t[]){MAC16_MULS, MAC16_LH, 0},
3504 .name = "muls.ad.ll",
3505 .translate = translate_mac16,
3506 .par = (const uint32_t[]){MAC16_MULS, MAC16_LL, 0},
3508 .name = "muls.da.hh",
3509 .translate = translate_mac16,
3510 .par = (const uint32_t[]){MAC16_MULS, MAC16_HH, 0},
3512 .name = "muls.da.hl",
3513 .translate = translate_mac16,
3514 .par = (const uint32_t[]){MAC16_MULS, MAC16_HL, 0},
3516 .name = "muls.da.lh",
3517 .translate = translate_mac16,
3518 .par = (const uint32_t[]){MAC16_MULS, MAC16_LH, 0},
3520 .name = "muls.da.ll",
3521 .translate = translate_mac16,
3522 .par = (const uint32_t[]){MAC16_MULS, MAC16_LL, 0},
3524 .name = "muls.dd.hh",
3525 .translate = translate_mac16,
3526 .par = (const uint32_t[]){MAC16_MULS, MAC16_HH, 0},
3528 .name = "muls.dd.hl",
3529 .translate = translate_mac16,
3530 .par = (const uint32_t[]){MAC16_MULS, MAC16_HL, 0},
3532 .name = "muls.dd.lh",
3533 .translate = translate_mac16,
3534 .par = (const uint32_t[]){MAC16_MULS, MAC16_LH, 0},
3536 .name = "muls.dd.ll",
3537 .translate = translate_mac16,
3538 .par = (const uint32_t[]){MAC16_MULS, MAC16_LL, 0},
3541 .translate = translate_mulh,
3542 .par = (const uint32_t[]){true},
3545 .translate = translate_mulh,
3546 .par = (const uint32_t[]){false},
3549 .translate = translate_neg,
3551 .name = (const char * const[]) {
3552 "nop", "nop.n", NULL,
3554 .translate = translate_nop,
3555 .op_flags = XTENSA_OP_NAME_ARRAY,
3558 .translate = translate_nsa,
3561 .translate = translate_nsau,
3564 .translate = translate_or,
3567 .translate = translate_boolean,
3568 .par = (const uint32_t[]){BOOLEAN_OR},
3571 .translate = translate_boolean,
3572 .par = (const uint32_t[]){BOOLEAN_ORC},
3575 .translate = translate_ptlb,
3576 .par = (const uint32_t[]){true},
3577 .op_flags = XTENSA_OP_PRIVILEGED,
3580 .translate = translate_ptlb,
3581 .par = (const uint32_t[]){false},
3582 .op_flags = XTENSA_OP_PRIVILEGED,
3585 .translate = translate_quos,
3586 .par = (const uint32_t[]){true},
3587 .op_flags = XTENSA_OP_DIVIDE_BY_ZERO,
3590 .translate = translate_quou,
3591 .op_flags = XTENSA_OP_DIVIDE_BY_ZERO,
3594 .translate = translate_rtlb,
3595 .par = (const uint32_t[]){true, 0},
3596 .op_flags = XTENSA_OP_PRIVILEGED,
3599 .translate = translate_rtlb,
3600 .par = (const uint32_t[]){true, 1},
3601 .op_flags = XTENSA_OP_PRIVILEGED,
3603 .name = "read_impwire",
3604 .translate = translate_read_impwire,
3607 .translate = translate_quos,
3608 .par = (const uint32_t[]){false},
3609 .op_flags = XTENSA_OP_DIVIDE_BY_ZERO,
3612 .translate = translate_remu,
3613 .op_flags = XTENSA_OP_DIVIDE_BY_ZERO,
3616 .translate = translate_rer,
3617 .op_flags = XTENSA_OP_PRIVILEGED,
3619 .name = (const char * const[]) {
3620 "ret", "ret.n", NULL,
3622 .translate = translate_ret,
3623 .op_flags = XTENSA_OP_NAME_ARRAY,
3625 .name = (const char * const[]) {
3626 "retw", "retw.n", NULL,
3628 .translate = translate_retw,
3629 .test_ill = test_ill_retw,
3630 .op_flags = XTENSA_OP_UNDERFLOW | XTENSA_OP_NAME_ARRAY,
3633 .op_flags = XTENSA_OP_ILL,
3636 .translate = translate_rfde,
3637 .op_flags = XTENSA_OP_PRIVILEGED,
3640 .op_flags = XTENSA_OP_ILL,
3643 .translate = translate_rfe,
3644 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_CHECK_INTERRUPTS,
3647 .translate = translate_rfi,
3648 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_CHECK_INTERRUPTS,
3651 .translate = translate_rfw,
3652 .par = (const uint32_t[]){true},
3653 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_CHECK_INTERRUPTS,
3656 .translate = translate_rfw,
3657 .par = (const uint32_t[]){false},
3658 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_CHECK_INTERRUPTS,
3661 .translate = translate_rtlb,
3662 .par = (const uint32_t[]){false, 0},
3663 .op_flags = XTENSA_OP_PRIVILEGED,
3666 .translate = translate_rtlb,
3667 .par = (const uint32_t[]){false, 1},
3668 .op_flags = XTENSA_OP_PRIVILEGED,
3671 .translate = translate_rotw,
3672 .op_flags = XTENSA_OP_PRIVILEGED |
3673 XTENSA_OP_EXIT_TB_M1 |
3674 XTENSA_OP_SYNC_REGISTER_WINDOW,
3677 .translate = translate_rsil,
3679 XTENSA_OP_PRIVILEGED |
3680 XTENSA_OP_EXIT_TB_0 |
3681 XTENSA_OP_CHECK_INTERRUPTS,
3684 .translate = translate_rsr,
3685 .par = (const uint32_t[]){176},
3686 .op_flags = XTENSA_OP_PRIVILEGED,
3689 .translate = translate_rsr,
3690 .par = (const uint32_t[]){208},
3691 .op_flags = XTENSA_OP_PRIVILEGED,
3693 .name = "rsr.acchi",
3694 .translate = translate_rsr,
3695 .test_ill = test_ill_sr,
3696 .par = (const uint32_t[]){
3698 XTENSA_OPTION_MAC16,
3701 .name = "rsr.acclo",
3702 .translate = translate_rsr,
3703 .test_ill = test_ill_sr,
3704 .par = (const uint32_t[]){
3706 XTENSA_OPTION_MAC16,
3709 .name = "rsr.atomctl",
3710 .translate = translate_rsr,
3711 .test_ill = test_ill_sr,
3712 .par = (const uint32_t[]){
3714 XTENSA_OPTION_ATOMCTL,
3716 .op_flags = XTENSA_OP_PRIVILEGED,
3719 .translate = translate_rsr,
3720 .test_ill = test_ill_sr,
3721 .par = (const uint32_t[]){
3723 XTENSA_OPTION_BOOLEAN,
3726 .name = "rsr.cacheattr",
3727 .translate = translate_rsr,
3728 .test_ill = test_ill_sr,
3729 .par = (const uint32_t[]){
3731 XTENSA_OPTION_CACHEATTR,
3733 .op_flags = XTENSA_OP_PRIVILEGED,
3735 .name = "rsr.ccompare0",
3736 .translate = translate_rsr,
3737 .test_ill = test_ill_ccompare,
3738 .par = (const uint32_t[]){
3740 XTENSA_OPTION_TIMER_INTERRUPT,
3742 .op_flags = XTENSA_OP_PRIVILEGED,
3744 .name = "rsr.ccompare1",
3745 .translate = translate_rsr,
3746 .test_ill = test_ill_ccompare,
3747 .par = (const uint32_t[]){
3749 XTENSA_OPTION_TIMER_INTERRUPT,
3751 .op_flags = XTENSA_OP_PRIVILEGED,
3753 .name = "rsr.ccompare2",
3754 .translate = translate_rsr,
3755 .test_ill = test_ill_ccompare,
3756 .par = (const uint32_t[]){
3758 XTENSA_OPTION_TIMER_INTERRUPT,
3760 .op_flags = XTENSA_OP_PRIVILEGED,
3762 .name = "rsr.ccount",
3763 .translate = translate_rsr_ccount,
3764 .test_ill = test_ill_sr,
3765 .par = (const uint32_t[]){
3767 XTENSA_OPTION_TIMER_INTERRUPT,
3769 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
3771 .name = "rsr.configid0",
3772 .translate = translate_rsr,
3773 .par = (const uint32_t[]){CONFIGID0},
3774 .op_flags = XTENSA_OP_PRIVILEGED,
3776 .name = "rsr.configid1",
3777 .translate = translate_rsr,
3778 .par = (const uint32_t[]){CONFIGID1},
3779 .op_flags = XTENSA_OP_PRIVILEGED,
3781 .name = "rsr.cpenable",
3782 .translate = translate_rsr,
3783 .test_ill = test_ill_sr,
3784 .par = (const uint32_t[]){
3786 XTENSA_OPTION_COPROCESSOR,
3788 .op_flags = XTENSA_OP_PRIVILEGED,
3790 .name = "rsr.dbreaka0",
3791 .translate = translate_rsr,
3792 .test_ill = test_ill_dbreak,
3793 .par = (const uint32_t[]){
3795 XTENSA_OPTION_DEBUG,
3797 .op_flags = XTENSA_OP_PRIVILEGED,
3799 .name = "rsr.dbreaka1",
3800 .translate = translate_rsr,
3801 .test_ill = test_ill_dbreak,
3802 .par = (const uint32_t[]){
3804 XTENSA_OPTION_DEBUG,
3806 .op_flags = XTENSA_OP_PRIVILEGED,
3808 .name = "rsr.dbreakc0",
3809 .translate = translate_rsr,
3810 .test_ill = test_ill_dbreak,
3811 .par = (const uint32_t[]){
3813 XTENSA_OPTION_DEBUG,
3815 .op_flags = XTENSA_OP_PRIVILEGED,
3817 .name = "rsr.dbreakc1",
3818 .translate = translate_rsr,
3819 .test_ill = test_ill_dbreak,
3820 .par = (const uint32_t[]){
3822 XTENSA_OPTION_DEBUG,
3824 .op_flags = XTENSA_OP_PRIVILEGED,
3827 .translate = translate_rsr,
3828 .test_ill = test_ill_sr,
3829 .par = (const uint32_t[]){
3831 XTENSA_OPTION_DEBUG,
3833 .op_flags = XTENSA_OP_PRIVILEGED,
3835 .name = "rsr.debugcause",
3836 .translate = translate_rsr,
3837 .test_ill = test_ill_sr,
3838 .par = (const uint32_t[]){
3840 XTENSA_OPTION_DEBUG,
3842 .op_flags = XTENSA_OP_PRIVILEGED,
3845 .translate = translate_rsr,
3846 .test_ill = test_ill_sr,
3847 .par = (const uint32_t[]){
3849 XTENSA_OPTION_EXCEPTION,
3851 .op_flags = XTENSA_OP_PRIVILEGED,
3853 .name = "rsr.dtlbcfg",
3854 .translate = translate_rsr,
3855 .test_ill = test_ill_sr,
3856 .par = (const uint32_t[]){
3860 .op_flags = XTENSA_OP_PRIVILEGED,
3863 .translate = translate_rsr,
3864 .test_ill = test_ill_sr,
3865 .par = (const uint32_t[]){
3867 XTENSA_OPTION_EXCEPTION,
3869 .op_flags = XTENSA_OP_PRIVILEGED,
3872 .translate = translate_rsr,
3873 .test_ill = test_ill_hpi,
3874 .par = (const uint32_t[]){
3876 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
3878 .op_flags = XTENSA_OP_PRIVILEGED,
3881 .translate = translate_rsr,
3882 .test_ill = test_ill_hpi,
3883 .par = (const uint32_t[]){
3885 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
3887 .op_flags = XTENSA_OP_PRIVILEGED,
3890 .translate = translate_rsr,
3891 .test_ill = test_ill_hpi,
3892 .par = (const uint32_t[]){
3894 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
3896 .op_flags = XTENSA_OP_PRIVILEGED,
3899 .translate = translate_rsr,
3900 .test_ill = test_ill_hpi,
3901 .par = (const uint32_t[]){
3903 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
3905 .op_flags = XTENSA_OP_PRIVILEGED,
3908 .translate = translate_rsr,
3909 .test_ill = test_ill_hpi,
3910 .par = (const uint32_t[]){
3912 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
3914 .op_flags = XTENSA_OP_PRIVILEGED,
3917 .translate = translate_rsr,
3918 .test_ill = test_ill_hpi,
3919 .par = (const uint32_t[]){
3921 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
3923 .op_flags = XTENSA_OP_PRIVILEGED,
3926 .translate = translate_rsr,
3927 .test_ill = test_ill_hpi,
3928 .par = (const uint32_t[]){
3930 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
3932 .op_flags = XTENSA_OP_PRIVILEGED,
3935 .translate = translate_rsr,
3936 .test_ill = test_ill_hpi,
3937 .par = (const uint32_t[]){
3939 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
3941 .op_flags = XTENSA_OP_PRIVILEGED,
3944 .translate = translate_rsr,
3945 .test_ill = test_ill_hpi,
3946 .par = (const uint32_t[]){
3948 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
3950 .op_flags = XTENSA_OP_PRIVILEGED,
3953 .translate = translate_rsr,
3954 .test_ill = test_ill_hpi,
3955 .par = (const uint32_t[]){
3957 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
3959 .op_flags = XTENSA_OP_PRIVILEGED,
3962 .translate = translate_rsr,
3963 .test_ill = test_ill_hpi,
3964 .par = (const uint32_t[]){
3966 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
3968 .op_flags = XTENSA_OP_PRIVILEGED,
3971 .translate = translate_rsr,
3972 .test_ill = test_ill_hpi,
3973 .par = (const uint32_t[]){
3975 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
3977 .op_flags = XTENSA_OP_PRIVILEGED,
3979 .name = "rsr.exccause",
3980 .translate = translate_rsr,
3981 .test_ill = test_ill_sr,
3982 .par = (const uint32_t[]){
3984 XTENSA_OPTION_EXCEPTION,
3986 .op_flags = XTENSA_OP_PRIVILEGED,
3988 .name = "rsr.excsave1",
3989 .translate = translate_rsr,
3990 .test_ill = test_ill_sr,
3991 .par = (const uint32_t[]){
3993 XTENSA_OPTION_EXCEPTION,
3995 .op_flags = XTENSA_OP_PRIVILEGED,
3997 .name = "rsr.excsave2",
3998 .translate = translate_rsr,
3999 .test_ill = test_ill_hpi,
4000 .par = (const uint32_t[]){
4002 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4004 .op_flags = XTENSA_OP_PRIVILEGED,
4006 .name = "rsr.excsave3",
4007 .translate = translate_rsr,
4008 .test_ill = test_ill_hpi,
4009 .par = (const uint32_t[]){
4011 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4013 .op_flags = XTENSA_OP_PRIVILEGED,
4015 .name = "rsr.excsave4",
4016 .translate = translate_rsr,
4017 .test_ill = test_ill_hpi,
4018 .par = (const uint32_t[]){
4020 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4022 .op_flags = XTENSA_OP_PRIVILEGED,
4024 .name = "rsr.excsave5",
4025 .translate = translate_rsr,
4026 .test_ill = test_ill_hpi,
4027 .par = (const uint32_t[]){
4029 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4031 .op_flags = XTENSA_OP_PRIVILEGED,
4033 .name = "rsr.excsave6",
4034 .translate = translate_rsr,
4035 .test_ill = test_ill_hpi,
4036 .par = (const uint32_t[]){
4038 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4040 .op_flags = XTENSA_OP_PRIVILEGED,
4042 .name = "rsr.excsave7",
4043 .translate = translate_rsr,
4044 .test_ill = test_ill_hpi,
4045 .par = (const uint32_t[]){
4047 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4049 .op_flags = XTENSA_OP_PRIVILEGED,
4051 .name = "rsr.excvaddr",
4052 .translate = translate_rsr,
4053 .test_ill = test_ill_sr,
4054 .par = (const uint32_t[]){
4056 XTENSA_OPTION_EXCEPTION,
4058 .op_flags = XTENSA_OP_PRIVILEGED,
4060 .name = "rsr.ibreaka0",
4061 .translate = translate_rsr,
4062 .test_ill = test_ill_ibreak,
4063 .par = (const uint32_t[]){
4065 XTENSA_OPTION_DEBUG,
4067 .op_flags = XTENSA_OP_PRIVILEGED,
4069 .name = "rsr.ibreaka1",
4070 .translate = translate_rsr,
4071 .test_ill = test_ill_ibreak,
4072 .par = (const uint32_t[]){
4074 XTENSA_OPTION_DEBUG,
4076 .op_flags = XTENSA_OP_PRIVILEGED,
4078 .name = "rsr.ibreakenable",
4079 .translate = translate_rsr,
4080 .test_ill = test_ill_sr,
4081 .par = (const uint32_t[]){
4083 XTENSA_OPTION_DEBUG,
4085 .op_flags = XTENSA_OP_PRIVILEGED,
4087 .name = "rsr.icount",
4088 .translate = translate_rsr,
4089 .test_ill = test_ill_sr,
4090 .par = (const uint32_t[]){
4092 XTENSA_OPTION_DEBUG,
4094 .op_flags = XTENSA_OP_PRIVILEGED,
4096 .name = "rsr.icountlevel",
4097 .translate = translate_rsr,
4098 .test_ill = test_ill_sr,
4099 .par = (const uint32_t[]){
4101 XTENSA_OPTION_DEBUG,
4103 .op_flags = XTENSA_OP_PRIVILEGED,
4105 .name = "rsr.intclear",
4106 .translate = translate_rsr,
4107 .test_ill = test_ill_sr,
4108 .par = (const uint32_t[]){
4110 XTENSA_OPTION_INTERRUPT,
4112 .op_flags = XTENSA_OP_PRIVILEGED,
4114 .name = "rsr.intenable",
4115 .translate = translate_rsr,
4116 .test_ill = test_ill_sr,
4117 .par = (const uint32_t[]){
4119 XTENSA_OPTION_INTERRUPT,
4121 .op_flags = XTENSA_OP_PRIVILEGED,
4123 .name = "rsr.interrupt",
4124 .translate = translate_rsr_ccount,
4125 .test_ill = test_ill_sr,
4126 .par = (const uint32_t[]){
4128 XTENSA_OPTION_INTERRUPT,
4130 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
4132 .name = "rsr.intset",
4133 .translate = translate_rsr_ccount,
4134 .test_ill = test_ill_sr,
4135 .par = (const uint32_t[]){
4137 XTENSA_OPTION_INTERRUPT,
4139 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
4141 .name = "rsr.itlbcfg",
4142 .translate = translate_rsr,
4143 .test_ill = test_ill_sr,
4144 .par = (const uint32_t[]){
4148 .op_flags = XTENSA_OP_PRIVILEGED,
4151 .translate = translate_rsr,
4152 .test_ill = test_ill_sr,
4153 .par = (const uint32_t[]){
4158 .name = "rsr.lcount",
4159 .translate = translate_rsr,
4160 .test_ill = test_ill_sr,
4161 .par = (const uint32_t[]){
4167 .translate = translate_rsr,
4168 .test_ill = test_ill_sr,
4169 .par = (const uint32_t[]){
4174 .name = "rsr.litbase",
4175 .translate = translate_rsr,
4176 .test_ill = test_ill_sr,
4177 .par = (const uint32_t[]){
4179 XTENSA_OPTION_EXTENDED_L32R,
4183 .translate = translate_rsr,
4184 .test_ill = test_ill_sr,
4185 .par = (const uint32_t[]){
4187 XTENSA_OPTION_MAC16,
4191 .translate = translate_rsr,
4192 .test_ill = test_ill_sr,
4193 .par = (const uint32_t[]){
4195 XTENSA_OPTION_MAC16,
4199 .translate = translate_rsr,
4200 .test_ill = test_ill_sr,
4201 .par = (const uint32_t[]){
4203 XTENSA_OPTION_MAC16,
4207 .translate = translate_rsr,
4208 .test_ill = test_ill_sr,
4209 .par = (const uint32_t[]){
4211 XTENSA_OPTION_MAC16,
4214 .name = "rsr.memctl",
4215 .translate = translate_rsr,
4216 .par = (const uint32_t[]){MEMCTL},
4217 .op_flags = XTENSA_OP_PRIVILEGED,
4220 .translate = translate_rsr,
4221 .test_ill = test_ill_sr,
4222 .par = (const uint32_t[]){
4224 XTENSA_OPTION_MEMORY_ECC_PARITY,
4226 .op_flags = XTENSA_OP_PRIVILEGED,
4229 .translate = translate_rsr,
4230 .test_ill = test_ill_sr,
4231 .par = (const uint32_t[]){
4233 XTENSA_OPTION_MEMORY_ECC_PARITY,
4235 .op_flags = XTENSA_OP_PRIVILEGED,
4238 .translate = translate_rsr,
4239 .test_ill = test_ill_sr,
4240 .par = (const uint32_t[]){
4242 XTENSA_OPTION_MEMORY_ECC_PARITY,
4244 .op_flags = XTENSA_OP_PRIVILEGED,
4246 .name = "rsr.mesave",
4247 .translate = translate_rsr,
4248 .test_ill = test_ill_sr,
4249 .par = (const uint32_t[]){
4251 XTENSA_OPTION_MEMORY_ECC_PARITY,
4253 .op_flags = XTENSA_OP_PRIVILEGED,
4256 .translate = translate_rsr,
4257 .test_ill = test_ill_sr,
4258 .par = (const uint32_t[]){
4260 XTENSA_OPTION_MEMORY_ECC_PARITY,
4262 .op_flags = XTENSA_OP_PRIVILEGED,
4264 .name = "rsr.mevaddr",
4265 .translate = translate_rsr,
4266 .test_ill = test_ill_sr,
4267 .par = (const uint32_t[]){
4269 XTENSA_OPTION_MEMORY_ECC_PARITY,
4271 .op_flags = XTENSA_OP_PRIVILEGED,
4273 .name = "rsr.misc0",
4274 .translate = translate_rsr,
4275 .test_ill = test_ill_sr,
4276 .par = (const uint32_t[]){
4278 XTENSA_OPTION_MISC_SR,
4280 .op_flags = XTENSA_OP_PRIVILEGED,
4282 .name = "rsr.misc1",
4283 .translate = translate_rsr,
4284 .test_ill = test_ill_sr,
4285 .par = (const uint32_t[]){
4287 XTENSA_OPTION_MISC_SR,
4289 .op_flags = XTENSA_OP_PRIVILEGED,
4291 .name = "rsr.misc2",
4292 .translate = translate_rsr,
4293 .test_ill = test_ill_sr,
4294 .par = (const uint32_t[]){
4296 XTENSA_OPTION_MISC_SR,
4298 .op_flags = XTENSA_OP_PRIVILEGED,
4300 .name = "rsr.misc3",
4301 .translate = translate_rsr,
4302 .test_ill = test_ill_sr,
4303 .par = (const uint32_t[]){
4305 XTENSA_OPTION_MISC_SR,
4307 .op_flags = XTENSA_OP_PRIVILEGED,
4309 .name = "rsr.prefctl",
4310 .translate = translate_rsr,
4311 .par = (const uint32_t[]){PREFCTL},
4314 .translate = translate_rsr,
4315 .test_ill = test_ill_sr,
4316 .par = (const uint32_t[]){
4318 XTENSA_OPTION_PROCESSOR_ID,
4320 .op_flags = XTENSA_OP_PRIVILEGED,
4323 .translate = translate_rsr,
4324 .test_ill = test_ill_sr,
4325 .par = (const uint32_t[]){
4327 XTENSA_OPTION_EXCEPTION,
4329 .op_flags = XTENSA_OP_PRIVILEGED,
4331 .name = "rsr.ptevaddr",
4332 .translate = translate_rsr_ptevaddr,
4333 .test_ill = test_ill_sr,
4334 .par = (const uint32_t[]){
4338 .op_flags = XTENSA_OP_PRIVILEGED,
4340 .name = "rsr.rasid",
4341 .translate = translate_rsr,
4342 .test_ill = test_ill_sr,
4343 .par = (const uint32_t[]){
4347 .op_flags = XTENSA_OP_PRIVILEGED,
4350 .translate = translate_rsr,
4351 .par = (const uint32_t[]){SAR},
4353 .name = "rsr.scompare1",
4354 .translate = translate_rsr,
4355 .test_ill = test_ill_sr,
4356 .par = (const uint32_t[]){
4358 XTENSA_OPTION_CONDITIONAL_STORE,
4361 .name = "rsr.vecbase",
4362 .translate = translate_rsr,
4363 .test_ill = test_ill_sr,
4364 .par = (const uint32_t[]){
4366 XTENSA_OPTION_RELOCATABLE_VECTOR,
4368 .op_flags = XTENSA_OP_PRIVILEGED,
4370 .name = "rsr.windowbase",
4371 .translate = translate_rsr,
4372 .test_ill = test_ill_sr,
4373 .par = (const uint32_t[]){
4375 XTENSA_OPTION_WINDOWED_REGISTER,
4377 .op_flags = XTENSA_OP_PRIVILEGED,
4379 .name = "rsr.windowstart",
4380 .translate = translate_rsr,
4381 .test_ill = test_ill_sr,
4382 .par = (const uint32_t[]){
4384 XTENSA_OPTION_WINDOWED_REGISTER,
4386 .op_flags = XTENSA_OP_PRIVILEGED,
4389 .translate = translate_nop,
4391 .name = "rur.expstate",
4392 .translate = translate_rur,
4393 .par = (const uint32_t[]){EXPSTATE},
4396 .translate = translate_rur,
4397 .par = (const uint32_t[]){FCR},
4401 .translate = translate_rur,
4402 .par = (const uint32_t[]){FSR},
4405 .name = "rur.threadptr",
4406 .translate = translate_rur,
4407 .par = (const uint32_t[]){THREADPTR},
4410 .translate = translate_ldst,
4411 .par = (const uint32_t[]){MO_TEUW, false, true},
4412 .op_flags = XTENSA_OP_STORE,
4415 .translate = translate_s32c1i,
4416 .op_flags = XTENSA_OP_LOAD | XTENSA_OP_STORE,
4419 .translate = translate_s32e,
4420 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_STORE,
4422 .name = (const char * const[]) {
4423 "s32i", "s32i.n", "s32nb", NULL,
4425 .translate = translate_ldst,
4426 .par = (const uint32_t[]){MO_TEUL, false, true},
4427 .op_flags = XTENSA_OP_NAME_ARRAY | XTENSA_OP_STORE,
4430 .translate = translate_ldst,
4431 .par = (const uint32_t[]){MO_TEUL, true, true},
4432 .op_flags = XTENSA_OP_STORE,
4435 .translate = translate_ldst,
4436 .par = (const uint32_t[]){MO_UB, false, true},
4437 .op_flags = XTENSA_OP_STORE,
4440 .translate = translate_salt,
4441 .par = (const uint32_t[]){TCG_COND_LT},
4444 .translate = translate_salt,
4445 .par = (const uint32_t[]){TCG_COND_LTU},
4447 .name = "setb_expstate",
4448 .translate = translate_setb_expstate,
4451 .translate = translate_sext,
4454 .translate = translate_simcall,
4455 .test_ill = test_ill_simcall,
4456 .op_flags = XTENSA_OP_PRIVILEGED,
4459 .translate = translate_sll,
4462 .translate = translate_slli,
4465 .translate = translate_sra,
4468 .translate = translate_srai,
4471 .translate = translate_src,
4474 .translate = translate_srl,
4477 .translate = translate_srli,
4480 .translate = translate_ssa8b,
4483 .translate = translate_ssa8l,
4486 .translate = translate_ssai,
4489 .translate = translate_ssl,
4492 .translate = translate_ssr,
4495 .translate = translate_sub,
4498 .translate = translate_subx,
4499 .par = (const uint32_t[]){1},
4502 .translate = translate_subx,
4503 .par = (const uint32_t[]){2},
4506 .translate = translate_subx,
4507 .par = (const uint32_t[]){3},
4510 .op_flags = XTENSA_OP_SYSCALL,
4512 .name = "umul.aa.hh",
4513 .translate = translate_mac16,
4514 .par = (const uint32_t[]){MAC16_UMUL, MAC16_HH, 0},
4516 .name = "umul.aa.hl",
4517 .translate = translate_mac16,
4518 .par = (const uint32_t[]){MAC16_UMUL, MAC16_HL, 0},
4520 .name = "umul.aa.lh",
4521 .translate = translate_mac16,
4522 .par = (const uint32_t[]){MAC16_UMUL, MAC16_LH, 0},
4524 .name = "umul.aa.ll",
4525 .translate = translate_mac16,
4526 .par = (const uint32_t[]){MAC16_UMUL, MAC16_LL, 0},
4529 .translate = translate_waiti,
4530 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
4533 .translate = translate_wtlb,
4534 .par = (const uint32_t[]){true},
4535 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
4538 .translate = translate_wer,
4539 .op_flags = XTENSA_OP_PRIVILEGED,
4542 .translate = translate_wtlb,
4543 .par = (const uint32_t[]){false},
4544 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
4546 .name = "wrmsk_expstate",
4547 .translate = translate_wrmsk_expstate,
4550 .op_flags = XTENSA_OP_ILL,
4553 .op_flags = XTENSA_OP_ILL,
4555 .name = "wsr.acchi",
4556 .translate = translate_wsr_acchi,
4557 .test_ill = test_ill_sr,
4558 .par = (const uint32_t[]){
4560 XTENSA_OPTION_MAC16,
4563 .name = "wsr.acclo",
4564 .translate = translate_wsr,
4565 .test_ill = test_ill_sr,
4566 .par = (const uint32_t[]){
4568 XTENSA_OPTION_MAC16,
4571 .name = "wsr.atomctl",
4572 .translate = translate_wsr_mask,
4573 .test_ill = test_ill_sr,
4574 .par = (const uint32_t[]){
4576 XTENSA_OPTION_ATOMCTL,
4579 .op_flags = XTENSA_OP_PRIVILEGED,
4582 .translate = translate_wsr_mask,
4583 .test_ill = test_ill_sr,
4584 .par = (const uint32_t[]){
4586 XTENSA_OPTION_BOOLEAN,
4590 .name = "wsr.cacheattr",
4591 .translate = translate_wsr,
4592 .test_ill = test_ill_sr,
4593 .par = (const uint32_t[]){
4595 XTENSA_OPTION_CACHEATTR,
4597 .op_flags = XTENSA_OP_PRIVILEGED,
4599 .name = "wsr.ccompare0",
4600 .translate = translate_wsr_ccompare,
4601 .test_ill = test_ill_ccompare,
4602 .par = (const uint32_t[]){
4604 XTENSA_OPTION_TIMER_INTERRUPT,
4606 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
4608 .name = "wsr.ccompare1",
4609 .translate = translate_wsr_ccompare,
4610 .test_ill = test_ill_ccompare,
4611 .par = (const uint32_t[]){
4613 XTENSA_OPTION_TIMER_INTERRUPT,
4615 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
4617 .name = "wsr.ccompare2",
4618 .translate = translate_wsr_ccompare,
4619 .test_ill = test_ill_ccompare,
4620 .par = (const uint32_t[]){
4622 XTENSA_OPTION_TIMER_INTERRUPT,
4624 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
4626 .name = "wsr.ccount",
4627 .translate = translate_wsr_ccount,
4628 .test_ill = test_ill_sr,
4629 .par = (const uint32_t[]){
4631 XTENSA_OPTION_TIMER_INTERRUPT,
4633 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
4635 .name = "wsr.configid0",
4636 .op_flags = XTENSA_OP_ILL,
4638 .name = "wsr.configid1",
4639 .op_flags = XTENSA_OP_ILL,
4641 .name = "wsr.cpenable",
4642 .translate = translate_wsr_mask,
4643 .test_ill = test_ill_sr,
4644 .par = (const uint32_t[]){
4646 XTENSA_OPTION_COPROCESSOR,
4649 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
4651 .name = "wsr.dbreaka0",
4652 .translate = translate_wsr_dbreaka,
4653 .test_ill = test_ill_dbreak,
4654 .par = (const uint32_t[]){
4656 XTENSA_OPTION_DEBUG,
4658 .op_flags = XTENSA_OP_PRIVILEGED,
4660 .name = "wsr.dbreaka1",
4661 .translate = translate_wsr_dbreaka,
4662 .test_ill = test_ill_dbreak,
4663 .par = (const uint32_t[]){
4665 XTENSA_OPTION_DEBUG,
4667 .op_flags = XTENSA_OP_PRIVILEGED,
4669 .name = "wsr.dbreakc0",
4670 .translate = translate_wsr_dbreakc,
4671 .test_ill = test_ill_dbreak,
4672 .par = (const uint32_t[]){
4674 XTENSA_OPTION_DEBUG,
4676 .op_flags = XTENSA_OP_PRIVILEGED,
4678 .name = "wsr.dbreakc1",
4679 .translate = translate_wsr_dbreakc,
4680 .test_ill = test_ill_dbreak,
4681 .par = (const uint32_t[]){
4683 XTENSA_OPTION_DEBUG,
4685 .op_flags = XTENSA_OP_PRIVILEGED,
4688 .translate = translate_wsr,
4689 .test_ill = test_ill_sr,
4690 .par = (const uint32_t[]){
4692 XTENSA_OPTION_DEBUG,
4694 .op_flags = XTENSA_OP_PRIVILEGED,
4696 .name = "wsr.debugcause",
4697 .op_flags = XTENSA_OP_ILL,
4700 .translate = translate_wsr,
4701 .test_ill = test_ill_sr,
4702 .par = (const uint32_t[]){
4704 XTENSA_OPTION_EXCEPTION,
4706 .op_flags = XTENSA_OP_PRIVILEGED,
4708 .name = "wsr.dtlbcfg",
4709 .translate = translate_wsr_mask,
4710 .test_ill = test_ill_sr,
4711 .par = (const uint32_t[]){
4716 .op_flags = XTENSA_OP_PRIVILEGED,
4719 .translate = translate_wsr,
4720 .test_ill = test_ill_sr,
4721 .par = (const uint32_t[]){
4723 XTENSA_OPTION_EXCEPTION,
4725 .op_flags = XTENSA_OP_PRIVILEGED,
4728 .translate = translate_wsr,
4729 .test_ill = test_ill_hpi,
4730 .par = (const uint32_t[]){
4732 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4734 .op_flags = XTENSA_OP_PRIVILEGED,
4737 .translate = translate_wsr,
4738 .test_ill = test_ill_hpi,
4739 .par = (const uint32_t[]){
4741 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4743 .op_flags = XTENSA_OP_PRIVILEGED,
4746 .translate = translate_wsr,
4747 .test_ill = test_ill_hpi,
4748 .par = (const uint32_t[]){
4750 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4752 .op_flags = XTENSA_OP_PRIVILEGED,
4755 .translate = translate_wsr,
4756 .test_ill = test_ill_hpi,
4757 .par = (const uint32_t[]){
4759 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4761 .op_flags = XTENSA_OP_PRIVILEGED,
4764 .translate = translate_wsr,
4765 .test_ill = test_ill_hpi,
4766 .par = (const uint32_t[]){
4768 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4770 .op_flags = XTENSA_OP_PRIVILEGED,
4773 .translate = translate_wsr,
4774 .test_ill = test_ill_hpi,
4775 .par = (const uint32_t[]){
4777 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4779 .op_flags = XTENSA_OP_PRIVILEGED,
4782 .translate = translate_wsr,
4783 .test_ill = test_ill_hpi,
4784 .par = (const uint32_t[]){
4786 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4788 .op_flags = XTENSA_OP_PRIVILEGED,
4791 .translate = translate_wsr,
4792 .test_ill = test_ill_hpi,
4793 .par = (const uint32_t[]){
4795 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4797 .op_flags = XTENSA_OP_PRIVILEGED,
4800 .translate = translate_wsr,
4801 .test_ill = test_ill_hpi,
4802 .par = (const uint32_t[]){
4804 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4806 .op_flags = XTENSA_OP_PRIVILEGED,
4809 .translate = translate_wsr,
4810 .test_ill = test_ill_hpi,
4811 .par = (const uint32_t[]){
4813 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4815 .op_flags = XTENSA_OP_PRIVILEGED,
4818 .translate = translate_wsr,
4819 .test_ill = test_ill_hpi,
4820 .par = (const uint32_t[]){
4822 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4824 .op_flags = XTENSA_OP_PRIVILEGED,
4827 .translate = translate_wsr,
4828 .test_ill = test_ill_hpi,
4829 .par = (const uint32_t[]){
4831 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4833 .op_flags = XTENSA_OP_PRIVILEGED,
4835 .name = "wsr.exccause",
4836 .translate = translate_wsr,
4837 .test_ill = test_ill_sr,
4838 .par = (const uint32_t[]){
4840 XTENSA_OPTION_EXCEPTION,
4842 .op_flags = XTENSA_OP_PRIVILEGED,
4844 .name = "wsr.excsave1",
4845 .translate = translate_wsr,
4846 .test_ill = test_ill_sr,
4847 .par = (const uint32_t[]){
4849 XTENSA_OPTION_EXCEPTION,
4851 .op_flags = XTENSA_OP_PRIVILEGED,
4853 .name = "wsr.excsave2",
4854 .translate = translate_wsr,
4855 .test_ill = test_ill_hpi,
4856 .par = (const uint32_t[]){
4858 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4860 .op_flags = XTENSA_OP_PRIVILEGED,
4862 .name = "wsr.excsave3",
4863 .translate = translate_wsr,
4864 .test_ill = test_ill_hpi,
4865 .par = (const uint32_t[]){
4867 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4869 .op_flags = XTENSA_OP_PRIVILEGED,
4871 .name = "wsr.excsave4",
4872 .translate = translate_wsr,
4873 .test_ill = test_ill_hpi,
4874 .par = (const uint32_t[]){
4876 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4878 .op_flags = XTENSA_OP_PRIVILEGED,
4880 .name = "wsr.excsave5",
4881 .translate = translate_wsr,
4882 .test_ill = test_ill_hpi,
4883 .par = (const uint32_t[]){
4885 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4887 .op_flags = XTENSA_OP_PRIVILEGED,
4889 .name = "wsr.excsave6",
4890 .translate = translate_wsr,
4891 .test_ill = test_ill_hpi,
4892 .par = (const uint32_t[]){
4894 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4896 .op_flags = XTENSA_OP_PRIVILEGED,
4898 .name = "wsr.excsave7",
4899 .translate = translate_wsr,
4900 .test_ill = test_ill_hpi,
4901 .par = (const uint32_t[]){
4903 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4905 .op_flags = XTENSA_OP_PRIVILEGED,
4907 .name = "wsr.excvaddr",
4908 .translate = translate_wsr,
4909 .test_ill = test_ill_sr,
4910 .par = (const uint32_t[]){
4912 XTENSA_OPTION_EXCEPTION,
4914 .op_flags = XTENSA_OP_PRIVILEGED,
4916 .name = "wsr.ibreaka0",
4917 .translate = translate_wsr_ibreaka,
4918 .test_ill = test_ill_ibreak,
4919 .par = (const uint32_t[]){
4921 XTENSA_OPTION_DEBUG,
4923 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
4925 .name = "wsr.ibreaka1",
4926 .translate = translate_wsr_ibreaka,
4927 .test_ill = test_ill_ibreak,
4928 .par = (const uint32_t[]){
4930 XTENSA_OPTION_DEBUG,
4932 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
4934 .name = "wsr.ibreakenable",
4935 .translate = translate_wsr_ibreakenable,
4936 .test_ill = test_ill_sr,
4937 .par = (const uint32_t[]){
4939 XTENSA_OPTION_DEBUG,
4941 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
4943 .name = "wsr.icount",
4944 .translate = translate_wsr_icount,
4945 .test_ill = test_ill_sr,
4946 .par = (const uint32_t[]){
4948 XTENSA_OPTION_DEBUG,
4950 .op_flags = XTENSA_OP_PRIVILEGED,
4952 .name = "wsr.icountlevel",
4953 .translate = translate_wsr_mask,
4954 .test_ill = test_ill_sr,
4955 .par = (const uint32_t[]){
4957 XTENSA_OPTION_DEBUG,
4960 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
4962 .name = "wsr.intclear",
4963 .translate = translate_wsr_intclear,
4964 .test_ill = test_ill_sr,
4965 .par = (const uint32_t[]){
4967 XTENSA_OPTION_INTERRUPT,
4970 XTENSA_OP_PRIVILEGED |
4971 XTENSA_OP_EXIT_TB_0 |
4972 XTENSA_OP_CHECK_INTERRUPTS,
4974 .name = "wsr.intenable",
4975 .translate = translate_wsr,
4976 .test_ill = test_ill_sr,
4977 .par = (const uint32_t[]){
4979 XTENSA_OPTION_INTERRUPT,
4982 XTENSA_OP_PRIVILEGED |
4983 XTENSA_OP_EXIT_TB_0 |
4984 XTENSA_OP_CHECK_INTERRUPTS,
4986 .name = "wsr.interrupt",
4987 .translate = translate_wsr,
4988 .test_ill = test_ill_sr,
4989 .par = (const uint32_t[]){
4991 XTENSA_OPTION_INTERRUPT,
4994 XTENSA_OP_PRIVILEGED |
4995 XTENSA_OP_EXIT_TB_0 |
4996 XTENSA_OP_CHECK_INTERRUPTS,
4998 .name = "wsr.intset",
4999 .translate = translate_wsr_intset,
5000 .test_ill = test_ill_sr,
5001 .par = (const uint32_t[]){
5003 XTENSA_OPTION_INTERRUPT,
5006 XTENSA_OP_PRIVILEGED |
5007 XTENSA_OP_EXIT_TB_0 |
5008 XTENSA_OP_CHECK_INTERRUPTS,
5010 .name = "wsr.itlbcfg",
5011 .translate = translate_wsr_mask,
5012 .test_ill = test_ill_sr,
5013 .par = (const uint32_t[]){
5018 .op_flags = XTENSA_OP_PRIVILEGED,
5021 .translate = translate_wsr,
5022 .test_ill = test_ill_sr,
5023 .par = (const uint32_t[]){
5027 .op_flags = XTENSA_OP_EXIT_TB_M1,
5029 .name = "wsr.lcount",
5030 .translate = translate_wsr,
5031 .test_ill = test_ill_sr,
5032 .par = (const uint32_t[]){
5038 .translate = translate_wsr,
5039 .test_ill = test_ill_sr,
5040 .par = (const uint32_t[]){
5044 .op_flags = XTENSA_OP_EXIT_TB_M1,
5046 .name = "wsr.litbase",
5047 .translate = translate_wsr_mask,
5048 .test_ill = test_ill_sr,
5049 .par = (const uint32_t[]){
5051 XTENSA_OPTION_EXTENDED_L32R,
5054 .op_flags = XTENSA_OP_EXIT_TB_M1,
5057 .translate = translate_wsr,
5058 .test_ill = test_ill_sr,
5059 .par = (const uint32_t[]){
5061 XTENSA_OPTION_MAC16,
5065 .translate = translate_wsr,
5066 .test_ill = test_ill_sr,
5067 .par = (const uint32_t[]){
5069 XTENSA_OPTION_MAC16,
5073 .translate = translate_wsr,
5074 .test_ill = test_ill_sr,
5075 .par = (const uint32_t[]){
5077 XTENSA_OPTION_MAC16,
5081 .translate = translate_wsr,
5082 .test_ill = test_ill_sr,
5083 .par = (const uint32_t[]){
5085 XTENSA_OPTION_MAC16,
5088 .name = "wsr.memctl",
5089 .translate = translate_wsr_memctl,
5090 .par = (const uint32_t[]){MEMCTL},
5091 .op_flags = XTENSA_OP_PRIVILEGED,
5094 .translate = translate_wsr,
5095 .test_ill = test_ill_sr,
5096 .par = (const uint32_t[]){
5098 XTENSA_OPTION_MEMORY_ECC_PARITY,
5100 .op_flags = XTENSA_OP_PRIVILEGED,
5103 .translate = translate_wsr,
5104 .test_ill = test_ill_sr,
5105 .par = (const uint32_t[]){
5107 XTENSA_OPTION_MEMORY_ECC_PARITY,
5109 .op_flags = XTENSA_OP_PRIVILEGED,
5112 .translate = translate_wsr,
5113 .test_ill = test_ill_sr,
5114 .par = (const uint32_t[]){
5116 XTENSA_OPTION_MEMORY_ECC_PARITY,
5118 .op_flags = XTENSA_OP_PRIVILEGED,
5120 .name = "wsr.mesave",
5121 .translate = translate_wsr,
5122 .test_ill = test_ill_sr,
5123 .par = (const uint32_t[]){
5125 XTENSA_OPTION_MEMORY_ECC_PARITY,
5127 .op_flags = XTENSA_OP_PRIVILEGED,
5130 .translate = translate_wsr,
5131 .test_ill = test_ill_sr,
5132 .par = (const uint32_t[]){
5134 XTENSA_OPTION_MEMORY_ECC_PARITY,
5136 .op_flags = XTENSA_OP_PRIVILEGED,
5138 .name = "wsr.mevaddr",
5139 .translate = translate_wsr,
5140 .test_ill = test_ill_sr,
5141 .par = (const uint32_t[]){
5143 XTENSA_OPTION_MEMORY_ECC_PARITY,
5145 .op_flags = XTENSA_OP_PRIVILEGED,
5147 .name = "wsr.misc0",
5148 .translate = translate_wsr,
5149 .test_ill = test_ill_sr,
5150 .par = (const uint32_t[]){
5152 XTENSA_OPTION_MISC_SR,
5154 .op_flags = XTENSA_OP_PRIVILEGED,
5156 .name = "wsr.misc1",
5157 .translate = translate_wsr,
5158 .test_ill = test_ill_sr,
5159 .par = (const uint32_t[]){
5161 XTENSA_OPTION_MISC_SR,
5163 .op_flags = XTENSA_OP_PRIVILEGED,
5165 .name = "wsr.misc2",
5166 .translate = translate_wsr,
5167 .test_ill = test_ill_sr,
5168 .par = (const uint32_t[]){
5170 XTENSA_OPTION_MISC_SR,
5172 .op_flags = XTENSA_OP_PRIVILEGED,
5174 .name = "wsr.misc3",
5175 .translate = translate_wsr,
5176 .test_ill = test_ill_sr,
5177 .par = (const uint32_t[]){
5179 XTENSA_OPTION_MISC_SR,
5181 .op_flags = XTENSA_OP_PRIVILEGED,
5184 .translate = translate_wsr,
5185 .test_ill = test_ill_sr,
5186 .par = (const uint32_t[]){
5188 XTENSA_OPTION_TRACE_PORT,
5190 .op_flags = XTENSA_OP_PRIVILEGED,
5192 .name = "wsr.prefctl",
5193 .translate = translate_wsr,
5194 .par = (const uint32_t[]){PREFCTL},
5197 .op_flags = XTENSA_OP_ILL,
5200 .translate = translate_wsr_ps,
5201 .test_ill = test_ill_sr,
5202 .par = (const uint32_t[]){
5204 XTENSA_OPTION_EXCEPTION,
5207 XTENSA_OP_PRIVILEGED |
5208 XTENSA_OP_EXIT_TB_M1 |
5209 XTENSA_OP_CHECK_INTERRUPTS,
5211 .name = "wsr.ptevaddr",
5212 .translate = translate_wsr_mask,
5213 .test_ill = test_ill_sr,
5214 .par = (const uint32_t[]){
5219 .op_flags = XTENSA_OP_PRIVILEGED,
5221 .name = "wsr.rasid",
5222 .translate = translate_wsr_rasid,
5223 .test_ill = test_ill_sr,
5224 .par = (const uint32_t[]){
5228 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
5231 .translate = translate_wsr_sar,
5232 .par = (const uint32_t[]){SAR},
5234 .name = "wsr.scompare1",
5235 .translate = translate_wsr,
5236 .test_ill = test_ill_sr,
5237 .par = (const uint32_t[]){
5239 XTENSA_OPTION_CONDITIONAL_STORE,
5242 .name = "wsr.vecbase",
5243 .translate = translate_wsr,
5244 .test_ill = test_ill_sr,
5245 .par = (const uint32_t[]){
5247 XTENSA_OPTION_RELOCATABLE_VECTOR,
5249 .op_flags = XTENSA_OP_PRIVILEGED,
5251 .name = "wsr.windowbase",
5252 .translate = translate_wsr_windowbase,
5253 .test_ill = test_ill_sr,
5254 .par = (const uint32_t[]){
5256 XTENSA_OPTION_WINDOWED_REGISTER,
5258 .op_flags = XTENSA_OP_PRIVILEGED |
5259 XTENSA_OP_EXIT_TB_M1 |
5260 XTENSA_OP_SYNC_REGISTER_WINDOW,
5262 .name = "wsr.windowstart",
5263 .translate = translate_wsr_windowstart,
5264 .test_ill = test_ill_sr,
5265 .par = (const uint32_t[]){
5267 XTENSA_OPTION_WINDOWED_REGISTER,
5269 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
5271 .name = "wur.expstate",
5272 .translate = translate_wur,
5273 .par = (const uint32_t[]){EXPSTATE},
5276 .translate = translate_wur_fcr,
5277 .par = (const uint32_t[]){FCR},
5281 .translate = translate_wur_fsr,
5282 .par = (const uint32_t[]){FSR},
5285 .name = "wur.threadptr",
5286 .translate = translate_wur,
5287 .par = (const uint32_t[]){THREADPTR},
5290 .translate = translate_xor,
5293 .translate = translate_boolean,
5294 .par = (const uint32_t[]){BOOLEAN_XOR},
5297 .op_flags = XTENSA_OP_ILL,
5300 .op_flags = XTENSA_OP_ILL,
5302 .name = "xsr.acchi",
5303 .translate = translate_xsr_acchi,
5304 .test_ill = test_ill_sr,
5305 .par = (const uint32_t[]){
5307 XTENSA_OPTION_MAC16,
5310 .name = "xsr.acclo",
5311 .translate = translate_xsr,
5312 .test_ill = test_ill_sr,
5313 .par = (const uint32_t[]){
5315 XTENSA_OPTION_MAC16,
5318 .name = "xsr.atomctl",
5319 .translate = translate_xsr_mask,
5320 .test_ill = test_ill_sr,
5321 .par = (const uint32_t[]){
5323 XTENSA_OPTION_ATOMCTL,
5326 .op_flags = XTENSA_OP_PRIVILEGED,
5329 .translate = translate_xsr_mask,
5330 .test_ill = test_ill_sr,
5331 .par = (const uint32_t[]){
5333 XTENSA_OPTION_BOOLEAN,
5337 .name = "xsr.cacheattr",
5338 .translate = translate_xsr,
5339 .test_ill = test_ill_sr,
5340 .par = (const uint32_t[]){
5342 XTENSA_OPTION_CACHEATTR,
5344 .op_flags = XTENSA_OP_PRIVILEGED,
5346 .name = "xsr.ccompare0",
5347 .translate = translate_xsr_ccompare,
5348 .test_ill = test_ill_ccompare,
5349 .par = (const uint32_t[]){
5351 XTENSA_OPTION_TIMER_INTERRUPT,
5353 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5355 .name = "xsr.ccompare1",
5356 .translate = translate_xsr_ccompare,
5357 .test_ill = test_ill_ccompare,
5358 .par = (const uint32_t[]){
5360 XTENSA_OPTION_TIMER_INTERRUPT,
5362 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5364 .name = "xsr.ccompare2",
5365 .translate = translate_xsr_ccompare,
5366 .test_ill = test_ill_ccompare,
5367 .par = (const uint32_t[]){
5369 XTENSA_OPTION_TIMER_INTERRUPT,
5371 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5373 .name = "xsr.ccount",
5374 .translate = translate_xsr_ccount,
5375 .test_ill = test_ill_sr,
5376 .par = (const uint32_t[]){
5378 XTENSA_OPTION_TIMER_INTERRUPT,
5380 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5382 .name = "xsr.configid0",
5383 .op_flags = XTENSA_OP_ILL,
5385 .name = "xsr.configid1",
5386 .op_flags = XTENSA_OP_ILL,
5388 .name = "xsr.cpenable",
5389 .translate = translate_xsr_mask,
5390 .test_ill = test_ill_sr,
5391 .par = (const uint32_t[]){
5393 XTENSA_OPTION_COPROCESSOR,
5396 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
5398 .name = "xsr.dbreaka0",
5399 .translate = translate_xsr_dbreaka,
5400 .test_ill = test_ill_dbreak,
5401 .par = (const uint32_t[]){
5403 XTENSA_OPTION_DEBUG,
5405 .op_flags = XTENSA_OP_PRIVILEGED,
5407 .name = "xsr.dbreaka1",
5408 .translate = translate_xsr_dbreaka,
5409 .test_ill = test_ill_dbreak,
5410 .par = (const uint32_t[]){
5412 XTENSA_OPTION_DEBUG,
5414 .op_flags = XTENSA_OP_PRIVILEGED,
5416 .name = "xsr.dbreakc0",
5417 .translate = translate_xsr_dbreakc,
5418 .test_ill = test_ill_dbreak,
5419 .par = (const uint32_t[]){
5421 XTENSA_OPTION_DEBUG,
5423 .op_flags = XTENSA_OP_PRIVILEGED,
5425 .name = "xsr.dbreakc1",
5426 .translate = translate_xsr_dbreakc,
5427 .test_ill = test_ill_dbreak,
5428 .par = (const uint32_t[]){
5430 XTENSA_OPTION_DEBUG,
5432 .op_flags = XTENSA_OP_PRIVILEGED,
5435 .translate = translate_xsr,
5436 .test_ill = test_ill_sr,
5437 .par = (const uint32_t[]){
5439 XTENSA_OPTION_DEBUG,
5441 .op_flags = XTENSA_OP_PRIVILEGED,
5443 .name = "xsr.debugcause",
5444 .op_flags = XTENSA_OP_ILL,
5447 .translate = translate_xsr,
5448 .test_ill = test_ill_sr,
5449 .par = (const uint32_t[]){
5451 XTENSA_OPTION_EXCEPTION,
5453 .op_flags = XTENSA_OP_PRIVILEGED,
5455 .name = "xsr.dtlbcfg",
5456 .translate = translate_xsr_mask,
5457 .test_ill = test_ill_sr,
5458 .par = (const uint32_t[]){
5463 .op_flags = XTENSA_OP_PRIVILEGED,
5466 .translate = translate_xsr,
5467 .test_ill = test_ill_sr,
5468 .par = (const uint32_t[]){
5470 XTENSA_OPTION_EXCEPTION,
5472 .op_flags = XTENSA_OP_PRIVILEGED,
5475 .translate = translate_xsr,
5476 .test_ill = test_ill_hpi,
5477 .par = (const uint32_t[]){
5479 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5481 .op_flags = XTENSA_OP_PRIVILEGED,
5484 .translate = translate_xsr,
5485 .test_ill = test_ill_hpi,
5486 .par = (const uint32_t[]){
5488 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5490 .op_flags = XTENSA_OP_PRIVILEGED,
5493 .translate = translate_xsr,
5494 .test_ill = test_ill_hpi,
5495 .par = (const uint32_t[]){
5497 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5499 .op_flags = XTENSA_OP_PRIVILEGED,
5502 .translate = translate_xsr,
5503 .test_ill = test_ill_hpi,
5504 .par = (const uint32_t[]){
5506 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5508 .op_flags = XTENSA_OP_PRIVILEGED,
5511 .translate = translate_xsr,
5512 .test_ill = test_ill_hpi,
5513 .par = (const uint32_t[]){
5515 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5517 .op_flags = XTENSA_OP_PRIVILEGED,
5520 .translate = translate_xsr,
5521 .test_ill = test_ill_hpi,
5522 .par = (const uint32_t[]){
5524 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5526 .op_flags = XTENSA_OP_PRIVILEGED,
5529 .translate = translate_xsr,
5530 .test_ill = test_ill_hpi,
5531 .par = (const uint32_t[]){
5533 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5535 .op_flags = XTENSA_OP_PRIVILEGED,
5538 .translate = translate_xsr,
5539 .test_ill = test_ill_hpi,
5540 .par = (const uint32_t[]){
5542 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5544 .op_flags = XTENSA_OP_PRIVILEGED,
5547 .translate = translate_xsr,
5548 .test_ill = test_ill_hpi,
5549 .par = (const uint32_t[]){
5551 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5553 .op_flags = XTENSA_OP_PRIVILEGED,
5556 .translate = translate_xsr,
5557 .test_ill = test_ill_hpi,
5558 .par = (const uint32_t[]){
5560 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5562 .op_flags = XTENSA_OP_PRIVILEGED,
5565 .translate = translate_xsr,
5566 .test_ill = test_ill_hpi,
5567 .par = (const uint32_t[]){
5569 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5571 .op_flags = XTENSA_OP_PRIVILEGED,
5574 .translate = translate_xsr,
5575 .test_ill = test_ill_hpi,
5576 .par = (const uint32_t[]){
5578 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5580 .op_flags = XTENSA_OP_PRIVILEGED,
5582 .name = "xsr.exccause",
5583 .translate = translate_xsr,
5584 .test_ill = test_ill_sr,
5585 .par = (const uint32_t[]){
5587 XTENSA_OPTION_EXCEPTION,
5589 .op_flags = XTENSA_OP_PRIVILEGED,
5591 .name = "xsr.excsave1",
5592 .translate = translate_xsr,
5593 .test_ill = test_ill_sr,
5594 .par = (const uint32_t[]){
5596 XTENSA_OPTION_EXCEPTION,
5598 .op_flags = XTENSA_OP_PRIVILEGED,
5600 .name = "xsr.excsave2",
5601 .translate = translate_xsr,
5602 .test_ill = test_ill_hpi,
5603 .par = (const uint32_t[]){
5605 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5607 .op_flags = XTENSA_OP_PRIVILEGED,
5609 .name = "xsr.excsave3",
5610 .translate = translate_xsr,
5611 .test_ill = test_ill_hpi,
5612 .par = (const uint32_t[]){
5614 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5616 .op_flags = XTENSA_OP_PRIVILEGED,
5618 .name = "xsr.excsave4",
5619 .translate = translate_xsr,
5620 .test_ill = test_ill_hpi,
5621 .par = (const uint32_t[]){
5623 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5625 .op_flags = XTENSA_OP_PRIVILEGED,
5627 .name = "xsr.excsave5",
5628 .translate = translate_xsr,
5629 .test_ill = test_ill_hpi,
5630 .par = (const uint32_t[]){
5632 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5634 .op_flags = XTENSA_OP_PRIVILEGED,
5636 .name = "xsr.excsave6",
5637 .translate = translate_xsr,
5638 .test_ill = test_ill_hpi,
5639 .par = (const uint32_t[]){
5641 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5643 .op_flags = XTENSA_OP_PRIVILEGED,
5645 .name = "xsr.excsave7",
5646 .translate = translate_xsr,
5647 .test_ill = test_ill_hpi,
5648 .par = (const uint32_t[]){
5650 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5652 .op_flags = XTENSA_OP_PRIVILEGED,
5654 .name = "xsr.excvaddr",
5655 .translate = translate_xsr,
5656 .test_ill = test_ill_sr,
5657 .par = (const uint32_t[]){
5659 XTENSA_OPTION_EXCEPTION,
5661 .op_flags = XTENSA_OP_PRIVILEGED,
5663 .name = "xsr.ibreaka0",
5664 .translate = translate_xsr_ibreaka,
5665 .test_ill = test_ill_ibreak,
5666 .par = (const uint32_t[]){
5668 XTENSA_OPTION_DEBUG,
5670 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5672 .name = "xsr.ibreaka1",
5673 .translate = translate_xsr_ibreaka,
5674 .test_ill = test_ill_ibreak,
5675 .par = (const uint32_t[]){
5677 XTENSA_OPTION_DEBUG,
5679 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5681 .name = "xsr.ibreakenable",
5682 .translate = translate_xsr_ibreakenable,
5683 .test_ill = test_ill_sr,
5684 .par = (const uint32_t[]){
5686 XTENSA_OPTION_DEBUG,
5688 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5690 .name = "xsr.icount",
5691 .translate = translate_xsr_icount,
5692 .test_ill = test_ill_sr,
5693 .par = (const uint32_t[]){
5695 XTENSA_OPTION_DEBUG,
5697 .op_flags = XTENSA_OP_PRIVILEGED,
5699 .name = "xsr.icountlevel",
5700 .translate = translate_xsr_mask,
5701 .test_ill = test_ill_sr,
5702 .par = (const uint32_t[]){
5704 XTENSA_OPTION_DEBUG,
5707 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
5709 .name = "xsr.intclear",
5710 .op_flags = XTENSA_OP_ILL,
5712 .name = "xsr.intenable",
5713 .translate = translate_xsr,
5714 .test_ill = test_ill_sr,
5715 .par = (const uint32_t[]){
5717 XTENSA_OPTION_INTERRUPT,
5720 XTENSA_OP_PRIVILEGED |
5721 XTENSA_OP_EXIT_TB_0 |
5722 XTENSA_OP_CHECK_INTERRUPTS,
5724 .name = "xsr.interrupt",
5725 .op_flags = XTENSA_OP_ILL,
5727 .name = "xsr.intset",
5728 .op_flags = XTENSA_OP_ILL,
5730 .name = "xsr.itlbcfg",
5731 .translate = translate_xsr_mask,
5732 .test_ill = test_ill_sr,
5733 .par = (const uint32_t[]){
5738 .op_flags = XTENSA_OP_PRIVILEGED,
5741 .translate = translate_xsr,
5742 .test_ill = test_ill_sr,
5743 .par = (const uint32_t[]){
5747 .op_flags = XTENSA_OP_EXIT_TB_M1,
5749 .name = "xsr.lcount",
5750 .translate = translate_xsr,
5751 .test_ill = test_ill_sr,
5752 .par = (const uint32_t[]){
5758 .translate = translate_xsr,
5759 .test_ill = test_ill_sr,
5760 .par = (const uint32_t[]){
5764 .op_flags = XTENSA_OP_EXIT_TB_M1,
5766 .name = "xsr.litbase",
5767 .translate = translate_xsr_mask,
5768 .test_ill = test_ill_sr,
5769 .par = (const uint32_t[]){
5771 XTENSA_OPTION_EXTENDED_L32R,
5774 .op_flags = XTENSA_OP_EXIT_TB_M1,
5777 .translate = translate_xsr,
5778 .test_ill = test_ill_sr,
5779 .par = (const uint32_t[]){
5781 XTENSA_OPTION_MAC16,
5785 .translate = translate_xsr,
5786 .test_ill = test_ill_sr,
5787 .par = (const uint32_t[]){
5789 XTENSA_OPTION_MAC16,
5793 .translate = translate_xsr,
5794 .test_ill = test_ill_sr,
5795 .par = (const uint32_t[]){
5797 XTENSA_OPTION_MAC16,
5801 .translate = translate_xsr,
5802 .test_ill = test_ill_sr,
5803 .par = (const uint32_t[]){
5805 XTENSA_OPTION_MAC16,
5808 .name = "xsr.memctl",
5809 .translate = translate_xsr_memctl,
5810 .par = (const uint32_t[]){MEMCTL},
5811 .op_flags = XTENSA_OP_PRIVILEGED,
5814 .translate = translate_xsr,
5815 .test_ill = test_ill_sr,
5816 .par = (const uint32_t[]){
5818 XTENSA_OPTION_MEMORY_ECC_PARITY,
5820 .op_flags = XTENSA_OP_PRIVILEGED,
5823 .translate = translate_xsr,
5824 .test_ill = test_ill_sr,
5825 .par = (const uint32_t[]){
5827 XTENSA_OPTION_MEMORY_ECC_PARITY,
5829 .op_flags = XTENSA_OP_PRIVILEGED,
5832 .translate = translate_xsr,
5833 .test_ill = test_ill_sr,
5834 .par = (const uint32_t[]){
5836 XTENSA_OPTION_MEMORY_ECC_PARITY,
5838 .op_flags = XTENSA_OP_PRIVILEGED,
5840 .name = "xsr.mesave",
5841 .translate = translate_xsr,
5842 .test_ill = test_ill_sr,
5843 .par = (const uint32_t[]){
5845 XTENSA_OPTION_MEMORY_ECC_PARITY,
5847 .op_flags = XTENSA_OP_PRIVILEGED,
5850 .translate = translate_xsr,
5851 .test_ill = test_ill_sr,
5852 .par = (const uint32_t[]){
5854 XTENSA_OPTION_MEMORY_ECC_PARITY,
5856 .op_flags = XTENSA_OP_PRIVILEGED,
5858 .name = "xsr.mevaddr",
5859 .translate = translate_xsr,
5860 .test_ill = test_ill_sr,
5861 .par = (const uint32_t[]){
5863 XTENSA_OPTION_MEMORY_ECC_PARITY,
5865 .op_flags = XTENSA_OP_PRIVILEGED,
5867 .name = "xsr.misc0",
5868 .translate = translate_xsr,
5869 .test_ill = test_ill_sr,
5870 .par = (const uint32_t[]){
5872 XTENSA_OPTION_MISC_SR,
5874 .op_flags = XTENSA_OP_PRIVILEGED,
5876 .name = "xsr.misc1",
5877 .translate = translate_xsr,
5878 .test_ill = test_ill_sr,
5879 .par = (const uint32_t[]){
5881 XTENSA_OPTION_MISC_SR,
5883 .op_flags = XTENSA_OP_PRIVILEGED,
5885 .name = "xsr.misc2",
5886 .translate = translate_xsr,
5887 .test_ill = test_ill_sr,
5888 .par = (const uint32_t[]){
5890 XTENSA_OPTION_MISC_SR,
5892 .op_flags = XTENSA_OP_PRIVILEGED,
5894 .name = "xsr.misc3",
5895 .translate = translate_xsr,
5896 .test_ill = test_ill_sr,
5897 .par = (const uint32_t[]){
5899 XTENSA_OPTION_MISC_SR,
5901 .op_flags = XTENSA_OP_PRIVILEGED,
5903 .name = "xsr.prefctl",
5904 .translate = translate_xsr,
5905 .par = (const uint32_t[]){PREFCTL},
5908 .op_flags = XTENSA_OP_ILL,
5911 .translate = translate_xsr_ps,
5912 .test_ill = test_ill_sr,
5913 .par = (const uint32_t[]){
5915 XTENSA_OPTION_EXCEPTION,
5918 XTENSA_OP_PRIVILEGED |
5919 XTENSA_OP_EXIT_TB_M1 |
5920 XTENSA_OP_CHECK_INTERRUPTS,
5922 .name = "xsr.ptevaddr",
5923 .translate = translate_xsr_mask,
5924 .test_ill = test_ill_sr,
5925 .par = (const uint32_t[]){
5930 .op_flags = XTENSA_OP_PRIVILEGED,
5932 .name = "xsr.rasid",
5933 .translate = translate_xsr_rasid,
5934 .test_ill = test_ill_sr,
5935 .par = (const uint32_t[]){
5939 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
5942 .translate = translate_xsr_sar,
5943 .par = (const uint32_t[]){SAR},
5945 .name = "xsr.scompare1",
5946 .translate = translate_xsr,
5947 .test_ill = test_ill_sr,
5948 .par = (const uint32_t[]){
5950 XTENSA_OPTION_CONDITIONAL_STORE,
5953 .name = "xsr.vecbase",
5954 .translate = translate_xsr,
5955 .test_ill = test_ill_sr,
5956 .par = (const uint32_t[]){
5958 XTENSA_OPTION_RELOCATABLE_VECTOR,
5960 .op_flags = XTENSA_OP_PRIVILEGED,
5962 .name = "xsr.windowbase",
5963 .translate = translate_xsr_windowbase,
5964 .test_ill = test_ill_sr,
5965 .par = (const uint32_t[]){
5967 XTENSA_OPTION_WINDOWED_REGISTER,
5969 .op_flags = XTENSA_OP_PRIVILEGED |
5970 XTENSA_OP_EXIT_TB_M1 |
5971 XTENSA_OP_SYNC_REGISTER_WINDOW,
5973 .name = "xsr.windowstart",
5974 .translate = translate_xsr_windowstart,
5975 .test_ill = test_ill_sr,
5976 .par = (const uint32_t[]){
5978 XTENSA_OPTION_WINDOWED_REGISTER,
5980 .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
5984 const XtensaOpcodeTranslators xtensa_core_opcodes = {
5985 .num_opcodes = ARRAY_SIZE(core_ops),
5990 static void translate_abs_s(DisasContext *dc, const OpcodeArg arg[],
5991 const uint32_t par[])
5993 gen_helper_abs_s(arg[0].out, arg[1].in);
5996 static void translate_add_s(DisasContext *dc, const OpcodeArg arg[],
5997 const uint32_t par[])
5999 gen_helper_add_s(arg[0].out, cpu_env,
6000 arg[1].in, arg[2].in);
6013 static void translate_compare_s(DisasContext *dc, const OpcodeArg arg[],
6014 const uint32_t par[])
6016 static void (* const helper[])(TCGv_env env, TCGv_i32 bit,
6017 TCGv_i32 s, TCGv_i32 t) = {
6018 [COMPARE_UN] = gen_helper_un_s,
6019 [COMPARE_OEQ] = gen_helper_oeq_s,
6020 [COMPARE_UEQ] = gen_helper_ueq_s,
6021 [COMPARE_OLT] = gen_helper_olt_s,
6022 [COMPARE_ULT] = gen_helper_ult_s,
6023 [COMPARE_OLE] = gen_helper_ole_s,
6024 [COMPARE_ULE] = gen_helper_ule_s,
6026 TCGv_i32 bit = tcg_const_i32(1 << arg[0].imm);
6028 helper[par[0]](cpu_env, bit, arg[1].in, arg[2].in);
6032 static void translate_float_s(DisasContext *dc, const OpcodeArg arg[],
6033 const uint32_t par[])
6035 TCGv_i32 scale = tcg_const_i32(-arg[2].imm);
6038 gen_helper_uitof(arg[0].out, cpu_env, arg[1].in, scale);
6040 gen_helper_itof(arg[0].out, cpu_env, arg[1].in, scale);
6042 tcg_temp_free(scale);
6045 static void translate_ftoi_s(DisasContext *dc, const OpcodeArg arg[],
6046 const uint32_t par[])
6048 TCGv_i32 rounding_mode = tcg_const_i32(par[0]);
6049 TCGv_i32 scale = tcg_const_i32(arg[2].imm);
6052 gen_helper_ftoui(arg[0].out, arg[1].in,
6053 rounding_mode, scale);
6055 gen_helper_ftoi(arg[0].out, arg[1].in,
6056 rounding_mode, scale);
6058 tcg_temp_free(rounding_mode);
6059 tcg_temp_free(scale);
6062 static void translate_ldsti(DisasContext *dc, const OpcodeArg arg[],
6063 const uint32_t par[])
6065 TCGv_i32 addr = tcg_temp_new_i32();
6067 tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm);
6068 gen_load_store_alignment(dc, 2, addr, false);
6070 tcg_gen_qemu_st32(arg[0].in, addr, dc->cring);
6072 tcg_gen_qemu_ld32u(arg[0].out, addr, dc->cring);
6075 tcg_gen_mov_i32(arg[1].out, addr);
6077 tcg_temp_free(addr);
6080 static void translate_ldstx(DisasContext *dc, const OpcodeArg arg[],
6081 const uint32_t par[])
6083 TCGv_i32 addr = tcg_temp_new_i32();
6085 tcg_gen_add_i32(addr, arg[1].in, arg[2].in);
6086 gen_load_store_alignment(dc, 2, addr, false);
6088 tcg_gen_qemu_st32(arg[0].in, addr, dc->cring);
6090 tcg_gen_qemu_ld32u(arg[0].out, addr, dc->cring);
6093 tcg_gen_mov_i32(arg[1].out, addr);
6095 tcg_temp_free(addr);
6098 static void translate_madd_s(DisasContext *dc, const OpcodeArg arg[],
6099 const uint32_t par[])
6101 gen_helper_madd_s(arg[0].out, cpu_env,
6102 arg[0].in, arg[1].in, arg[2].in);
6105 static void translate_mov_s(DisasContext *dc, const OpcodeArg arg[],
6106 const uint32_t par[])
6108 tcg_gen_mov_i32(arg[0].out, arg[1].in);
6111 static void translate_movcond_s(DisasContext *dc, const OpcodeArg arg[],
6112 const uint32_t par[])
6114 TCGv_i32 zero = tcg_const_i32(0);
6116 tcg_gen_movcond_i32(par[0], arg[0].out,
6118 arg[1].in, arg[0].in);
6119 tcg_temp_free(zero);
6122 static void translate_movp_s(DisasContext *dc, const OpcodeArg arg[],
6123 const uint32_t par[])
6125 TCGv_i32 zero = tcg_const_i32(0);
6126 TCGv_i32 tmp = tcg_temp_new_i32();
6128 tcg_gen_andi_i32(tmp, arg[2].in, 1 << arg[2].imm);
6129 tcg_gen_movcond_i32(par[0],
6130 arg[0].out, tmp, zero,
6131 arg[1].in, arg[0].in);
6133 tcg_temp_free(zero);
6136 static void translate_mul_s(DisasContext *dc, const OpcodeArg arg[],
6137 const uint32_t par[])
6139 gen_helper_mul_s(arg[0].out, cpu_env,
6140 arg[1].in, arg[2].in);
6143 static void translate_msub_s(DisasContext *dc, const OpcodeArg arg[],
6144 const uint32_t par[])
6146 gen_helper_msub_s(arg[0].out, cpu_env,
6147 arg[0].in, arg[1].in, arg[2].in);
6150 static void translate_neg_s(DisasContext *dc, const OpcodeArg arg[],
6151 const uint32_t par[])
6153 gen_helper_neg_s(arg[0].out, arg[1].in);
6156 static void translate_rfr_s(DisasContext *dc, const OpcodeArg arg[],
6157 const uint32_t par[])
6159 tcg_gen_mov_i32(arg[0].out, arg[1].in);
6162 static void translate_sub_s(DisasContext *dc, const OpcodeArg arg[],
6163 const uint32_t par[])
6165 gen_helper_sub_s(arg[0].out, cpu_env,
6166 arg[1].in, arg[2].in);
6169 static void translate_wfr_s(DisasContext *dc, const OpcodeArg arg[],
6170 const uint32_t par[])
6172 tcg_gen_mov_i32(arg[0].out, arg[1].in);
6175 static const XtensaOpcodeOps fpu2000_ops[] = {
6178 .translate = translate_abs_s,
6182 .translate = translate_add_s,
6186 .translate = translate_ftoi_s,
6187 .par = (const uint32_t[]){float_round_up, false},
6191 .translate = translate_float_s,
6192 .par = (const uint32_t[]){false},
6196 .translate = translate_ftoi_s,
6197 .par = (const uint32_t[]){float_round_down, false},
6201 .translate = translate_ldsti,
6202 .par = (const uint32_t[]){false, false},
6203 .op_flags = XTENSA_OP_LOAD,
6207 .translate = translate_ldsti,
6208 .par = (const uint32_t[]){false, true},
6209 .op_flags = XTENSA_OP_LOAD,
6213 .translate = translate_ldstx,
6214 .par = (const uint32_t[]){false, false},
6215 .op_flags = XTENSA_OP_LOAD,
6219 .translate = translate_ldstx,
6220 .par = (const uint32_t[]){false, true},
6221 .op_flags = XTENSA_OP_LOAD,
6225 .translate = translate_madd_s,
6229 .translate = translate_mov_s,
6233 .translate = translate_movcond_s,
6234 .par = (const uint32_t[]){TCG_COND_EQ},
6238 .translate = translate_movp_s,
6239 .par = (const uint32_t[]){TCG_COND_EQ},
6243 .translate = translate_movcond_s,
6244 .par = (const uint32_t[]){TCG_COND_GE},
6248 .translate = translate_movcond_s,
6249 .par = (const uint32_t[]){TCG_COND_LT},
6253 .translate = translate_movcond_s,
6254 .par = (const uint32_t[]){TCG_COND_NE},
6258 .translate = translate_movp_s,
6259 .par = (const uint32_t[]){TCG_COND_NE},
6263 .translate = translate_msub_s,
6267 .translate = translate_mul_s,
6271 .translate = translate_neg_s,
6275 .translate = translate_compare_s,
6276 .par = (const uint32_t[]){COMPARE_OEQ},
6280 .translate = translate_compare_s,
6281 .par = (const uint32_t[]){COMPARE_OLE},
6285 .translate = translate_compare_s,
6286 .par = (const uint32_t[]){COMPARE_OLT},
6290 .translate = translate_rfr_s,
6294 .translate = translate_ftoi_s,
6295 .par = (const uint32_t[]){float_round_nearest_even, false},
6299 .translate = translate_ldsti,
6300 .par = (const uint32_t[]){true, false},
6301 .op_flags = XTENSA_OP_STORE,
6305 .translate = translate_ldsti,
6306 .par = (const uint32_t[]){true, true},
6307 .op_flags = XTENSA_OP_STORE,
6311 .translate = translate_ldstx,
6312 .par = (const uint32_t[]){true, false},
6313 .op_flags = XTENSA_OP_STORE,
6317 .translate = translate_ldstx,
6318 .par = (const uint32_t[]){true, true},
6319 .op_flags = XTENSA_OP_STORE,
6323 .translate = translate_sub_s,
6327 .translate = translate_ftoi_s,
6328 .par = (const uint32_t[]){float_round_to_zero, false},
6332 .translate = translate_compare_s,
6333 .par = (const uint32_t[]){COMPARE_UEQ},
6337 .translate = translate_float_s,
6338 .par = (const uint32_t[]){true},
6342 .translate = translate_compare_s,
6343 .par = (const uint32_t[]){COMPARE_ULE},
6347 .translate = translate_compare_s,
6348 .par = (const uint32_t[]){COMPARE_ULT},
6352 .translate = translate_compare_s,
6353 .par = (const uint32_t[]){COMPARE_UN},
6357 .translate = translate_ftoi_s,
6358 .par = (const uint32_t[]){float_round_to_zero, true},
6362 .translate = translate_wfr_s,
6367 const XtensaOpcodeTranslators xtensa_fpu2000_opcodes = {
6368 .num_opcodes = ARRAY_SIZE(fpu2000_ops),
6369 .opcode = fpu2000_ops,