@@ -37,6 +37,7 @@
#include "cpu-qom.h"
#include "exec/cpu-defs.h"
#include "fpu/softfloat.h"
+#include "xtensa-isa.h"
#define NB_MMU_MODES 4
@@ -205,6 +206,8 @@ enum {
#define MEMCTL_DSNP 0x2
#define MEMCTL_IL0EN 0x1
+#define MAX_INSN_LENGTH 64
+#define MAX_OPCODE_ARGS 16
#define MAX_NAREG 64
#define MAX_NINTERRUPT 32
#define MAX_NLEVEL 6
@@ -330,6 +333,23 @@ typedef struct XtensaMemory {
} location[MAX_NMEMORY];
} XtensaMemory;
+typedef struct DisasContext DisasContext;
+typedef void (*XtensaOpcodeOp)(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[]);
+
+typedef struct XtensaOpcodeOps {
+ const char *name;
+ XtensaOpcodeOp translate;
+ const uint32_t *par;
+} XtensaOpcodeOps;
+
+typedef struct XtensaOpcodeTranslators {
+ unsigned num_opcodes;
+ const XtensaOpcodeOps *opcode;
+} XtensaOpcodeTranslators;
+
+extern const XtensaOpcodeTranslators xtensa_core_opcodes;
+
struct XtensaConfig {
const char *name;
uint64_t options;
@@ -370,6 +390,8 @@ struct XtensaConfig {
uint32_t configid[2];
+ void *isa_internal;
+
uint32_t clock_freq_khz;
xtensa_tlb itlb;
@@ -518,6 +540,8 @@ static inline void xtensa_select_static_vectors(CPUXtensaState *env,
env->static_vectors = n;
}
void xtensa_runstall(CPUXtensaState *env, bool runstall);
+XtensaOpcodeOps *xtensa_find_opcode_ops(const XtensaOpcodeTranslators *t,
+ const char *opcode);
#define XTENSA_OPTION_BIT(opt) (((uint64_t)1) << (opt))
#define XTENSA_OPTION_ALL (~(uint64_t)0)
@@ -75,6 +75,8 @@ typedef struct DisasContext {
TCGv_i32 next_icount;
unsigned cpenable;
+
+ uint32_t *raw_arg;
} DisasContext;
static TCGv_i32 cpu_pc;
@@ -3312,3 +3314,3122 @@ void restore_state_to_opc(CPUXtensaState *env, TranslationBlock *tb,
{
env->pc = data[0];
}
+
+static int compare_opcode_ops(const void *a, const void *b)
+{
+ return strcmp((const char *)a,
+ ((const XtensaOpcodeOps *)b)->name);
+}
+
+XtensaOpcodeOps *
+xtensa_find_opcode_ops(const XtensaOpcodeTranslators *t,
+ const char *name)
+{
+ XtensaOpcodeOps *ops;
+
+ ops = bsearch(name, t->opcode, t->num_opcodes,
+ sizeof(XtensaOpcodeOps), compare_opcode_ops);
+ return ops;
+}
+
+static void translate_abs(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check2(dc, arg[0], arg[1])) {
+ TCGv_i32 zero = tcg_const_i32(0);
+ TCGv_i32 neg = tcg_temp_new_i32();
+
+ tcg_gen_neg_i32(neg, cpu_R[arg[1]]);
+ tcg_gen_movcond_i32(TCG_COND_GE, cpu_R[arg[0]],
+ cpu_R[arg[1]], zero, cpu_R[arg[1]], neg);
+ tcg_temp_free(neg);
+ tcg_temp_free(zero);
+ }
+}
+
+static void translate_add(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
+ tcg_gen_add_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
+ }
+}
+
+static void translate_addi(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check2(dc, arg[0], arg[1])) {
+ tcg_gen_addi_i32(cpu_R[arg[0]], cpu_R[arg[1]], arg[2]);
+ }
+}
+
+static void translate_addx(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
+ TCGv_i32 tmp = tcg_temp_new_i32();
+ tcg_gen_shli_i32(tmp, cpu_R[arg[1]], par[0]);
+ tcg_gen_add_i32(cpu_R[arg[0]], tmp, cpu_R[arg[2]]);
+ tcg_temp_free(tmp);
+ }
+}
+
+static void translate_all(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ uint32_t shift = par[1];
+ TCGv_i32 mask = tcg_const_i32(((1 << shift) - 1) << arg[1]);
+ TCGv_i32 tmp = tcg_temp_new_i32();
+
+ tcg_gen_and_i32(tmp, cpu_SR[BR], mask);
+ if (par[0]) {
+ tcg_gen_addi_i32(tmp, tmp, 1 << arg[1]);
+ } else {
+ tcg_gen_add_i32(tmp, tmp, mask);
+ }
+ tcg_gen_shri_i32(tmp, tmp, arg[1] + shift);
+ tcg_gen_deposit_i32(cpu_SR[BR], cpu_SR[BR],
+ tmp, arg[0], 1);
+ tcg_temp_free(mask);
+ tcg_temp_free(tmp);
+}
+
+static void translate_and(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
+ tcg_gen_and_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
+ }
+}
+
+static void translate_ball(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check2(dc, arg[0], arg[1])) {
+ TCGv_i32 tmp = tcg_temp_new_i32();
+ tcg_gen_and_i32(tmp, cpu_R[arg[0]], cpu_R[arg[1]]);
+ gen_brcond(dc, par[0], tmp, cpu_R[arg[1]], arg[2]);
+ tcg_temp_free(tmp);
+ }
+}
+
+static void translate_bany(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check2(dc, arg[0], arg[1])) {
+ TCGv_i32 tmp = tcg_temp_new_i32();
+ tcg_gen_and_i32(tmp, cpu_R[arg[0]], cpu_R[arg[1]]);
+ gen_brcondi(dc, par[0], tmp, 0, arg[2]);
+ tcg_temp_free(tmp);
+ }
+}
+
+static void translate_b(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check2(dc, arg[0], arg[1])) {
+ gen_brcond(dc, par[0], cpu_R[arg[0]], cpu_R[arg[1]], arg[2]);
+ }
+}
+
+static void translate_bb(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check2(dc, arg[0], arg[1])) {
+#ifdef TARGET_WORDS_BIGENDIAN
+ TCGv_i32 bit = tcg_const_i32(0x80000000u);
+#else
+ TCGv_i32 bit = tcg_const_i32(0x00000001u);
+#endif
+ TCGv_i32 tmp = tcg_temp_new_i32();
+ tcg_gen_andi_i32(tmp, cpu_R[arg[1]], 0x1f);
+#ifdef TARGET_WORDS_BIGENDIAN
+ tcg_gen_shr_i32(bit, bit, tmp);
+#else
+ tcg_gen_shl_i32(bit, bit, tmp);
+#endif
+ tcg_gen_and_i32(tmp, cpu_R[arg[0]], bit);
+ gen_brcondi(dc, par[0], tmp, 0, arg[2]);
+ tcg_temp_free(tmp);
+ tcg_temp_free(bit);
+ }
+}
+
+static void translate_bbi(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check1(dc, arg[0])) {
+ TCGv_i32 tmp = tcg_temp_new_i32();
+#ifdef TARGET_WORDS_BIGENDIAN
+ tcg_gen_andi_i32(tmp, cpu_R[arg[0]], 0x80000000u >> arg[1]);
+#else
+ tcg_gen_andi_i32(tmp, cpu_R[arg[0]], 0x00000001u << arg[1]);
+#endif
+ gen_brcondi(dc, par[0], tmp, 0, arg[2]);
+ tcg_temp_free(tmp);
+ }
+}
+
+static void translate_bi(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check1(dc, arg[0])) {
+ gen_brcondi(dc, par[0], cpu_R[arg[0]], arg[1], arg[2]);
+ }
+}
+
+static void translate_bz(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check1(dc, arg[0])) {
+ gen_brcondi(dc, par[0], cpu_R[arg[0]], 0, arg[1]);
+ }
+}
+
+enum {
+ BOOLEAN_AND,
+ BOOLEAN_ANDC,
+ BOOLEAN_OR,
+ BOOLEAN_ORC,
+ BOOLEAN_XOR,
+};
+
+static void translate_boolean(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ static void (* const op[])(TCGv_i32, TCGv_i32, TCGv_i32) = {
+ [BOOLEAN_AND] = tcg_gen_and_i32,
+ [BOOLEAN_ANDC] = tcg_gen_andc_i32,
+ [BOOLEAN_OR] = tcg_gen_or_i32,
+ [BOOLEAN_ORC] = tcg_gen_orc_i32,
+ [BOOLEAN_XOR] = tcg_gen_xor_i32,
+ };
+
+ TCGv_i32 tmp1 = tcg_temp_new_i32();
+ TCGv_i32 tmp2 = tcg_temp_new_i32();
+
+ tcg_gen_shri_i32(tmp1, cpu_SR[BR], arg[1]);
+ tcg_gen_shri_i32(tmp2, cpu_SR[BR], arg[2]);
+ op[par[0]](tmp1, tmp1, tmp2);
+ tcg_gen_deposit_i32(cpu_SR[BR], cpu_SR[BR], tmp1, arg[0], 1);
+ tcg_temp_free(tmp1);
+ tcg_temp_free(tmp2);
+}
+
+static void translate_bp(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ TCGv_i32 tmp = tcg_temp_new_i32();
+
+ tcg_gen_andi_i32(tmp, cpu_SR[BR], 1 << arg[0]);
+ gen_brcondi(dc, par[0], tmp, 0, arg[1]);
+ tcg_temp_free(tmp);
+}
+
+static void translate_break(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (dc->debug) {
+ gen_debug_exception(dc, par[0]);
+ }
+}
+
+static void translate_call0(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ tcg_gen_movi_i32(cpu_R[0], dc->next_pc);
+ gen_jumpi(dc, arg[0], 0);
+}
+
+static void translate_callw(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check1(dc, par[0] << 2)) {
+ gen_callwi(dc, par[0], arg[0], 0);
+ }
+}
+
+static void translate_callx0(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check1(dc, arg[0])) {
+ TCGv_i32 tmp = tcg_temp_new_i32();
+ tcg_gen_mov_i32(tmp, cpu_R[arg[0]]);
+ tcg_gen_movi_i32(cpu_R[0], dc->next_pc);
+ gen_jump(dc, tmp);
+ tcg_temp_free(tmp);
+ }
+}
+
+static void translate_callxw(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check2(dc, arg[0], par[0] << 2)) {
+ TCGv_i32 tmp = tcg_temp_new_i32();
+
+ tcg_gen_mov_i32(tmp, cpu_R[arg[0]]);
+ gen_callw(dc, par[0], tmp);
+ tcg_temp_free(tmp);
+ }
+}
+
+static void translate_clamps(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check2(dc, arg[0], arg[1])) {
+ TCGv_i32 tmp1 = tcg_const_i32(-1u << arg[2]);
+ TCGv_i32 tmp2 = tcg_const_i32((1 << arg[2]) - 1);
+
+ tcg_gen_movcond_i32(TCG_COND_GT, tmp1,
+ cpu_R[arg[1]], tmp1, cpu_R[arg[1]], tmp1);
+ tcg_gen_movcond_i32(TCG_COND_LT, cpu_R[arg[0]],
+ tmp1, tmp2, tmp1, tmp2);
+ tcg_temp_free(tmp1);
+ tcg_temp_free(tmp2);
+ }
+}
+
+/* par[0]: privileged, par[1]: check memory access */
+static void translate_dcache(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if ((!par[0] || gen_check_privilege(dc)) &&
+ gen_window_check1(dc, arg[0]) && par[1]) {
+ TCGv_i32 addr = tcg_temp_new_i32();
+ TCGv_i32 res = tcg_temp_new_i32();
+
+ tcg_gen_addi_i32(addr, cpu_R[arg[0]], arg[1]);
+ tcg_gen_qemu_ld8u(res, addr, dc->cring);
+ tcg_temp_free(addr);
+ tcg_temp_free(res);
+ }
+}
+
+static void translate_depbits(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check2(dc, arg[0], arg[1])) {
+ tcg_gen_deposit_i32(cpu_R[arg[1]], cpu_R[arg[1]], cpu_R[arg[0]],
+ arg[2], arg[3]);
+ }
+}
+
+static void translate_entry(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ TCGv_i32 pc = tcg_const_i32(dc->pc);
+ TCGv_i32 s = tcg_const_i32(arg[0]);
+ TCGv_i32 imm = tcg_const_i32(arg[1]);
+ gen_helper_entry(cpu_env, pc, s, imm);
+ tcg_temp_free(imm);
+ tcg_temp_free(s);
+ tcg_temp_free(pc);
+ /* This can change tb->flags, so exit tb */
+ gen_jumpi_check_loop_end(dc, -1);
+}
+
+static void translate_extui(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check2(dc, arg[0], arg[1])) {
+ int maskimm = (1 << arg[3]) - 1;
+
+ TCGv_i32 tmp = tcg_temp_new_i32();
+ tcg_gen_shri_i32(tmp, cpu_R[arg[1]], arg[2]);
+ tcg_gen_andi_i32(cpu_R[arg[0]], tmp, maskimm);
+ tcg_temp_free(tmp);
+ }
+}
+
+/* par[0]: privileged, par[1]: check memory access */
+static void translate_icache(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if ((!par[0] || gen_check_privilege(dc)) &&
+ gen_window_check1(dc, arg[0]) && par[1]) {
+ TCGv_i32 addr = tcg_temp_new_i32();
+
+ tcg_gen_movi_i32(cpu_pc, dc->pc);
+ tcg_gen_addi_i32(addr, cpu_R[arg[0]], arg[1]);
+ gen_helper_itlb_hit_test(cpu_env, addr);
+ tcg_temp_free(addr);
+ }
+}
+
+static void translate_itlb(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_check_privilege(dc) &&
+ gen_window_check1(dc, arg[0])) {
+ TCGv_i32 dtlb = tcg_const_i32(par[0]);
+
+ gen_helper_itlb(cpu_env, cpu_R[arg[0]], dtlb);
+ /* This could change memory mapping, so exit tb */
+ gen_jumpi_check_loop_end(dc, -1);
+ tcg_temp_free(dtlb);
+ }
+}
+
+static void translate_ill(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
+}
+
+static void translate_j(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ gen_jumpi(dc, arg[0], 0);
+}
+
+static void translate_jx(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check1(dc, arg[0])) {
+ gen_jump(dc, cpu_R[arg[0]]);
+ }
+}
+
+static void translate_l32e(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_check_privilege(dc) &&
+ gen_window_check2(dc, arg[0], arg[1])) {
+ TCGv_i32 addr = tcg_temp_new_i32();
+
+ tcg_gen_addi_i32(addr, cpu_R[arg[1]], arg[2]);
+ gen_load_store_alignment(dc, 2, addr, false);
+ tcg_gen_qemu_ld_tl(cpu_R[arg[0]], addr, dc->ring, MO_TEUL);
+ tcg_temp_free(addr);
+ }
+}
+
+static void translate_ldst(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check2(dc, arg[0], arg[1])) {
+ TCGv_i32 addr = tcg_temp_new_i32();
+
+ tcg_gen_addi_i32(addr, cpu_R[arg[1]], arg[2]);
+ if (par[0] & MO_SIZE) {
+ gen_load_store_alignment(dc, par[0] & MO_SIZE, addr, par[1]);
+ }
+ if (par[2]) {
+ tcg_gen_qemu_st_tl(cpu_R[arg[0]], addr, dc->cring, par[0]);
+ } else {
+ tcg_gen_qemu_ld_tl(cpu_R[arg[0]], addr, dc->cring, par[0]);
+ }
+ tcg_temp_free(addr);
+ }
+}
+
+static void translate_l32r(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check1(dc, arg[0])) {
+ TCGv_i32 tmp = (dc->tb->flags & XTENSA_TBFLAG_LITBASE) ?
+ tcg_const_i32(dc->raw_arg[1] - 1) :
+ tcg_const_i32(arg[1]);
+
+ if (dc->tb->flags & XTENSA_TBFLAG_LITBASE) {
+ tcg_gen_add_i32(tmp, tmp, dc->litbase);
+ }
+ tcg_gen_qemu_ld32u(cpu_R[arg[0]], tmp, dc->cring);
+ tcg_temp_free(tmp);
+ }
+}
+
+static void translate_loop(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check1(dc, arg[0])) {
+ uint32_t lend = arg[1];
+ TCGv_i32 tmp = tcg_const_i32(lend);
+
+ tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_R[arg[0]], 1);
+ tcg_gen_movi_i32(cpu_SR[LBEG], dc->next_pc);
+ gen_helper_wsr_lend(cpu_env, tmp);
+ tcg_temp_free(tmp);
+
+ if (par[0] != TCG_COND_NEVER) {
+ TCGLabel *label = gen_new_label();
+ tcg_gen_brcondi_i32(par[0], cpu_R[arg[0]], 0, label);
+ gen_jumpi(dc, lend, 1);
+ gen_set_label(label);
+ }
+
+ gen_jumpi(dc, dc->next_pc, 0);
+ }
+}
+
+enum {
+ MAC16_UMUL,
+ MAC16_MUL,
+ MAC16_MULA,
+ MAC16_MULS,
+ MAC16_NONE,
+};
+
+enum {
+ MAC16_LL,
+ MAC16_HL,
+ MAC16_LH,
+ MAC16_HH,
+
+ MAC16_HX = 0x1,
+ MAC16_XH = 0x2,
+};
+
+enum {
+ MAC16_AA,
+ MAC16_AD,
+ MAC16_DA,
+ MAC16_DD,
+
+ MAC16_XD = 0x1,
+ MAC16_DX = 0x2,
+};
+
+static void translate_mac16(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ int op = par[0];
+ bool is_m1_sr = par[1] & MAC16_DX;
+ bool is_m2_sr = par[1] & MAC16_XD;
+ unsigned half = par[2];
+ uint32_t ld_offset = par[3];
+ unsigned off = ld_offset ? 2 : 0;
+ uint32_t ar[3] = {0};
+ unsigned n_ar = 0;
+
+ if (op != MAC16_NONE) {
+ if (!is_m1_sr) {
+ ar[n_ar++] = arg[off];
+ }
+ if (!is_m2_sr) {
+ ar[n_ar++] = arg[off + 1];
+ }
+ }
+
+ if (ld_offset) {
+ ar[n_ar++] = arg[1];
+ }
+
+ if (gen_window_check3(dc, ar[0], ar[1], ar[2])) {
+ TCGv_i32 vaddr = tcg_temp_new_i32();
+ TCGv_i32 mem32 = tcg_temp_new_i32();
+
+ if (ld_offset) {
+ tcg_gen_addi_i32(vaddr, cpu_R[arg[1]], ld_offset);
+ gen_load_store_alignment(dc, 2, vaddr, false);
+ tcg_gen_qemu_ld32u(mem32, vaddr, dc->cring);
+ }
+ if (op != MAC16_NONE) {
+ TCGv_i32 m1 = gen_mac16_m(is_m1_sr ?
+ cpu_SR[MR + arg[off]] :
+ cpu_R[arg[off]],
+ half & MAC16_HX, op == MAC16_UMUL);
+ TCGv_i32 m2 = gen_mac16_m(is_m2_sr ?
+ cpu_SR[MR + arg[off + 1]] :
+ cpu_R[arg[off + 1]],
+ half & MAC16_XH, op == MAC16_UMUL);
+
+ if (op == MAC16_MUL || op == MAC16_UMUL) {
+ tcg_gen_mul_i32(cpu_SR[ACCLO], m1, m2);
+ if (op == MAC16_UMUL) {
+ tcg_gen_movi_i32(cpu_SR[ACCHI], 0);
+ } else {
+ tcg_gen_sari_i32(cpu_SR[ACCHI], cpu_SR[ACCLO], 31);
+ }
+ } else {
+ TCGv_i32 lo = tcg_temp_new_i32();
+ TCGv_i32 hi = tcg_temp_new_i32();
+
+ tcg_gen_mul_i32(lo, m1, m2);
+ tcg_gen_sari_i32(hi, lo, 31);
+ if (op == MAC16_MULA) {
+ tcg_gen_add2_i32(cpu_SR[ACCLO], cpu_SR[ACCHI],
+ cpu_SR[ACCLO], cpu_SR[ACCHI],
+ lo, hi);
+ } else {
+ tcg_gen_sub2_i32(cpu_SR[ACCLO], cpu_SR[ACCHI],
+ cpu_SR[ACCLO], cpu_SR[ACCHI],
+ lo, hi);
+ }
+ tcg_gen_ext8s_i32(cpu_SR[ACCHI], cpu_SR[ACCHI]);
+
+ tcg_temp_free_i32(lo);
+ tcg_temp_free_i32(hi);
+ }
+ tcg_temp_free(m1);
+ tcg_temp_free(m2);
+ }
+ if (ld_offset) {
+ tcg_gen_mov_i32(cpu_R[arg[1]], vaddr);
+ tcg_gen_mov_i32(cpu_SR[MR + arg[0]], mem32);
+ }
+ tcg_temp_free(vaddr);
+ tcg_temp_free(mem32);
+ }
+}
+
+static void translate_minmax(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
+ tcg_gen_movcond_i32(par[0], cpu_R[arg[0]],
+ cpu_R[arg[1]], cpu_R[arg[2]],
+ cpu_R[arg[1]], cpu_R[arg[2]]);
+ }
+}
+
+static void translate_mov(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check2(dc, arg[0], arg[1])) {
+ tcg_gen_mov_i32(cpu_R[arg[0]], cpu_R[arg[1]]);
+ }
+}
+
+static void translate_movcond(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
+ TCGv_i32 zero = tcg_const_i32(0);
+
+ tcg_gen_movcond_i32(par[0], cpu_R[arg[0]],
+ cpu_R[arg[2]], zero, cpu_R[arg[1]], cpu_R[arg[0]]);
+ tcg_temp_free(zero);
+ }
+}
+
+static void translate_movi(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check1(dc, arg[0])) {
+ tcg_gen_movi_i32(cpu_R[arg[0]], arg[1]);
+ }
+}
+
+static void translate_movp(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check2(dc, arg[0], arg[1])) {
+ TCGv_i32 zero = tcg_const_i32(0);
+ TCGv_i32 tmp = tcg_temp_new_i32();
+
+ tcg_gen_andi_i32(tmp, cpu_SR[BR], 1 << arg[2]);
+ tcg_gen_movcond_i32(par[0],
+ cpu_R[arg[0]], tmp, zero,
+ cpu_R[arg[1]], cpu_R[arg[0]]);
+ tcg_temp_free(tmp);
+ tcg_temp_free(zero);
+ }
+}
+
+static void translate_movsp(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check2(dc, arg[0], arg[1])) {
+ TCGv_i32 pc = tcg_const_i32(dc->pc);
+ gen_helper_movsp(cpu_env, pc);
+ tcg_gen_mov_i32(cpu_R[arg[0]], cpu_R[arg[1]]);
+ tcg_temp_free(pc);
+ }
+}
+
+static void translate_mul16(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
+ TCGv_i32 v1 = tcg_temp_new_i32();
+ TCGv_i32 v2 = tcg_temp_new_i32();
+
+ if (par[0]) {
+ tcg_gen_ext16s_i32(v1, cpu_R[arg[1]]);
+ tcg_gen_ext16s_i32(v2, cpu_R[arg[2]]);
+ } else {
+ tcg_gen_ext16u_i32(v1, cpu_R[arg[1]]);
+ tcg_gen_ext16u_i32(v2, cpu_R[arg[2]]);
+ }
+ tcg_gen_mul_i32(cpu_R[arg[0]], v1, v2);
+ tcg_temp_free(v2);
+ tcg_temp_free(v1);
+ }
+}
+
+static void translate_mull(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
+ tcg_gen_mul_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
+ }
+}
+
+static void translate_mulh(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
+ TCGv_i32 lo = tcg_temp_new();
+
+ if (par[0]) {
+ tcg_gen_muls2_i32(lo, cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
+ } else {
+ tcg_gen_mulu2_i32(lo, cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
+ }
+ tcg_temp_free(lo);
+ }
+}
+
+static void translate_neg(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check2(dc, arg[0], arg[1])) {
+ tcg_gen_neg_i32(cpu_R[arg[0]], cpu_R[arg[1]]);
+ }
+}
+
+static void translate_nop(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+}
+
+static void translate_nsa(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check2(dc, arg[0], arg[1])) {
+ tcg_gen_clrsb_i32(cpu_R[arg[0]], cpu_R[arg[1]]);
+ }
+}
+
+static void translate_nsau(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check2(dc, arg[0], arg[1])) {
+ tcg_gen_clzi_i32(cpu_R[arg[0]], cpu_R[arg[1]], 32);
+ }
+}
+
+static void translate_or(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
+ tcg_gen_or_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
+ }
+}
+
+static void translate_ptlb(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_check_privilege(dc) &&
+ gen_window_check2(dc, arg[0], arg[1])) {
+ TCGv_i32 dtlb = tcg_const_i32(par[0]);
+
+ tcg_gen_movi_i32(cpu_pc, dc->pc);
+ gen_helper_ptlb(cpu_R[arg[0]], cpu_env, cpu_R[arg[1]], dtlb);
+ tcg_temp_free(dtlb);
+ }
+}
+
+static void gen_zero_check(DisasContext *dc, const uint32_t arg[])
+{
+ TCGLabel *label = gen_new_label();
+
+ tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[arg[2]], 0, label);
+ gen_exception_cause(dc, INTEGER_DIVIDE_BY_ZERO_CAUSE);
+ gen_set_label(label);
+}
+
+static void translate_quos(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
+ TCGLabel *label1 = gen_new_label();
+ TCGLabel *label2 = gen_new_label();
+
+ gen_zero_check(dc, arg);
+
+ tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[arg[1]], 0x80000000,
+ label1);
+ tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[arg[2]], 0xffffffff,
+ label1);
+ tcg_gen_movi_i32(cpu_R[arg[0]],
+ par[0] ? 0x80000000 : 0);
+ tcg_gen_br(label2);
+ gen_set_label(label1);
+ if (par[0]) {
+ tcg_gen_div_i32(cpu_R[arg[0]],
+ cpu_R[arg[1]], cpu_R[arg[2]]);
+ } else {
+ tcg_gen_rem_i32(cpu_R[arg[0]],
+ cpu_R[arg[1]], cpu_R[arg[2]]);
+ }
+ gen_set_label(label2);
+ }
+}
+
+static void translate_quou(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
+ gen_zero_check(dc, arg);
+ if (par[0]) {
+ tcg_gen_divu_i32(cpu_R[arg[0]],
+ cpu_R[arg[1]], cpu_R[arg[2]]);
+ } else {
+ tcg_gen_remu_i32(cpu_R[arg[0]],
+ cpu_R[arg[1]], cpu_R[arg[2]]);
+ }
+ }
+}
+
+static void translate_rer(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_check_privilege(dc) &&
+ gen_window_check2(dc, arg[0], arg[1])) {
+ gen_helper_rer(cpu_R[arg[0]], cpu_env, cpu_R[arg[1]]);
+ }
+}
+
+static void translate_ret(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ gen_jump(dc, cpu_R[0]);
+}
+
+static void translate_retw(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ TCGv_i32 tmp = tcg_const_i32(dc->pc);
+ gen_helper_retw(tmp, cpu_env, tmp);
+ gen_jump(dc, tmp);
+ tcg_temp_free(tmp);
+}
+
+static void translate_rfde(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_check_privilege(dc)) {
+ gen_jump(dc, cpu_SR[dc->config->ndepc ? DEPC : EPC1]);
+ }
+}
+
+static void translate_rfe(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_check_privilege(dc)) {
+ tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_EXCM);
+ gen_check_interrupts(dc);
+ gen_jump(dc, cpu_SR[EPC1]);
+ }
+}
+
+static void translate_rfi(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_check_privilege(dc)) {
+ tcg_gen_mov_i32(cpu_SR[PS], cpu_SR[EPS2 + arg[0] - 2]);
+ gen_check_interrupts(dc);
+ gen_jump(dc, cpu_SR[EPC1 + arg[0] - 1]);
+ }
+}
+
+static void translate_rfw(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_check_privilege(dc)) {
+ TCGv_i32 tmp = tcg_const_i32(1);
+
+ tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_EXCM);
+ tcg_gen_shl_i32(tmp, tmp, cpu_SR[WINDOW_BASE]);
+
+ if (par[0]) {
+ tcg_gen_andc_i32(cpu_SR[WINDOW_START],
+ cpu_SR[WINDOW_START], tmp);
+ } else {
+ tcg_gen_or_i32(cpu_SR[WINDOW_START],
+ cpu_SR[WINDOW_START], tmp);
+ }
+
+ gen_helper_restore_owb(cpu_env);
+ gen_check_interrupts(dc);
+ gen_jump(dc, cpu_SR[EPC1]);
+
+ tcg_temp_free(tmp);
+ }
+}
+
+static void translate_rotw(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_check_privilege(dc)) {
+ TCGv_i32 tmp = tcg_const_i32(arg[0]);
+ gen_helper_rotw(cpu_env, tmp);
+ tcg_temp_free(tmp);
+ /* This can change tb->flags, so exit tb */
+ gen_jumpi_check_loop_end(dc, -1);
+ }
+}
+
+static void translate_rsil(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_check_privilege(dc) &&
+ gen_window_check1(dc, arg[0])) {
+ tcg_gen_mov_i32(cpu_R[arg[0]], cpu_SR[PS]);
+ tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_INTLEVEL);
+ tcg_gen_ori_i32(cpu_SR[PS], cpu_SR[PS], arg[1]);
+ gen_check_interrupts(dc);
+ gen_jumpi_check_loop_end(dc, 0);
+ }
+}
+
+static void translate_rsr(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_check_sr(dc, par[0], SR_R) &&
+ (par[0] < 64 || gen_check_privilege(dc)) &&
+ gen_window_check1(dc, arg[0])) {
+ if (gen_rsr(dc, cpu_R[arg[0]], par[0])) {
+ gen_jumpi_check_loop_end(dc, 0);
+ }
+ }
+}
+
+static void translate_rtlb(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ static void (* const helper[])(TCGv_i32 r, TCGv_env env, TCGv_i32 a1,
+ TCGv_i32 a2) = {
+ gen_helper_rtlb0,
+ gen_helper_rtlb1,
+ };
+
+ if (gen_check_privilege(dc) &&
+ gen_window_check2(dc, arg[0], arg[1])) {
+ TCGv_i32 dtlb = tcg_const_i32(par[0]);
+
+ helper[par[1]](cpu_R[arg[0]], cpu_env, cpu_R[arg[1]], dtlb);
+ tcg_temp_free(dtlb);
+ }
+}
+
+static void translate_rur(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check1(dc, arg[0])) {
+ if (uregnames[par[0]].name) {
+ tcg_gen_mov_i32(cpu_R[arg[0]], cpu_UR[par[0]]);
+ } else {
+ qemu_log_mask(LOG_UNIMP, "RUR %d not implemented, ", par[0]);
+ }
+ }
+}
+
+static void translate_s32c1i(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check2(dc, arg[0], arg[1])) {
+ TCGLabel *label = gen_new_label();
+ TCGv_i32 tmp = tcg_temp_local_new_i32();
+ TCGv_i32 addr = tcg_temp_local_new_i32();
+ TCGv_i32 tpc;
+
+ tcg_gen_mov_i32(tmp, cpu_R[arg[0]]);
+ tcg_gen_addi_i32(addr, cpu_R[arg[1]], arg[2]);
+ gen_load_store_alignment(dc, 2, addr, true);
+
+ tpc = tcg_const_i32(dc->pc);
+ gen_helper_check_atomctl(cpu_env, tpc, addr);
+ tcg_gen_qemu_ld32u(cpu_R[arg[0]], addr, dc->cring);
+ tcg_gen_brcond_i32(TCG_COND_NE, cpu_R[arg[0]],
+ cpu_SR[SCOMPARE1], label);
+
+ tcg_gen_qemu_st32(tmp, addr, dc->cring);
+
+ gen_set_label(label);
+ tcg_temp_free(tpc);
+ tcg_temp_free(addr);
+ tcg_temp_free(tmp);
+ }
+}
+
+static void translate_s32e(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_check_privilege(dc) &&
+ gen_window_check2(dc, arg[0], arg[1])) {
+ TCGv_i32 addr = tcg_temp_new_i32();
+
+ tcg_gen_addi_i32(addr, cpu_R[arg[1]], arg[2]);
+ gen_load_store_alignment(dc, 2, addr, false);
+ tcg_gen_qemu_st_tl(cpu_R[arg[0]], addr, dc->ring, MO_TEUL);
+ tcg_temp_free(addr);
+ }
+}
+
+static void translate_sext(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check2(dc, arg[0], arg[1])) {
+ int shift = 31 - arg[2];
+
+ if (shift == 24) {
+ tcg_gen_ext8s_i32(cpu_R[arg[0]], cpu_R[arg[1]]);
+ } else if (shift == 16) {
+ tcg_gen_ext16s_i32(cpu_R[arg[0]], cpu_R[arg[1]]);
+ } else {
+ TCGv_i32 tmp = tcg_temp_new_i32();
+ tcg_gen_shli_i32(tmp, cpu_R[arg[1]], shift);
+ tcg_gen_sari_i32(cpu_R[arg[0]], tmp, shift);
+ tcg_temp_free(tmp);
+ }
+ }
+}
+
+static void translate_simcall(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (semihosting_enabled()) {
+ if (gen_check_privilege(dc)) {
+ gen_helper_simcall(cpu_env);
+ }
+ } else {
+ qemu_log_mask(LOG_GUEST_ERROR, "SIMCALL but semihosting is disabled\n");
+ gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
+ }
+}
+
+/*
+ * Note: 64 bit ops are used here solely because SAR values
+ * have range 0..63
+ */
+#define gen_shift_reg(cmd, reg) do { \
+ TCGv_i64 tmp = tcg_temp_new_i64(); \
+ tcg_gen_extu_i32_i64(tmp, reg); \
+ tcg_gen_##cmd##_i64(v, v, tmp); \
+ tcg_gen_extrl_i64_i32(cpu_R[arg[0]], v); \
+ tcg_temp_free_i64(v); \
+ tcg_temp_free_i64(tmp); \
+ } while (0)
+
+#define gen_shift(cmd) gen_shift_reg(cmd, cpu_SR[SAR])
+
+static void translate_sll(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check2(dc, arg[0], arg[1])) {
+ if (dc->sar_m32_5bit) {
+ tcg_gen_shl_i32(cpu_R[arg[0]], cpu_R[arg[1]], dc->sar_m32);
+ } else {
+ TCGv_i64 v = tcg_temp_new_i64();
+ TCGv_i32 s = tcg_const_i32(32);
+ tcg_gen_sub_i32(s, s, cpu_SR[SAR]);
+ tcg_gen_andi_i32(s, s, 0x3f);
+ tcg_gen_extu_i32_i64(v, cpu_R[arg[1]]);
+ gen_shift_reg(shl, s);
+ tcg_temp_free(s);
+ }
+ }
+}
+
+static void translate_slli(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check2(dc, arg[0], arg[1])) {
+ if (arg[2] == 32) {
+ qemu_log_mask(LOG_GUEST_ERROR, "slli a%d, a%d, 32 is undefined",
+ arg[0], arg[1]);
+ }
+ tcg_gen_shli_i32(cpu_R[arg[0]], cpu_R[arg[1]], arg[2] & 0x1f);
+ }
+}
+
+static void translate_sra(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check2(dc, arg[0], arg[1])) {
+ if (dc->sar_m32_5bit) {
+ tcg_gen_sar_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_SR[SAR]);
+ } else {
+ TCGv_i64 v = tcg_temp_new_i64();
+ tcg_gen_ext_i32_i64(v, cpu_R[arg[1]]);
+ gen_shift(sar);
+ }
+ }
+}
+
+static void translate_srai(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check2(dc, arg[0], arg[1])) {
+ tcg_gen_sari_i32(cpu_R[arg[0]], cpu_R[arg[1]], arg[2]);
+ }
+}
+
+static void translate_src(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
+ TCGv_i64 v = tcg_temp_new_i64();
+ tcg_gen_concat_i32_i64(v, cpu_R[arg[2]], cpu_R[arg[1]]);
+ gen_shift(shr);
+ }
+}
+
+static void translate_srl(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check2(dc, arg[0], arg[1])) {
+ if (dc->sar_m32_5bit) {
+ tcg_gen_shr_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_SR[SAR]);
+ } else {
+ TCGv_i64 v = tcg_temp_new_i64();
+ tcg_gen_extu_i32_i64(v, cpu_R[arg[1]]);
+ gen_shift(shr);
+ }
+ }
+}
+
+#undef gen_shift
+#undef gen_shift_reg
+
+static void translate_srli(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check2(dc, arg[0], arg[1])) {
+ tcg_gen_shri_i32(cpu_R[arg[0]], cpu_R[arg[1]], arg[2]);
+ }
+}
+
+static void translate_ssa8b(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check1(dc, arg[0])) {
+ TCGv_i32 tmp = tcg_temp_new_i32();
+ tcg_gen_shli_i32(tmp, cpu_R[arg[0]], 3);
+ gen_left_shift_sar(dc, tmp);
+ tcg_temp_free(tmp);
+ }
+}
+
+static void translate_ssa8l(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check1(dc, arg[0])) {
+ TCGv_i32 tmp = tcg_temp_new_i32();
+ tcg_gen_shli_i32(tmp, cpu_R[arg[0]], 3);
+ gen_right_shift_sar(dc, tmp);
+ tcg_temp_free(tmp);
+ }
+}
+
+static void translate_ssai(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ TCGv_i32 tmp = tcg_const_i32(arg[0]);
+ gen_right_shift_sar(dc, tmp);
+ tcg_temp_free(tmp);
+}
+
+static void translate_ssl(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check1(dc, arg[0])) {
+ gen_left_shift_sar(dc, cpu_R[arg[0]]);
+ }
+}
+
+static void translate_ssr(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check1(dc, arg[0])) {
+ gen_right_shift_sar(dc, cpu_R[arg[0]]);
+ }
+}
+
+static void translate_sub(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
+ tcg_gen_sub_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
+ }
+}
+
+static void translate_subx(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
+ TCGv_i32 tmp = tcg_temp_new_i32();
+ tcg_gen_shli_i32(tmp, cpu_R[arg[1]], par[0]);
+ tcg_gen_sub_i32(cpu_R[arg[0]], tmp, cpu_R[arg[2]]);
+ tcg_temp_free(tmp);
+ }
+}
+
+static void translate_syscall(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ gen_exception_cause(dc, SYSCALL_CAUSE);
+}
+
+static void translate_waiti(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_check_privilege(dc)) {
+ gen_waiti(dc, arg[0]);
+ }
+}
+
+static void translate_wtlb(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_check_privilege(dc) &&
+ gen_window_check2(dc, arg[0], arg[1])) {
+ TCGv_i32 dtlb = tcg_const_i32(par[0]);
+
+ gen_helper_wtlb(cpu_env, cpu_R[arg[0]], cpu_R[arg[1]], dtlb);
+ /* This could change memory mapping, so exit tb */
+ gen_jumpi_check_loop_end(dc, -1);
+ tcg_temp_free(dtlb);
+ }
+}
+
+static void translate_wer(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_check_privilege(dc) &&
+ gen_window_check2(dc, arg[0], arg[1])) {
+ gen_helper_wer(cpu_env, cpu_R[arg[0]], cpu_R[arg[1]]);
+ }
+}
+
+static void translate_wsr(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_check_sr(dc, par[0], SR_W) &&
+ (par[0] < 64 || gen_check_privilege(dc)) &&
+ gen_window_check1(dc, arg[0])) {
+ gen_wsr(dc, par[0], cpu_R[arg[0]]);
+ }
+}
+
+static void translate_wur(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check1(dc, arg[0])) {
+ if (uregnames[par[0]].name) {
+ gen_wur(par[0], cpu_R[arg[0]]);
+ } else {
+ qemu_log_mask(LOG_UNIMP, "WUR %d not implemented, ", par[0]);
+ }
+ }
+}
+
+static void translate_xor(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
+ tcg_gen_xor_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
+ }
+}
+
+static void translate_xsr(DisasContext *dc, const uint32_t arg[],
+ const uint32_t par[])
+{
+ if (gen_check_sr(dc, par[0], SR_X) &&
+ (par[0] < 64 || gen_check_privilege(dc)) &&
+ gen_window_check1(dc, arg[0])) {
+ TCGv_i32 tmp = tcg_temp_new_i32();
+ bool rsr_end, wsr_end;
+
+ tcg_gen_mov_i32(tmp, cpu_R[arg[0]]);
+ rsr_end = gen_rsr(dc, cpu_R[arg[0]], par[0]);
+ wsr_end = gen_wsr(dc, par[0], tmp);
+ tcg_temp_free(tmp);
+ if (rsr_end && !wsr_end) {
+ gen_jumpi_check_loop_end(dc, 0);
+ }
+ }
+}
+
+static const XtensaOpcodeOps core_ops[] = {
+ {
+ .name = "abs",
+ .translate = translate_abs,
+ }, {
+ .name = "add",
+ .translate = translate_add,
+ }, {
+ .name = "add.n",
+ .translate = translate_add,
+ }, {
+ .name = "addi",
+ .translate = translate_addi,
+ }, {
+ .name = "addi.n",
+ .translate = translate_addi,
+ }, {
+ .name = "addmi",
+ .translate = translate_addi,
+ }, {
+ .name = "addx2",
+ .translate = translate_addx,
+ .par = (const uint32_t[]){1},
+ }, {
+ .name = "addx4",
+ .translate = translate_addx,
+ .par = (const uint32_t[]){2},
+ }, {
+ .name = "addx8",
+ .translate = translate_addx,
+ .par = (const uint32_t[]){3},
+ }, {
+ .name = "all4",
+ .translate = translate_all,
+ .par = (const uint32_t[]){true, 4},
+ }, {
+ .name = "all8",
+ .translate = translate_all,
+ .par = (const uint32_t[]){true, 8},
+ }, {
+ .name = "and",
+ .translate = translate_and,
+ }, {
+ .name = "andb",
+ .translate = translate_boolean,
+ .par = (const uint32_t[]){BOOLEAN_AND},
+ }, {
+ .name = "andbc",
+ .translate = translate_boolean,
+ .par = (const uint32_t[]){BOOLEAN_ANDC},
+ }, {
+ .name = "any4",
+ .translate = translate_all,
+ .par = (const uint32_t[]){false, 4},
+ }, {
+ .name = "any8",
+ .translate = translate_all,
+ .par = (const uint32_t[]){false, 8},
+ }, {
+ .name = "ball",
+ .translate = translate_ball,
+ .par = (const uint32_t[]){TCG_COND_EQ},
+ }, {
+ .name = "bany",
+ .translate = translate_bany,
+ .par = (const uint32_t[]){TCG_COND_NE},
+ }, {
+ .name = "bbc",
+ .translate = translate_bb,
+ .par = (const uint32_t[]){TCG_COND_EQ},
+ }, {
+ .name = "bbci",
+ .translate = translate_bbi,
+ .par = (const uint32_t[]){TCG_COND_EQ},
+ }, {
+ .name = "bbs",
+ .translate = translate_bb,
+ .par = (const uint32_t[]){TCG_COND_NE},
+ }, {
+ .name = "bbsi",
+ .translate = translate_bbi,
+ .par = (const uint32_t[]){TCG_COND_NE},
+ }, {
+ .name = "beq",
+ .translate = translate_b,
+ .par = (const uint32_t[]){TCG_COND_EQ},
+ }, {
+ .name = "beqi",
+ .translate = translate_bi,
+ .par = (const uint32_t[]){TCG_COND_EQ},
+ }, {
+ .name = "beqz",
+ .translate = translate_bz,
+ .par = (const uint32_t[]){TCG_COND_EQ},
+ }, {
+ .name = "beqz.n",
+ .translate = translate_bz,
+ .par = (const uint32_t[]){TCG_COND_EQ},
+ }, {
+ .name = "bf",
+ .translate = translate_bp,
+ .par = (const uint32_t[]){TCG_COND_EQ},
+ }, {
+ .name = "bge",
+ .translate = translate_b,
+ .par = (const uint32_t[]){TCG_COND_GE},
+ }, {
+ .name = "bgei",
+ .translate = translate_bi,
+ .par = (const uint32_t[]){TCG_COND_GE},
+ }, {
+ .name = "bgeu",
+ .translate = translate_b,
+ .par = (const uint32_t[]){TCG_COND_GEU},
+ }, {
+ .name = "bgeui",
+ .translate = translate_bi,
+ .par = (const uint32_t[]){TCG_COND_GEU},
+ }, {
+ .name = "bgez",
+ .translate = translate_bz,
+ .par = (const uint32_t[]){TCG_COND_GE},
+ }, {
+ .name = "blt",
+ .translate = translate_b,
+ .par = (const uint32_t[]){TCG_COND_LT},
+ }, {
+ .name = "blti",
+ .translate = translate_bi,
+ .par = (const uint32_t[]){TCG_COND_LT},
+ }, {
+ .name = "bltu",
+ .translate = translate_b,
+ .par = (const uint32_t[]){TCG_COND_LTU},
+ }, {
+ .name = "bltui",
+ .translate = translate_bi,
+ .par = (const uint32_t[]){TCG_COND_LTU},
+ }, {
+ .name = "bltz",
+ .translate = translate_bz,
+ .par = (const uint32_t[]){TCG_COND_LT},
+ }, {
+ .name = "bnall",
+ .translate = translate_ball,
+ .par = (const uint32_t[]){TCG_COND_NE},
+ }, {
+ .name = "bne",
+ .translate = translate_b,
+ .par = (const uint32_t[]){TCG_COND_NE},
+ }, {
+ .name = "bnei",
+ .translate = translate_bi,
+ .par = (const uint32_t[]){TCG_COND_NE},
+ }, {
+ .name = "bnez",
+ .translate = translate_bz,
+ .par = (const uint32_t[]){TCG_COND_NE},
+ }, {
+ .name = "bnez.n",
+ .translate = translate_bz,
+ .par = (const uint32_t[]){TCG_COND_NE},
+ }, {
+ .name = "bnone",
+ .translate = translate_bany,
+ .par = (const uint32_t[]){TCG_COND_EQ},
+ }, {
+ .name = "break",
+ .translate = translate_break,
+ .par = (const uint32_t[]){DEBUGCAUSE_BI},
+ }, {
+ .name = "break.n",
+ .translate = translate_break,
+ .par = (const uint32_t[]){DEBUGCAUSE_BN},
+ }, {
+ .name = "bt",
+ .translate = translate_bp,
+ .par = (const uint32_t[]){TCG_COND_NE},
+ }, {
+ .name = "call0",
+ .translate = translate_call0,
+ }, {
+ .name = "call12",
+ .translate = translate_callw,
+ .par = (const uint32_t[]){3},
+ }, {
+ .name = "call4",
+ .translate = translate_callw,
+ .par = (const uint32_t[]){1},
+ }, {
+ .name = "call8",
+ .translate = translate_callw,
+ .par = (const uint32_t[]){2},
+ }, {
+ .name = "callx0",
+ .translate = translate_callx0,
+ }, {
+ .name = "callx12",
+ .translate = translate_callxw,
+ .par = (const uint32_t[]){3},
+ }, {
+ .name = "callx4",
+ .translate = translate_callxw,
+ .par = (const uint32_t[]){1},
+ }, {
+ .name = "callx8",
+ .translate = translate_callxw,
+ .par = (const uint32_t[]){2},
+ }, {
+ .name = "clamps",
+ .translate = translate_clamps,
+ }, {
+ .name = "depbits",
+ .translate = translate_depbits,
+ }, {
+ .name = "dhi",
+ .translate = translate_dcache,
+ .par = (const uint32_t[]){true, true},
+ }, {
+ .name = "dhu",
+ .translate = translate_dcache,
+ .par = (const uint32_t[]){true, true},
+ }, {
+ .name = "dhwb",
+ .translate = translate_dcache,
+ .par = (const uint32_t[]){false, true},
+ }, {
+ .name = "dhwbi",
+ .translate = translate_dcache,
+ .par = (const uint32_t[]){false, true},
+ }, {
+ .name = "dii",
+ .translate = translate_dcache,
+ .par = (const uint32_t[]){true, false},
+ }, {
+ .name = "diu",
+ .translate = translate_dcache,
+ .par = (const uint32_t[]){true, false},
+ }, {
+ .name = "diwb",
+ .translate = translate_dcache,
+ .par = (const uint32_t[]){true, false},
+ }, {
+ .name = "diwbi",
+ .translate = translate_dcache,
+ .par = (const uint32_t[]){true, false},
+ }, {
+ .name = "dpfl",
+ .translate = translate_dcache,
+ .par = (const uint32_t[]){true, true},
+ }, {
+ .name = "dpfr",
+ .translate = translate_dcache,
+ .par = (const uint32_t[]){false, false},
+ }, {
+ .name = "dpfro",
+ .translate = translate_dcache,
+ .par = (const uint32_t[]){false, false},
+ }, {
+ .name = "dpfw",
+ .translate = translate_dcache,
+ .par = (const uint32_t[]){false, false},
+ }, {
+ .name = "dpfwo",
+ .translate = translate_dcache,
+ .par = (const uint32_t[]){false, false},
+ }, {
+ .name = "dsync",
+ .translate = translate_nop,
+ }, {
+ .name = "entry",
+ .translate = translate_entry,
+ }, {
+ .name = "esync",
+ .translate = translate_nop,
+ }, {
+ .name = "excw",
+ .translate = translate_nop,
+ }, {
+ .name = "extui",
+ .translate = translate_extui,
+ }, {
+ .name = "extw",
+ .translate = translate_nop,
+ }, {
+ .name = "idtlb",
+ .translate = translate_itlb,
+ .par = (const uint32_t[]){true},
+ }, {
+ .name = "ihi",
+ .translate = translate_icache,
+ .par = (const uint32_t[]){false, true},
+ }, {
+ .name = "ihu",
+ .translate = translate_icache,
+ .par = (const uint32_t[]){true, true},
+ }, {
+ .name = "iii",
+ .translate = translate_icache,
+ .par = (const uint32_t[]){true, false},
+ }, {
+ .name = "iitlb",
+ .translate = translate_itlb,
+ .par = (const uint32_t[]){false},
+ }, {
+ .name = "iiu",
+ .translate = translate_icache,
+ .par = (const uint32_t[]){true, false},
+ }, {
+ .name = "ill",
+ .translate = translate_ill,
+ }, {
+ .name = "ill.n",
+ .translate = translate_ill,
+ }, {
+ .name = "ipf",
+ .translate = translate_icache,
+ .par = (const uint32_t[]){false, false},
+ }, {
+ .name = "ipfl",
+ .translate = translate_icache,
+ .par = (const uint32_t[]){true, true},
+ }, {
+ .name = "isync",
+ .translate = translate_nop,
+ }, {
+ .name = "j",
+ .translate = translate_j,
+ }, {
+ .name = "jx",
+ .translate = translate_jx,
+ }, {
+ .name = "l16si",
+ .translate = translate_ldst,
+ .par = (const uint32_t[]){MO_TESW, false, false},
+ }, {
+ .name = "l16ui",
+ .translate = translate_ldst,
+ .par = (const uint32_t[]){MO_TEUW, false, false},
+ }, {
+ .name = "l32ai",
+ .translate = translate_ldst,
+ .par = (const uint32_t[]){MO_TEUL, true, false},
+ }, {
+ .name = "l32e",
+ .translate = translate_l32e,
+ }, {
+ .name = "l32i",
+ .translate = translate_ldst,
+ .par = (const uint32_t[]){MO_TEUL, false, false},
+ }, {
+ .name = "l32i.n",
+ .translate = translate_ldst,
+ .par = (const uint32_t[]){MO_TEUL, false, false},
+ }, {
+ .name = "l32r",
+ .translate = translate_l32r,
+ }, {
+ .name = "l8ui",
+ .translate = translate_ldst,
+ .par = (const uint32_t[]){MO_UB, false, false},
+ }, {
+ .name = "lddec",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_NONE, 0, 0, -4},
+ }, {
+ .name = "ldinc",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_NONE, 0, 0, 4},
+ }, {
+ .name = "loop",
+ .translate = translate_loop,
+ .par = (const uint32_t[]){TCG_COND_NEVER},
+ }, {
+ .name = "loopgtz",
+ .translate = translate_loop,
+ .par = (const uint32_t[]){TCG_COND_GT},
+ }, {
+ .name = "loopnez",
+ .translate = translate_loop,
+ .par = (const uint32_t[]){TCG_COND_NE},
+ }, {
+ .name = "max",
+ .translate = translate_minmax,
+ .par = (const uint32_t[]){TCG_COND_GE},
+ }, {
+ .name = "maxu",
+ .translate = translate_minmax,
+ .par = (const uint32_t[]){TCG_COND_GEU},
+ }, {
+ .name = "memw",
+ .translate = translate_nop,
+ }, {
+ .name = "min",
+ .translate = translate_minmax,
+ .par = (const uint32_t[]){TCG_COND_LT},
+ }, {
+ .name = "minu",
+ .translate = translate_minmax,
+ .par = (const uint32_t[]){TCG_COND_LTU},
+ }, {
+ .name = "mov",
+ .translate = translate_mov,
+ }, {
+ .name = "mov.n",
+ .translate = translate_mov,
+ }, {
+ .name = "moveqz",
+ .translate = translate_movcond,
+ .par = (const uint32_t[]){TCG_COND_EQ},
+ }, {
+ .name = "movf",
+ .translate = translate_movp,
+ .par = (const uint32_t[]){TCG_COND_EQ},
+ }, {
+ .name = "movgez",
+ .translate = translate_movcond,
+ .par = (const uint32_t[]){TCG_COND_GE},
+ }, {
+ .name = "movi",
+ .translate = translate_movi,
+ }, {
+ .name = "movi.n",
+ .translate = translate_movi,
+ }, {
+ .name = "movltz",
+ .translate = translate_movcond,
+ .par = (const uint32_t[]){TCG_COND_LT},
+ }, {
+ .name = "movnez",
+ .translate = translate_movcond,
+ .par = (const uint32_t[]){TCG_COND_NE},
+ }, {
+ .name = "movsp",
+ .translate = translate_movsp,
+ }, {
+ .name = "movt",
+ .translate = translate_movp,
+ .par = (const uint32_t[]){TCG_COND_NE},
+ }, {
+ .name = "mul.aa.hh",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MUL, MAC16_AA, MAC16_HH, 0},
+ }, {
+ .name = "mul.aa.hl",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MUL, MAC16_AA, MAC16_HL, 0},
+ }, {
+ .name = "mul.aa.lh",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MUL, MAC16_AA, MAC16_LH, 0},
+ }, {
+ .name = "mul.aa.ll",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MUL, MAC16_AA, MAC16_LL, 0},
+ }, {
+ .name = "mul.ad.hh",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MUL, MAC16_AD, MAC16_HH, 0},
+ }, {
+ .name = "mul.ad.hl",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MUL, MAC16_AD, MAC16_HL, 0},
+ }, {
+ .name = "mul.ad.lh",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MUL, MAC16_AD, MAC16_LH, 0},
+ }, {
+ .name = "mul.ad.ll",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MUL, MAC16_AD, MAC16_LL, 0},
+ }, {
+ .name = "mul.da.hh",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MUL, MAC16_DA, MAC16_HH, 0},
+ }, {
+ .name = "mul.da.hl",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MUL, MAC16_DA, MAC16_HL, 0},
+ }, {
+ .name = "mul.da.lh",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MUL, MAC16_DA, MAC16_LH, 0},
+ }, {
+ .name = "mul.da.ll",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MUL, MAC16_DA, MAC16_LL, 0},
+ }, {
+ .name = "mul.dd.hh",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MUL, MAC16_DD, MAC16_HH, 0},
+ }, {
+ .name = "mul.dd.hl",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MUL, MAC16_DD, MAC16_HL, 0},
+ }, {
+ .name = "mul.dd.lh",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MUL, MAC16_DD, MAC16_LH, 0},
+ }, {
+ .name = "mul.dd.ll",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MUL, MAC16_DD, MAC16_LL, 0},
+ }, {
+ .name = "mul16s",
+ .translate = translate_mul16,
+ .par = (const uint32_t[]){true},
+ }, {
+ .name = "mul16u",
+ .translate = translate_mul16,
+ .par = (const uint32_t[]){false},
+ }, {
+ .name = "mula.aa.hh",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_AA, MAC16_HH, 0},
+ }, {
+ .name = "mula.aa.hl",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_AA, MAC16_HL, 0},
+ }, {
+ .name = "mula.aa.lh",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_AA, MAC16_LH, 0},
+ }, {
+ .name = "mula.aa.ll",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_AA, MAC16_LL, 0},
+ }, {
+ .name = "mula.ad.hh",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_AD, MAC16_HH, 0},
+ }, {
+ .name = "mula.ad.hl",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_AD, MAC16_HL, 0},
+ }, {
+ .name = "mula.ad.lh",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_AD, MAC16_LH, 0},
+ }, {
+ .name = "mula.ad.ll",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_AD, MAC16_LL, 0},
+ }, {
+ .name = "mula.da.hh",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_HH, 0},
+ }, {
+ .name = "mula.da.hh.lddec",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_HH, -4},
+ }, {
+ .name = "mula.da.hh.ldinc",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_HH, 4},
+ }, {
+ .name = "mula.da.hl",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_HL, 0},
+ }, {
+ .name = "mula.da.hl.lddec",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_HL, -4},
+ }, {
+ .name = "mula.da.hl.ldinc",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_HL, 4},
+ }, {
+ .name = "mula.da.lh",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_LH, 0},
+ }, {
+ .name = "mula.da.lh.lddec",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_LH, -4},
+ }, {
+ .name = "mula.da.lh.ldinc",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_LH, 4},
+ }, {
+ .name = "mula.da.ll",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_LL, 0},
+ }, {
+ .name = "mula.da.ll.lddec",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_LL, -4},
+ }, {
+ .name = "mula.da.ll.ldinc",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_LL, 4},
+ }, {
+ .name = "mula.dd.hh",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_HH, 0},
+ }, {
+ .name = "mula.dd.hh.lddec",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_HH, -4},
+ }, {
+ .name = "mula.dd.hh.ldinc",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_HH, 4},
+ }, {
+ .name = "mula.dd.hl",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_HL, 0},
+ }, {
+ .name = "mula.dd.hl.lddec",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_HL, -4},
+ }, {
+ .name = "mula.dd.hl.ldinc",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_HL, 4},
+ }, {
+ .name = "mula.dd.lh",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_LH, 0},
+ }, {
+ .name = "mula.dd.lh.lddec",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_LH, -4},
+ }, {
+ .name = "mula.dd.lh.ldinc",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_LH, 4},
+ }, {
+ .name = "mula.dd.ll",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_LL, 0},
+ }, {
+ .name = "mula.dd.ll.lddec",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_LL, -4},
+ }, {
+ .name = "mula.dd.ll.ldinc",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_LL, 4},
+ }, {
+ .name = "mull",
+ .translate = translate_mull,
+ }, {
+ .name = "muls.aa.hh",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULS, MAC16_AA, MAC16_HH, 0},
+ }, {
+ .name = "muls.aa.hl",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULS, MAC16_AA, MAC16_HL, 0},
+ }, {
+ .name = "muls.aa.lh",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULS, MAC16_AA, MAC16_LH, 0},
+ }, {
+ .name = "muls.aa.ll",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULS, MAC16_AA, MAC16_LL, 0},
+ }, {
+ .name = "muls.ad.hh",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULS, MAC16_AD, MAC16_HH, 0},
+ }, {
+ .name = "muls.ad.hl",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULS, MAC16_AD, MAC16_HL, 0},
+ }, {
+ .name = "muls.ad.lh",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULS, MAC16_AD, MAC16_LH, 0},
+ }, {
+ .name = "muls.ad.ll",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULS, MAC16_AD, MAC16_LL, 0},
+ }, {
+ .name = "muls.da.hh",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULS, MAC16_DA, MAC16_HH, 0},
+ }, {
+ .name = "muls.da.hl",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULS, MAC16_DA, MAC16_HL, 0},
+ }, {
+ .name = "muls.da.lh",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULS, MAC16_DA, MAC16_LH, 0},
+ }, {
+ .name = "muls.da.ll",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULS, MAC16_DA, MAC16_LL, 0},
+ }, {
+ .name = "muls.dd.hh",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULS, MAC16_DD, MAC16_HH, 0},
+ }, {
+ .name = "muls.dd.hl",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULS, MAC16_DD, MAC16_HL, 0},
+ }, {
+ .name = "muls.dd.lh",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULS, MAC16_DD, MAC16_LH, 0},
+ }, {
+ .name = "muls.dd.ll",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_MULS, MAC16_DD, MAC16_LL, 0},
+ }, {
+ .name = "mulsh",
+ .translate = translate_mulh,
+ .par = (const uint32_t[]){true},
+ }, {
+ .name = "muluh",
+ .translate = translate_mulh,
+ .par = (const uint32_t[]){false},
+ }, {
+ .name = "neg",
+ .translate = translate_neg,
+ }, {
+ .name = "nop",
+ .translate = translate_nop,
+ }, {
+ .name = "nop.n",
+ .translate = translate_nop,
+ }, {
+ .name = "nsa",
+ .translate = translate_nsa,
+ }, {
+ .name = "nsau",
+ .translate = translate_nsau,
+ }, {
+ .name = "or",
+ .translate = translate_or,
+ }, {
+ .name = "orb",
+ .translate = translate_boolean,
+ .par = (const uint32_t[]){BOOLEAN_OR},
+ }, {
+ .name = "orbc",
+ .translate = translate_boolean,
+ .par = (const uint32_t[]){BOOLEAN_ORC},
+ }, {
+ .name = "pdtlb",
+ .translate = translate_ptlb,
+ .par = (const uint32_t[]){true},
+ }, {
+ .name = "pitlb",
+ .translate = translate_ptlb,
+ .par = (const uint32_t[]){false},
+ }, {
+ .name = "quos",
+ .translate = translate_quos,
+ .par = (const uint32_t[]){true},
+ }, {
+ .name = "quou",
+ .translate = translate_quou,
+ .par = (const uint32_t[]){true},
+ }, {
+ .name = "rdtlb0",
+ .translate = translate_rtlb,
+ .par = (const uint32_t[]){true, 0},
+ }, {
+ .name = "rdtlb1",
+ .translate = translate_rtlb,
+ .par = (const uint32_t[]){true, 1},
+ }, {
+ .name = "rems",
+ .translate = translate_quos,
+ .par = (const uint32_t[]){false},
+ }, {
+ .name = "remu",
+ .translate = translate_quou,
+ .par = (const uint32_t[]){false},
+ }, {
+ .name = "rer",
+ .translate = translate_rer,
+ }, {
+ .name = "ret",
+ .translate = translate_ret,
+ }, {
+ .name = "ret.n",
+ .translate = translate_ret,
+ }, {
+ .name = "retw",
+ .translate = translate_retw,
+ }, {
+ .name = "retw.n",
+ .translate = translate_retw,
+ }, {
+ .name = "rfde",
+ .translate = translate_rfde,
+ }, {
+ .name = "rfe",
+ .translate = translate_rfe,
+ }, {
+ .name = "rfi",
+ .translate = translate_rfi,
+ }, {
+ .name = "rfwo",
+ .translate = translate_rfw,
+ .par = (const uint32_t[]){true},
+ }, {
+ .name = "rfwu",
+ .translate = translate_rfw,
+ .par = (const uint32_t[]){false},
+ }, {
+ .name = "ritlb0",
+ .translate = translate_rtlb,
+ .par = (const uint32_t[]){false, 0},
+ }, {
+ .name = "ritlb1",
+ .translate = translate_rtlb,
+ .par = (const uint32_t[]){false, 1},
+ }, {
+ .name = "rotw",
+ .translate = translate_rotw,
+ }, {
+ .name = "rsil",
+ .translate = translate_rsil,
+ }, {
+ .name = "rsr.176",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){176},
+ }, {
+ .name = "rsr.208",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){208},
+ }, {
+ .name = "rsr.acchi",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){ACCHI},
+ }, {
+ .name = "rsr.acclo",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){ACCLO},
+ }, {
+ .name = "rsr.atomctl",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){ATOMCTL},
+ }, {
+ .name = "rsr.br",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){BR},
+ }, {
+ .name = "rsr.cacheattr",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){CACHEATTR},
+ }, {
+ .name = "rsr.ccompare0",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){CCOMPARE},
+ }, {
+ .name = "rsr.ccompare1",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){CCOMPARE + 1},
+ }, {
+ .name = "rsr.ccompare2",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){CCOMPARE + 2},
+ }, {
+ .name = "rsr.ccount",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){CCOUNT},
+ }, {
+ .name = "rsr.configid0",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){CONFIGID0},
+ }, {
+ .name = "rsr.configid1",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){CONFIGID1},
+ }, {
+ .name = "rsr.cpenable",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){CPENABLE},
+ }, {
+ .name = "rsr.dbreaka0",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){DBREAKA},
+ }, {
+ .name = "rsr.dbreaka1",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){DBREAKA + 1},
+ }, {
+ .name = "rsr.dbreakc0",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){DBREAKC},
+ }, {
+ .name = "rsr.dbreakc1",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){DBREAKC + 1},
+ }, {
+ .name = "rsr.debugcause",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){DEBUGCAUSE},
+ }, {
+ .name = "rsr.depc",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){DEPC},
+ }, {
+ .name = "rsr.dtlbcfg",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){DTLBCFG},
+ }, {
+ .name = "rsr.epc1",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){EPC1},
+ }, {
+ .name = "rsr.epc2",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){EPC1 + 1},
+ }, {
+ .name = "rsr.epc3",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){EPC1 + 2},
+ }, {
+ .name = "rsr.epc4",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){EPC1 + 3},
+ }, {
+ .name = "rsr.epc5",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){EPC1 + 4},
+ }, {
+ .name = "rsr.epc6",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){EPC1 + 5},
+ }, {
+ .name = "rsr.epc7",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){EPC1 + 6},
+ }, {
+ .name = "rsr.eps2",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){EPS2},
+ }, {
+ .name = "rsr.eps3",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){EPS2 + 1},
+ }, {
+ .name = "rsr.eps4",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){EPS2 + 2},
+ }, {
+ .name = "rsr.eps5",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){EPS2 + 3},
+ }, {
+ .name = "rsr.eps6",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){EPS2 + 4},
+ }, {
+ .name = "rsr.eps7",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){EPS2 + 5},
+ }, {
+ .name = "rsr.exccause",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){EXCCAUSE},
+ }, {
+ .name = "rsr.excsave1",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){EXCSAVE1},
+ }, {
+ .name = "rsr.excsave2",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){EXCSAVE1 + 1},
+ }, {
+ .name = "rsr.excsave3",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){EXCSAVE1 + 2},
+ }, {
+ .name = "rsr.excsave4",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){EXCSAVE1 + 3},
+ }, {
+ .name = "rsr.excsave5",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){EXCSAVE1 + 4},
+ }, {
+ .name = "rsr.excsave6",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){EXCSAVE1 + 5},
+ }, {
+ .name = "rsr.excsave7",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){EXCSAVE1 + 6},
+ }, {
+ .name = "rsr.excvaddr",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){EXCVADDR},
+ }, {
+ .name = "rsr.ibreaka0",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){IBREAKA},
+ }, {
+ .name = "rsr.ibreaka1",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){IBREAKA + 1},
+ }, {
+ .name = "rsr.ibreakenable",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){IBREAKENABLE},
+ }, {
+ .name = "rsr.icount",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){ICOUNT},
+ }, {
+ .name = "rsr.icountlevel",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){ICOUNTLEVEL},
+ }, {
+ .name = "rsr.intclear",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){INTCLEAR},
+ }, {
+ .name = "rsr.intenable",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){INTENABLE},
+ }, {
+ .name = "rsr.interrupt",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){INTSET},
+ }, {
+ .name = "rsr.intset",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){INTSET},
+ }, {
+ .name = "rsr.itlbcfg",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){ITLBCFG},
+ }, {
+ .name = "rsr.lbeg",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){LBEG},
+ }, {
+ .name = "rsr.lcount",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){LCOUNT},
+ }, {
+ .name = "rsr.lend",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){LEND},
+ }, {
+ .name = "rsr.litbase",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){LITBASE},
+ }, {
+ .name = "rsr.m0",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){MR},
+ }, {
+ .name = "rsr.m1",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){MR + 1},
+ }, {
+ .name = "rsr.m2",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){MR + 2},
+ }, {
+ .name = "rsr.m3",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){MR + 3},
+ }, {
+ .name = "rsr.memctl",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){MEMCTL},
+ }, {
+ .name = "rsr.misc0",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){MISC},
+ }, {
+ .name = "rsr.misc1",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){MISC + 1},
+ }, {
+ .name = "rsr.misc2",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){MISC + 2},
+ }, {
+ .name = "rsr.misc3",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){MISC + 3},
+ }, {
+ .name = "rsr.prid",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){PRID},
+ }, {
+ .name = "rsr.ps",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){PS},
+ }, {
+ .name = "rsr.ptevaddr",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){PTEVADDR},
+ }, {
+ .name = "rsr.rasid",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){RASID},
+ }, {
+ .name = "rsr.sar",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){SAR},
+ }, {
+ .name = "rsr.scompare1",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){SCOMPARE1},
+ }, {
+ .name = "rsr.vecbase",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){VECBASE},
+ }, {
+ .name = "rsr.windowbase",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){WINDOW_BASE},
+ }, {
+ .name = "rsr.windowstart",
+ .translate = translate_rsr,
+ .par = (const uint32_t[]){WINDOW_START},
+ }, {
+ .name = "rsync",
+ .translate = translate_nop,
+ }, {
+ .name = "rur.fcr",
+ .translate = translate_rur,
+ .par = (const uint32_t[]){FCR},
+ }, {
+ .name = "rur.fsr",
+ .translate = translate_rur,
+ .par = (const uint32_t[]){FSR},
+ }, {
+ .name = "rur.threadptr",
+ .translate = translate_rur,
+ .par = (const uint32_t[]){THREADPTR},
+ }, {
+ .name = "s16i",
+ .translate = translate_ldst,
+ .par = (const uint32_t[]){MO_TEUW, false, true},
+ }, {
+ .name = "s32c1i",
+ .translate = translate_s32c1i,
+ }, {
+ .name = "s32e",
+ .translate = translate_s32e,
+ }, {
+ .name = "s32i",
+ .translate = translate_ldst,
+ .par = (const uint32_t[]){MO_TEUL, false, true},
+ }, {
+ .name = "s32i.n",
+ .translate = translate_ldst,
+ .par = (const uint32_t[]){MO_TEUL, false, true},
+ }, {
+ .name = "s32nb",
+ .translate = translate_ldst,
+ .par = (const uint32_t[]){MO_TEUL, false, true},
+ }, {
+ .name = "s32ri",
+ .translate = translate_ldst,
+ .par = (const uint32_t[]){MO_TEUL, true, true},
+ }, {
+ .name = "s8i",
+ .translate = translate_ldst,
+ .par = (const uint32_t[]){MO_UB, false, true},
+ }, {
+ .name = "sext",
+ .translate = translate_sext,
+ }, {
+ .name = "simcall",
+ .translate = translate_simcall,
+ }, {
+ .name = "sll",
+ .translate = translate_sll,
+ }, {
+ .name = "slli",
+ .translate = translate_slli,
+ }, {
+ .name = "sra",
+ .translate = translate_sra,
+ }, {
+ .name = "srai",
+ .translate = translate_srai,
+ }, {
+ .name = "src",
+ .translate = translate_src,
+ }, {
+ .name = "srl",
+ .translate = translate_srl,
+ }, {
+ .name = "srli",
+ .translate = translate_srli,
+ }, {
+ .name = "ssa8b",
+ .translate = translate_ssa8b,
+ }, {
+ .name = "ssa8l",
+ .translate = translate_ssa8l,
+ }, {
+ .name = "ssai",
+ .translate = translate_ssai,
+ }, {
+ .name = "ssl",
+ .translate = translate_ssl,
+ }, {
+ .name = "ssr",
+ .translate = translate_ssr,
+ }, {
+ .name = "sub",
+ .translate = translate_sub,
+ }, {
+ .name = "subx2",
+ .translate = translate_subx,
+ .par = (const uint32_t[]){1},
+ }, {
+ .name = "subx4",
+ .translate = translate_subx,
+ .par = (const uint32_t[]){2},
+ }, {
+ .name = "subx8",
+ .translate = translate_subx,
+ .par = (const uint32_t[]){3},
+ }, {
+ .name = "syscall",
+ .translate = translate_syscall,
+ }, {
+ .name = "umul.aa.hh",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_UMUL, MAC16_AA, MAC16_HH, 0},
+ }, {
+ .name = "umul.aa.hl",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_UMUL, MAC16_AA, MAC16_HL, 0},
+ }, {
+ .name = "umul.aa.lh",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_UMUL, MAC16_AA, MAC16_LH, 0},
+ }, {
+ .name = "umul.aa.ll",
+ .translate = translate_mac16,
+ .par = (const uint32_t[]){MAC16_UMUL, MAC16_AA, MAC16_LL, 0},
+ }, {
+ .name = "waiti",
+ .translate = translate_waiti,
+ }, {
+ .name = "wdtlb",
+ .translate = translate_wtlb,
+ .par = (const uint32_t[]){true},
+ }, {
+ .name = "wer",
+ .translate = translate_wer,
+ }, {
+ .name = "witlb",
+ .translate = translate_wtlb,
+ .par = (const uint32_t[]){false},
+ }, {
+ .name = "wsr.176",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){176},
+ }, {
+ .name = "wsr.208",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){208},
+ }, {
+ .name = "wsr.acchi",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){ACCHI},
+ }, {
+ .name = "wsr.acclo",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){ACCLO},
+ }, {
+ .name = "wsr.atomctl",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){ATOMCTL},
+ }, {
+ .name = "wsr.br",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){BR},
+ }, {
+ .name = "wsr.cacheattr",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){CACHEATTR},
+ }, {
+ .name = "wsr.ccompare0",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){CCOMPARE},
+ }, {
+ .name = "wsr.ccompare1",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){CCOMPARE + 1},
+ }, {
+ .name = "wsr.ccompare2",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){CCOMPARE + 2},
+ }, {
+ .name = "wsr.ccount",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){CCOUNT},
+ }, {
+ .name = "wsr.configid0",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){CONFIGID0},
+ }, {
+ .name = "wsr.configid1",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){CONFIGID1},
+ }, {
+ .name = "wsr.cpenable",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){CPENABLE},
+ }, {
+ .name = "wsr.dbreaka0",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){DBREAKA},
+ }, {
+ .name = "wsr.dbreaka1",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){DBREAKA + 1},
+ }, {
+ .name = "wsr.dbreakc0",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){DBREAKC},
+ }, {
+ .name = "wsr.dbreakc1",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){DBREAKC + 1},
+ }, {
+ .name = "wsr.debugcause",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){DEBUGCAUSE},
+ }, {
+ .name = "wsr.depc",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){DEPC},
+ }, {
+ .name = "wsr.dtlbcfg",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){DTLBCFG},
+ }, {
+ .name = "wsr.epc1",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){EPC1},
+ }, {
+ .name = "wsr.epc2",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){EPC1 + 1},
+ }, {
+ .name = "wsr.epc3",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){EPC1 + 2},
+ }, {
+ .name = "wsr.epc4",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){EPC1 + 3},
+ }, {
+ .name = "wsr.epc5",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){EPC1 + 4},
+ }, {
+ .name = "wsr.epc6",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){EPC1 + 5},
+ }, {
+ .name = "wsr.epc7",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){EPC1 + 6},
+ }, {
+ .name = "wsr.eps2",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){EPS2},
+ }, {
+ .name = "wsr.eps3",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){EPS2 + 1},
+ }, {
+ .name = "wsr.eps4",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){EPS2 + 2},
+ }, {
+ .name = "wsr.eps5",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){EPS2 + 3},
+ }, {
+ .name = "wsr.eps6",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){EPS2 + 4},
+ }, {
+ .name = "wsr.eps7",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){EPS2 + 5},
+ }, {
+ .name = "wsr.exccause",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){EXCCAUSE},
+ }, {
+ .name = "wsr.excsave1",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){EXCSAVE1},
+ }, {
+ .name = "wsr.excsave2",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){EXCSAVE1 + 1},
+ }, {
+ .name = "wsr.excsave3",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){EXCSAVE1 + 2},
+ }, {
+ .name = "wsr.excsave4",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){EXCSAVE1 + 3},
+ }, {
+ .name = "wsr.excsave5",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){EXCSAVE1 + 4},
+ }, {
+ .name = "wsr.excsave6",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){EXCSAVE1 + 5},
+ }, {
+ .name = "wsr.excsave7",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){EXCSAVE1 + 6},
+ }, {
+ .name = "wsr.excvaddr",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){EXCVADDR},
+ }, {
+ .name = "wsr.ibreaka0",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){IBREAKA},
+ }, {
+ .name = "wsr.ibreaka1",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){IBREAKA + 1},
+ }, {
+ .name = "wsr.ibreakenable",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){IBREAKENABLE},
+ }, {
+ .name = "wsr.icount",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){ICOUNT},
+ }, {
+ .name = "wsr.icountlevel",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){ICOUNTLEVEL},
+ }, {
+ .name = "wsr.intclear",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){INTCLEAR},
+ }, {
+ .name = "wsr.intenable",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){INTENABLE},
+ }, {
+ .name = "wsr.interrupt",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){INTSET},
+ }, {
+ .name = "wsr.intset",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){INTSET},
+ }, {
+ .name = "wsr.itlbcfg",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){ITLBCFG},
+ }, {
+ .name = "wsr.lbeg",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){LBEG},
+ }, {
+ .name = "wsr.lcount",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){LCOUNT},
+ }, {
+ .name = "wsr.lend",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){LEND},
+ }, {
+ .name = "wsr.litbase",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){LITBASE},
+ }, {
+ .name = "wsr.m0",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){MR},
+ }, {
+ .name = "wsr.m1",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){MR + 1},
+ }, {
+ .name = "wsr.m2",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){MR + 2},
+ }, {
+ .name = "wsr.m3",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){MR + 3},
+ }, {
+ .name = "wsr.memctl",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){MEMCTL},
+ }, {
+ .name = "wsr.misc0",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){MISC},
+ }, {
+ .name = "wsr.misc1",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){MISC + 1},
+ }, {
+ .name = "wsr.misc2",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){MISC + 2},
+ }, {
+ .name = "wsr.misc3",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){MISC + 3},
+ }, {
+ .name = "wsr.prid",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){PRID},
+ }, {
+ .name = "wsr.ps",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){PS},
+ }, {
+ .name = "wsr.ptevaddr",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){PTEVADDR},
+ }, {
+ .name = "wsr.rasid",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){RASID},
+ }, {
+ .name = "wsr.sar",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){SAR},
+ }, {
+ .name = "wsr.scompare1",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){SCOMPARE1},
+ }, {
+ .name = "wsr.vecbase",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){VECBASE},
+ }, {
+ .name = "wsr.windowbase",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){WINDOW_BASE},
+ }, {
+ .name = "wsr.windowstart",
+ .translate = translate_wsr,
+ .par = (const uint32_t[]){WINDOW_START},
+ }, {
+ .name = "wur.fcr",
+ .translate = translate_wur,
+ .par = (const uint32_t[]){FCR},
+ }, {
+ .name = "wur.fsr",
+ .translate = translate_wur,
+ .par = (const uint32_t[]){FSR},
+ }, {
+ .name = "wur.threadptr",
+ .translate = translate_wur,
+ .par = (const uint32_t[]){THREADPTR},
+ }, {
+ .name = "xor",
+ .translate = translate_xor,
+ }, {
+ .name = "xorb",
+ .translate = translate_boolean,
+ .par = (const uint32_t[]){BOOLEAN_XOR},
+ }, {
+ .name = "xsr.176",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){176},
+ }, {
+ .name = "xsr.208",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){208},
+ }, {
+ .name = "xsr.acchi",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){ACCHI},
+ }, {
+ .name = "xsr.acclo",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){ACCLO},
+ }, {
+ .name = "xsr.atomctl",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){ATOMCTL},
+ }, {
+ .name = "xsr.br",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){BR},
+ }, {
+ .name = "xsr.cacheattr",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){CACHEATTR},
+ }, {
+ .name = "xsr.ccompare0",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){CCOMPARE},
+ }, {
+ .name = "xsr.ccompare1",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){CCOMPARE + 1},
+ }, {
+ .name = "xsr.ccompare2",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){CCOMPARE + 2},
+ }, {
+ .name = "xsr.ccount",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){CCOUNT},
+ }, {
+ .name = "xsr.configid0",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){CONFIGID0},
+ }, {
+ .name = "xsr.configid1",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){CONFIGID1},
+ }, {
+ .name = "xsr.cpenable",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){CPENABLE},
+ }, {
+ .name = "xsr.dbreaka0",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){DBREAKA},
+ }, {
+ .name = "xsr.dbreaka1",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){DBREAKA + 1},
+ }, {
+ .name = "xsr.dbreakc0",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){DBREAKC},
+ }, {
+ .name = "xsr.dbreakc1",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){DBREAKC + 1},
+ }, {
+ .name = "xsr.debugcause",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){DEBUGCAUSE},
+ }, {
+ .name = "xsr.depc",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){DEPC},
+ }, {
+ .name = "xsr.dtlbcfg",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){DTLBCFG},
+ }, {
+ .name = "xsr.epc1",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){EPC1},
+ }, {
+ .name = "xsr.epc2",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){EPC1 + 1},
+ }, {
+ .name = "xsr.epc3",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){EPC1 + 2},
+ }, {
+ .name = "xsr.epc4",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){EPC1 + 3},
+ }, {
+ .name = "xsr.epc5",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){EPC1 + 4},
+ }, {
+ .name = "xsr.epc6",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){EPC1 + 5},
+ }, {
+ .name = "xsr.epc7",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){EPC1 + 6},
+ }, {
+ .name = "xsr.eps2",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){EPS2},
+ }, {
+ .name = "xsr.eps3",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){EPS2 + 1},
+ }, {
+ .name = "xsr.eps4",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){EPS2 + 2},
+ }, {
+ .name = "xsr.eps5",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){EPS2 + 3},
+ }, {
+ .name = "xsr.eps6",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){EPS2 + 4},
+ }, {
+ .name = "xsr.eps7",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){EPS2 + 5},
+ }, {
+ .name = "xsr.exccause",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){EXCCAUSE},
+ }, {
+ .name = "xsr.excsave1",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){EXCSAVE1},
+ }, {
+ .name = "xsr.excsave2",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){EXCSAVE1 + 1},
+ }, {
+ .name = "xsr.excsave3",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){EXCSAVE1 + 2},
+ }, {
+ .name = "xsr.excsave4",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){EXCSAVE1 + 3},
+ }, {
+ .name = "xsr.excsave5",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){EXCSAVE1 + 4},
+ }, {
+ .name = "xsr.excsave6",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){EXCSAVE1 + 5},
+ }, {
+ .name = "xsr.excsave7",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){EXCSAVE1 + 6},
+ }, {
+ .name = "xsr.excvaddr",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){EXCVADDR},
+ }, {
+ .name = "xsr.ibreaka0",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){IBREAKA},
+ }, {
+ .name = "xsr.ibreaka1",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){IBREAKA + 1},
+ }, {
+ .name = "xsr.ibreakenable",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){IBREAKENABLE},
+ }, {
+ .name = "xsr.icount",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){ICOUNT},
+ }, {
+ .name = "xsr.icountlevel",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){ICOUNTLEVEL},
+ }, {
+ .name = "xsr.intclear",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){INTCLEAR},
+ }, {
+ .name = "xsr.intenable",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){INTENABLE},
+ }, {
+ .name = "xsr.interrupt",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){INTSET},
+ }, {
+ .name = "xsr.intset",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){INTSET},
+ }, {
+ .name = "xsr.itlbcfg",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){ITLBCFG},
+ }, {
+ .name = "xsr.lbeg",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){LBEG},
+ }, {
+ .name = "xsr.lcount",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){LCOUNT},
+ }, {
+ .name = "xsr.lend",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){LEND},
+ }, {
+ .name = "xsr.litbase",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){LITBASE},
+ }, {
+ .name = "xsr.m0",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){MR},
+ }, {
+ .name = "xsr.m1",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){MR + 1},
+ }, {
+ .name = "xsr.m2",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){MR + 2},
+ }, {
+ .name = "xsr.m3",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){MR + 3},
+ }, {
+ .name = "xsr.memctl",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){MEMCTL},
+ }, {
+ .name = "xsr.misc0",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){MISC},
+ }, {
+ .name = "xsr.misc1",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){MISC + 1},
+ }, {
+ .name = "xsr.misc2",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){MISC + 2},
+ }, {
+ .name = "xsr.misc3",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){MISC + 3},
+ }, {
+ .name = "xsr.prid",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){PRID},
+ }, {
+ .name = "xsr.ps",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){PS},
+ }, {
+ .name = "xsr.ptevaddr",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){PTEVADDR},
+ }, {
+ .name = "xsr.rasid",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){RASID},
+ }, {
+ .name = "xsr.sar",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){SAR},
+ }, {
+ .name = "xsr.scompare1",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){SCOMPARE1},
+ }, {
+ .name = "xsr.vecbase",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){VECBASE},
+ }, {
+ .name = "xsr.windowbase",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){WINDOW_BASE},
+ }, {
+ .name = "xsr.windowstart",
+ .translate = translate_xsr,
+ .par = (const uint32_t[]){WINDOW_START},
+ },
+};
+
+const XtensaOpcodeTranslators xtensa_core_opcodes = {
+ .num_opcodes = ARRAY_SIZE(core_ops),
+ .opcode = core_ops,
+};
Move implementations of core opcodes into separate translation functions. Introduce data structures for mapping opcode name to translator function. Make an array of core opcode/translator structures. Signed-off-by: Max Filippov <jcmvbkbc@gmail.com> --- target/xtensa/cpu.h | 24 + target/xtensa/translate.c | 3121 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 3145 insertions(+)