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