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/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_word insnbuf[MAX_INSNBUF_LENGTH];
  76    xtensa_insnbuf_word slotbuf[MAX_INSNBUF_LENGTH];
  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    init_sar_tracker(dc);
1177}
1178
1179static void xtensa_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
1180{
1181    DisasContext *dc = container_of(dcbase, DisasContext, base);
1182
1183    if (dc->icount) {
1184        dc->next_icount = tcg_temp_local_new_i32();
1185    }
1186}
1187
1188static void xtensa_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
1189{
1190    tcg_gen_insn_start(dcbase->pc_next);
1191}
1192
1193static bool xtensa_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
1194                                       const CPUBreakpoint *bp)
1195{
1196    DisasContext *dc = container_of(dcbase, DisasContext, base);
1197
1198    tcg_gen_movi_i32(cpu_pc, dc->base.pc_next);
1199    gen_exception(dc, EXCP_DEBUG);
1200    dc->base.is_jmp = DISAS_NORETURN;
1201    /* The address covered by the breakpoint must be included in
1202       [tb->pc, tb->pc + tb->size) in order to for it to be
1203       properly cleared -- thus we increment the PC here so that
1204       the logic setting tb->size below does the right thing.  */
1205    dc->base.pc_next += 2;
1206    return true;
1207}
1208
1209static void xtensa_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
1210{
1211    DisasContext *dc = container_of(dcbase, DisasContext, base);
1212    CPUXtensaState *env = cpu->env_ptr;
1213    target_ulong page_start;
1214
1215    /* These two conditions only apply to the first insn in the TB,
1216       but this is the first TranslateOps hook that allows exiting.  */
1217    if ((tb_cflags(dc->base.tb) & CF_USE_ICOUNT)
1218        && (dc->base.tb->flags & XTENSA_TBFLAG_YIELD)) {
1219        gen_exception(dc, EXCP_YIELD);
1220        dc->base.is_jmp = DISAS_NORETURN;
1221        return;
1222    }
1223    if (dc->base.tb->flags & XTENSA_TBFLAG_EXCEPTION) {
1224        gen_exception(dc, EXCP_DEBUG);
1225        dc->base.is_jmp = DISAS_NORETURN;
1226        return;
1227    }
1228
1229    if (dc->icount) {
1230        TCGLabel *label = gen_new_label();
1231
1232        tcg_gen_addi_i32(dc->next_icount, cpu_SR[ICOUNT], 1);
1233        tcg_gen_brcondi_i32(TCG_COND_NE, dc->next_icount, 0, label);
1234        tcg_gen_mov_i32(dc->next_icount, cpu_SR[ICOUNT]);
1235        if (dc->debug) {
1236            gen_debug_exception(dc, DEBUGCAUSE_IC);
1237        }
1238        gen_set_label(label);
1239    }
1240
1241    if (dc->debug) {
1242        gen_ibreak_check(env, dc);
1243    }
1244
1245    disas_xtensa_insn(env, dc);
1246
1247    if (dc->icount) {
1248        tcg_gen_mov_i32(cpu_SR[ICOUNT], dc->next_icount);
1249    }
1250
1251    /* End the TB if the next insn will cross into the next page.  */
1252    page_start = dc->base.pc_first & TARGET_PAGE_MASK;
1253    if (dc->base.is_jmp == DISAS_NEXT &&
1254        (dc->pc - page_start >= TARGET_PAGE_SIZE ||
1255         dc->pc - page_start + xtensa_insn_len(env, dc) > TARGET_PAGE_SIZE)) {
1256        dc->base.is_jmp = DISAS_TOO_MANY;
1257    }
1258}
1259
1260static void xtensa_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
1261{
1262    DisasContext *dc = container_of(dcbase, DisasContext, base);
1263
1264    reset_sar_tracker(dc);
1265    if (dc->icount) {
1266        tcg_temp_free(dc->next_icount);
1267    }
1268
1269    switch (dc->base.is_jmp) {
1270    case DISAS_NORETURN:
1271        break;
1272    case DISAS_TOO_MANY:
1273        if (dc->base.singlestep_enabled) {
1274            tcg_gen_movi_i32(cpu_pc, dc->pc);
1275            gen_exception(dc, EXCP_DEBUG);
1276        } else {
1277            gen_jumpi(dc, dc->pc, 0);
1278        }
1279        break;
1280    default:
1281        g_assert_not_reached();
1282    }
1283}
1284
1285static void xtensa_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
1286{
1287    qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
1288    log_target_disas(cpu, dcbase->pc_first, dcbase->tb->size);
1289}
1290
1291static const TranslatorOps xtensa_translator_ops = {
1292    .init_disas_context = xtensa_tr_init_disas_context,
1293    .tb_start           = xtensa_tr_tb_start,
1294    .insn_start         = xtensa_tr_insn_start,
1295    .breakpoint_check   = xtensa_tr_breakpoint_check,
1296    .translate_insn     = xtensa_tr_translate_insn,
1297    .tb_stop            = xtensa_tr_tb_stop,
1298    .disas_log          = xtensa_tr_disas_log,
1299};
1300
1301void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
1302{
1303    DisasContext dc = {};
1304    translator_loop(&xtensa_translator_ops, &dc.base, cpu, tb, max_insns);
1305}
1306
1307void xtensa_cpu_dump_state(CPUState *cs, FILE *f, int flags)
1308{
1309    XtensaCPU *cpu = XTENSA_CPU(cs);
1310    CPUXtensaState *env = &cpu->env;
1311    xtensa_isa isa = env->config->isa;
1312    int i, j;
1313
1314    qemu_fprintf(f, "PC=%08x\n\n", env->pc);
1315
1316    for (i = j = 0; i < xtensa_isa_num_sysregs(isa); ++i) {
1317        const uint32_t *reg =
1318            xtensa_sysreg_is_user(isa, i) ? env->uregs : env->sregs;
1319        int regno = xtensa_sysreg_number(isa, i);
1320
1321        if (regno >= 0) {
1322            qemu_fprintf(f, "%12s=%08x%c",
1323                         xtensa_sysreg_name(isa, i),
1324                         reg[regno],
1325                         (j++ % 4) == 3 ? '\n' : ' ');
1326        }
1327    }
1328
1329    qemu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n");
1330
1331    for (i = 0; i < 16; ++i) {
1332        qemu_fprintf(f, " A%02d=%08x%c",
1333                     i, env->regs[i], (i % 4) == 3 ? '\n' : ' ');
1334    }
1335
1336    xtensa_sync_phys_from_window(env);
1337    qemu_fprintf(f, "\n");
1338
1339    for (i = 0; i < env->config->nareg; ++i) {
1340        qemu_fprintf(f, "AR%02d=%08x ", i, env->phys_regs[i]);
1341        if (i % 4 == 3) {
1342            bool ws = (env->sregs[WINDOW_START] & (1 << (i / 4))) != 0;
1343            bool cw = env->sregs[WINDOW_BASE] == i / 4;
1344
1345            qemu_fprintf(f, "%c%c\n", ws ? '<' : ' ', cw ? '=' : ' ');
1346        }
1347    }
1348
1349    if ((flags & CPU_DUMP_FPU) &&
1350        xtensa_option_enabled(env->config, XTENSA_OPTION_FP_COPROCESSOR)) {
1351        qemu_fprintf(f, "\n");
1352
1353        for (i = 0; i < 16; ++i) {
1354            qemu_fprintf(f, "F%02d=%08x (%+10.8e)%c", i,
1355                         float32_val(env->fregs[i].f32[FP_F32_LOW]),
1356                         *(float *)(env->fregs[i].f32 + FP_F32_LOW),
1357                         (i % 2) == 1 ? '\n' : ' ');
1358        }
1359    }
1360}
1361
1362void restore_state_to_opc(CPUXtensaState *env, TranslationBlock *tb,
1363                          target_ulong *data)
1364{
1365    env->pc = data[0];
1366}
1367
1368static void translate_abs(DisasContext *dc, const OpcodeArg arg[],
1369                          const uint32_t par[])
1370{
1371    tcg_gen_abs_i32(arg[0].out, arg[1].in);
1372}
1373
1374static void translate_add(DisasContext *dc, const OpcodeArg arg[],
1375                          const uint32_t par[])
1376{
1377    tcg_gen_add_i32(arg[0].out, arg[1].in, arg[2].in);
1378}
1379
1380static void translate_addi(DisasContext *dc, const OpcodeArg arg[],
1381                           const uint32_t par[])
1382{
1383    tcg_gen_addi_i32(arg[0].out, arg[1].in, arg[2].imm);
1384}
1385
1386static void translate_addx(DisasContext *dc, const OpcodeArg arg[],
1387                           const uint32_t par[])
1388{
1389    TCGv_i32 tmp = tcg_temp_new_i32();
1390    tcg_gen_shli_i32(tmp, arg[1].in, par[0]);
1391    tcg_gen_add_i32(arg[0].out, tmp, arg[2].in);
1392    tcg_temp_free(tmp);
1393}
1394
1395static void translate_all(DisasContext *dc, const OpcodeArg arg[],
1396                          const uint32_t par[])
1397{
1398    uint32_t shift = par[1];
1399    TCGv_i32 mask = tcg_const_i32(((1 << shift) - 1) << arg[1].imm);
1400    TCGv_i32 tmp = tcg_temp_new_i32();
1401
1402    tcg_gen_and_i32(tmp, arg[1].in, mask);
1403    if (par[0]) {
1404        tcg_gen_addi_i32(tmp, tmp, 1 << arg[1].imm);
1405    } else {
1406        tcg_gen_add_i32(tmp, tmp, mask);
1407    }
1408    tcg_gen_shri_i32(tmp, tmp, arg[1].imm + shift);
1409    tcg_gen_deposit_i32(arg[0].out, arg[0].out,
1410                        tmp, arg[0].imm, 1);
1411    tcg_temp_free(mask);
1412    tcg_temp_free(tmp);
1413}
1414
1415static void translate_and(DisasContext *dc, const OpcodeArg arg[],
1416                          const uint32_t par[])
1417{
1418    tcg_gen_and_i32(arg[0].out, arg[1].in, arg[2].in);
1419}
1420
1421static void translate_ball(DisasContext *dc, const OpcodeArg arg[],
1422                           const uint32_t par[])
1423{
1424    TCGv_i32 tmp = tcg_temp_new_i32();
1425    tcg_gen_and_i32(tmp, arg[0].in, arg[1].in);
1426    gen_brcond(dc, par[0], tmp, arg[1].in, arg[2].imm);
1427    tcg_temp_free(tmp);
1428}
1429
1430static void translate_bany(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_brcondi(dc, par[0], tmp, 0, arg[2].imm);
1436    tcg_temp_free(tmp);
1437}
1438
1439static void translate_b(DisasContext *dc, const OpcodeArg arg[],
1440                        const uint32_t par[])
1441{
1442    gen_brcond(dc, par[0], arg[0].in, arg[1].in, arg[2].imm);
1443}
1444
1445static void translate_bb(DisasContext *dc, const OpcodeArg arg[],
1446                         const uint32_t par[])
1447{
1448#ifdef TARGET_WORDS_BIGENDIAN
1449    TCGv_i32 bit = tcg_const_i32(0x80000000u);
1450#else
1451    TCGv_i32 bit = tcg_const_i32(0x00000001u);
1452#endif
1453    TCGv_i32 tmp = tcg_temp_new_i32();
1454    tcg_gen_andi_i32(tmp, arg[1].in, 0x1f);
1455#ifdef TARGET_WORDS_BIGENDIAN
1456    tcg_gen_shr_i32(bit, bit, tmp);
1457#else
1458    tcg_gen_shl_i32(bit, bit, tmp);
1459#endif
1460    tcg_gen_and_i32(tmp, arg[0].in, bit);
1461    gen_brcondi(dc, par[0], tmp, 0, arg[2].imm);
1462    tcg_temp_free(tmp);
1463    tcg_temp_free(bit);
1464}
1465
1466static void translate_bbi(DisasContext *dc, const OpcodeArg arg[],
1467                          const uint32_t par[])
1468{
1469    TCGv_i32 tmp = tcg_temp_new_i32();
1470#ifdef TARGET_WORDS_BIGENDIAN
1471    tcg_gen_andi_i32(tmp, arg[0].in, 0x80000000u >> arg[1].imm);
1472#else
1473    tcg_gen_andi_i32(tmp, arg[0].in, 0x00000001u << arg[1].imm);
1474#endif
1475    gen_brcondi(dc, par[0], tmp, 0, arg[2].imm);
1476    tcg_temp_free(tmp);
1477}
1478
1479static void translate_bi(DisasContext *dc, const OpcodeArg arg[],
1480                         const uint32_t par[])
1481{
1482    gen_brcondi(dc, par[0], arg[0].in, arg[1].imm, arg[2].imm);
1483}
1484
1485static void translate_bz(DisasContext *dc, const OpcodeArg arg[],
1486                         const uint32_t par[])
1487{
1488    gen_brcondi(dc, par[0], arg[0].in, 0, arg[1].imm);
1489}
1490
1491enum {
1492    BOOLEAN_AND,
1493    BOOLEAN_ANDC,
1494    BOOLEAN_OR,
1495    BOOLEAN_ORC,
1496    BOOLEAN_XOR,
1497};
1498
1499static void translate_boolean(DisasContext *dc, const OpcodeArg arg[],
1500                              const uint32_t par[])
1501{
1502    static void (* const op[])(TCGv_i32, TCGv_i32, TCGv_i32) = {
1503        [BOOLEAN_AND] = tcg_gen_and_i32,
1504        [BOOLEAN_ANDC] = tcg_gen_andc_i32,
1505        [BOOLEAN_OR] = tcg_gen_or_i32,
1506        [BOOLEAN_ORC] = tcg_gen_orc_i32,
1507        [BOOLEAN_XOR] = tcg_gen_xor_i32,
1508    };
1509
1510    TCGv_i32 tmp1 = tcg_temp_new_i32();
1511    TCGv_i32 tmp2 = tcg_temp_new_i32();
1512
1513    tcg_gen_shri_i32(tmp1, arg[1].in, arg[1].imm);
1514    tcg_gen_shri_i32(tmp2, arg[2].in, arg[2].imm);
1515    op[par[0]](tmp1, tmp1, tmp2);
1516    tcg_gen_deposit_i32(arg[0].out, arg[0].out, tmp1, arg[0].imm, 1);
1517    tcg_temp_free(tmp1);
1518    tcg_temp_free(tmp2);
1519}
1520
1521static void translate_bp(DisasContext *dc, const OpcodeArg arg[],
1522                         const uint32_t par[])
1523{
1524    TCGv_i32 tmp = tcg_temp_new_i32();
1525
1526    tcg_gen_andi_i32(tmp, arg[0].in, 1 << arg[0].imm);
1527    gen_brcondi(dc, par[0], tmp, 0, arg[1].imm);
1528    tcg_temp_free(tmp);
1529}
1530
1531static void translate_call0(DisasContext *dc, const OpcodeArg arg[],
1532                            const uint32_t par[])
1533{
1534    tcg_gen_movi_i32(cpu_R[0], dc->base.pc_next);
1535    gen_jumpi(dc, arg[0].imm, 0);
1536}
1537
1538static void translate_callw(DisasContext *dc, const OpcodeArg arg[],
1539                            const uint32_t par[])
1540{
1541    TCGv_i32 tmp = tcg_const_i32(arg[0].imm);
1542    gen_callw_slot(dc, par[0], tmp, adjust_jump_slot(dc, arg[0].imm, 0));
1543    tcg_temp_free(tmp);
1544}
1545
1546static void translate_callx0(DisasContext *dc, const OpcodeArg arg[],
1547                             const uint32_t par[])
1548{
1549    TCGv_i32 tmp = tcg_temp_new_i32();
1550    tcg_gen_mov_i32(tmp, arg[0].in);
1551    tcg_gen_movi_i32(cpu_R[0], dc->base.pc_next);
1552    gen_jump(dc, tmp);
1553    tcg_temp_free(tmp);
1554}
1555
1556static void translate_callxw(DisasContext *dc, const OpcodeArg arg[],
1557                             const uint32_t par[])
1558{
1559    TCGv_i32 tmp = tcg_temp_new_i32();
1560
1561    tcg_gen_mov_i32(tmp, arg[0].in);
1562    gen_callw_slot(dc, par[0], tmp, -1);
1563    tcg_temp_free(tmp);
1564}
1565
1566static void translate_clamps(DisasContext *dc, const OpcodeArg arg[],
1567                             const uint32_t par[])
1568{
1569    TCGv_i32 tmp1 = tcg_const_i32(-1u << arg[2].imm);
1570    TCGv_i32 tmp2 = tcg_const_i32((1 << arg[2].imm) - 1);
1571
1572    tcg_gen_smax_i32(tmp1, tmp1, arg[1].in);
1573    tcg_gen_smin_i32(arg[0].out, tmp1, tmp2);
1574    tcg_temp_free(tmp1);
1575    tcg_temp_free(tmp2);
1576}
1577
1578static void translate_clrb_expstate(DisasContext *dc, const OpcodeArg arg[],
1579                                    const uint32_t par[])
1580{
1581    /* TODO: GPIO32 may be a part of coprocessor */
1582    tcg_gen_andi_i32(cpu_UR[EXPSTATE], cpu_UR[EXPSTATE], ~(1u << arg[0].imm));
1583}
1584
1585static void translate_clrex(DisasContext *dc, const OpcodeArg arg[],
1586                            const uint32_t par[])
1587{
1588    tcg_gen_movi_i32(cpu_exclusive_addr, -1);
1589}
1590
1591static void translate_const16(DisasContext *dc, const OpcodeArg arg[],
1592                             const uint32_t par[])
1593{
1594    TCGv_i32 c = tcg_const_i32(arg[1].imm);
1595
1596    tcg_gen_deposit_i32(arg[0].out, c, arg[0].in, 16, 16);
1597    tcg_temp_free(c);
1598}
1599
1600static void translate_dcache(DisasContext *dc, const OpcodeArg arg[],
1601                             const uint32_t par[])
1602{
1603    TCGv_i32 addr = tcg_temp_new_i32();
1604    TCGv_i32 res = tcg_temp_new_i32();
1605
1606    tcg_gen_addi_i32(addr, arg[0].in, arg[1].imm);
1607    tcg_gen_qemu_ld8u(res, addr, dc->cring);
1608    tcg_temp_free(addr);
1609    tcg_temp_free(res);
1610}
1611
1612static void translate_depbits(DisasContext *dc, const OpcodeArg arg[],
1613                              const uint32_t par[])
1614{
1615    tcg_gen_deposit_i32(arg[1].out, arg[1].in, arg[0].in,
1616                        arg[2].imm, arg[3].imm);
1617}
1618
1619static void translate_diwbuip(DisasContext *dc, const OpcodeArg arg[],
1620                              const uint32_t par[])
1621{
1622    tcg_gen_addi_i32(arg[0].out, arg[0].in, dc->config->dcache_line_bytes);
1623}
1624
1625static bool test_ill_entry(DisasContext *dc, const OpcodeArg arg[],
1626                           const uint32_t par[])
1627{
1628    if (arg[0].imm > 3 || !dc->cwoe) {
1629        qemu_log_mask(LOG_GUEST_ERROR,
1630                      "Illegal entry instruction(pc = %08x)\n", dc->pc);
1631        return true;
1632    } else {
1633        return false;
1634    }
1635}
1636
1637static uint32_t test_overflow_entry(DisasContext *dc, const OpcodeArg arg[],
1638                                    const uint32_t par[])
1639{
1640    return 1 << (dc->callinc * 4);
1641}
1642
1643static void translate_entry(DisasContext *dc, const OpcodeArg arg[],
1644                            const uint32_t par[])
1645{
1646    TCGv_i32 pc = tcg_const_i32(dc->pc);
1647    TCGv_i32 s = tcg_const_i32(arg[0].imm);
1648    TCGv_i32 imm = tcg_const_i32(arg[1].imm);
1649    gen_helper_entry(cpu_env, pc, s, imm);
1650    tcg_temp_free(imm);
1651    tcg_temp_free(s);
1652    tcg_temp_free(pc);
1653}
1654
1655static void translate_extui(DisasContext *dc, const OpcodeArg arg[],
1656                            const uint32_t par[])
1657{
1658    int maskimm = (1 << arg[3].imm) - 1;
1659
1660    TCGv_i32 tmp = tcg_temp_new_i32();
1661    tcg_gen_shri_i32(tmp, arg[1].in, arg[2].imm);
1662    tcg_gen_andi_i32(arg[0].out, tmp, maskimm);
1663    tcg_temp_free(tmp);
1664}
1665
1666static void translate_getex(DisasContext *dc, const OpcodeArg arg[],
1667                            const uint32_t par[])
1668{
1669    TCGv_i32 tmp = tcg_temp_new_i32();
1670
1671    tcg_gen_extract_i32(tmp, cpu_SR[ATOMCTL], 8, 1);
1672    tcg_gen_deposit_i32(cpu_SR[ATOMCTL], cpu_SR[ATOMCTL], arg[0].in, 8, 1);
1673    tcg_gen_mov_i32(arg[0].out, tmp);
1674    tcg_temp_free(tmp);
1675}
1676
1677static void translate_icache(DisasContext *dc, const OpcodeArg arg[],
1678                             const uint32_t par[])
1679{
1680#ifndef CONFIG_USER_ONLY
1681    TCGv_i32 addr = tcg_temp_new_i32();
1682
1683    tcg_gen_movi_i32(cpu_pc, dc->pc);
1684    tcg_gen_addi_i32(addr, arg[0].in, arg[1].imm);
1685    gen_helper_itlb_hit_test(cpu_env, addr);
1686    tcg_temp_free(addr);
1687#endif
1688}
1689
1690static void translate_itlb(DisasContext *dc, const OpcodeArg arg[],
1691                           const uint32_t par[])
1692{
1693#ifndef CONFIG_USER_ONLY
1694    TCGv_i32 dtlb = tcg_const_i32(par[0]);
1695
1696    gen_helper_itlb(cpu_env, arg[0].in, dtlb);
1697    tcg_temp_free(dtlb);
1698#endif
1699}
1700
1701static void translate_j(DisasContext *dc, const OpcodeArg arg[],
1702                        const uint32_t par[])
1703{
1704    gen_jumpi(dc, arg[0].imm, 0);
1705}
1706
1707static void translate_jx(DisasContext *dc, const OpcodeArg arg[],
1708                         const uint32_t par[])
1709{
1710    gen_jump(dc, arg[0].in);
1711}
1712
1713static void translate_l32e(DisasContext *dc, const OpcodeArg arg[],
1714                           const uint32_t par[])
1715{
1716    TCGv_i32 addr = tcg_temp_new_i32();
1717
1718    tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm);
1719    gen_load_store_alignment(dc, 2, addr, false);
1720    tcg_gen_qemu_ld_tl(arg[0].out, addr, dc->ring, MO_TEUL);
1721    tcg_temp_free(addr);
1722}
1723
1724#ifdef CONFIG_USER_ONLY
1725static void gen_check_exclusive(DisasContext *dc, TCGv_i32 addr, bool is_write)
1726{
1727}
1728#else
1729static void gen_check_exclusive(DisasContext *dc, TCGv_i32 addr, bool is_write)
1730{
1731    if (!option_enabled(dc, XTENSA_OPTION_MPU)) {
1732        TCGv_i32 tpc = tcg_const_i32(dc->pc);
1733        TCGv_i32 write = tcg_const_i32(is_write);
1734
1735        gen_helper_check_exclusive(cpu_env, tpc, addr, write);
1736        tcg_temp_free(tpc);
1737        tcg_temp_free(write);
1738    }
1739}
1740#endif
1741
1742static void translate_l32ex(DisasContext *dc, const OpcodeArg arg[],
1743                            const uint32_t par[])
1744{
1745    TCGv_i32 addr = tcg_temp_new_i32();
1746
1747    tcg_gen_mov_i32(addr, arg[1].in);
1748    gen_load_store_alignment(dc, 2, addr, true);
1749    gen_check_exclusive(dc, addr, false);
1750    tcg_gen_qemu_ld_i32(arg[0].out, addr, dc->ring, MO_TEUL);
1751    tcg_gen_mov_i32(cpu_exclusive_addr, addr);
1752    tcg_gen_mov_i32(cpu_exclusive_val, arg[0].out);
1753    tcg_temp_free(addr);
1754}
1755
1756static void translate_ldst(DisasContext *dc, const OpcodeArg arg[],
1757                           const uint32_t par[])
1758{
1759    TCGv_i32 addr = tcg_temp_new_i32();
1760
1761    tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm);
1762    if (par[0] & MO_SIZE) {
1763        gen_load_store_alignment(dc, par[0] & MO_SIZE, addr, par[1]);
1764    }
1765    if (par[2]) {
1766        if (par[1]) {
1767            tcg_gen_mb(TCG_BAR_STRL | TCG_MO_ALL);
1768        }
1769        tcg_gen_qemu_st_tl(arg[0].in, addr, dc->cring, par[0]);
1770    } else {
1771        tcg_gen_qemu_ld_tl(arg[0].out, addr, dc->cring, par[0]);
1772        if (par[1]) {
1773            tcg_gen_mb(TCG_BAR_LDAQ | TCG_MO_ALL);
1774        }
1775    }
1776    tcg_temp_free(addr);
1777}
1778
1779static void translate_l32r(DisasContext *dc, const OpcodeArg arg[],
1780                           const uint32_t par[])
1781{
1782    TCGv_i32 tmp;
1783
1784    if (dc->base.tb->flags & XTENSA_TBFLAG_LITBASE) {
1785        tmp = tcg_const_i32(arg[1].raw_imm - 1);
1786        tcg_gen_add_i32(tmp, cpu_SR[LITBASE], tmp);
1787    } else {
1788        tmp = tcg_const_i32(arg[1].imm);
1789    }
1790    tcg_gen_qemu_ld32u(arg[0].out, tmp, dc->cring);
1791    tcg_temp_free(tmp);
1792}
1793
1794static void translate_loop(DisasContext *dc, const OpcodeArg arg[],
1795                           const uint32_t par[])
1796{
1797    uint32_t lend = arg[1].imm;
1798
1799    tcg_gen_subi_i32(cpu_SR[LCOUNT], arg[0].in, 1);
1800    tcg_gen_movi_i32(cpu_SR[LBEG], dc->base.pc_next);
1801    tcg_gen_movi_i32(cpu_SR[LEND], lend);
1802
1803    if (par[0] != TCG_COND_NEVER) {
1804        TCGLabel *label = gen_new_label();
1805        tcg_gen_brcondi_i32(par[0], arg[0].in, 0, label);
1806        gen_jumpi(dc, lend, 1);
1807        gen_set_label(label);
1808    }
1809
1810    gen_jumpi(dc, dc->base.pc_next, 0);
1811}
1812
1813enum {
1814    MAC16_UMUL,
1815    MAC16_MUL,
1816    MAC16_MULA,
1817    MAC16_MULS,
1818    MAC16_NONE,
1819};
1820
1821enum {
1822    MAC16_LL,
1823    MAC16_HL,
1824    MAC16_LH,
1825    MAC16_HH,
1826
1827    MAC16_HX = 0x1,
1828    MAC16_XH = 0x2,
1829};
1830
1831static void translate_mac16(DisasContext *dc, const OpcodeArg arg[],
1832                            const uint32_t par[])
1833{
1834    int op = par[0];
1835    unsigned half = par[1];
1836    uint32_t ld_offset = par[2];
1837    unsigned off = ld_offset ? 2 : 0;
1838    TCGv_i32 vaddr = tcg_temp_new_i32();
1839    TCGv_i32 mem32 = tcg_temp_new_i32();
1840
1841    if (ld_offset) {
1842        tcg_gen_addi_i32(vaddr, arg[1].in, ld_offset);
1843        gen_load_store_alignment(dc, 2, vaddr, false);
1844        tcg_gen_qemu_ld32u(mem32, vaddr, dc->cring);
1845    }
1846    if (op != MAC16_NONE) {
1847        TCGv_i32 m1 = gen_mac16_m(arg[off].in,
1848                                  half & MAC16_HX, op == MAC16_UMUL);
1849        TCGv_i32 m2 = gen_mac16_m(arg[off + 1].in,
1850                                  half & MAC16_XH, op == MAC16_UMUL);
1851
1852        if (op == MAC16_MUL || op == MAC16_UMUL) {
1853            tcg_gen_mul_i32(cpu_SR[ACCLO], m1, m2);
1854            if (op == MAC16_UMUL) {
1855                tcg_gen_movi_i32(cpu_SR[ACCHI], 0);
1856            } else {
1857                tcg_gen_sari_i32(cpu_SR[ACCHI], cpu_SR[ACCLO], 31);
1858            }
1859        } else {
1860            TCGv_i32 lo = tcg_temp_new_i32();
1861            TCGv_i32 hi = tcg_temp_new_i32();
1862
1863            tcg_gen_mul_i32(lo, m1, m2);
1864            tcg_gen_sari_i32(hi, lo, 31);
1865            if (op == MAC16_MULA) {
1866                tcg_gen_add2_i32(cpu_SR[ACCLO], cpu_SR[ACCHI],
1867                                 cpu_SR[ACCLO], cpu_SR[ACCHI],
1868                                 lo, hi);
1869            } else {
1870                tcg_gen_sub2_i32(cpu_SR[ACCLO], cpu_SR[ACCHI],
1871                                 cpu_SR[ACCLO], cpu_SR[ACCHI],
1872                                 lo, hi);
1873            }
1874            tcg_gen_ext8s_i32(cpu_SR[ACCHI], cpu_SR[ACCHI]);
1875
1876            tcg_temp_free_i32(lo);
1877            tcg_temp_free_i32(hi);
1878        }
1879        tcg_temp_free(m1);
1880        tcg_temp_free(m2);
1881    }
1882    if (ld_offset) {
1883        tcg_gen_mov_i32(arg[1].out, vaddr);
1884        tcg_gen_mov_i32(cpu_SR[MR + arg[0].imm], mem32);
1885    }
1886    tcg_temp_free(vaddr);
1887    tcg_temp_free(mem32);
1888}
1889
1890static void translate_memw(DisasContext *dc, const OpcodeArg arg[],
1891                           const uint32_t par[])
1892{
1893    tcg_gen_mb(TCG_BAR_SC | TCG_MO_ALL);
1894}
1895
1896static void translate_smin(DisasContext *dc, const OpcodeArg arg[],
1897                           const uint32_t par[])
1898{
1899    tcg_gen_smin_i32(arg[0].out, arg[1].in, arg[2].in);
1900}
1901
1902static void translate_umin(DisasContext *dc, const OpcodeArg arg[],
1903                           const uint32_t par[])
1904{
1905    tcg_gen_umin_i32(arg[0].out, arg[1].in, arg[2].in);
1906}
1907
1908static void translate_smax(DisasContext *dc, const OpcodeArg arg[],
1909                           const uint32_t par[])
1910{
1911    tcg_gen_smax_i32(arg[0].out, arg[1].in, arg[2].in);
1912}
1913
1914static void translate_umax(DisasContext *dc, const OpcodeArg arg[],
1915                           const uint32_t par[])
1916{
1917    tcg_gen_umax_i32(arg[0].out, arg[1].in, arg[2].in);
1918}
1919
1920static void translate_mov(DisasContext *dc, const OpcodeArg arg[],
1921                          const uint32_t par[])
1922{
1923    tcg_gen_mov_i32(arg[0].out, arg[1].in);
1924}
1925
1926static void translate_movcond(DisasContext *dc, const OpcodeArg arg[],
1927                              const uint32_t par[])
1928{
1929    TCGv_i32 zero = tcg_const_i32(0);
1930
1931    tcg_gen_movcond_i32(par[0], arg[0].out,
1932                        arg[2].in, zero, arg[1].in, arg[0].in);
1933    tcg_temp_free(zero);
1934}
1935
1936static void translate_movi(DisasContext *dc, const OpcodeArg arg[],
1937                           const uint32_t par[])
1938{
1939    tcg_gen_movi_i32(arg[0].out, arg[1].imm);
1940}
1941
1942static void translate_movp(DisasContext *dc, const OpcodeArg arg[],
1943                           const uint32_t par[])
1944{
1945    TCGv_i32 zero = tcg_const_i32(0);
1946    TCGv_i32 tmp = tcg_temp_new_i32();
1947
1948    tcg_gen_andi_i32(tmp, arg[2].in, 1 << arg[2].imm);
1949    tcg_gen_movcond_i32(par[0],
1950                        arg[0].out, tmp, zero,
1951                        arg[1].in, arg[0].in);
1952    tcg_temp_free(tmp);
1953    tcg_temp_free(zero);
1954}
1955
1956static void translate_movsp(DisasContext *dc, const OpcodeArg arg[],
1957                            const uint32_t par[])
1958{
1959    tcg_gen_mov_i32(arg[0].out, arg[1].in);
1960}
1961
1962static void translate_mul16(DisasContext *dc, const OpcodeArg arg[],
1963                            const uint32_t par[])
1964{
1965    TCGv_i32 v1 = tcg_temp_new_i32();
1966    TCGv_i32 v2 = tcg_temp_new_i32();
1967
1968    if (par[0]) {
1969        tcg_gen_ext16s_i32(v1, arg[1].in);
1970        tcg_gen_ext16s_i32(v2, arg[2].in);
1971    } else {
1972        tcg_gen_ext16u_i32(v1, arg[1].in);
1973        tcg_gen_ext16u_i32(v2, arg[2].in);
1974    }
1975    tcg_gen_mul_i32(arg[0].out, v1, v2);
1976    tcg_temp_free(v2);
1977    tcg_temp_free(v1);
1978}
1979
1980static void translate_mull(DisasContext *dc, const OpcodeArg arg[],
1981                           const uint32_t par[])
1982{
1983    tcg_gen_mul_i32(arg[0].out, arg[1].in, arg[2].in);
1984}
1985
1986static void translate_mulh(DisasContext *dc, const OpcodeArg arg[],
1987                           const uint32_t par[])
1988{
1989    TCGv_i32 lo = tcg_temp_new();
1990
1991    if (par[0]) {
1992        tcg_gen_muls2_i32(lo, arg[0].out, arg[1].in, arg[2].in);
1993    } else {
1994        tcg_gen_mulu2_i32(lo, arg[0].out, arg[1].in, arg[2].in);
1995    }
1996    tcg_temp_free(lo);
1997}
1998
1999static void translate_neg(DisasContext *dc, const OpcodeArg arg[],
2000                          const uint32_t par[])
2001{
2002    tcg_gen_neg_i32(arg[0].out, arg[1].in);
2003}
2004
2005static void translate_nop(DisasContext *dc, const OpcodeArg arg[],
2006                          const uint32_t par[])
2007{
2008}
2009
2010static void translate_nsa(DisasContext *dc, const OpcodeArg arg[],
2011                          const uint32_t par[])
2012{
2013    tcg_gen_clrsb_i32(arg[0].out, arg[1].in);
2014}
2015
2016static void translate_nsau(DisasContext *dc, const OpcodeArg arg[],
2017                           const uint32_t par[])
2018{
2019    tcg_gen_clzi_i32(arg[0].out, arg[1].in, 32);
2020}
2021
2022static void translate_or(DisasContext *dc, const OpcodeArg arg[],
2023                         const uint32_t par[])
2024{
2025    tcg_gen_or_i32(arg[0].out, arg[1].in, arg[2].in);
2026}
2027
2028static void translate_ptlb(DisasContext *dc, const OpcodeArg arg[],
2029                           const uint32_t par[])
2030{
2031#ifndef CONFIG_USER_ONLY
2032    TCGv_i32 dtlb = tcg_const_i32(par[0]);
2033
2034    tcg_gen_movi_i32(cpu_pc, dc->pc);
2035    gen_helper_ptlb(arg[0].out, cpu_env, arg[1].in, dtlb);
2036    tcg_temp_free(dtlb);
2037#endif
2038}
2039
2040static void translate_pptlb(DisasContext *dc, const OpcodeArg arg[],
2041                            const uint32_t par[])
2042{
2043#ifndef CONFIG_USER_ONLY
2044    tcg_gen_movi_i32(cpu_pc, dc->pc);
2045    gen_helper_pptlb(arg[0].out, cpu_env, arg[1].in);
2046#endif
2047}
2048
2049static void translate_quos(DisasContext *dc, const OpcodeArg arg[],
2050                           const uint32_t par[])
2051{
2052    TCGLabel *label1 = gen_new_label();
2053    TCGLabel *label2 = gen_new_label();
2054
2055    tcg_gen_brcondi_i32(TCG_COND_NE, arg[1].in, 0x80000000,
2056                        label1);
2057    tcg_gen_brcondi_i32(TCG_COND_NE, arg[2].in, 0xffffffff,
2058                        label1);
2059    tcg_gen_movi_i32(arg[0].out,
2060                     par[0] ? 0x80000000 : 0);
2061    tcg_gen_br(label2);
2062    gen_set_label(label1);
2063    if (par[0]) {
2064        tcg_gen_div_i32(arg[0].out,
2065                        arg[1].in, arg[2].in);
2066    } else {
2067        tcg_gen_rem_i32(arg[0].out,
2068                        arg[1].in, arg[2].in);
2069    }
2070    gen_set_label(label2);
2071}
2072
2073static void translate_quou(DisasContext *dc, const OpcodeArg arg[],
2074                           const uint32_t par[])
2075{
2076    tcg_gen_divu_i32(arg[0].out,
2077                     arg[1].in, arg[2].in);
2078}
2079
2080static void translate_read_impwire(DisasContext *dc, const OpcodeArg arg[],
2081                                   const uint32_t par[])
2082{
2083    /* TODO: GPIO32 may be a part of coprocessor */
2084    tcg_gen_movi_i32(arg[0].out, 0);
2085}
2086
2087static void translate_remu(DisasContext *dc, const OpcodeArg arg[],
2088                           const uint32_t par[])
2089{
2090    tcg_gen_remu_i32(arg[0].out,
2091                     arg[1].in, arg[2].in);
2092}
2093
2094static void translate_rer(DisasContext *dc, const OpcodeArg arg[],
2095                          const uint32_t par[])
2096{
2097    gen_helper_rer(arg[0].out, cpu_env, arg[1].in);
2098}
2099
2100static void translate_ret(DisasContext *dc, const OpcodeArg arg[],
2101                          const uint32_t par[])
2102{
2103    gen_jump(dc, cpu_R[0]);
2104}
2105
2106static bool test_ill_retw(DisasContext *dc, const OpcodeArg arg[],
2107                          const uint32_t par[])
2108{
2109    if (!dc->cwoe) {
2110        qemu_log_mask(LOG_GUEST_ERROR,
2111                      "Illegal retw instruction(pc = %08x)\n", dc->pc);
2112        return true;
2113    } else {
2114        TCGv_i32 tmp = tcg_const_i32(dc->pc);
2115
2116        gen_helper_test_ill_retw(cpu_env, tmp);
2117        tcg_temp_free(tmp);
2118        return false;
2119    }
2120}
2121
2122static void translate_retw(DisasContext *dc, const OpcodeArg arg[],
2123                           const uint32_t par[])
2124{
2125    TCGv_i32 tmp = tcg_const_i32(1);
2126    tcg_gen_shl_i32(tmp, tmp, cpu_SR[WINDOW_BASE]);
2127    tcg_gen_andc_i32(cpu_SR[WINDOW_START],
2128                     cpu_SR[WINDOW_START], tmp);
2129    tcg_gen_movi_i32(tmp, dc->pc);
2130    tcg_gen_deposit_i32(tmp, tmp, cpu_R[0], 0, 30);
2131    gen_helper_retw(cpu_env, cpu_R[0]);
2132    gen_jump(dc, tmp);
2133    tcg_temp_free(tmp);
2134}
2135
2136static void translate_rfde(DisasContext *dc, const OpcodeArg arg[],
2137                           const uint32_t par[])
2138{
2139    gen_jump(dc, cpu_SR[dc->config->ndepc ? DEPC : EPC1]);
2140}
2141
2142static void translate_rfe(DisasContext *dc, const OpcodeArg arg[],
2143                          const uint32_t par[])
2144{
2145    tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_EXCM);
2146    gen_jump(dc, cpu_SR[EPC1]);
2147}
2148
2149static void translate_rfi(DisasContext *dc, const OpcodeArg arg[],
2150                          const uint32_t par[])
2151{
2152    tcg_gen_mov_i32(cpu_SR[PS], cpu_SR[EPS2 + arg[0].imm - 2]);
2153    gen_jump(dc, cpu_SR[EPC1 + arg[0].imm - 1]);
2154}
2155
2156static void translate_rfw(DisasContext *dc, const OpcodeArg arg[],
2157                          const uint32_t par[])
2158{
2159    TCGv_i32 tmp = tcg_const_i32(1);
2160
2161    tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_EXCM);
2162    tcg_gen_shl_i32(tmp, tmp, cpu_SR[WINDOW_BASE]);
2163
2164    if (par[0]) {
2165        tcg_gen_andc_i32(cpu_SR[WINDOW_START],
2166                         cpu_SR[WINDOW_START], tmp);
2167    } else {
2168        tcg_gen_or_i32(cpu_SR[WINDOW_START],
2169                       cpu_SR[WINDOW_START], tmp);
2170    }
2171
2172    tcg_temp_free(tmp);
2173    gen_helper_restore_owb(cpu_env);
2174    gen_jump(dc, cpu_SR[EPC1]);
2175}
2176
2177static void translate_rotw(DisasContext *dc, const OpcodeArg arg[],
2178                           const uint32_t par[])
2179{
2180    tcg_gen_addi_i32(cpu_windowbase_next, cpu_SR[WINDOW_BASE], arg[0].imm);
2181}
2182
2183static void translate_rsil(DisasContext *dc, const OpcodeArg arg[],
2184                           const uint32_t par[])
2185{
2186    tcg_gen_mov_i32(arg[0].out, cpu_SR[PS]);
2187    tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_INTLEVEL);
2188    tcg_gen_ori_i32(cpu_SR[PS], cpu_SR[PS], arg[1].imm);
2189}
2190
2191static void translate_rsr(DisasContext *dc, const OpcodeArg arg[],
2192                          const uint32_t par[])
2193{
2194    tcg_gen_mov_i32(arg[0].out, cpu_SR[par[0]]);
2195}
2196
2197static void translate_rsr_ccount(DisasContext *dc, const OpcodeArg arg[],
2198                                 const uint32_t par[])
2199{
2200#ifndef CONFIG_USER_ONLY
2201    if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
2202        gen_io_start();
2203    }
2204    gen_helper_update_ccount(cpu_env);
2205    tcg_gen_mov_i32(arg[0].out, cpu_SR[par[0]]);
2206#endif
2207}
2208
2209static void translate_rsr_ptevaddr(DisasContext *dc, const OpcodeArg arg[],
2210                                   const uint32_t par[])
2211{
2212#ifndef CONFIG_USER_ONLY
2213    TCGv_i32 tmp = tcg_temp_new_i32();
2214
2215    tcg_gen_shri_i32(tmp, cpu_SR[EXCVADDR], 10);
2216    tcg_gen_or_i32(tmp, tmp, cpu_SR[PTEVADDR]);
2217    tcg_gen_andi_i32(arg[0].out, tmp, 0xfffffffc);
2218    tcg_temp_free(tmp);
2219#endif
2220}
2221
2222static void translate_rtlb(DisasContext *dc, const OpcodeArg arg[],
2223                           const uint32_t par[])
2224{
2225#ifndef CONFIG_USER_ONLY
2226    static void (* const helper[])(TCGv_i32 r, TCGv_env env, TCGv_i32 a1,
2227                                   TCGv_i32 a2) = {
2228        gen_helper_rtlb0,
2229        gen_helper_rtlb1,
2230    };
2231    TCGv_i32 dtlb = tcg_const_i32(par[0]);
2232
2233    helper[par[1]](arg[0].out, cpu_env, arg[1].in, dtlb);
2234    tcg_temp_free(dtlb);
2235#endif
2236}
2237
2238static void translate_rptlb0(DisasContext *dc, const OpcodeArg arg[],
2239                             const uint32_t par[])
2240{
2241#ifndef CONFIG_USER_ONLY
2242    gen_helper_rptlb0(arg[0].out, cpu_env, arg[1].in);
2243#endif
2244}
2245
2246static void translate_rptlb1(DisasContext *dc, const OpcodeArg arg[],
2247                             const uint32_t par[])
2248{
2249#ifndef CONFIG_USER_ONLY
2250    gen_helper_rptlb1(arg[0].out, cpu_env, arg[1].in);
2251#endif
2252}
2253
2254static void translate_rur(DisasContext *dc, const OpcodeArg arg[],
2255                          const uint32_t par[])
2256{
2257    tcg_gen_mov_i32(arg[0].out, cpu_UR[par[0]]);
2258}
2259
2260static void translate_setb_expstate(DisasContext *dc, const OpcodeArg arg[],
2261                                    const uint32_t par[])
2262{
2263    /* TODO: GPIO32 may be a part of coprocessor */
2264    tcg_gen_ori_i32(cpu_UR[EXPSTATE], cpu_UR[EXPSTATE], 1u << arg[0].imm);
2265}
2266
2267#ifdef CONFIG_USER_ONLY
2268static void gen_check_atomctl(DisasContext *dc, TCGv_i32 addr)
2269{
2270}
2271#else
2272static void gen_check_atomctl(DisasContext *dc, TCGv_i32 addr)
2273{
2274    TCGv_i32 tpc = tcg_const_i32(dc->pc);
2275
2276    gen_helper_check_atomctl(cpu_env, tpc, addr);
2277    tcg_temp_free(tpc);
2278}
2279#endif
2280
2281static void translate_s32c1i(DisasContext *dc, const OpcodeArg arg[],
2282                             const uint32_t par[])
2283{
2284    TCGv_i32 tmp = tcg_temp_local_new_i32();
2285    TCGv_i32 addr = tcg_temp_local_new_i32();
2286
2287    tcg_gen_mov_i32(tmp, arg[0].in);
2288    tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm);
2289    gen_load_store_alignment(dc, 2, addr, true);
2290    gen_check_atomctl(dc, addr);
2291    tcg_gen_atomic_cmpxchg_i32(arg[0].out, addr, cpu_SR[SCOMPARE1],
2292                               tmp, dc->cring, MO_TEUL);
2293    tcg_temp_free(addr);
2294    tcg_temp_free(tmp);
2295}
2296
2297static void translate_s32e(DisasContext *dc, const OpcodeArg arg[],
2298                           const uint32_t par[])
2299{
2300    TCGv_i32 addr = tcg_temp_new_i32();
2301
2302    tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm);
2303    gen_load_store_alignment(dc, 2, addr, false);
2304    tcg_gen_qemu_st_tl(arg[0].in, addr, dc->ring, MO_TEUL);
2305    tcg_temp_free(addr);
2306}
2307
2308static void translate_s32ex(DisasContext *dc, const OpcodeArg arg[],
2309                            const uint32_t par[])
2310{
2311    TCGv_i32 prev = tcg_temp_new_i32();
2312    TCGv_i32 addr = tcg_temp_local_new_i32();
2313    TCGv_i32 res = tcg_temp_local_new_i32();
2314    TCGLabel *label = gen_new_label();
2315
2316    tcg_gen_movi_i32(res, 0);
2317    tcg_gen_mov_i32(addr, arg[1].in);
2318    gen_load_store_alignment(dc, 2, addr, true);
2319    tcg_gen_brcond_i32(TCG_COND_NE, addr, cpu_exclusive_addr, label);
2320    gen_check_exclusive(dc, addr, true);
2321    tcg_gen_atomic_cmpxchg_i32(prev, cpu_exclusive_addr, cpu_exclusive_val,
2322                               arg[0].in, dc->cring, MO_TEUL);
2323    tcg_gen_setcond_i32(TCG_COND_EQ, res, prev, cpu_exclusive_val);
2324    tcg_gen_movcond_i32(TCG_COND_EQ, cpu_exclusive_val,
2325                        prev, cpu_exclusive_val, prev, cpu_exclusive_val);
2326    tcg_gen_movi_i32(cpu_exclusive_addr, -1);
2327    gen_set_label(label);
2328    tcg_gen_extract_i32(arg[0].out, cpu_SR[ATOMCTL], 8, 1);
2329    tcg_gen_deposit_i32(cpu_SR[ATOMCTL], cpu_SR[ATOMCTL], res, 8, 1);
2330    tcg_temp_free(prev);
2331    tcg_temp_free(addr);
2332    tcg_temp_free(res);
2333}
2334
2335static void translate_salt(DisasContext *dc, const OpcodeArg arg[],
2336                           const uint32_t par[])
2337{
2338    tcg_gen_setcond_i32(par[0],
2339                        arg[0].out,
2340                        arg[1].in, arg[2].in);
2341}
2342
2343static void translate_sext(DisasContext *dc, const OpcodeArg arg[],
2344                           const uint32_t par[])
2345{
2346    int shift = 31 - arg[2].imm;
2347
2348    if (shift == 24) {
2349        tcg_gen_ext8s_i32(arg[0].out, arg[1].in);
2350    } else if (shift == 16) {
2351        tcg_gen_ext16s_i32(arg[0].out, arg[1].in);
2352    } else {
2353        TCGv_i32 tmp = tcg_temp_new_i32();
2354        tcg_gen_shli_i32(tmp, arg[1].in, shift);
2355        tcg_gen_sari_i32(arg[0].out, tmp, shift);
2356        tcg_temp_free(tmp);
2357    }
2358}
2359
2360static bool test_ill_simcall(DisasContext *dc, const OpcodeArg arg[],
2361                             const uint32_t par[])
2362{
2363#ifdef CONFIG_USER_ONLY
2364    bool ill = true;
2365#else
2366    bool ill = !semihosting_enabled();
2367#endif
2368    if (ill) {
2369        qemu_log_mask(LOG_GUEST_ERROR, "SIMCALL but semihosting is disabled\n");
2370    }
2371    return ill;
2372}
2373
2374static void translate_simcall(DisasContext *dc, const OpcodeArg arg[],
2375                              const uint32_t par[])
2376{
2377#ifndef CONFIG_USER_ONLY
2378    gen_helper_simcall(cpu_env);
2379#endif
2380}
2381
2382/*
2383 * Note: 64 bit ops are used here solely because SAR values
2384 * have range 0..63
2385 */
2386#define gen_shift_reg(cmd, reg) do { \
2387                    TCGv_i64 tmp = tcg_temp_new_i64(); \
2388                    tcg_gen_extu_i32_i64(tmp, reg); \
2389                    tcg_gen_##cmd##_i64(v, v, tmp); \
2390                    tcg_gen_extrl_i64_i32(arg[0].out, v); \
2391                    tcg_temp_free_i64(v); \
2392                    tcg_temp_free_i64(tmp); \
2393                } while (0)
2394
2395#define gen_shift(cmd) gen_shift_reg(cmd, cpu_SR[SAR])
2396
2397static void translate_sll(DisasContext *dc, const OpcodeArg arg[],
2398                          const uint32_t par[])
2399{
2400    if (dc->sar_m32_5bit) {
2401        tcg_gen_shl_i32(arg[0].out, arg[1].in, dc->sar_m32);
2402    } else {
2403        TCGv_i64 v = tcg_temp_new_i64();
2404        TCGv_i32 s = tcg_const_i32(32);
2405        tcg_gen_sub_i32(s, s, cpu_SR[SAR]);
2406        tcg_gen_andi_i32(s, s, 0x3f);
2407        tcg_gen_extu_i32_i64(v, arg[1].in);
2408        gen_shift_reg(shl, s);
2409        tcg_temp_free(s);
2410    }
2411}
2412
2413static void translate_slli(DisasContext *dc, const OpcodeArg arg[],
2414                           const uint32_t par[])
2415{
2416    if (arg[2].imm == 32) {
2417        qemu_log_mask(LOG_GUEST_ERROR, "slli a%d, a%d, 32 is undefined\n",
2418                      arg[0].imm, arg[1].imm);
2419    }
2420    tcg_gen_shli_i32(arg[0].out, arg[1].in, arg[2].imm & 0x1f);
2421}
2422
2423static void translate_sra(DisasContext *dc, const OpcodeArg arg[],
2424                          const uint32_t par[])
2425{
2426    if (dc->sar_m32_5bit) {
2427        tcg_gen_sar_i32(arg[0].out, arg[1].in, cpu_SR[SAR]);
2428    } else {
2429        TCGv_i64 v = tcg_temp_new_i64();
2430        tcg_gen_ext_i32_i64(v, arg[1].in);
2431        gen_shift(sar);
2432    }
2433}
2434
2435static void translate_srai(DisasContext *dc, const OpcodeArg arg[],
2436                           const uint32_t par[])
2437{
2438    tcg_gen_sari_i32(arg[0].out, arg[1].in, arg[2].imm);
2439}
2440
2441static void translate_src(DisasContext *dc, const OpcodeArg arg[],
2442                          const uint32_t par[])
2443{
2444    TCGv_i64 v = tcg_temp_new_i64();
2445    tcg_gen_concat_i32_i64(v, arg[2].in, arg[1].in);
2446    gen_shift(shr);
2447}
2448
2449static void translate_srl(DisasContext *dc, const OpcodeArg arg[],
2450                          const uint32_t par[])
2451{
2452    if (dc->sar_m32_5bit) {
2453        tcg_gen_shr_i32(arg[0].out, arg[1].in, cpu_SR[SAR]);
2454    } else {
2455        TCGv_i64 v = tcg_temp_new_i64();
2456        tcg_gen_extu_i32_i64(v, arg[1].in);
2457        gen_shift(shr);
2458    }
2459}
2460
2461#undef gen_shift
2462#undef gen_shift_reg
2463
2464static void translate_srli(DisasContext *dc, const OpcodeArg arg[],
2465                           const uint32_t par[])
2466{
2467    tcg_gen_shri_i32(arg[0].out, arg[1].in, arg[2].imm);
2468}
2469
2470static void translate_ssa8b(DisasContext *dc, const OpcodeArg arg[],
2471                            const uint32_t par[])
2472{
2473    TCGv_i32 tmp = tcg_temp_new_i32();
2474    tcg_gen_shli_i32(tmp, arg[0].in, 3);
2475    gen_left_shift_sar(dc, tmp);
2476    tcg_temp_free(tmp);
2477}
2478
2479static void translate_ssa8l(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_right_shift_sar(dc, tmp);
2485    tcg_temp_free(tmp);
2486}
2487
2488static void translate_ssai(DisasContext *dc, const OpcodeArg arg[],
2489                           const uint32_t par[])
2490{
2491    TCGv_i32 tmp = tcg_const_i32(arg[0].imm);
2492    gen_right_shift_sar(dc, tmp);
2493    tcg_temp_free(tmp);
2494}
2495
2496static void translate_ssl(DisasContext *dc, const OpcodeArg arg[],
2497                          const uint32_t par[])
2498{
2499    gen_left_shift_sar(dc, arg[0].in);
2500}
2501
2502static void translate_ssr(DisasContext *dc, const OpcodeArg arg[],
2503                          const uint32_t par[])
2504{
2505    gen_right_shift_sar(dc, arg[0].in);
2506}
2507
2508static void translate_sub(DisasContext *dc, const OpcodeArg arg[],
2509                          const uint32_t par[])
2510{
2511    tcg_gen_sub_i32(arg[0].out, arg[1].in, arg[2].in);
2512}
2513
2514static void translate_subx(DisasContext *dc, const OpcodeArg arg[],
2515                           const uint32_t par[])
2516{
2517    TCGv_i32 tmp = tcg_temp_new_i32();
2518    tcg_gen_shli_i32(tmp, arg[1].in, par[0]);
2519    tcg_gen_sub_i32(arg[0].out, tmp, arg[2].in);
2520    tcg_temp_free(tmp);
2521}
2522
2523static void translate_waiti(DisasContext *dc, const OpcodeArg arg[],
2524                            const uint32_t par[])
2525{
2526#ifndef CONFIG_USER_ONLY
2527    gen_waiti(dc, arg[0].imm);
2528#endif
2529}
2530
2531static void translate_wtlb(DisasContext *dc, const OpcodeArg arg[],
2532                           const uint32_t par[])
2533{
2534#ifndef CONFIG_USER_ONLY
2535    TCGv_i32 dtlb = tcg_const_i32(par[0]);
2536
2537    gen_helper_wtlb(cpu_env, arg[0].in, arg[1].in, dtlb);
2538    tcg_temp_free(dtlb);
2539#endif
2540}
2541
2542static void translate_wptlb(DisasContext *dc, const OpcodeArg arg[],
2543                            const uint32_t par[])
2544{
2545#ifndef CONFIG_USER_ONLY
2546    gen_helper_wptlb(cpu_env, arg[0].in, arg[1].in);
2547#endif
2548}
2549
2550static void translate_wer(DisasContext *dc, const OpcodeArg arg[],
2551                          const uint32_t par[])
2552{
2553    gen_helper_wer(cpu_env, arg[0].in, arg[1].in);
2554}
2555
2556static void translate_wrmsk_expstate(DisasContext *dc, const OpcodeArg arg[],
2557                                     const uint32_t par[])
2558{
2559    /* TODO: GPIO32 may be a part of coprocessor */
2560    tcg_gen_and_i32(cpu_UR[EXPSTATE], arg[0].in, arg[1].in);
2561}
2562
2563static void translate_wsr(DisasContext *dc, const OpcodeArg arg[],
2564                          const uint32_t par[])
2565{
2566    tcg_gen_mov_i32(cpu_SR[par[0]], arg[0].in);
2567}
2568
2569static void translate_wsr_mask(DisasContext *dc, const OpcodeArg arg[],
2570                               const uint32_t par[])
2571{
2572    tcg_gen_andi_i32(cpu_SR[par[0]], arg[0].in, par[2]);
2573}
2574
2575static void translate_wsr_acchi(DisasContext *dc, const OpcodeArg arg[],
2576                                const uint32_t par[])
2577{
2578    tcg_gen_ext8s_i32(cpu_SR[par[0]], arg[0].in);
2579}
2580
2581static void translate_wsr_ccompare(DisasContext *dc, const OpcodeArg arg[],
2582                                   const uint32_t par[])
2583{
2584#ifndef CONFIG_USER_ONLY
2585    uint32_t id = par[0] - CCOMPARE;
2586    TCGv_i32 tmp = tcg_const_i32(id);
2587
2588    assert(id < dc->config->nccompare);
2589    if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
2590        gen_io_start();
2591    }
2592    tcg_gen_mov_i32(cpu_SR[par[0]], arg[0].in);
2593    gen_helper_update_ccompare(cpu_env, tmp);
2594    tcg_temp_free(tmp);
2595#endif
2596}
2597
2598static void translate_wsr_ccount(DisasContext *dc, const OpcodeArg arg[],
2599                                 const uint32_t par[])
2600{
2601#ifndef CONFIG_USER_ONLY
2602    if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
2603        gen_io_start();
2604    }
2605    gen_helper_wsr_ccount(cpu_env, arg[0].in);
2606#endif
2607}
2608
2609static void translate_wsr_dbreaka(DisasContext *dc, const OpcodeArg arg[],
2610                                  const uint32_t par[])
2611{
2612#ifndef CONFIG_USER_ONLY
2613    unsigned id = par[0] - DBREAKA;
2614    TCGv_i32 tmp = tcg_const_i32(id);
2615
2616    assert(id < dc->config->ndbreak);
2617    gen_helper_wsr_dbreaka(cpu_env, tmp, arg[0].in);
2618    tcg_temp_free(tmp);
2619#endif
2620}
2621
2622static void translate_wsr_dbreakc(DisasContext *dc, const OpcodeArg arg[],
2623                                  const uint32_t par[])
2624{
2625#ifndef CONFIG_USER_ONLY
2626    unsigned id = par[0] - DBREAKC;
2627    TCGv_i32 tmp = tcg_const_i32(id);
2628
2629    assert(id < dc->config->ndbreak);
2630    gen_helper_wsr_dbreakc(cpu_env, tmp, arg[0].in);
2631    tcg_temp_free(tmp);
2632#endif
2633}
2634
2635static void translate_wsr_ibreaka(DisasContext *dc, const OpcodeArg arg[],
2636                                  const uint32_t par[])
2637{
2638#ifndef CONFIG_USER_ONLY
2639    unsigned id = par[0] - IBREAKA;
2640    TCGv_i32 tmp = tcg_const_i32(id);
2641
2642    assert(id < dc->config->nibreak);
2643    gen_helper_wsr_ibreaka(cpu_env, tmp, arg[0].in);
2644    tcg_temp_free(tmp);
2645#endif
2646}
2647
2648static void translate_wsr_ibreakenable(DisasContext *dc, const OpcodeArg arg[],
2649                                       const uint32_t par[])
2650{
2651#ifndef CONFIG_USER_ONLY
2652    gen_helper_wsr_ibreakenable(cpu_env, arg[0].in);
2653#endif
2654}
2655
2656static void translate_wsr_icount(DisasContext *dc, const OpcodeArg arg[],
2657                                 const uint32_t par[])
2658{
2659#ifndef CONFIG_USER_ONLY
2660    if (dc->icount) {
2661        tcg_gen_mov_i32(dc->next_icount, arg[0].in);
2662    } else {
2663        tcg_gen_mov_i32(cpu_SR[par[0]], arg[0].in);
2664    }
2665#endif
2666}
2667
2668static void translate_wsr_intclear(DisasContext *dc, const OpcodeArg arg[],
2669                                   const uint32_t par[])
2670{
2671#ifndef CONFIG_USER_ONLY
2672    gen_helper_intclear(cpu_env, arg[0].in);
2673#endif
2674}
2675
2676static void translate_wsr_intset(DisasContext *dc, const OpcodeArg arg[],
2677                                 const uint32_t par[])
2678{
2679#ifndef CONFIG_USER_ONLY
2680    gen_helper_intset(cpu_env, arg[0].in);
2681#endif
2682}
2683
2684static void translate_wsr_memctl(DisasContext *dc, const OpcodeArg arg[],
2685                                 const uint32_t par[])
2686{
2687#ifndef CONFIG_USER_ONLY
2688    gen_helper_wsr_memctl(cpu_env, arg[0].in);
2689#endif
2690}
2691
2692static void translate_wsr_mpuenb(DisasContext *dc, const OpcodeArg arg[],
2693                                 const uint32_t par[])
2694{
2695#ifndef CONFIG_USER_ONLY
2696    gen_helper_wsr_mpuenb(cpu_env, arg[0].in);
2697#endif
2698}
2699
2700static void translate_wsr_ps(DisasContext *dc, const OpcodeArg arg[],
2701                             const uint32_t par[])
2702{
2703#ifndef CONFIG_USER_ONLY
2704    uint32_t mask = PS_WOE | PS_CALLINC | PS_OWB |
2705        PS_UM | PS_EXCM | PS_INTLEVEL;
2706
2707    if (option_enabled(dc, XTENSA_OPTION_MMU) ||
2708        option_enabled(dc, XTENSA_OPTION_MPU)) {
2709        mask |= PS_RING;
2710    }
2711    tcg_gen_andi_i32(cpu_SR[par[0]], arg[0].in, mask);
2712#endif
2713}
2714
2715static void translate_wsr_rasid(DisasContext *dc, const OpcodeArg arg[],
2716                                const uint32_t par[])
2717{
2718#ifndef CONFIG_USER_ONLY
2719    gen_helper_wsr_rasid(cpu_env, arg[0].in);
2720#endif
2721}
2722
2723static void translate_wsr_sar(DisasContext *dc, const OpcodeArg arg[],
2724                              const uint32_t par[])
2725{
2726    tcg_gen_andi_i32(cpu_SR[par[0]], arg[0].in, 0x3f);
2727    if (dc->sar_m32_5bit) {
2728        tcg_gen_discard_i32(dc->sar_m32);
2729    }
2730    dc->sar_5bit = false;
2731    dc->sar_m32_5bit = false;
2732}
2733
2734static void translate_wsr_windowbase(DisasContext *dc, const OpcodeArg arg[],
2735                                     const uint32_t par[])
2736{
2737#ifndef CONFIG_USER_ONLY
2738    tcg_gen_mov_i32(cpu_windowbase_next, arg[0].in);
2739#endif
2740}
2741
2742static void translate_wsr_windowstart(DisasContext *dc, const OpcodeArg arg[],
2743                                      const uint32_t par[])
2744{
2745#ifndef CONFIG_USER_ONLY
2746    tcg_gen_andi_i32(cpu_SR[par[0]], arg[0].in,
2747                     (1 << dc->config->nareg / 4) - 1);
2748#endif
2749}
2750
2751static void translate_wur(DisasContext *dc, const OpcodeArg arg[],
2752                          const uint32_t par[])
2753{
2754    tcg_gen_mov_i32(cpu_UR[par[0]], arg[0].in);
2755}
2756
2757static void translate_wur_fcr(DisasContext *dc, const OpcodeArg arg[],
2758                              const uint32_t par[])
2759{
2760    gen_helper_wur_fcr(cpu_env, arg[0].in);
2761}
2762
2763static void translate_wur_fsr(DisasContext *dc, const OpcodeArg arg[],
2764                              const uint32_t par[])
2765{
2766    tcg_gen_andi_i32(cpu_UR[par[0]], arg[0].in, 0xffffff80);
2767}
2768
2769static void translate_xor(DisasContext *dc, const OpcodeArg arg[],
2770                          const uint32_t par[])
2771{
2772    tcg_gen_xor_i32(arg[0].out, arg[1].in, arg[2].in);
2773}
2774
2775static void translate_xsr(DisasContext *dc, const OpcodeArg arg[],
2776                          const uint32_t par[])
2777{
2778    TCGv_i32 tmp = tcg_temp_new_i32();
2779
2780    tcg_gen_mov_i32(tmp, arg[0].in);
2781    tcg_gen_mov_i32(arg[0].out, cpu_SR[par[0]]);
2782    tcg_gen_mov_i32(cpu_SR[par[0]], tmp);
2783    tcg_temp_free(tmp);
2784}
2785
2786static void translate_xsr_mask(DisasContext *dc, const OpcodeArg arg[],
2787                               const uint32_t par[])
2788{
2789    TCGv_i32 tmp = tcg_temp_new_i32();
2790
2791    tcg_gen_mov_i32(tmp, arg[0].in);
2792    tcg_gen_mov_i32(arg[0].out, cpu_SR[par[0]]);
2793    tcg_gen_andi_i32(cpu_SR[par[0]], tmp, par[2]);
2794    tcg_temp_free(tmp);
2795}
2796
2797static void translate_xsr_ccount(DisasContext *dc, const OpcodeArg arg[],
2798                                 const uint32_t par[])
2799{
2800#ifndef CONFIG_USER_ONLY
2801    TCGv_i32 tmp = tcg_temp_new_i32();
2802
2803    if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
2804        gen_io_start();
2805    }
2806
2807    gen_helper_update_ccount(cpu_env);
2808    tcg_gen_mov_i32(tmp, cpu_SR[par[0]]);
2809    gen_helper_wsr_ccount(cpu_env, arg[0].in);
2810    tcg_gen_mov_i32(arg[0].out, tmp);
2811    tcg_temp_free(tmp);
2812
2813#endif
2814}
2815
2816#define gen_translate_xsr(name) \
2817    static void translate_xsr_##name(DisasContext *dc, const OpcodeArg arg[], \
2818                                     const uint32_t par[]) \
2819{ \
2820    TCGv_i32 tmp = tcg_temp_new_i32(); \
2821 \
2822    tcg_gen_mov_i32(tmp, cpu_SR[par[0]]); \
2823    translate_wsr_##name(dc, arg, par); \
2824    tcg_gen_mov_i32(arg[0].out, tmp); \
2825    tcg_temp_free(tmp); \
2826}
2827
2828gen_translate_xsr(acchi)
2829gen_translate_xsr(ccompare)
2830gen_translate_xsr(dbreaka)
2831gen_translate_xsr(dbreakc)
2832gen_translate_xsr(ibreaka)
2833gen_translate_xsr(ibreakenable)
2834gen_translate_xsr(icount)
2835gen_translate_xsr(memctl)
2836gen_translate_xsr(mpuenb)
2837gen_translate_xsr(ps)
2838gen_translate_xsr(rasid)
2839gen_translate_xsr(sar)
2840gen_translate_xsr(windowbase)
2841gen_translate_xsr(windowstart)
2842
2843#undef gen_translate_xsr
2844
2845static const XtensaOpcodeOps core_ops[] = {
2846    {
2847        .name = "abs",
2848        .translate = translate_abs,
2849    }, {
2850        .name = (const char * const[]) {
2851            "add", "add.n", NULL,
2852        },
2853        .translate = translate_add,
2854        .op_flags = XTENSA_OP_NAME_ARRAY,
2855    }, {
2856        .name = (const char * const[]) {
2857            "addi", "addi.n", NULL,
2858        },
2859        .translate = translate_addi,
2860        .op_flags = XTENSA_OP_NAME_ARRAY,
2861    }, {
2862        .name = "addmi",
2863        .translate = translate_addi,
2864    }, {
2865        .name = "addx2",
2866        .translate = translate_addx,
2867        .par = (const uint32_t[]){1},
2868    }, {
2869        .name = "addx4",
2870        .translate = translate_addx,
2871        .par = (const uint32_t[]){2},
2872    }, {
2873        .name = "addx8",
2874        .translate = translate_addx,
2875        .par = (const uint32_t[]){3},
2876    }, {
2877        .name = "all4",
2878        .translate = translate_all,
2879        .par = (const uint32_t[]){true, 4},
2880    }, {
2881        .name = "all8",
2882        .translate = translate_all,
2883        .par = (const uint32_t[]){true, 8},
2884    }, {
2885        .name = "and",
2886        .translate = translate_and,
2887    }, {
2888        .name = "andb",
2889        .translate = translate_boolean,
2890        .par = (const uint32_t[]){BOOLEAN_AND},
2891    }, {
2892        .name = "andbc",
2893        .translate = translate_boolean,
2894        .par = (const uint32_t[]){BOOLEAN_ANDC},
2895    }, {
2896        .name = "any4",
2897        .translate = translate_all,
2898        .par = (const uint32_t[]){false, 4},
2899    }, {
2900        .name = "any8",
2901        .translate = translate_all,
2902        .par = (const uint32_t[]){false, 8},
2903    }, {
2904        .name = (const char * const[]) {
2905            "ball", "ball.w15", "ball.w18", NULL,
2906        },
2907        .translate = translate_ball,
2908        .par = (const uint32_t[]){TCG_COND_EQ},
2909        .op_flags = XTENSA_OP_NAME_ARRAY,
2910    }, {
2911        .name = (const char * const[]) {
2912            "bany", "bany.w15", "bany.w18", NULL,
2913        },
2914        .translate = translate_bany,
2915        .par = (const uint32_t[]){TCG_COND_NE},
2916        .op_flags = XTENSA_OP_NAME_ARRAY,
2917    }, {
2918        .name = (const char * const[]) {
2919            "bbc", "bbc.w15", "bbc.w18", NULL,
2920        },
2921        .translate = translate_bb,
2922        .par = (const uint32_t[]){TCG_COND_EQ},
2923        .op_flags = XTENSA_OP_NAME_ARRAY,
2924    }, {
2925        .name = (const char * const[]) {
2926            "bbci", "bbci.w15", "bbci.w18", NULL,
2927        },
2928        .translate = translate_bbi,
2929        .par = (const uint32_t[]){TCG_COND_EQ},
2930        .op_flags = XTENSA_OP_NAME_ARRAY,
2931    }, {
2932        .name = (const char * const[]) {
2933            "bbs", "bbs.w15", "bbs.w18", NULL,
2934        },
2935        .translate = translate_bb,
2936        .par = (const uint32_t[]){TCG_COND_NE},
2937        .op_flags = XTENSA_OP_NAME_ARRAY,
2938    }, {
2939        .name = (const char * const[]) {
2940            "bbsi", "bbsi.w15", "bbsi.w18", NULL,
2941        },
2942        .translate = translate_bbi,
2943        .par = (const uint32_t[]){TCG_COND_NE},
2944        .op_flags = XTENSA_OP_NAME_ARRAY,
2945    }, {
2946        .name = (const char * const[]) {
2947            "beq", "beq.w15", "beq.w18", NULL,
2948        },
2949        .translate = translate_b,
2950        .par = (const uint32_t[]){TCG_COND_EQ},
2951        .op_flags = XTENSA_OP_NAME_ARRAY,
2952    }, {
2953        .name = (const char * const[]) {
2954            "beqi", "beqi.w15", "beqi.w18", NULL,
2955        },
2956        .translate = translate_bi,
2957        .par = (const uint32_t[]){TCG_COND_EQ},
2958        .op_flags = XTENSA_OP_NAME_ARRAY,
2959    }, {
2960        .name = (const char * const[]) {
2961            "beqz", "beqz.n", "beqz.w15", "beqz.w18", NULL,
2962        },
2963        .translate = translate_bz,
2964        .par = (const uint32_t[]){TCG_COND_EQ},
2965        .op_flags = XTENSA_OP_NAME_ARRAY,
2966    }, {
2967        .name = "bf",
2968        .translate = translate_bp,
2969        .par = (const uint32_t[]){TCG_COND_EQ},
2970    }, {
2971        .name = (const char * const[]) {
2972            "bge", "bge.w15", "bge.w18", NULL,
2973        },
2974        .translate = translate_b,
2975        .par = (const uint32_t[]){TCG_COND_GE},
2976        .op_flags = XTENSA_OP_NAME_ARRAY,
2977    }, {
2978        .name = (const char * const[]) {
2979            "bgei", "bgei.w15", "bgei.w18", NULL,
2980        },
2981        .translate = translate_bi,
2982        .par = (const uint32_t[]){TCG_COND_GE},
2983        .op_flags = XTENSA_OP_NAME_ARRAY,
2984    }, {
2985        .name = (const char * const[]) {
2986            "bgeu", "bgeu.w15", "bgeu.w18", NULL,
2987        },
2988        .translate = translate_b,
2989        .par = (const uint32_t[]){TCG_COND_GEU},
2990        .op_flags = XTENSA_OP_NAME_ARRAY,
2991    }, {
2992        .name = (const char * const[]) {
2993            "bgeui", "bgeui.w15", "bgeui.w18", NULL,
2994        },
2995        .translate = translate_bi,
2996        .par = (const uint32_t[]){TCG_COND_GEU},
2997        .op_flags = XTENSA_OP_NAME_ARRAY,
2998    }, {
2999        .name = (const char * const[]) {
3000            "bgez", "bgez.w15", "bgez.w18", NULL,
3001        },
3002        .translate = translate_bz,
3003        .par = (const uint32_t[]){TCG_COND_GE},
3004        .op_flags = XTENSA_OP_NAME_ARRAY,
3005    }, {
3006        .name = (const char * const[]) {
3007            "blt", "blt.w15", "blt.w18", NULL,
3008        },
3009        .translate = translate_b,
3010        .par = (const uint32_t[]){TCG_COND_LT},
3011        .op_flags = XTENSA_OP_NAME_ARRAY,
3012    }, {
3013        .name = (const char * const[]) {
3014            "blti", "blti.w15", "blti.w18", NULL,
3015        },
3016        .translate = translate_bi,
3017        .par = (const uint32_t[]){TCG_COND_LT},
3018        .op_flags = XTENSA_OP_NAME_ARRAY,
3019    }, {
3020        .name = (const char * const[]) {
3021            "bltu", "bltu.w15", "bltu.w18", NULL,
3022        },
3023        .translate = translate_b,
3024        .par = (const uint32_t[]){TCG_COND_LTU},
3025        .op_flags = XTENSA_OP_NAME_ARRAY,
3026    }, {
3027        .name = (const char * const[]) {
3028            "bltui", "bltui.w15", "bltui.w18", NULL,
3029        },
3030        .translate = translate_bi,
3031        .par = (const uint32_t[]){TCG_COND_LTU},
3032        .op_flags = XTENSA_OP_NAME_ARRAY,
3033    }, {
3034        .name = (const char * const[]) {
3035            "bltz", "bltz.w15", "bltz.w18", NULL,
3036        },
3037        .translate = translate_bz,
3038        .par = (const uint32_t[]){TCG_COND_LT},
3039        .op_flags = XTENSA_OP_NAME_ARRAY,
3040    }, {
3041        .name = (const char * const[]) {
3042            "bnall", "bnall.w15", "bnall.w18", NULL,
3043        },
3044        .translate = translate_ball,
3045        .par = (const uint32_t[]){TCG_COND_NE},
3046        .op_flags = XTENSA_OP_NAME_ARRAY,
3047    }, {
3048        .name = (const char * const[]) {
3049            "bne", "bne.w15", "bne.w18", NULL,
3050        },
3051        .translate = translate_b,
3052        .par = (const uint32_t[]){TCG_COND_NE},
3053        .op_flags = XTENSA_OP_NAME_ARRAY,
3054    }, {
3055        .name = (const char * const[]) {
3056            "bnei", "bnei.w15", "bnei.w18", NULL,
3057        },
3058        .translate = translate_bi,
3059        .par = (const uint32_t[]){TCG_COND_NE},
3060        .op_flags = XTENSA_OP_NAME_ARRAY,
3061    }, {
3062        .name = (const char * const[]) {
3063            "bnez", "bnez.n", "bnez.w15", "bnez.w18", NULL,
3064        },
3065        .translate = translate_bz,
3066        .par = (const uint32_t[]){TCG_COND_NE},
3067        .op_flags = XTENSA_OP_NAME_ARRAY,
3068    }, {
3069        .name = (const char * const[]) {
3070            "bnone", "bnone.w15", "bnone.w18", NULL,
3071        },
3072        .translate = translate_bany,
3073        .par = (const uint32_t[]){TCG_COND_EQ},
3074        .op_flags = XTENSA_OP_NAME_ARRAY,
3075    }, {
3076        .name = "break",
3077        .translate = translate_nop,
3078        .par = (const uint32_t[]){DEBUGCAUSE_BI},
3079        .op_flags = XTENSA_OP_DEBUG_BREAK,
3080    }, {
3081        .name = "break.n",
3082        .translate = translate_nop,
3083        .par = (const uint32_t[]){DEBUGCAUSE_BN},
3084        .op_flags = XTENSA_OP_DEBUG_BREAK,
3085    }, {
3086        .name = "bt",
3087        .translate = translate_bp,
3088        .par = (const uint32_t[]){TCG_COND_NE},
3089    }, {
3090        .name = "call0",
3091        .translate = translate_call0,
3092    }, {
3093        .name = "call12",
3094        .translate = translate_callw,
3095        .par = (const uint32_t[]){3},
3096    }, {
3097        .name = "call4",
3098        .translate = translate_callw,
3099        .par = (const uint32_t[]){1},
3100    }, {
3101        .name = "call8",
3102        .translate = translate_callw,
3103        .par = (const uint32_t[]){2},
3104    }, {
3105        .name = "callx0",
3106        .translate = translate_callx0,
3107    }, {
3108        .name = "callx12",
3109        .translate = translate_callxw,
3110        .par = (const uint32_t[]){3},
3111    }, {
3112        .name = "callx4",
3113        .translate = translate_callxw,
3114        .par = (const uint32_t[]){1},
3115    }, {
3116        .name = "callx8",
3117        .translate = translate_callxw,
3118        .par = (const uint32_t[]){2},
3119    }, {
3120        .name = "clamps",
3121        .translate = translate_clamps,
3122    }, {
3123        .name = "clrb_expstate",
3124        .translate = translate_clrb_expstate,
3125    }, {
3126        .name = "clrex",
3127        .translate = translate_clrex,
3128    }, {
3129        .name = "const16",
3130        .translate = translate_const16,
3131    }, {
3132        .name = "depbits",
3133        .translate = translate_depbits,
3134    }, {
3135        .name = "dhi",
3136        .translate = translate_dcache,
3137        .op_flags = XTENSA_OP_PRIVILEGED,
3138    }, {
3139        .name = "dhi.b",
3140        .translate = translate_nop,
3141    }, {
3142        .name = "dhu",
3143        .translate = translate_dcache,
3144        .op_flags = XTENSA_OP_PRIVILEGED,
3145    }, {
3146        .name = "dhwb",
3147        .translate = translate_dcache,
3148    }, {
3149        .name = "dhwb.b",
3150        .translate = translate_nop,
3151    }, {
3152        .name = "dhwbi",
3153        .translate = translate_dcache,
3154    }, {
3155        .name = "dhwbi.b",
3156        .translate = translate_nop,
3157    }, {
3158        .name = "dii",
3159        .translate = translate_nop,
3160        .op_flags = XTENSA_OP_PRIVILEGED,
3161    }, {
3162        .name = "diu",
3163        .translate = translate_nop,
3164        .op_flags = XTENSA_OP_PRIVILEGED,
3165    }, {
3166        .name = "diwb",
3167        .translate = translate_nop,
3168        .op_flags = XTENSA_OP_PRIVILEGED,
3169    }, {
3170        .name = "diwbi",
3171        .translate = translate_nop,
3172        .op_flags = XTENSA_OP_PRIVILEGED,
3173    }, {
3174        .name = "diwbui.p",
3175        .translate = translate_diwbuip,
3176        .op_flags = XTENSA_OP_PRIVILEGED,
3177    }, {
3178        .name = "dpfl",
3179        .translate = translate_dcache,
3180        .op_flags = XTENSA_OP_PRIVILEGED,
3181    }, {
3182        .name = "dpfm.b",
3183        .translate = translate_nop,
3184    }, {
3185        .name = "dpfm.bf",
3186        .translate = translate_nop,
3187    }, {
3188        .name = "dpfr",
3189        .translate = translate_nop,
3190    }, {
3191        .name = "dpfr.b",
3192        .translate = translate_nop,
3193    }, {
3194        .name = "dpfr.bf",
3195        .translate = translate_nop,
3196    }, {
3197        .name = "dpfro",
3198        .translate = translate_nop,
3199    }, {
3200        .name = "dpfw",
3201        .translate = translate_nop,
3202    }, {
3203        .name = "dpfw.b",
3204        .translate = translate_nop,
3205    }, {
3206        .name = "dpfw.bf",
3207        .translate = translate_nop,
3208    }, {
3209        .name = "dpfwo",
3210        .translate = translate_nop,
3211    }, {
3212        .name = "dsync",
3213        .translate = translate_nop,
3214    }, {
3215        .name = "entry",
3216        .translate = translate_entry,
3217        .test_ill = test_ill_entry,
3218        .test_overflow = test_overflow_entry,
3219        .op_flags = XTENSA_OP_EXIT_TB_M1 |
3220            XTENSA_OP_SYNC_REGISTER_WINDOW,
3221    }, {
3222        .name = "esync",
3223        .translate = translate_nop,
3224    }, {
3225        .name = "excw",
3226        .translate = translate_nop,
3227    }, {
3228        .name = "extui",
3229        .translate = translate_extui,
3230    }, {
3231        .name = "extw",
3232        .translate = translate_memw,
3233    }, {
3234        .name = "getex",
3235        .translate = translate_getex,
3236    }, {
3237        .name = "hwwdtlba",
3238        .op_flags = XTENSA_OP_ILL,
3239    }, {
3240        .name = "hwwitlba",
3241        .op_flags = XTENSA_OP_ILL,
3242    }, {
3243        .name = "idtlb",
3244        .translate = translate_itlb,
3245        .par = (const uint32_t[]){true},
3246        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
3247    }, {
3248        .name = "ihi",
3249        .translate = translate_icache,
3250    }, {
3251        .name = "ihu",
3252        .translate = translate_icache,
3253        .op_flags = XTENSA_OP_PRIVILEGED,
3254    }, {
3255        .name = "iii",
3256        .translate = translate_nop,
3257        .op_flags = XTENSA_OP_PRIVILEGED,
3258    }, {
3259        .name = "iitlb",
3260        .translate = translate_itlb,
3261        .par = (const uint32_t[]){false},
3262        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
3263    }, {
3264        .name = "iiu",
3265        .translate = translate_nop,
3266        .op_flags = XTENSA_OP_PRIVILEGED,
3267    }, {
3268        .name = (const char * const[]) {
3269            "ill", "ill.n", NULL,
3270        },
3271        .op_flags = XTENSA_OP_ILL | XTENSA_OP_NAME_ARRAY,
3272    }, {
3273        .name = "ipf",
3274        .translate = translate_nop,
3275    }, {
3276        .name = "ipfl",
3277        .translate = translate_icache,
3278        .op_flags = XTENSA_OP_PRIVILEGED,
3279    }, {
3280        .name = "isync",
3281        .translate = translate_nop,
3282    }, {
3283        .name = "j",
3284        .translate = translate_j,
3285    }, {
3286        .name = "jx",
3287        .translate = translate_jx,
3288    }, {
3289        .name = "l16si",
3290        .translate = translate_ldst,
3291        .par = (const uint32_t[]){MO_TESW, false, false},
3292        .op_flags = XTENSA_OP_LOAD,
3293    }, {
3294        .name = "l16ui",
3295        .translate = translate_ldst,
3296        .par = (const uint32_t[]){MO_TEUW, false, false},
3297        .op_flags = XTENSA_OP_LOAD,
3298    }, {
3299        .name = "l32ai",
3300        .translate = translate_ldst,
3301        .par = (const uint32_t[]){MO_TEUL, true, false},
3302        .op_flags = XTENSA_OP_LOAD,
3303    }, {
3304        .name = "l32e",
3305        .translate = translate_l32e,
3306        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_LOAD,
3307    }, {
3308        .name = "l32ex",
3309        .translate = translate_l32ex,
3310        .op_flags = XTENSA_OP_LOAD,
3311    }, {
3312        .name = (const char * const[]) {
3313            "l32i", "l32i.n", NULL,
3314        },
3315        .translate = translate_ldst,
3316        .par = (const uint32_t[]){MO_TEUL, false, false},
3317        .op_flags = XTENSA_OP_NAME_ARRAY | XTENSA_OP_LOAD,
3318    }, {
3319        .name = "l32r",
3320        .translate = translate_l32r,
3321        .op_flags = XTENSA_OP_LOAD,
3322    }, {
3323        .name = "l8ui",
3324        .translate = translate_ldst,
3325        .par = (const uint32_t[]){MO_UB, false, false},
3326        .op_flags = XTENSA_OP_LOAD,
3327    }, {
3328        .name = "lddec",
3329        .translate = translate_mac16,
3330        .par = (const uint32_t[]){MAC16_NONE, 0, -4},
3331        .op_flags = XTENSA_OP_LOAD,
3332    }, {
3333        .name = "ldinc",
3334        .translate = translate_mac16,
3335        .par = (const uint32_t[]){MAC16_NONE, 0, 4},
3336        .op_flags = XTENSA_OP_LOAD,
3337    }, {
3338        .name = "ldpte",
3339        .op_flags = XTENSA_OP_ILL,
3340    }, {
3341        .name = (const char * const[]) {
3342            "loop", "loop.w15", NULL,
3343        },
3344        .translate = translate_loop,
3345        .par = (const uint32_t[]){TCG_COND_NEVER},
3346        .op_flags = XTENSA_OP_NAME_ARRAY,
3347    }, {
3348        .name = (const char * const[]) {
3349            "loopgtz", "loopgtz.w15", NULL,
3350        },
3351        .translate = translate_loop,
3352        .par = (const uint32_t[]){TCG_COND_GT},
3353        .op_flags = XTENSA_OP_NAME_ARRAY,
3354    }, {
3355        .name = (const char * const[]) {
3356            "loopnez", "loopnez.w15", NULL,
3357        },
3358        .translate = translate_loop,
3359        .par = (const uint32_t[]){TCG_COND_NE},
3360        .op_flags = XTENSA_OP_NAME_ARRAY,
3361    }, {
3362        .name = "max",
3363        .translate = translate_smax,
3364    }, {
3365        .name = "maxu",
3366        .translate = translate_umax,
3367    }, {
3368        .name = "memw",
3369        .translate = translate_memw,
3370    }, {
3371        .name = "min",
3372        .translate = translate_smin,
3373    }, {
3374        .name = "minu",
3375        .translate = translate_umin,
3376    }, {
3377        .name = (const char * const[]) {
3378            "mov", "mov.n", NULL,
3379        },
3380        .translate = translate_mov,
3381        .op_flags = XTENSA_OP_NAME_ARRAY,
3382    }, {
3383        .name = "moveqz",
3384        .translate = translate_movcond,
3385        .par = (const uint32_t[]){TCG_COND_EQ},
3386    }, {
3387        .name = "movf",
3388        .translate = translate_movp,
3389        .par = (const uint32_t[]){TCG_COND_EQ},
3390    }, {
3391        .name = "movgez",
3392        .translate = translate_movcond,
3393        .par = (const uint32_t[]){TCG_COND_GE},
3394    }, {
3395        .name = "movi",
3396        .translate = translate_movi,
3397    }, {
3398        .name = "movi.n",
3399        .translate = translate_movi,
3400    }, {
3401        .name = "movltz",
3402        .translate = translate_movcond,
3403        .par = (const uint32_t[]){TCG_COND_LT},
3404    }, {
3405        .name = "movnez",
3406        .translate = translate_movcond,
3407        .par = (const uint32_t[]){TCG_COND_NE},
3408    }, {
3409        .name = "movsp",
3410        .translate = translate_movsp,
3411        .op_flags = XTENSA_OP_ALLOCA,
3412    }, {
3413        .name = "movt",
3414        .translate = translate_movp,
3415        .par = (const uint32_t[]){TCG_COND_NE},
3416    }, {
3417        .name = "mul.aa.hh",
3418        .translate = translate_mac16,
3419        .par = (const uint32_t[]){MAC16_MUL, MAC16_HH, 0},
3420    }, {
3421        .name = "mul.aa.hl",
3422        .translate = translate_mac16,
3423        .par = (const uint32_t[]){MAC16_MUL, MAC16_HL, 0},
3424    }, {
3425        .name = "mul.aa.lh",
3426        .translate = translate_mac16,
3427        .par = (const uint32_t[]){MAC16_MUL, MAC16_LH, 0},
3428    }, {
3429        .name = "mul.aa.ll",
3430        .translate = translate_mac16,
3431        .par = (const uint32_t[]){MAC16_MUL, MAC16_LL, 0},
3432    }, {
3433        .name = "mul.ad.hh",
3434        .translate = translate_mac16,
3435        .par = (const uint32_t[]){MAC16_MUL, MAC16_HH, 0},
3436    }, {
3437        .name = "mul.ad.hl",
3438        .translate = translate_mac16,
3439        .par = (const uint32_t[]){MAC16_MUL, MAC16_HL, 0},
3440    }, {
3441        .name = "mul.ad.lh",
3442        .translate = translate_mac16,
3443        .par = (const uint32_t[]){MAC16_MUL, MAC16_LH, 0},
3444    }, {
3445        .name = "mul.ad.ll",
3446        .translate = translate_mac16,
3447        .par = (const uint32_t[]){MAC16_MUL, MAC16_LL, 0},
3448    }, {
3449        .name = "mul.da.hh",
3450        .translate = translate_mac16,
3451        .par = (const uint32_t[]){MAC16_MUL, MAC16_HH, 0},
3452    }, {
3453        .name = "mul.da.hl",
3454        .translate = translate_mac16,
3455        .par = (const uint32_t[]){MAC16_MUL, MAC16_HL, 0},
3456    }, {
3457        .name = "mul.da.lh",
3458        .translate = translate_mac16,
3459        .par = (const uint32_t[]){MAC16_MUL, MAC16_LH, 0},
3460    }, {
3461        .name = "mul.da.ll",
3462        .translate = translate_mac16,
3463        .par = (const uint32_t[]){MAC16_MUL, MAC16_LL, 0},
3464    }, {
3465        .name = "mul.dd.hh",
3466        .translate = translate_mac16,
3467        .par = (const uint32_t[]){MAC16_MUL, MAC16_HH, 0},
3468    }, {
3469        .name = "mul.dd.hl",
3470        .translate = translate_mac16,
3471        .par = (const uint32_t[]){MAC16_MUL, MAC16_HL, 0},
3472    }, {
3473        .name = "mul.dd.lh",
3474        .translate = translate_mac16,
3475        .par = (const uint32_t[]){MAC16_MUL, MAC16_LH, 0},
3476    }, {
3477        .name = "mul.dd.ll",
3478        .translate = translate_mac16,
3479        .par = (const uint32_t[]){MAC16_MUL, MAC16_LL, 0},
3480    }, {
3481        .name = "mul16s",
3482        .translate = translate_mul16,
3483        .par = (const uint32_t[]){true},
3484    }, {
3485        .name = "mul16u",
3486        .translate = translate_mul16,
3487        .par = (const uint32_t[]){false},
3488    }, {
3489        .name = "mula.aa.hh",
3490        .translate = translate_mac16,
3491        .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 0},
3492    }, {
3493        .name = "mula.aa.hl",
3494        .translate = translate_mac16,
3495        .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 0},
3496    }, {
3497        .name = "mula.aa.lh",
3498        .translate = translate_mac16,
3499        .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 0},
3500    }, {
3501        .name = "mula.aa.ll",
3502        .translate = translate_mac16,
3503        .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 0},
3504    }, {
3505        .name = "mula.ad.hh",
3506        .translate = translate_mac16,
3507        .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 0},
3508    }, {
3509        .name = "mula.ad.hl",
3510        .translate = translate_mac16,
3511        .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 0},
3512    }, {
3513        .name = "mula.ad.lh",
3514        .translate = translate_mac16,
3515        .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 0},
3516    }, {
3517        .name = "mula.ad.ll",
3518        .translate = translate_mac16,
3519        .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 0},
3520    }, {
3521        .name = "mula.da.hh",
3522        .translate = translate_mac16,
3523        .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 0},
3524    }, {
3525        .name = "mula.da.hh.lddec",
3526        .translate = translate_mac16,
3527        .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, -4},
3528    }, {
3529        .name = "mula.da.hh.ldinc",
3530        .translate = translate_mac16,
3531        .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 4},
3532    }, {
3533        .name = "mula.da.hl",
3534        .translate = translate_mac16,
3535        .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 0},
3536    }, {
3537        .name = "mula.da.hl.lddec",
3538        .translate = translate_mac16,
3539        .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, -4},
3540    }, {
3541        .name = "mula.da.hl.ldinc",
3542        .translate = translate_mac16,
3543        .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 4},
3544    }, {
3545        .name = "mula.da.lh",
3546        .translate = translate_mac16,
3547        .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 0},
3548    }, {
3549        .name = "mula.da.lh.lddec",
3550        .translate = translate_mac16,
3551        .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, -4},
3552    }, {
3553        .name = "mula.da.lh.ldinc",
3554        .translate = translate_mac16,
3555        .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 4},
3556    }, {
3557        .name = "mula.da.ll",
3558        .translate = translate_mac16,
3559        .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 0},
3560    }, {
3561        .name = "mula.da.ll.lddec",
3562        .translate = translate_mac16,
3563        .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, -4},
3564    }, {
3565        .name = "mula.da.ll.ldinc",
3566        .translate = translate_mac16,
3567        .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 4},
3568    }, {
3569        .name = "mula.dd.hh",
3570        .translate = translate_mac16,
3571        .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 0},
3572    }, {
3573        .name = "mula.dd.hh.lddec",
3574        .translate = translate_mac16,
3575        .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, -4},
3576    }, {
3577        .name = "mula.dd.hh.ldinc",
3578        .translate = translate_mac16,
3579        .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 4},
3580    }, {
3581        .name = "mula.dd.hl",
3582        .translate = translate_mac16,
3583        .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 0},
3584    }, {
3585        .name = "mula.dd.hl.lddec",
3586        .translate = translate_mac16,
3587        .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, -4},
3588    }, {
3589        .name = "mula.dd.hl.ldinc",
3590        .translate = translate_mac16,
3591        .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 4},
3592    }, {
3593        .name = "mula.dd.lh",
3594        .translate = translate_mac16,
3595        .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 0},
3596    }, {
3597        .name = "mula.dd.lh.lddec",
3598        .translate = translate_mac16,
3599        .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, -4},
3600    }, {
3601        .name = "mula.dd.lh.ldinc",
3602        .translate = translate_mac16,
3603        .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 4},
3604    }, {
3605        .name = "mula.dd.ll",
3606        .translate = translate_mac16,
3607        .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 0},
3608    }, {
3609        .name = "mula.dd.ll.lddec",
3610        .translate = translate_mac16,
3611        .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, -4},
3612    }, {
3613        .name = "mula.dd.ll.ldinc",
3614        .translate = translate_mac16,
3615        .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 4},
3616    }, {
3617        .name = "mull",
3618        .translate = translate_mull,
3619    }, {
3620        .name = "muls.aa.hh",
3621        .translate = translate_mac16,
3622        .par = (const uint32_t[]){MAC16_MULS, MAC16_HH, 0},
3623    }, {
3624        .name = "muls.aa.hl",
3625        .translate = translate_mac16,
3626        .par = (const uint32_t[]){MAC16_MULS, MAC16_HL, 0},
3627    }, {
3628        .name = "muls.aa.lh",
3629        .translate = translate_mac16,
3630        .par = (const uint32_t[]){MAC16_MULS, MAC16_LH, 0},
3631    }, {
3632        .name = "muls.aa.ll",
3633        .translate = translate_mac16,
3634        .par = (const uint32_t[]){MAC16_MULS, MAC16_LL, 0},
3635    }, {
3636        .name = "muls.ad.hh",
3637        .translate = translate_mac16,
3638        .par = (const uint32_t[]){MAC16_MULS, MAC16_HH, 0},
3639    }, {
3640        .name = "muls.ad.hl",
3641        .translate = translate_mac16,
3642        .par = (const uint32_t[]){MAC16_MULS, MAC16_HL, 0},
3643    }, {
3644        .name = "muls.ad.lh",
3645        .translate = translate_mac16,
3646        .par = (const uint32_t[]){MAC16_MULS, MAC16_LH, 0},
3647    }, {
3648        .name = "muls.ad.ll",
3649        .translate = translate_mac16,
3650        .par = (const uint32_t[]){MAC16_MULS, MAC16_LL, 0},
3651    }, {
3652        .name = "muls.da.hh",
3653        .translate = translate_mac16,
3654        .par = (const uint32_t[]){MAC16_MULS, MAC16_HH, 0},
3655    }, {
3656        .name = "muls.da.hl",
3657        .translate = translate_mac16,
3658        .par = (const uint32_t[]){MAC16_MULS, MAC16_HL, 0},
3659    }, {
3660        .name = "muls.da.lh",
3661        .translate = translate_mac16,
3662        .par = (const uint32_t[]){MAC16_MULS, MAC16_LH, 0},
3663    }, {
3664        .name = "muls.da.ll",
3665        .translate = translate_mac16,
3666        .par = (const uint32_t[]){MAC16_MULS, MAC16_LL, 0},
3667    }, {
3668        .name = "muls.dd.hh",
3669        .translate = translate_mac16,
3670        .par = (const uint32_t[]){MAC16_MULS, MAC16_HH, 0},
3671    }, {
3672        .name = "muls.dd.hl",
3673        .translate = translate_mac16,
3674        .par = (const uint32_t[]){MAC16_MULS, MAC16_HL, 0},
3675    }, {
3676        .name = "muls.dd.lh",
3677        .translate = translate_mac16,
3678        .par = (const uint32_t[]){MAC16_MULS, MAC16_LH, 0},
3679    }, {
3680        .name = "muls.dd.ll",
3681        .translate = translate_mac16,
3682        .par = (const uint32_t[]){MAC16_MULS, MAC16_LL, 0},
3683    }, {
3684        .name = "mulsh",
3685        .translate = translate_mulh,
3686        .par = (const uint32_t[]){true},
3687    }, {
3688        .name = "muluh",
3689        .translate = translate_mulh,
3690        .par = (const uint32_t[]){false},
3691    }, {
3692        .name = "neg",
3693        .translate = translate_neg,
3694    }, {
3695        .name = (const char * const[]) {
3696            "nop", "nop.n", NULL,
3697        },
3698        .translate = translate_nop,
3699        .op_flags = XTENSA_OP_NAME_ARRAY,
3700    }, {
3701        .name = "nsa",
3702        .translate = translate_nsa,
3703    }, {
3704        .name = "nsau",
3705        .translate = translate_nsau,
3706    }, {
3707        .name = "or",
3708        .translate = translate_or,
3709    }, {
3710        .name = "orb",
3711        .translate = translate_boolean,
3712        .par = (const uint32_t[]){BOOLEAN_OR},
3713    }, {
3714        .name = "orbc",
3715        .translate = translate_boolean,
3716        .par = (const uint32_t[]){BOOLEAN_ORC},
3717    }, {
3718        .name = "pdtlb",
3719        .translate = translate_ptlb,
3720        .par = (const uint32_t[]){true},
3721        .op_flags = XTENSA_OP_PRIVILEGED,
3722    }, {
3723        .name = "pfend.a",
3724        .translate = translate_nop,
3725    }, {
3726        .name = "pfend.o",
3727        .translate = translate_nop,
3728    }, {
3729        .name = "pfnxt.f",
3730        .translate = translate_nop,
3731    }, {
3732        .name = "pfwait.a",
3733        .translate = translate_nop,
3734    }, {
3735        .name = "pfwait.r",
3736        .translate = translate_nop,
3737    }, {
3738        .name = "pitlb",
3739        .translate = translate_ptlb,
3740        .par = (const uint32_t[]){false},
3741        .op_flags = XTENSA_OP_PRIVILEGED,
3742    }, {
3743        .name = "pptlb",
3744        .translate = translate_pptlb,
3745        .op_flags = XTENSA_OP_PRIVILEGED,
3746    }, {
3747        .name = "quos",
3748        .translate = translate_quos,
3749        .par = (const uint32_t[]){true},
3750        .op_flags = XTENSA_OP_DIVIDE_BY_ZERO,
3751    }, {
3752        .name = "quou",
3753        .translate = translate_quou,
3754        .op_flags = XTENSA_OP_DIVIDE_BY_ZERO,
3755    }, {
3756        .name = "rdtlb0",
3757        .translate = translate_rtlb,
3758        .par = (const uint32_t[]){true, 0},
3759        .op_flags = XTENSA_OP_PRIVILEGED,
3760    }, {
3761        .name = "rdtlb1",
3762        .translate = translate_rtlb,
3763        .par = (const uint32_t[]){true, 1},
3764        .op_flags = XTENSA_OP_PRIVILEGED,
3765    }, {
3766        .name = "read_impwire",
3767        .translate = translate_read_impwire,
3768    }, {
3769        .name = "rems",
3770        .translate = translate_quos,
3771        .par = (const uint32_t[]){false},
3772        .op_flags = XTENSA_OP_DIVIDE_BY_ZERO,
3773    }, {
3774        .name = "remu",
3775        .translate = translate_remu,
3776        .op_flags = XTENSA_OP_DIVIDE_BY_ZERO,
3777    }, {
3778        .name = "rer",
3779        .translate = translate_rer,
3780        .op_flags = XTENSA_OP_PRIVILEGED,
3781    }, {
3782        .name = (const char * const[]) {
3783            "ret", "ret.n", NULL,
3784        },
3785        .translate = translate_ret,
3786        .op_flags = XTENSA_OP_NAME_ARRAY,
3787    }, {
3788        .name = (const char * const[]) {
3789            "retw", "retw.n", NULL,
3790        },
3791        .translate = translate_retw,
3792        .test_ill = test_ill_retw,
3793        .op_flags = XTENSA_OP_UNDERFLOW | XTENSA_OP_NAME_ARRAY,
3794    }, {
3795        .name = "rfdd",
3796        .op_flags = XTENSA_OP_ILL,
3797    }, {
3798        .name = "rfde",
3799        .translate = translate_rfde,
3800        .op_flags = XTENSA_OP_PRIVILEGED,
3801    }, {
3802        .name = "rfdo",
3803        .op_flags = XTENSA_OP_ILL,
3804    }, {
3805        .name = "rfe",
3806        .translate = translate_rfe,
3807        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_CHECK_INTERRUPTS,
3808    }, {
3809        .name = "rfi",
3810        .translate = translate_rfi,
3811        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_CHECK_INTERRUPTS,
3812    }, {
3813        .name = "rfwo",
3814        .translate = translate_rfw,
3815        .par = (const uint32_t[]){true},
3816        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_CHECK_INTERRUPTS,
3817    }, {
3818        .name = "rfwu",
3819        .translate = translate_rfw,
3820        .par = (const uint32_t[]){false},
3821        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_CHECK_INTERRUPTS,
3822    }, {
3823        .name = "ritlb0",
3824        .translate = translate_rtlb,
3825        .par = (const uint32_t[]){false, 0},
3826        .op_flags = XTENSA_OP_PRIVILEGED,
3827    }, {
3828        .name = "ritlb1",
3829        .translate = translate_rtlb,
3830        .par = (const uint32_t[]){false, 1},
3831        .op_flags = XTENSA_OP_PRIVILEGED,
3832    }, {
3833        .name = "rptlb0",
3834        .translate = translate_rptlb0,
3835        .op_flags = XTENSA_OP_PRIVILEGED,
3836    }, {
3837        .name = "rptlb1",
3838        .translate = translate_rptlb1,
3839        .op_flags = XTENSA_OP_PRIVILEGED,
3840    }, {
3841        .name = "rotw",
3842        .translate = translate_rotw,
3843        .op_flags = XTENSA_OP_PRIVILEGED |
3844            XTENSA_OP_EXIT_TB_M1 |
3845            XTENSA_OP_SYNC_REGISTER_WINDOW,
3846    }, {
3847        .name = "rsil",
3848        .translate = translate_rsil,
3849        .op_flags =
3850            XTENSA_OP_PRIVILEGED |
3851            XTENSA_OP_EXIT_TB_0 |
3852            XTENSA_OP_CHECK_INTERRUPTS,
3853    }, {
3854        .name = "rsr.176",
3855        .translate = translate_rsr,
3856        .par = (const uint32_t[]){176},
3857        .op_flags = XTENSA_OP_PRIVILEGED,
3858    }, {
3859        .name = "rsr.208",
3860        .translate = translate_rsr,
3861        .par = (const uint32_t[]){208},
3862        .op_flags = XTENSA_OP_PRIVILEGED,
3863    }, {
3864        .name = "rsr.acchi",
3865        .translate = translate_rsr,
3866        .test_ill = test_ill_sr,
3867        .par = (const uint32_t[]){
3868            ACCHI,
3869            XTENSA_OPTION_MAC16,
3870        },
3871    }, {
3872        .name = "rsr.acclo",
3873        .translate = translate_rsr,
3874        .test_ill = test_ill_sr,
3875        .par = (const uint32_t[]){
3876            ACCLO,
3877            XTENSA_OPTION_MAC16,
3878        },
3879    }, {
3880        .name = "rsr.atomctl",
3881        .translate = translate_rsr,
3882        .test_ill = test_ill_sr,
3883        .par = (const uint32_t[]){
3884            ATOMCTL,
3885            XTENSA_OPTION_ATOMCTL,
3886        },
3887        .op_flags = XTENSA_OP_PRIVILEGED,
3888    }, {
3889        .name = "rsr.br",
3890        .translate = translate_rsr,
3891        .test_ill = test_ill_sr,
3892        .par = (const uint32_t[]){
3893            BR,
3894            XTENSA_OPTION_BOOLEAN,
3895        },
3896    }, {
3897        .name = "rsr.cacheadrdis",
3898        .translate = translate_rsr,
3899        .test_ill = test_ill_sr,
3900        .par = (const uint32_t[]){
3901            CACHEADRDIS,
3902            XTENSA_OPTION_MPU,
3903        },
3904        .op_flags = XTENSA_OP_PRIVILEGED,
3905    }, {
3906        .name = "rsr.cacheattr",
3907        .translate = translate_rsr,
3908        .test_ill = test_ill_sr,
3909        .par = (const uint32_t[]){
3910            CACHEATTR,
3911            XTENSA_OPTION_CACHEATTR,
3912        },
3913        .op_flags = XTENSA_OP_PRIVILEGED,
3914    }, {
3915        .name = "rsr.ccompare0",
3916        .translate = translate_rsr,
3917        .test_ill = test_ill_ccompare,
3918        .par = (const uint32_t[]){
3919            CCOMPARE,
3920            XTENSA_OPTION_TIMER_INTERRUPT,
3921        },
3922        .op_flags = XTENSA_OP_PRIVILEGED,
3923    }, {
3924        .name = "rsr.ccompare1",
3925        .translate = translate_rsr,
3926        .test_ill = test_ill_ccompare,
3927        .par = (const uint32_t[]){
3928            CCOMPARE + 1,
3929            XTENSA_OPTION_TIMER_INTERRUPT,
3930        },
3931        .op_flags = XTENSA_OP_PRIVILEGED,
3932    }, {
3933        .name = "rsr.ccompare2",
3934        .translate = translate_rsr,
3935        .test_ill = test_ill_ccompare,
3936        .par = (const uint32_t[]){
3937            CCOMPARE + 2,
3938            XTENSA_OPTION_TIMER_INTERRUPT,
3939        },
3940        .op_flags = XTENSA_OP_PRIVILEGED,
3941    }, {
3942        .name = "rsr.ccount",
3943        .translate = translate_rsr_ccount,
3944        .test_ill = test_ill_sr,
3945        .par = (const uint32_t[]){
3946            CCOUNT,
3947            XTENSA_OPTION_TIMER_INTERRUPT,
3948        },
3949        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
3950    }, {
3951        .name = "rsr.configid0",
3952        .translate = translate_rsr,
3953        .par = (const uint32_t[]){CONFIGID0},
3954        .op_flags = XTENSA_OP_PRIVILEGED,
3955    }, {
3956        .name = "rsr.configid1",
3957        .translate = translate_rsr,
3958        .par = (const uint32_t[]){CONFIGID1},
3959        .op_flags = XTENSA_OP_PRIVILEGED,
3960    }, {
3961        .name = "rsr.cpenable",
3962        .translate = translate_rsr,
3963        .test_ill = test_ill_sr,
3964        .par = (const uint32_t[]){
3965            CPENABLE,
3966            XTENSA_OPTION_COPROCESSOR,
3967        },
3968        .op_flags = XTENSA_OP_PRIVILEGED,
3969    }, {
3970        .name = "rsr.dbreaka0",
3971        .translate = translate_rsr,
3972        .test_ill = test_ill_dbreak,
3973        .par = (const uint32_t[]){
3974            DBREAKA,
3975            XTENSA_OPTION_DEBUG,
3976        },
3977        .op_flags = XTENSA_OP_PRIVILEGED,
3978    }, {
3979        .name = "rsr.dbreaka1",
3980        .translate = translate_rsr,
3981        .test_ill = test_ill_dbreak,
3982        .par = (const uint32_t[]){
3983            DBREAKA + 1,
3984            XTENSA_OPTION_DEBUG,
3985        },
3986        .op_flags = XTENSA_OP_PRIVILEGED,
3987    }, {
3988        .name = "rsr.dbreakc0",
3989        .translate = translate_rsr,
3990        .test_ill = test_ill_dbreak,
3991        .par = (const uint32_t[]){
3992            DBREAKC,
3993            XTENSA_OPTION_DEBUG,
3994        },
3995        .op_flags = XTENSA_OP_PRIVILEGED,
3996    }, {
3997        .name = "rsr.dbreakc1",
3998        .translate = translate_rsr,
3999        .test_ill = test_ill_dbreak,
4000        .par = (const uint32_t[]){
4001            DBREAKC + 1,
4002            XTENSA_OPTION_DEBUG,
4003        },
4004        .op_flags = XTENSA_OP_PRIVILEGED,
4005    }, {
4006        .name = "rsr.ddr",
4007        .translate = translate_rsr,
4008        .test_ill = test_ill_sr,
4009        .par = (const uint32_t[]){
4010            DDR,
4011            XTENSA_OPTION_DEBUG,
4012        },
4013        .op_flags = XTENSA_OP_PRIVILEGED,
4014    }, {
4015        .name = "rsr.debugcause",
4016        .translate = translate_rsr,
4017        .test_ill = test_ill_sr,
4018        .par = (const uint32_t[]){
4019            DEBUGCAUSE,
4020            XTENSA_OPTION_DEBUG,
4021        },
4022        .op_flags = XTENSA_OP_PRIVILEGED,
4023    }, {
4024        .name = "rsr.depc",
4025        .translate = translate_rsr,
4026        .test_ill = test_ill_sr,
4027        .par = (const uint32_t[]){
4028            DEPC,
4029            XTENSA_OPTION_EXCEPTION,
4030        },
4031        .op_flags = XTENSA_OP_PRIVILEGED,
4032    }, {
4033        .name = "rsr.dtlbcfg",
4034        .translate = translate_rsr,
4035        .test_ill = test_ill_sr,
4036        .par = (const uint32_t[]){
4037            DTLBCFG,
4038            XTENSA_OPTION_MMU,
4039        },
4040        .op_flags = XTENSA_OP_PRIVILEGED,
4041    }, {
4042        .name = "rsr.epc1",
4043        .translate = translate_rsr,
4044        .test_ill = test_ill_sr,
4045        .par = (const uint32_t[]){
4046            EPC1,
4047            XTENSA_OPTION_EXCEPTION,
4048        },
4049        .op_flags = XTENSA_OP_PRIVILEGED,
4050    }, {
4051        .name = "rsr.epc2",
4052        .translate = translate_rsr,
4053        .test_ill = test_ill_hpi,
4054        .par = (const uint32_t[]){
4055            EPC1 + 1,
4056            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4057        },
4058        .op_flags = XTENSA_OP_PRIVILEGED,
4059    }, {
4060        .name = "rsr.epc3",
4061        .translate = translate_rsr,
4062        .test_ill = test_ill_hpi,
4063        .par = (const uint32_t[]){
4064            EPC1 + 2,
4065            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4066        },
4067        .op_flags = XTENSA_OP_PRIVILEGED,
4068    }, {
4069        .name = "rsr.epc4",
4070        .translate = translate_rsr,
4071        .test_ill = test_ill_hpi,
4072        .par = (const uint32_t[]){
4073            EPC1 + 3,
4074            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4075        },
4076        .op_flags = XTENSA_OP_PRIVILEGED,
4077    }, {
4078        .name = "rsr.epc5",
4079        .translate = translate_rsr,
4080        .test_ill = test_ill_hpi,
4081        .par = (const uint32_t[]){
4082            EPC1 + 4,
4083            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4084        },
4085        .op_flags = XTENSA_OP_PRIVILEGED,
4086    }, {
4087        .name = "rsr.epc6",
4088        .translate = translate_rsr,
4089        .test_ill = test_ill_hpi,
4090        .par = (const uint32_t[]){
4091            EPC1 + 5,
4092            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4093        },
4094        .op_flags = XTENSA_OP_PRIVILEGED,
4095    }, {
4096        .name = "rsr.epc7",
4097        .translate = translate_rsr,
4098        .test_ill = test_ill_hpi,
4099        .par = (const uint32_t[]){
4100            EPC1 + 6,
4101            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4102        },
4103        .op_flags = XTENSA_OP_PRIVILEGED,
4104    }, {
4105        .name = "rsr.eps2",
4106        .translate = translate_rsr,
4107        .test_ill = test_ill_hpi,
4108        .par = (const uint32_t[]){
4109            EPS2,
4110            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4111        },
4112        .op_flags = XTENSA_OP_PRIVILEGED,
4113    }, {
4114        .name = "rsr.eps3",
4115        .translate = translate_rsr,
4116        .test_ill = test_ill_hpi,
4117        .par = (const uint32_t[]){
4118            EPS2 + 1,
4119            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4120        },
4121        .op_flags = XTENSA_OP_PRIVILEGED,
4122    }, {
4123        .name = "rsr.eps4",
4124        .translate = translate_rsr,
4125        .test_ill = test_ill_hpi,
4126        .par = (const uint32_t[]){
4127            EPS2 + 2,
4128            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4129        },
4130        .op_flags = XTENSA_OP_PRIVILEGED,
4131    }, {
4132        .name = "rsr.eps5",
4133        .translate = translate_rsr,
4134        .test_ill = test_ill_hpi,
4135        .par = (const uint32_t[]){
4136            EPS2 + 3,
4137            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4138        },
4139        .op_flags = XTENSA_OP_PRIVILEGED,
4140    }, {
4141        .name = "rsr.eps6",
4142        .translate = translate_rsr,
4143        .test_ill = test_ill_hpi,
4144        .par = (const uint32_t[]){
4145            EPS2 + 4,
4146            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4147        },
4148        .op_flags = XTENSA_OP_PRIVILEGED,
4149    }, {
4150        .name = "rsr.eps7",
4151        .translate = translate_rsr,
4152        .test_ill = test_ill_hpi,
4153        .par = (const uint32_t[]){
4154            EPS2 + 5,
4155            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4156        },
4157        .op_flags = XTENSA_OP_PRIVILEGED,
4158    }, {
4159        .name = "rsr.eraccess",
4160        .translate = translate_rsr,
4161        .par = (const uint32_t[]){ERACCESS},
4162        .op_flags = XTENSA_OP_PRIVILEGED,
4163    }, {
4164        .name = "rsr.exccause",
4165        .translate = translate_rsr,
4166        .test_ill = test_ill_sr,
4167        .par = (const uint32_t[]){
4168            EXCCAUSE,
4169            XTENSA_OPTION_EXCEPTION,
4170        },
4171        .op_flags = XTENSA_OP_PRIVILEGED,
4172    }, {
4173        .name = "rsr.excsave1",
4174        .translate = translate_rsr,
4175        .test_ill = test_ill_sr,
4176        .par = (const uint32_t[]){
4177            EXCSAVE1,
4178            XTENSA_OPTION_EXCEPTION,
4179        },
4180        .op_flags = XTENSA_OP_PRIVILEGED,
4181    }, {
4182        .name = "rsr.excsave2",
4183        .translate = translate_rsr,
4184        .test_ill = test_ill_hpi,
4185        .par = (const uint32_t[]){
4186            EXCSAVE1 + 1,
4187            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4188        },
4189        .op_flags = XTENSA_OP_PRIVILEGED,
4190    }, {
4191        .name = "rsr.excsave3",
4192        .translate = translate_rsr,
4193        .test_ill = test_ill_hpi,
4194        .par = (const uint32_t[]){
4195            EXCSAVE1 + 2,
4196            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4197        },
4198        .op_flags = XTENSA_OP_PRIVILEGED,
4199    }, {
4200        .name = "rsr.excsave4",
4201        .translate = translate_rsr,
4202        .test_ill = test_ill_hpi,
4203        .par = (const uint32_t[]){
4204            EXCSAVE1 + 3,
4205            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4206        },
4207        .op_flags = XTENSA_OP_PRIVILEGED,
4208    }, {
4209        .name = "rsr.excsave5",
4210        .translate = translate_rsr,
4211        .test_ill = test_ill_hpi,
4212        .par = (const uint32_t[]){
4213            EXCSAVE1 + 4,
4214            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4215        },
4216        .op_flags = XTENSA_OP_PRIVILEGED,
4217    }, {
4218        .name = "rsr.excsave6",
4219        .translate = translate_rsr,
4220        .test_ill = test_ill_hpi,
4221        .par = (const uint32_t[]){
4222            EXCSAVE1 + 5,
4223            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4224        },
4225        .op_flags = XTENSA_OP_PRIVILEGED,
4226    }, {
4227        .name = "rsr.excsave7",
4228        .translate = translate_rsr,
4229        .test_ill = test_ill_hpi,
4230        .par = (const uint32_t[]){
4231            EXCSAVE1 + 6,
4232            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4233        },
4234        .op_flags = XTENSA_OP_PRIVILEGED,
4235    }, {
4236        .name = "rsr.excvaddr",
4237        .translate = translate_rsr,
4238        .test_ill = test_ill_sr,
4239        .par = (const uint32_t[]){
4240            EXCVADDR,
4241            XTENSA_OPTION_EXCEPTION,
4242        },
4243        .op_flags = XTENSA_OP_PRIVILEGED,
4244    }, {
4245        .name = "rsr.ibreaka0",
4246        .translate = translate_rsr,
4247        .test_ill = test_ill_ibreak,
4248        .par = (const uint32_t[]){
4249            IBREAKA,
4250            XTENSA_OPTION_DEBUG,
4251        },
4252        .op_flags = XTENSA_OP_PRIVILEGED,
4253    }, {
4254        .name = "rsr.ibreaka1",
4255        .translate = translate_rsr,
4256        .test_ill = test_ill_ibreak,
4257        .par = (const uint32_t[]){
4258            IBREAKA + 1,
4259            XTENSA_OPTION_DEBUG,
4260        },
4261        .op_flags = XTENSA_OP_PRIVILEGED,
4262    }, {
4263        .name = "rsr.ibreakenable",
4264        .translate = translate_rsr,
4265        .test_ill = test_ill_sr,
4266        .par = (const uint32_t[]){
4267            IBREAKENABLE,
4268            XTENSA_OPTION_DEBUG,
4269        },
4270        .op_flags = XTENSA_OP_PRIVILEGED,
4271    }, {
4272        .name = "rsr.icount",
4273        .translate = translate_rsr,
4274        .test_ill = test_ill_sr,
4275        .par = (const uint32_t[]){
4276            ICOUNT,
4277            XTENSA_OPTION_DEBUG,
4278        },
4279        .op_flags = XTENSA_OP_PRIVILEGED,
4280    }, {
4281        .name = "rsr.icountlevel",
4282        .translate = translate_rsr,
4283        .test_ill = test_ill_sr,
4284        .par = (const uint32_t[]){
4285            ICOUNTLEVEL,
4286            XTENSA_OPTION_DEBUG,
4287        },
4288        .op_flags = XTENSA_OP_PRIVILEGED,
4289    }, {
4290        .name = "rsr.intclear",
4291        .translate = translate_rsr,
4292        .test_ill = test_ill_sr,
4293        .par = (const uint32_t[]){
4294            INTCLEAR,
4295            XTENSA_OPTION_INTERRUPT,
4296        },
4297        .op_flags = XTENSA_OP_PRIVILEGED,
4298    }, {
4299        .name = "rsr.intenable",
4300        .translate = translate_rsr,
4301        .test_ill = test_ill_sr,
4302        .par = (const uint32_t[]){
4303            INTENABLE,
4304            XTENSA_OPTION_INTERRUPT,
4305        },
4306        .op_flags = XTENSA_OP_PRIVILEGED,
4307    }, {
4308        .name = "rsr.interrupt",
4309        .translate = translate_rsr_ccount,
4310        .test_ill = test_ill_sr,
4311        .par = (const uint32_t[]){
4312            INTSET,
4313            XTENSA_OPTION_INTERRUPT,
4314        },
4315        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
4316    }, {
4317        .name = "rsr.intset",
4318        .translate = translate_rsr_ccount,
4319        .test_ill = test_ill_sr,
4320        .par = (const uint32_t[]){
4321            INTSET,
4322            XTENSA_OPTION_INTERRUPT,
4323        },
4324        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
4325    }, {
4326        .name = "rsr.itlbcfg",
4327        .translate = translate_rsr,
4328        .test_ill = test_ill_sr,
4329        .par = (const uint32_t[]){
4330            ITLBCFG,
4331            XTENSA_OPTION_MMU,
4332        },
4333        .op_flags = XTENSA_OP_PRIVILEGED,
4334    }, {
4335        .name = "rsr.lbeg",
4336        .translate = translate_rsr,
4337        .test_ill = test_ill_sr,
4338        .par = (const uint32_t[]){
4339            LBEG,
4340            XTENSA_OPTION_LOOP,
4341        },
4342    }, {
4343        .name = "rsr.lcount",
4344        .translate = translate_rsr,
4345        .test_ill = test_ill_sr,
4346        .par = (const uint32_t[]){
4347            LCOUNT,
4348            XTENSA_OPTION_LOOP,
4349        },
4350    }, {
4351        .name = "rsr.lend",
4352        .translate = translate_rsr,
4353        .test_ill = test_ill_sr,
4354        .par = (const uint32_t[]){
4355            LEND,
4356            XTENSA_OPTION_LOOP,
4357        },
4358    }, {
4359        .name = "rsr.litbase",
4360        .translate = translate_rsr,
4361        .test_ill = test_ill_sr,
4362        .par = (const uint32_t[]){
4363            LITBASE,
4364            XTENSA_OPTION_EXTENDED_L32R,
4365        },
4366    }, {
4367        .name = "rsr.m0",
4368        .translate = translate_rsr,
4369        .test_ill = test_ill_sr,
4370        .par = (const uint32_t[]){
4371            MR,
4372            XTENSA_OPTION_MAC16,
4373        },
4374    }, {
4375        .name = "rsr.m1",
4376        .translate = translate_rsr,
4377        .test_ill = test_ill_sr,
4378        .par = (const uint32_t[]){
4379            MR + 1,
4380            XTENSA_OPTION_MAC16,
4381        },
4382    }, {
4383        .name = "rsr.m2",
4384        .translate = translate_rsr,
4385        .test_ill = test_ill_sr,
4386        .par = (const uint32_t[]){
4387            MR + 2,
4388            XTENSA_OPTION_MAC16,
4389        },
4390    }, {
4391        .name = "rsr.m3",
4392        .translate = translate_rsr,
4393        .test_ill = test_ill_sr,
4394        .par = (const uint32_t[]){
4395            MR + 3,
4396            XTENSA_OPTION_MAC16,
4397        },
4398    }, {
4399        .name = "rsr.memctl",
4400        .translate = translate_rsr,
4401        .par = (const uint32_t[]){MEMCTL},
4402        .op_flags = XTENSA_OP_PRIVILEGED,
4403    }, {
4404        .name = "rsr.mecr",
4405        .translate = translate_rsr,
4406        .test_ill = test_ill_sr,
4407        .par = (const uint32_t[]){
4408            MECR,
4409            XTENSA_OPTION_MEMORY_ECC_PARITY,
4410        },
4411        .op_flags = XTENSA_OP_PRIVILEGED,
4412    }, {
4413        .name = "rsr.mepc",
4414        .translate = translate_rsr,
4415        .test_ill = test_ill_sr,
4416        .par = (const uint32_t[]){
4417            MEPC,
4418            XTENSA_OPTION_MEMORY_ECC_PARITY,
4419        },
4420        .op_flags = XTENSA_OP_PRIVILEGED,
4421    }, {
4422        .name = "rsr.meps",
4423        .translate = translate_rsr,
4424        .test_ill = test_ill_sr,
4425        .par = (const uint32_t[]){
4426            MEPS,
4427            XTENSA_OPTION_MEMORY_ECC_PARITY,
4428        },
4429        .op_flags = XTENSA_OP_PRIVILEGED,
4430    }, {
4431        .name = "rsr.mesave",
4432        .translate = translate_rsr,
4433        .test_ill = test_ill_sr,
4434        .par = (const uint32_t[]){
4435            MESAVE,
4436            XTENSA_OPTION_MEMORY_ECC_PARITY,
4437        },
4438        .op_flags = XTENSA_OP_PRIVILEGED,
4439    }, {
4440        .name = "rsr.mesr",
4441        .translate = translate_rsr,
4442        .test_ill = test_ill_sr,
4443        .par = (const uint32_t[]){
4444            MESR,
4445            XTENSA_OPTION_MEMORY_ECC_PARITY,
4446        },
4447        .op_flags = XTENSA_OP_PRIVILEGED,
4448    }, {
4449        .name = "rsr.mevaddr",
4450        .translate = translate_rsr,
4451        .test_ill = test_ill_sr,
4452        .par = (const uint32_t[]){
4453            MESR,
4454            XTENSA_OPTION_MEMORY_ECC_PARITY,
4455        },
4456        .op_flags = XTENSA_OP_PRIVILEGED,
4457    }, {
4458        .name = "rsr.misc0",
4459        .translate = translate_rsr,
4460        .test_ill = test_ill_sr,
4461        .par = (const uint32_t[]){
4462            MISC,
4463            XTENSA_OPTION_MISC_SR,
4464        },
4465        .op_flags = XTENSA_OP_PRIVILEGED,
4466    }, {
4467        .name = "rsr.misc1",
4468        .translate = translate_rsr,
4469        .test_ill = test_ill_sr,
4470        .par = (const uint32_t[]){
4471            MISC + 1,
4472            XTENSA_OPTION_MISC_SR,
4473        },
4474        .op_flags = XTENSA_OP_PRIVILEGED,
4475    }, {
4476        .name = "rsr.misc2",
4477        .translate = translate_rsr,
4478        .test_ill = test_ill_sr,
4479        .par = (const uint32_t[]){
4480            MISC + 2,
4481            XTENSA_OPTION_MISC_SR,
4482        },
4483        .op_flags = XTENSA_OP_PRIVILEGED,
4484    }, {
4485        .name = "rsr.misc3",
4486        .translate = translate_rsr,
4487        .test_ill = test_ill_sr,
4488        .par = (const uint32_t[]){
4489            MISC + 3,
4490            XTENSA_OPTION_MISC_SR,
4491        },
4492        .op_flags = XTENSA_OP_PRIVILEGED,
4493    }, {
4494        .name = "rsr.mpucfg",
4495        .translate = translate_rsr,
4496        .test_ill = test_ill_sr,
4497        .par = (const uint32_t[]){
4498            MPUCFG,
4499            XTENSA_OPTION_MPU,
4500        },
4501        .op_flags = XTENSA_OP_PRIVILEGED,
4502    }, {
4503        .name = "rsr.mpuenb",
4504        .translate = translate_rsr,
4505        .test_ill = test_ill_sr,
4506        .par = (const uint32_t[]){
4507            MPUENB,
4508            XTENSA_OPTION_MPU,
4509        },
4510        .op_flags = XTENSA_OP_PRIVILEGED,
4511    }, {
4512        .name = "rsr.prefctl",
4513        .translate = translate_rsr,
4514        .par = (const uint32_t[]){PREFCTL},
4515    }, {
4516        .name = "rsr.prid",
4517        .translate = translate_rsr,
4518        .test_ill = test_ill_sr,
4519        .par = (const uint32_t[]){
4520            PRID,
4521            XTENSA_OPTION_PROCESSOR_ID,
4522        },
4523        .op_flags = XTENSA_OP_PRIVILEGED,
4524    }, {
4525        .name = "rsr.ps",
4526        .translate = translate_rsr,
4527        .test_ill = test_ill_sr,
4528        .par = (const uint32_t[]){
4529            PS,
4530            XTENSA_OPTION_EXCEPTION,
4531        },
4532        .op_flags = XTENSA_OP_PRIVILEGED,
4533    }, {
4534        .name = "rsr.ptevaddr",
4535        .translate = translate_rsr_ptevaddr,
4536        .test_ill = test_ill_sr,
4537        .par = (const uint32_t[]){
4538            PTEVADDR,
4539            XTENSA_OPTION_MMU,
4540        },
4541        .op_flags = XTENSA_OP_PRIVILEGED,
4542    }, {
4543        .name = "rsr.rasid",
4544        .translate = translate_rsr,
4545        .test_ill = test_ill_sr,
4546        .par = (const uint32_t[]){
4547            RASID,
4548            XTENSA_OPTION_MMU,
4549        },
4550        .op_flags = XTENSA_OP_PRIVILEGED,
4551    }, {
4552        .name = "rsr.sar",
4553        .translate = translate_rsr,
4554        .par = (const uint32_t[]){SAR},
4555    }, {
4556        .name = "rsr.scompare1",
4557        .translate = translate_rsr,
4558        .test_ill = test_ill_sr,
4559        .par = (const uint32_t[]){
4560            SCOMPARE1,
4561            XTENSA_OPTION_CONDITIONAL_STORE,
4562        },
4563    }, {
4564        .name = "rsr.vecbase",
4565        .translate = translate_rsr,
4566        .test_ill = test_ill_sr,
4567        .par = (const uint32_t[]){
4568            VECBASE,
4569            XTENSA_OPTION_RELOCATABLE_VECTOR,
4570        },
4571        .op_flags = XTENSA_OP_PRIVILEGED,
4572    }, {
4573        .name = "rsr.windowbase",
4574        .translate = translate_rsr,
4575        .test_ill = test_ill_sr,
4576        .par = (const uint32_t[]){
4577            WINDOW_BASE,
4578            XTENSA_OPTION_WINDOWED_REGISTER,
4579        },
4580        .op_flags = XTENSA_OP_PRIVILEGED,
4581    }, {
4582        .name = "rsr.windowstart",
4583        .translate = translate_rsr,
4584        .test_ill = test_ill_sr,
4585        .par = (const uint32_t[]){
4586            WINDOW_START,
4587            XTENSA_OPTION_WINDOWED_REGISTER,
4588        },
4589        .op_flags = XTENSA_OP_PRIVILEGED,
4590    }, {
4591        .name = "rsync",
4592        .translate = translate_nop,
4593    }, {
4594        .name = "rur.expstate",
4595        .translate = translate_rur,
4596        .par = (const uint32_t[]){EXPSTATE},
4597    }, {
4598        .name = "rur.fcr",
4599        .translate = translate_rur,
4600        .par = (const uint32_t[]){FCR},
4601        .coprocessor = 0x1,
4602    }, {
4603        .name = "rur.fsr",
4604        .translate = translate_rur,
4605        .par = (const uint32_t[]){FSR},
4606        .coprocessor = 0x1,
4607    }, {
4608        .name = "rur.threadptr",
4609        .translate = translate_rur,
4610        .par = (const uint32_t[]){THREADPTR},
4611    }, {
4612        .name = "s16i",
4613        .translate = translate_ldst,
4614        .par = (const uint32_t[]){MO_TEUW, false, true},
4615        .op_flags = XTENSA_OP_STORE,
4616    }, {
4617        .name = "s32c1i",
4618        .translate = translate_s32c1i,
4619        .op_flags = XTENSA_OP_LOAD | XTENSA_OP_STORE,
4620    }, {
4621        .name = "s32e",
4622        .translate = translate_s32e,
4623        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_STORE,
4624    }, {
4625        .name = "s32ex",
4626        .translate = translate_s32ex,
4627        .op_flags = XTENSA_OP_LOAD | XTENSA_OP_STORE,
4628    }, {
4629        .name = (const char * const[]) {
4630            "s32i", "s32i.n", "s32nb", NULL,
4631        },
4632        .translate = translate_ldst,
4633        .par = (const uint32_t[]){MO_TEUL, false, true},
4634        .op_flags = XTENSA_OP_NAME_ARRAY | XTENSA_OP_STORE,
4635    }, {
4636        .name = "s32ri",
4637        .translate = translate_ldst,
4638        .par = (const uint32_t[]){MO_TEUL, true, true},
4639        .op_flags = XTENSA_OP_STORE,
4640    }, {
4641        .name = "s8i",
4642        .translate = translate_ldst,
4643        .par = (const uint32_t[]){MO_UB, false, true},
4644        .op_flags = XTENSA_OP_STORE,
4645    }, {
4646        .name = "salt",
4647        .translate = translate_salt,
4648        .par = (const uint32_t[]){TCG_COND_LT},
4649    }, {
4650        .name = "saltu",
4651        .translate = translate_salt,
4652        .par = (const uint32_t[]){TCG_COND_LTU},
4653    }, {
4654        .name = "setb_expstate",
4655        .translate = translate_setb_expstate,
4656    }, {
4657        .name = "sext",
4658        .translate = translate_sext,
4659    }, {
4660        .name = "simcall",
4661        .translate = translate_simcall,
4662        .test_ill = test_ill_simcall,
4663        .op_flags = XTENSA_OP_PRIVILEGED,
4664    }, {
4665        .name = "sll",
4666        .translate = translate_sll,
4667    }, {
4668        .name = "slli",
4669        .translate = translate_slli,
4670    }, {
4671        .name = "sra",
4672        .translate = translate_sra,
4673    }, {
4674        .name = "srai",
4675        .translate = translate_srai,
4676    }, {
4677        .name = "src",
4678        .translate = translate_src,
4679    }, {
4680        .name = "srl",
4681        .translate = translate_srl,
4682    }, {
4683        .name = "srli",
4684        .translate = translate_srli,
4685    }, {
4686        .name = "ssa8b",
4687        .translate = translate_ssa8b,
4688    }, {
4689        .name = "ssa8l",
4690        .translate = translate_ssa8l,
4691    }, {
4692        .name = "ssai",
4693        .translate = translate_ssai,
4694    }, {
4695        .name = "ssl",
4696        .translate = translate_ssl,
4697    }, {
4698        .name = "ssr",
4699        .translate = translate_ssr,
4700    }, {
4701        .name = "sub",
4702        .translate = translate_sub,
4703    }, {
4704        .name = "subx2",
4705        .translate = translate_subx,
4706        .par = (const uint32_t[]){1},
4707    }, {
4708        .name = "subx4",
4709        .translate = translate_subx,
4710        .par = (const uint32_t[]){2},
4711    }, {
4712        .name = "subx8",
4713        .translate = translate_subx,
4714        .par = (const uint32_t[]){3},
4715    }, {
4716        .name = "syscall",
4717        .op_flags = XTENSA_OP_SYSCALL,
4718    }, {
4719        .name = "umul.aa.hh",
4720        .translate = translate_mac16,
4721        .par = (const uint32_t[]){MAC16_UMUL, MAC16_HH, 0},
4722    }, {
4723        .name = "umul.aa.hl",
4724        .translate = translate_mac16,
4725        .par = (const uint32_t[]){MAC16_UMUL, MAC16_HL, 0},
4726    }, {
4727        .name = "umul.aa.lh",
4728        .translate = translate_mac16,
4729        .par = (const uint32_t[]){MAC16_UMUL, MAC16_LH, 0},
4730    }, {
4731        .name = "umul.aa.ll",
4732        .translate = translate_mac16,
4733        .par = (const uint32_t[]){MAC16_UMUL, MAC16_LL, 0},
4734    }, {
4735        .name = "waiti",
4736        .translate = translate_waiti,
4737        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
4738    }, {
4739        .name = "wdtlb",
4740        .translate = translate_wtlb,
4741        .par = (const uint32_t[]){true},
4742        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
4743    }, {
4744        .name = "wer",
4745        .translate = translate_wer,
4746        .op_flags = XTENSA_OP_PRIVILEGED,
4747    }, {
4748        .name = "witlb",
4749        .translate = translate_wtlb,
4750        .par = (const uint32_t[]){false},
4751        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
4752    }, {
4753        .name = "wptlb",
4754        .translate = translate_wptlb,
4755        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
4756    }, {
4757        .name = "wrmsk_expstate",
4758        .translate = translate_wrmsk_expstate,
4759    }, {
4760        .name = "wsr.176",
4761        .op_flags = XTENSA_OP_ILL,
4762    }, {
4763        .name = "wsr.208",
4764        .op_flags = XTENSA_OP_ILL,
4765    }, {
4766        .name = "wsr.acchi",
4767        .translate = translate_wsr_acchi,
4768        .test_ill = test_ill_sr,
4769        .par = (const uint32_t[]){
4770            ACCHI,
4771            XTENSA_OPTION_MAC16,
4772        },
4773    }, {
4774        .name = "wsr.acclo",
4775        .translate = translate_wsr,
4776        .test_ill = test_ill_sr,
4777        .par = (const uint32_t[]){
4778            ACCLO,
4779            XTENSA_OPTION_MAC16,
4780        },
4781    }, {
4782        .name = "wsr.atomctl",
4783        .translate = translate_wsr_mask,
4784        .test_ill = test_ill_sr,
4785        .par = (const uint32_t[]){
4786            ATOMCTL,
4787            XTENSA_OPTION_ATOMCTL,
4788            0x3f,
4789        },
4790        .op_flags = XTENSA_OP_PRIVILEGED,
4791    }, {
4792        .name = "wsr.br",
4793        .translate = translate_wsr_mask,
4794        .test_ill = test_ill_sr,
4795        .par = (const uint32_t[]){
4796            BR,
4797            XTENSA_OPTION_BOOLEAN,
4798            0xffff,
4799        },
4800    }, {
4801        .name = "wsr.cacheadrdis",
4802        .translate = translate_wsr_mask,
4803        .test_ill = test_ill_sr,
4804        .par = (const uint32_t[]){
4805            CACHEADRDIS,
4806            XTENSA_OPTION_MPU,
4807            0xff,
4808        },
4809        .op_flags = XTENSA_OP_PRIVILEGED,
4810    }, {
4811        .name = "wsr.cacheattr",
4812        .translate = translate_wsr,
4813        .test_ill = test_ill_sr,
4814        .par = (const uint32_t[]){
4815            CACHEATTR,
4816            XTENSA_OPTION_CACHEATTR,
4817        },
4818        .op_flags = XTENSA_OP_PRIVILEGED,
4819    }, {
4820        .name = "wsr.ccompare0",
4821        .translate = translate_wsr_ccompare,
4822        .test_ill = test_ill_ccompare,
4823        .par = (const uint32_t[]){
4824            CCOMPARE,
4825            XTENSA_OPTION_TIMER_INTERRUPT,
4826        },
4827        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
4828    }, {
4829        .name = "wsr.ccompare1",
4830        .translate = translate_wsr_ccompare,
4831        .test_ill = test_ill_ccompare,
4832        .par = (const uint32_t[]){
4833            CCOMPARE + 1,
4834            XTENSA_OPTION_TIMER_INTERRUPT,
4835        },
4836        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
4837    }, {
4838        .name = "wsr.ccompare2",
4839        .translate = translate_wsr_ccompare,
4840        .test_ill = test_ill_ccompare,
4841        .par = (const uint32_t[]){
4842            CCOMPARE + 2,
4843            XTENSA_OPTION_TIMER_INTERRUPT,
4844        },
4845        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
4846    }, {
4847        .name = "wsr.ccount",
4848        .translate = translate_wsr_ccount,
4849        .test_ill = test_ill_sr,
4850        .par = (const uint32_t[]){
4851            CCOUNT,
4852            XTENSA_OPTION_TIMER_INTERRUPT,
4853        },
4854        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
4855    }, {
4856        .name = "wsr.configid0",
4857        .op_flags = XTENSA_OP_ILL,
4858    }, {
4859        .name = "wsr.configid1",
4860        .op_flags = XTENSA_OP_ILL,
4861    }, {
4862        .name = "wsr.cpenable",
4863        .translate = translate_wsr_mask,
4864        .test_ill = test_ill_sr,
4865        .par = (const uint32_t[]){
4866            CPENABLE,
4867            XTENSA_OPTION_COPROCESSOR,
4868            0xff,
4869        },
4870        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
4871    }, {
4872        .name = "wsr.dbreaka0",
4873        .translate = translate_wsr_dbreaka,
4874        .test_ill = test_ill_dbreak,
4875        .par = (const uint32_t[]){
4876            DBREAKA,
4877            XTENSA_OPTION_DEBUG,
4878        },
4879        .op_flags = XTENSA_OP_PRIVILEGED,
4880    }, {
4881        .name = "wsr.dbreaka1",
4882        .translate = translate_wsr_dbreaka,
4883        .test_ill = test_ill_dbreak,
4884        .par = (const uint32_t[]){
4885            DBREAKA + 1,
4886            XTENSA_OPTION_DEBUG,
4887        },
4888        .op_flags = XTENSA_OP_PRIVILEGED,
4889    }, {
4890        .name = "wsr.dbreakc0",
4891        .translate = translate_wsr_dbreakc,
4892        .test_ill = test_ill_dbreak,
4893        .par = (const uint32_t[]){
4894            DBREAKC,
4895            XTENSA_OPTION_DEBUG,
4896        },
4897        .op_flags = XTENSA_OP_PRIVILEGED,
4898    }, {
4899        .name = "wsr.dbreakc1",
4900        .translate = translate_wsr_dbreakc,
4901        .test_ill = test_ill_dbreak,
4902        .par = (const uint32_t[]){
4903            DBREAKC + 1,
4904            XTENSA_OPTION_DEBUG,
4905        },
4906        .op_flags = XTENSA_OP_PRIVILEGED,
4907    }, {
4908        .name = "wsr.ddr",
4909        .translate = translate_wsr,
4910        .test_ill = test_ill_sr,
4911        .par = (const uint32_t[]){
4912            DDR,
4913            XTENSA_OPTION_DEBUG,
4914        },
4915        .op_flags = XTENSA_OP_PRIVILEGED,
4916    }, {
4917        .name = "wsr.debugcause",
4918        .op_flags = XTENSA_OP_ILL,
4919    }, {
4920        .name = "wsr.depc",
4921        .translate = translate_wsr,
4922        .test_ill = test_ill_sr,
4923        .par = (const uint32_t[]){
4924            DEPC,
4925            XTENSA_OPTION_EXCEPTION,
4926        },
4927        .op_flags = XTENSA_OP_PRIVILEGED,
4928    }, {
4929        .name = "wsr.dtlbcfg",
4930        .translate = translate_wsr_mask,
4931        .test_ill = test_ill_sr,
4932        .par = (const uint32_t[]){
4933            DTLBCFG,
4934            XTENSA_OPTION_MMU,
4935            0x01130000,
4936        },
4937        .op_flags = XTENSA_OP_PRIVILEGED,
4938    }, {
4939        .name = "wsr.epc1",
4940        .translate = translate_wsr,
4941        .test_ill = test_ill_sr,
4942        .par = (const uint32_t[]){
4943            EPC1,
4944            XTENSA_OPTION_EXCEPTION,
4945        },
4946        .op_flags = XTENSA_OP_PRIVILEGED,
4947    }, {
4948        .name = "wsr.epc2",
4949        .translate = translate_wsr,
4950        .test_ill = test_ill_hpi,
4951        .par = (const uint32_t[]){
4952            EPC1 + 1,
4953            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4954        },
4955        .op_flags = XTENSA_OP_PRIVILEGED,
4956    }, {
4957        .name = "wsr.epc3",
4958        .translate = translate_wsr,
4959        .test_ill = test_ill_hpi,
4960        .par = (const uint32_t[]){
4961            EPC1 + 2,
4962            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4963        },
4964        .op_flags = XTENSA_OP_PRIVILEGED,
4965    }, {
4966        .name = "wsr.epc4",
4967        .translate = translate_wsr,
4968        .test_ill = test_ill_hpi,
4969        .par = (const uint32_t[]){
4970            EPC1 + 3,
4971            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4972        },
4973        .op_flags = XTENSA_OP_PRIVILEGED,
4974    }, {
4975        .name = "wsr.epc5",
4976        .translate = translate_wsr,
4977        .test_ill = test_ill_hpi,
4978        .par = (const uint32_t[]){
4979            EPC1 + 4,
4980            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4981        },
4982        .op_flags = XTENSA_OP_PRIVILEGED,
4983    }, {
4984        .name = "wsr.epc6",
4985        .translate = translate_wsr,
4986        .test_ill = test_ill_hpi,
4987        .par = (const uint32_t[]){
4988            EPC1 + 5,
4989            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4990        },
4991        .op_flags = XTENSA_OP_PRIVILEGED,
4992    }, {
4993        .name = "wsr.epc7",
4994        .translate = translate_wsr,
4995        .test_ill = test_ill_hpi,
4996        .par = (const uint32_t[]){
4997            EPC1 + 6,
4998            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
4999        },
5000        .op_flags = XTENSA_OP_PRIVILEGED,
5001    }, {
5002        .name = "wsr.eps2",
5003        .translate = translate_wsr,
5004        .test_ill = test_ill_hpi,
5005        .par = (const uint32_t[]){
5006            EPS2,
5007            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5008        },
5009        .op_flags = XTENSA_OP_PRIVILEGED,
5010    }, {
5011        .name = "wsr.eps3",
5012        .translate = translate_wsr,
5013        .test_ill = test_ill_hpi,
5014        .par = (const uint32_t[]){
5015            EPS2 + 1,
5016            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5017        },
5018        .op_flags = XTENSA_OP_PRIVILEGED,
5019    }, {
5020        .name = "wsr.eps4",
5021        .translate = translate_wsr,
5022        .test_ill = test_ill_hpi,
5023        .par = (const uint32_t[]){
5024            EPS2 + 2,
5025            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5026        },
5027        .op_flags = XTENSA_OP_PRIVILEGED,
5028    }, {
5029        .name = "wsr.eps5",
5030        .translate = translate_wsr,
5031        .test_ill = test_ill_hpi,
5032        .par = (const uint32_t[]){
5033            EPS2 + 3,
5034            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5035        },
5036        .op_flags = XTENSA_OP_PRIVILEGED,
5037    }, {
5038        .name = "wsr.eps6",
5039        .translate = translate_wsr,
5040        .test_ill = test_ill_hpi,
5041        .par = (const uint32_t[]){
5042            EPS2 + 4,
5043            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5044        },
5045        .op_flags = XTENSA_OP_PRIVILEGED,
5046    }, {
5047        .name = "wsr.eps7",
5048        .translate = translate_wsr,
5049        .test_ill = test_ill_hpi,
5050        .par = (const uint32_t[]){
5051            EPS2 + 5,
5052            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5053        },
5054        .op_flags = XTENSA_OP_PRIVILEGED,
5055    }, {
5056        .name = "wsr.eraccess",
5057        .translate = translate_wsr_mask,
5058        .par = (const uint32_t[]){
5059            ERACCESS,
5060            0,
5061            0xffff,
5062        },
5063        .op_flags = XTENSA_OP_PRIVILEGED,
5064    }, {
5065        .name = "wsr.exccause",
5066        .translate = translate_wsr,
5067        .test_ill = test_ill_sr,
5068        .par = (const uint32_t[]){
5069            EXCCAUSE,
5070            XTENSA_OPTION_EXCEPTION,
5071        },
5072        .op_flags = XTENSA_OP_PRIVILEGED,
5073    }, {
5074        .name = "wsr.excsave1",
5075        .translate = translate_wsr,
5076        .test_ill = test_ill_sr,
5077        .par = (const uint32_t[]){
5078            EXCSAVE1,
5079            XTENSA_OPTION_EXCEPTION,
5080        },
5081        .op_flags = XTENSA_OP_PRIVILEGED,
5082    }, {
5083        .name = "wsr.excsave2",
5084        .translate = translate_wsr,
5085        .test_ill = test_ill_hpi,
5086        .par = (const uint32_t[]){
5087            EXCSAVE1 + 1,
5088            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5089        },
5090        .op_flags = XTENSA_OP_PRIVILEGED,
5091    }, {
5092        .name = "wsr.excsave3",
5093        .translate = translate_wsr,
5094        .test_ill = test_ill_hpi,
5095        .par = (const uint32_t[]){
5096            EXCSAVE1 + 2,
5097            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5098        },
5099        .op_flags = XTENSA_OP_PRIVILEGED,
5100    }, {
5101        .name = "wsr.excsave4",
5102        .translate = translate_wsr,
5103        .test_ill = test_ill_hpi,
5104        .par = (const uint32_t[]){
5105            EXCSAVE1 + 3,
5106            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5107        },
5108        .op_flags = XTENSA_OP_PRIVILEGED,
5109    }, {
5110        .name = "wsr.excsave5",
5111        .translate = translate_wsr,
5112        .test_ill = test_ill_hpi,
5113        .par = (const uint32_t[]){
5114            EXCSAVE1 + 4,
5115            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5116        },
5117        .op_flags = XTENSA_OP_PRIVILEGED,
5118    }, {
5119        .name = "wsr.excsave6",
5120        .translate = translate_wsr,
5121        .test_ill = test_ill_hpi,
5122        .par = (const uint32_t[]){
5123            EXCSAVE1 + 5,
5124            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5125        },
5126        .op_flags = XTENSA_OP_PRIVILEGED,
5127    }, {
5128        .name = "wsr.excsave7",
5129        .translate = translate_wsr,
5130        .test_ill = test_ill_hpi,
5131        .par = (const uint32_t[]){
5132            EXCSAVE1 + 6,
5133            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5134        },
5135        .op_flags = XTENSA_OP_PRIVILEGED,
5136    }, {
5137        .name = "wsr.excvaddr",
5138        .translate = translate_wsr,
5139        .test_ill = test_ill_sr,
5140        .par = (const uint32_t[]){
5141            EXCVADDR,
5142            XTENSA_OPTION_EXCEPTION,
5143        },
5144        .op_flags = XTENSA_OP_PRIVILEGED,
5145    }, {
5146        .name = "wsr.ibreaka0",
5147        .translate = translate_wsr_ibreaka,
5148        .test_ill = test_ill_ibreak,
5149        .par = (const uint32_t[]){
5150            IBREAKA,
5151            XTENSA_OPTION_DEBUG,
5152        },
5153        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5154    }, {
5155        .name = "wsr.ibreaka1",
5156        .translate = translate_wsr_ibreaka,
5157        .test_ill = test_ill_ibreak,
5158        .par = (const uint32_t[]){
5159            IBREAKA + 1,
5160            XTENSA_OPTION_DEBUG,
5161        },
5162        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5163    }, {
5164        .name = "wsr.ibreakenable",
5165        .translate = translate_wsr_ibreakenable,
5166        .test_ill = test_ill_sr,
5167        .par = (const uint32_t[]){
5168            IBREAKENABLE,
5169            XTENSA_OPTION_DEBUG,
5170        },
5171        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5172    }, {
5173        .name = "wsr.icount",
5174        .translate = translate_wsr_icount,
5175        .test_ill = test_ill_sr,
5176        .par = (const uint32_t[]){
5177            ICOUNT,
5178            XTENSA_OPTION_DEBUG,
5179        },
5180        .op_flags = XTENSA_OP_PRIVILEGED,
5181    }, {
5182        .name = "wsr.icountlevel",
5183        .translate = translate_wsr_mask,
5184        .test_ill = test_ill_sr,
5185        .par = (const uint32_t[]){
5186            ICOUNTLEVEL,
5187            XTENSA_OPTION_DEBUG,
5188            0xf,
5189        },
5190        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
5191    }, {
5192        .name = "wsr.intclear",
5193        .translate = translate_wsr_intclear,
5194        .test_ill = test_ill_sr,
5195        .par = (const uint32_t[]){
5196            INTCLEAR,
5197            XTENSA_OPTION_INTERRUPT,
5198        },
5199        .op_flags =
5200            XTENSA_OP_PRIVILEGED |
5201            XTENSA_OP_EXIT_TB_0 |
5202            XTENSA_OP_CHECK_INTERRUPTS,
5203    }, {
5204        .name = "wsr.intenable",
5205        .translate = translate_wsr,
5206        .test_ill = test_ill_sr,
5207        .par = (const uint32_t[]){
5208            INTENABLE,
5209            XTENSA_OPTION_INTERRUPT,
5210        },
5211        .op_flags =
5212            XTENSA_OP_PRIVILEGED |
5213            XTENSA_OP_EXIT_TB_0 |
5214            XTENSA_OP_CHECK_INTERRUPTS,
5215    }, {
5216        .name = "wsr.interrupt",
5217        .translate = translate_wsr,
5218        .test_ill = test_ill_sr,
5219        .par = (const uint32_t[]){
5220            INTSET,
5221            XTENSA_OPTION_INTERRUPT,
5222        },
5223        .op_flags =
5224            XTENSA_OP_PRIVILEGED |
5225            XTENSA_OP_EXIT_TB_0 |
5226            XTENSA_OP_CHECK_INTERRUPTS,
5227    }, {
5228        .name = "wsr.intset",
5229        .translate = translate_wsr_intset,
5230        .test_ill = test_ill_sr,
5231        .par = (const uint32_t[]){
5232            INTSET,
5233            XTENSA_OPTION_INTERRUPT,
5234        },
5235        .op_flags =
5236            XTENSA_OP_PRIVILEGED |
5237            XTENSA_OP_EXIT_TB_0 |
5238            XTENSA_OP_CHECK_INTERRUPTS,
5239    }, {
5240        .name = "wsr.itlbcfg",
5241        .translate = translate_wsr_mask,
5242        .test_ill = test_ill_sr,
5243        .par = (const uint32_t[]){
5244            ITLBCFG,
5245            XTENSA_OPTION_MMU,
5246            0x01130000,
5247        },
5248        .op_flags = XTENSA_OP_PRIVILEGED,
5249    }, {
5250        .name = "wsr.lbeg",
5251        .translate = translate_wsr,
5252        .test_ill = test_ill_sr,
5253        .par = (const uint32_t[]){
5254            LBEG,
5255            XTENSA_OPTION_LOOP,
5256        },
5257        .op_flags = XTENSA_OP_EXIT_TB_M1,
5258    }, {
5259        .name = "wsr.lcount",
5260        .translate = translate_wsr,
5261        .test_ill = test_ill_sr,
5262        .par = (const uint32_t[]){
5263            LCOUNT,
5264            XTENSA_OPTION_LOOP,
5265        },
5266    }, {
5267        .name = "wsr.lend",
5268        .translate = translate_wsr,
5269        .test_ill = test_ill_sr,
5270        .par = (const uint32_t[]){
5271            LEND,
5272            XTENSA_OPTION_LOOP,
5273        },
5274        .op_flags = XTENSA_OP_EXIT_TB_M1,
5275    }, {
5276        .name = "wsr.litbase",
5277        .translate = translate_wsr_mask,
5278        .test_ill = test_ill_sr,
5279        .par = (const uint32_t[]){
5280            LITBASE,
5281            XTENSA_OPTION_EXTENDED_L32R,
5282            0xfffff001,
5283        },
5284        .op_flags = XTENSA_OP_EXIT_TB_M1,
5285    }, {
5286        .name = "wsr.m0",
5287        .translate = translate_wsr,
5288        .test_ill = test_ill_sr,
5289        .par = (const uint32_t[]){
5290            MR,
5291            XTENSA_OPTION_MAC16,
5292        },
5293    }, {
5294        .name = "wsr.m1",
5295        .translate = translate_wsr,
5296        .test_ill = test_ill_sr,
5297        .par = (const uint32_t[]){
5298            MR + 1,
5299            XTENSA_OPTION_MAC16,
5300        },
5301    }, {
5302        .name = "wsr.m2",
5303        .translate = translate_wsr,
5304        .test_ill = test_ill_sr,
5305        .par = (const uint32_t[]){
5306            MR + 2,
5307            XTENSA_OPTION_MAC16,
5308        },
5309    }, {
5310        .name = "wsr.m3",
5311        .translate = translate_wsr,
5312        .test_ill = test_ill_sr,
5313        .par = (const uint32_t[]){
5314            MR + 3,
5315            XTENSA_OPTION_MAC16,
5316        },
5317    }, {
5318        .name = "wsr.memctl",
5319        .translate = translate_wsr_memctl,
5320        .par = (const uint32_t[]){MEMCTL},
5321        .op_flags = XTENSA_OP_PRIVILEGED,
5322    }, {
5323        .name = "wsr.mecr",
5324        .translate = translate_wsr,
5325        .test_ill = test_ill_sr,
5326        .par = (const uint32_t[]){
5327            MECR,
5328            XTENSA_OPTION_MEMORY_ECC_PARITY,
5329        },
5330        .op_flags = XTENSA_OP_PRIVILEGED,
5331    }, {
5332        .name = "wsr.mepc",
5333        .translate = translate_wsr,
5334        .test_ill = test_ill_sr,
5335        .par = (const uint32_t[]){
5336            MEPC,
5337            XTENSA_OPTION_MEMORY_ECC_PARITY,
5338        },
5339        .op_flags = XTENSA_OP_PRIVILEGED,
5340    }, {
5341        .name = "wsr.meps",
5342        .translate = translate_wsr,
5343        .test_ill = test_ill_sr,
5344        .par = (const uint32_t[]){
5345            MEPS,
5346            XTENSA_OPTION_MEMORY_ECC_PARITY,
5347        },
5348        .op_flags = XTENSA_OP_PRIVILEGED,
5349    }, {
5350        .name = "wsr.mesave",
5351        .translate = translate_wsr,
5352        .test_ill = test_ill_sr,
5353        .par = (const uint32_t[]){
5354            MESAVE,
5355            XTENSA_OPTION_MEMORY_ECC_PARITY,
5356        },
5357        .op_flags = XTENSA_OP_PRIVILEGED,
5358    }, {
5359        .name = "wsr.mesr",
5360        .translate = translate_wsr,
5361        .test_ill = test_ill_sr,
5362        .par = (const uint32_t[]){
5363            MESR,
5364            XTENSA_OPTION_MEMORY_ECC_PARITY,
5365        },
5366        .op_flags = XTENSA_OP_PRIVILEGED,
5367    }, {
5368        .name = "wsr.mevaddr",
5369        .translate = translate_wsr,
5370        .test_ill = test_ill_sr,
5371        .par = (const uint32_t[]){
5372            MESR,
5373            XTENSA_OPTION_MEMORY_ECC_PARITY,
5374        },
5375        .op_flags = XTENSA_OP_PRIVILEGED,
5376    }, {
5377        .name = "wsr.misc0",
5378        .translate = translate_wsr,
5379        .test_ill = test_ill_sr,
5380        .par = (const uint32_t[]){
5381            MISC,
5382            XTENSA_OPTION_MISC_SR,
5383        },
5384        .op_flags = XTENSA_OP_PRIVILEGED,
5385    }, {
5386        .name = "wsr.misc1",
5387        .translate = translate_wsr,
5388        .test_ill = test_ill_sr,
5389        .par = (const uint32_t[]){
5390            MISC + 1,
5391            XTENSA_OPTION_MISC_SR,
5392        },
5393        .op_flags = XTENSA_OP_PRIVILEGED,
5394    }, {
5395        .name = "wsr.misc2",
5396        .translate = translate_wsr,
5397        .test_ill = test_ill_sr,
5398        .par = (const uint32_t[]){
5399            MISC + 2,
5400            XTENSA_OPTION_MISC_SR,
5401        },
5402        .op_flags = XTENSA_OP_PRIVILEGED,
5403    }, {
5404        .name = "wsr.misc3",
5405        .translate = translate_wsr,
5406        .test_ill = test_ill_sr,
5407        .par = (const uint32_t[]){
5408            MISC + 3,
5409            XTENSA_OPTION_MISC_SR,
5410        },
5411        .op_flags = XTENSA_OP_PRIVILEGED,
5412    }, {
5413        .name = "wsr.mmid",
5414        .translate = translate_wsr,
5415        .test_ill = test_ill_sr,
5416        .par = (const uint32_t[]){
5417            MMID,
5418            XTENSA_OPTION_TRACE_PORT,
5419        },
5420        .op_flags = XTENSA_OP_PRIVILEGED,
5421    }, {
5422        .name = "wsr.mpuenb",
5423        .translate = translate_wsr_mpuenb,
5424        .test_ill = test_ill_sr,
5425        .par = (const uint32_t[]){
5426            MPUENB,
5427            XTENSA_OPTION_MPU,
5428        },
5429        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
5430    }, {
5431        .name = "wsr.prefctl",
5432        .translate = translate_wsr,
5433        .par = (const uint32_t[]){PREFCTL},
5434    }, {
5435        .name = "wsr.prid",
5436        .op_flags = XTENSA_OP_ILL,
5437    }, {
5438        .name = "wsr.ps",
5439        .translate = translate_wsr_ps,
5440        .test_ill = test_ill_sr,
5441        .par = (const uint32_t[]){
5442            PS,
5443            XTENSA_OPTION_EXCEPTION,
5444        },
5445        .op_flags =
5446            XTENSA_OP_PRIVILEGED |
5447            XTENSA_OP_EXIT_TB_M1 |
5448            XTENSA_OP_CHECK_INTERRUPTS,
5449    }, {
5450        .name = "wsr.ptevaddr",
5451        .translate = translate_wsr_mask,
5452        .test_ill = test_ill_sr,
5453        .par = (const uint32_t[]){
5454            PTEVADDR,
5455            XTENSA_OPTION_MMU,
5456            0xffc00000,
5457        },
5458        .op_flags = XTENSA_OP_PRIVILEGED,
5459    }, {
5460        .name = "wsr.rasid",
5461        .translate = translate_wsr_rasid,
5462        .test_ill = test_ill_sr,
5463        .par = (const uint32_t[]){
5464            RASID,
5465            XTENSA_OPTION_MMU,
5466        },
5467        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
5468    }, {
5469        .name = "wsr.sar",
5470        .translate = translate_wsr_sar,
5471        .par = (const uint32_t[]){SAR},
5472    }, {
5473        .name = "wsr.scompare1",
5474        .translate = translate_wsr,
5475        .test_ill = test_ill_sr,
5476        .par = (const uint32_t[]){
5477            SCOMPARE1,
5478            XTENSA_OPTION_CONDITIONAL_STORE,
5479        },
5480    }, {
5481        .name = "wsr.vecbase",
5482        .translate = translate_wsr,
5483        .test_ill = test_ill_sr,
5484        .par = (const uint32_t[]){
5485            VECBASE,
5486            XTENSA_OPTION_RELOCATABLE_VECTOR,
5487        },
5488        .op_flags = XTENSA_OP_PRIVILEGED,
5489    }, {
5490        .name = "wsr.windowbase",
5491        .translate = translate_wsr_windowbase,
5492        .test_ill = test_ill_sr,
5493        .par = (const uint32_t[]){
5494            WINDOW_BASE,
5495            XTENSA_OPTION_WINDOWED_REGISTER,
5496        },
5497        .op_flags = XTENSA_OP_PRIVILEGED |
5498            XTENSA_OP_EXIT_TB_M1 |
5499            XTENSA_OP_SYNC_REGISTER_WINDOW,
5500    }, {
5501        .name = "wsr.windowstart",
5502        .translate = translate_wsr_windowstart,
5503        .test_ill = test_ill_sr,
5504        .par = (const uint32_t[]){
5505            WINDOW_START,
5506            XTENSA_OPTION_WINDOWED_REGISTER,
5507        },
5508        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
5509    }, {
5510        .name = "wur.expstate",
5511        .translate = translate_wur,
5512        .par = (const uint32_t[]){EXPSTATE},
5513    }, {
5514        .name = "wur.fcr",
5515        .translate = translate_wur_fcr,
5516        .par = (const uint32_t[]){FCR},
5517        .coprocessor = 0x1,
5518    }, {
5519        .name = "wur.fsr",
5520        .translate = translate_wur_fsr,
5521        .par = (const uint32_t[]){FSR},
5522        .coprocessor = 0x1,
5523    }, {
5524        .name = "wur.threadptr",
5525        .translate = translate_wur,
5526        .par = (const uint32_t[]){THREADPTR},
5527    }, {
5528        .name = "xor",
5529        .translate = translate_xor,
5530    }, {
5531        .name = "xorb",
5532        .translate = translate_boolean,
5533        .par = (const uint32_t[]){BOOLEAN_XOR},
5534    }, {
5535        .name = "xsr.176",
5536        .op_flags = XTENSA_OP_ILL,
5537    }, {
5538        .name = "xsr.208",
5539        .op_flags = XTENSA_OP_ILL,
5540    }, {
5541        .name = "xsr.acchi",
5542        .translate = translate_xsr_acchi,
5543        .test_ill = test_ill_sr,
5544        .par = (const uint32_t[]){
5545            ACCHI,
5546            XTENSA_OPTION_MAC16,
5547        },
5548    }, {
5549        .name = "xsr.acclo",
5550        .translate = translate_xsr,
5551        .test_ill = test_ill_sr,
5552        .par = (const uint32_t[]){
5553            ACCLO,
5554            XTENSA_OPTION_MAC16,
5555        },
5556    }, {
5557        .name = "xsr.atomctl",
5558        .translate = translate_xsr_mask,
5559        .test_ill = test_ill_sr,
5560        .par = (const uint32_t[]){
5561            ATOMCTL,
5562            XTENSA_OPTION_ATOMCTL,
5563            0x3f,
5564        },
5565        .op_flags = XTENSA_OP_PRIVILEGED,
5566    }, {
5567        .name = "xsr.br",
5568        .translate = translate_xsr_mask,
5569        .test_ill = test_ill_sr,
5570        .par = (const uint32_t[]){
5571            BR,
5572            XTENSA_OPTION_BOOLEAN,
5573            0xffff,
5574        },
5575    }, {
5576        .name = "xsr.cacheadrdis",
5577        .translate = translate_xsr_mask,
5578        .test_ill = test_ill_sr,
5579        .par = (const uint32_t[]){
5580            CACHEADRDIS,
5581            XTENSA_OPTION_MPU,
5582            0xff,
5583        },
5584        .op_flags = XTENSA_OP_PRIVILEGED,
5585    }, {
5586        .name = "xsr.cacheattr",
5587        .translate = translate_xsr,
5588        .test_ill = test_ill_sr,
5589        .par = (const uint32_t[]){
5590            CACHEATTR,
5591            XTENSA_OPTION_CACHEATTR,
5592        },
5593        .op_flags = XTENSA_OP_PRIVILEGED,
5594    }, {
5595        .name = "xsr.ccompare0",
5596        .translate = translate_xsr_ccompare,
5597        .test_ill = test_ill_ccompare,
5598        .par = (const uint32_t[]){
5599            CCOMPARE,
5600            XTENSA_OPTION_TIMER_INTERRUPT,
5601        },
5602        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5603    }, {
5604        .name = "xsr.ccompare1",
5605        .translate = translate_xsr_ccompare,
5606        .test_ill = test_ill_ccompare,
5607        .par = (const uint32_t[]){
5608            CCOMPARE + 1,
5609            XTENSA_OPTION_TIMER_INTERRUPT,
5610        },
5611        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5612    }, {
5613        .name = "xsr.ccompare2",
5614        .translate = translate_xsr_ccompare,
5615        .test_ill = test_ill_ccompare,
5616        .par = (const uint32_t[]){
5617            CCOMPARE + 2,
5618            XTENSA_OPTION_TIMER_INTERRUPT,
5619        },
5620        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5621    }, {
5622        .name = "xsr.ccount",
5623        .translate = translate_xsr_ccount,
5624        .test_ill = test_ill_sr,
5625        .par = (const uint32_t[]){
5626            CCOUNT,
5627            XTENSA_OPTION_TIMER_INTERRUPT,
5628        },
5629        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5630    }, {
5631        .name = "xsr.configid0",
5632        .op_flags = XTENSA_OP_ILL,
5633    }, {
5634        .name = "xsr.configid1",
5635        .op_flags = XTENSA_OP_ILL,
5636    }, {
5637        .name = "xsr.cpenable",
5638        .translate = translate_xsr_mask,
5639        .test_ill = test_ill_sr,
5640        .par = (const uint32_t[]){
5641            CPENABLE,
5642            XTENSA_OPTION_COPROCESSOR,
5643            0xff,
5644        },
5645        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
5646    }, {
5647        .name = "xsr.dbreaka0",
5648        .translate = translate_xsr_dbreaka,
5649        .test_ill = test_ill_dbreak,
5650        .par = (const uint32_t[]){
5651            DBREAKA,
5652            XTENSA_OPTION_DEBUG,
5653        },
5654        .op_flags = XTENSA_OP_PRIVILEGED,
5655    }, {
5656        .name = "xsr.dbreaka1",
5657        .translate = translate_xsr_dbreaka,
5658        .test_ill = test_ill_dbreak,
5659        .par = (const uint32_t[]){
5660            DBREAKA + 1,
5661            XTENSA_OPTION_DEBUG,
5662        },
5663        .op_flags = XTENSA_OP_PRIVILEGED,
5664    }, {
5665        .name = "xsr.dbreakc0",
5666        .translate = translate_xsr_dbreakc,
5667        .test_ill = test_ill_dbreak,
5668        .par = (const uint32_t[]){
5669            DBREAKC,
5670            XTENSA_OPTION_DEBUG,
5671        },
5672        .op_flags = XTENSA_OP_PRIVILEGED,
5673    }, {
5674        .name = "xsr.dbreakc1",
5675        .translate = translate_xsr_dbreakc,
5676        .test_ill = test_ill_dbreak,
5677        .par = (const uint32_t[]){
5678            DBREAKC + 1,
5679            XTENSA_OPTION_DEBUG,
5680        },
5681        .op_flags = XTENSA_OP_PRIVILEGED,
5682    }, {
5683        .name = "xsr.ddr",
5684        .translate = translate_xsr,
5685        .test_ill = test_ill_sr,
5686        .par = (const uint32_t[]){
5687            DDR,
5688            XTENSA_OPTION_DEBUG,
5689        },
5690        .op_flags = XTENSA_OP_PRIVILEGED,
5691    }, {
5692        .name = "xsr.debugcause",
5693        .op_flags = XTENSA_OP_ILL,
5694    }, {
5695        .name = "xsr.depc",
5696        .translate = translate_xsr,
5697        .test_ill = test_ill_sr,
5698        .par = (const uint32_t[]){
5699            DEPC,
5700            XTENSA_OPTION_EXCEPTION,
5701        },
5702        .op_flags = XTENSA_OP_PRIVILEGED,
5703    }, {
5704        .name = "xsr.dtlbcfg",
5705        .translate = translate_xsr_mask,
5706        .test_ill = test_ill_sr,
5707        .par = (const uint32_t[]){
5708            DTLBCFG,
5709            XTENSA_OPTION_MMU,
5710            0x01130000,
5711        },
5712        .op_flags = XTENSA_OP_PRIVILEGED,
5713    }, {
5714        .name = "xsr.epc1",
5715        .translate = translate_xsr,
5716        .test_ill = test_ill_sr,
5717        .par = (const uint32_t[]){
5718            EPC1,
5719            XTENSA_OPTION_EXCEPTION,
5720        },
5721        .op_flags = XTENSA_OP_PRIVILEGED,
5722    }, {
5723        .name = "xsr.epc2",
5724        .translate = translate_xsr,
5725        .test_ill = test_ill_hpi,
5726        .par = (const uint32_t[]){
5727            EPC1 + 1,
5728            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5729        },
5730        .op_flags = XTENSA_OP_PRIVILEGED,
5731    }, {
5732        .name = "xsr.epc3",
5733        .translate = translate_xsr,
5734        .test_ill = test_ill_hpi,
5735        .par = (const uint32_t[]){
5736            EPC1 + 2,
5737            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5738        },
5739        .op_flags = XTENSA_OP_PRIVILEGED,
5740    }, {
5741        .name = "xsr.epc4",
5742        .translate = translate_xsr,
5743        .test_ill = test_ill_hpi,
5744        .par = (const uint32_t[]){
5745            EPC1 + 3,
5746            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5747        },
5748        .op_flags = XTENSA_OP_PRIVILEGED,
5749    }, {
5750        .name = "xsr.epc5",
5751        .translate = translate_xsr,
5752        .test_ill = test_ill_hpi,
5753        .par = (const uint32_t[]){
5754            EPC1 + 4,
5755            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5756        },
5757        .op_flags = XTENSA_OP_PRIVILEGED,
5758    }, {
5759        .name = "xsr.epc6",
5760        .translate = translate_xsr,
5761        .test_ill = test_ill_hpi,
5762        .par = (const uint32_t[]){
5763            EPC1 + 5,
5764            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5765        },
5766        .op_flags = XTENSA_OP_PRIVILEGED,
5767    }, {
5768        .name = "xsr.epc7",
5769        .translate = translate_xsr,
5770        .test_ill = test_ill_hpi,
5771        .par = (const uint32_t[]){
5772            EPC1 + 6,
5773            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5774        },
5775        .op_flags = XTENSA_OP_PRIVILEGED,
5776    }, {
5777        .name = "xsr.eps2",
5778        .translate = translate_xsr,
5779        .test_ill = test_ill_hpi,
5780        .par = (const uint32_t[]){
5781            EPS2,
5782            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5783        },
5784        .op_flags = XTENSA_OP_PRIVILEGED,
5785    }, {
5786        .name = "xsr.eps3",
5787        .translate = translate_xsr,
5788        .test_ill = test_ill_hpi,
5789        .par = (const uint32_t[]){
5790            EPS2 + 1,
5791            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5792        },
5793        .op_flags = XTENSA_OP_PRIVILEGED,
5794    }, {
5795        .name = "xsr.eps4",
5796        .translate = translate_xsr,
5797        .test_ill = test_ill_hpi,
5798        .par = (const uint32_t[]){
5799            EPS2 + 2,
5800            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5801        },
5802        .op_flags = XTENSA_OP_PRIVILEGED,
5803    }, {
5804        .name = "xsr.eps5",
5805        .translate = translate_xsr,
5806        .test_ill = test_ill_hpi,
5807        .par = (const uint32_t[]){
5808            EPS2 + 3,
5809            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5810        },
5811        .op_flags = XTENSA_OP_PRIVILEGED,
5812    }, {
5813        .name = "xsr.eps6",
5814        .translate = translate_xsr,
5815        .test_ill = test_ill_hpi,
5816        .par = (const uint32_t[]){
5817            EPS2 + 4,
5818            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5819        },
5820        .op_flags = XTENSA_OP_PRIVILEGED,
5821    }, {
5822        .name = "xsr.eps7",
5823        .translate = translate_xsr,
5824        .test_ill = test_ill_hpi,
5825        .par = (const uint32_t[]){
5826            EPS2 + 5,
5827            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5828        },
5829        .op_flags = XTENSA_OP_PRIVILEGED,
5830    }, {
5831        .name = "xsr.eraccess",
5832        .translate = translate_xsr_mask,
5833        .par = (const uint32_t[]){
5834            ERACCESS,
5835            0,
5836            0xffff,
5837        },
5838        .op_flags = XTENSA_OP_PRIVILEGED,
5839    }, {
5840        .name = "xsr.exccause",
5841        .translate = translate_xsr,
5842        .test_ill = test_ill_sr,
5843        .par = (const uint32_t[]){
5844            EXCCAUSE,
5845            XTENSA_OPTION_EXCEPTION,
5846        },
5847        .op_flags = XTENSA_OP_PRIVILEGED,
5848    }, {
5849        .name = "xsr.excsave1",
5850        .translate = translate_xsr,
5851        .test_ill = test_ill_sr,
5852        .par = (const uint32_t[]){
5853            EXCSAVE1,
5854            XTENSA_OPTION_EXCEPTION,
5855        },
5856        .op_flags = XTENSA_OP_PRIVILEGED,
5857    }, {
5858        .name = "xsr.excsave2",
5859        .translate = translate_xsr,
5860        .test_ill = test_ill_hpi,
5861        .par = (const uint32_t[]){
5862            EXCSAVE1 + 1,
5863            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5864        },
5865        .op_flags = XTENSA_OP_PRIVILEGED,
5866    }, {
5867        .name = "xsr.excsave3",
5868        .translate = translate_xsr,
5869        .test_ill = test_ill_hpi,
5870        .par = (const uint32_t[]){
5871            EXCSAVE1 + 2,
5872            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5873        },
5874        .op_flags = XTENSA_OP_PRIVILEGED,
5875    }, {
5876        .name = "xsr.excsave4",
5877        .translate = translate_xsr,
5878        .test_ill = test_ill_hpi,
5879        .par = (const uint32_t[]){
5880            EXCSAVE1 + 3,
5881            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5882        },
5883        .op_flags = XTENSA_OP_PRIVILEGED,
5884    }, {
5885        .name = "xsr.excsave5",
5886        .translate = translate_xsr,
5887        .test_ill = test_ill_hpi,
5888        .par = (const uint32_t[]){
5889            EXCSAVE1 + 4,
5890            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5891        },
5892        .op_flags = XTENSA_OP_PRIVILEGED,
5893    }, {
5894        .name = "xsr.excsave6",
5895        .translate = translate_xsr,
5896        .test_ill = test_ill_hpi,
5897        .par = (const uint32_t[]){
5898            EXCSAVE1 + 5,
5899            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5900        },
5901        .op_flags = XTENSA_OP_PRIVILEGED,
5902    }, {
5903        .name = "xsr.excsave7",
5904        .translate = translate_xsr,
5905        .test_ill = test_ill_hpi,
5906        .par = (const uint32_t[]){
5907            EXCSAVE1 + 6,
5908            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
5909        },
5910        .op_flags = XTENSA_OP_PRIVILEGED,
5911    }, {
5912        .name = "xsr.excvaddr",
5913        .translate = translate_xsr,
5914        .test_ill = test_ill_sr,
5915        .par = (const uint32_t[]){
5916            EXCVADDR,
5917            XTENSA_OPTION_EXCEPTION,
5918        },
5919        .op_flags = XTENSA_OP_PRIVILEGED,
5920    }, {
5921        .name = "xsr.ibreaka0",
5922        .translate = translate_xsr_ibreaka,
5923        .test_ill = test_ill_ibreak,
5924        .par = (const uint32_t[]){
5925            IBREAKA,
5926            XTENSA_OPTION_DEBUG,
5927        },
5928        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5929    }, {
5930        .name = "xsr.ibreaka1",
5931        .translate = translate_xsr_ibreaka,
5932        .test_ill = test_ill_ibreak,
5933        .par = (const uint32_t[]){
5934            IBREAKA + 1,
5935            XTENSA_OPTION_DEBUG,
5936        },
5937        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5938    }, {
5939        .name = "xsr.ibreakenable",
5940        .translate = translate_xsr_ibreakenable,
5941        .test_ill = test_ill_sr,
5942        .par = (const uint32_t[]){
5943            IBREAKENABLE,
5944            XTENSA_OPTION_DEBUG,
5945        },
5946        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0,
5947    }, {
5948        .name = "xsr.icount",
5949        .translate = translate_xsr_icount,
5950        .test_ill = test_ill_sr,
5951        .par = (const uint32_t[]){
5952            ICOUNT,
5953            XTENSA_OPTION_DEBUG,
5954        },
5955        .op_flags = XTENSA_OP_PRIVILEGED,
5956    }, {
5957        .name = "xsr.icountlevel",
5958        .translate = translate_xsr_mask,
5959        .test_ill = test_ill_sr,
5960        .par = (const uint32_t[]){
5961            ICOUNTLEVEL,
5962            XTENSA_OPTION_DEBUG,
5963            0xf,
5964        },
5965        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
5966    }, {
5967        .name = "xsr.intclear",
5968        .op_flags = XTENSA_OP_ILL,
5969    }, {
5970        .name = "xsr.intenable",
5971        .translate = translate_xsr,
5972        .test_ill = test_ill_sr,
5973        .par = (const uint32_t[]){
5974            INTENABLE,
5975            XTENSA_OPTION_INTERRUPT,
5976        },
5977        .op_flags =
5978            XTENSA_OP_PRIVILEGED |
5979            XTENSA_OP_EXIT_TB_0 |
5980            XTENSA_OP_CHECK_INTERRUPTS,
5981    }, {
5982        .name = "xsr.interrupt",
5983        .op_flags = XTENSA_OP_ILL,
5984    }, {
5985        .name = "xsr.intset",
5986        .op_flags = XTENSA_OP_ILL,
5987    }, {
5988        .name = "xsr.itlbcfg",
5989        .translate = translate_xsr_mask,
5990        .test_ill = test_ill_sr,
5991        .par = (const uint32_t[]){
5992            ITLBCFG,
5993            XTENSA_OPTION_MMU,
5994            0x01130000,
5995        },
5996        .op_flags = XTENSA_OP_PRIVILEGED,
5997    }, {
5998        .name = "xsr.lbeg",
5999        .translate = translate_xsr,
6000        .test_ill = test_ill_sr,
6001        .par = (const uint32_t[]){
6002            LBEG,
6003            XTENSA_OPTION_LOOP,
6004        },
6005        .op_flags = XTENSA_OP_EXIT_TB_M1,
6006    }, {
6007        .name = "xsr.lcount",
6008        .translate = translate_xsr,
6009        .test_ill = test_ill_sr,
6010        .par = (const uint32_t[]){
6011            LCOUNT,
6012            XTENSA_OPTION_LOOP,
6013        },
6014    }, {
6015        .name = "xsr.lend",
6016        .translate = translate_xsr,
6017        .test_ill = test_ill_sr,
6018        .par = (const uint32_t[]){
6019            LEND,
6020            XTENSA_OPTION_LOOP,
6021        },
6022        .op_flags = XTENSA_OP_EXIT_TB_M1,
6023    }, {
6024        .name = "xsr.litbase",
6025        .translate = translate_xsr_mask,
6026        .test_ill = test_ill_sr,
6027        .par = (const uint32_t[]){
6028            LITBASE,
6029            XTENSA_OPTION_EXTENDED_L32R,
6030            0xfffff001,
6031        },
6032        .op_flags = XTENSA_OP_EXIT_TB_M1,
6033    }, {
6034        .name = "xsr.m0",
6035        .translate = translate_xsr,
6036        .test_ill = test_ill_sr,
6037        .par = (const uint32_t[]){
6038            MR,
6039            XTENSA_OPTION_MAC16,
6040        },
6041    }, {
6042        .name = "xsr.m1",
6043        .translate = translate_xsr,
6044        .test_ill = test_ill_sr,
6045        .par = (const uint32_t[]){
6046            MR + 1,
6047            XTENSA_OPTION_MAC16,
6048        },
6049    }, {
6050        .name = "xsr.m2",
6051        .translate = translate_xsr,
6052        .test_ill = test_ill_sr,
6053        .par = (const uint32_t[]){
6054            MR + 2,
6055            XTENSA_OPTION_MAC16,
6056        },
6057    }, {
6058        .name = "xsr.m3",
6059        .translate = translate_xsr,
6060        .test_ill = test_ill_sr,
6061        .par = (const uint32_t[]){
6062            MR + 3,
6063            XTENSA_OPTION_MAC16,
6064        },
6065    }, {
6066        .name = "xsr.memctl",
6067        .translate = translate_xsr_memctl,
6068        .par = (const uint32_t[]){MEMCTL},
6069        .op_flags = XTENSA_OP_PRIVILEGED,
6070    }, {
6071        .name = "xsr.mecr",
6072        .translate = translate_xsr,
6073        .test_ill = test_ill_sr,
6074        .par = (const uint32_t[]){
6075            MECR,
6076            XTENSA_OPTION_MEMORY_ECC_PARITY,
6077        },
6078        .op_flags = XTENSA_OP_PRIVILEGED,
6079    }, {
6080        .name = "xsr.mepc",
6081        .translate = translate_xsr,
6082        .test_ill = test_ill_sr,
6083        .par = (const uint32_t[]){
6084            MEPC,
6085            XTENSA_OPTION_MEMORY_ECC_PARITY,
6086        },
6087        .op_flags = XTENSA_OP_PRIVILEGED,
6088    }, {
6089        .name = "xsr.meps",
6090        .translate = translate_xsr,
6091        .test_ill = test_ill_sr,
6092        .par = (const uint32_t[]){
6093            MEPS,
6094            XTENSA_OPTION_MEMORY_ECC_PARITY,
6095        },
6096        .op_flags = XTENSA_OP_PRIVILEGED,
6097    }, {
6098        .name = "xsr.mesave",
6099        .translate = translate_xsr,
6100        .test_ill = test_ill_sr,
6101        .par = (const uint32_t[]){
6102            MESAVE,
6103            XTENSA_OPTION_MEMORY_ECC_PARITY,
6104        },
6105        .op_flags = XTENSA_OP_PRIVILEGED,
6106    }, {
6107        .name = "xsr.mesr",
6108        .translate = translate_xsr,
6109        .test_ill = test_ill_sr,
6110        .par = (const uint32_t[]){
6111            MESR,
6112            XTENSA_OPTION_MEMORY_ECC_PARITY,
6113        },
6114        .op_flags = XTENSA_OP_PRIVILEGED,
6115    }, {
6116        .name = "xsr.mevaddr",
6117        .translate = translate_xsr,
6118        .test_ill = test_ill_sr,
6119        .par = (const uint32_t[]){
6120            MESR,
6121            XTENSA_OPTION_MEMORY_ECC_PARITY,
6122        },
6123        .op_flags = XTENSA_OP_PRIVILEGED,
6124    }, {
6125        .name = "xsr.misc0",
6126        .translate = translate_xsr,
6127        .test_ill = test_ill_sr,
6128        .par = (const uint32_t[]){
6129            MISC,
6130            XTENSA_OPTION_MISC_SR,
6131        },
6132        .op_flags = XTENSA_OP_PRIVILEGED,
6133    }, {
6134        .name = "xsr.misc1",
6135        .translate = translate_xsr,
6136        .test_ill = test_ill_sr,
6137        .par = (const uint32_t[]){
6138            MISC + 1,
6139            XTENSA_OPTION_MISC_SR,
6140        },
6141        .op_flags = XTENSA_OP_PRIVILEGED,
6142    }, {
6143        .name = "xsr.misc2",
6144        .translate = translate_xsr,
6145        .test_ill = test_ill_sr,
6146        .par = (const uint32_t[]){
6147            MISC + 2,
6148            XTENSA_OPTION_MISC_SR,
6149        },
6150        .op_flags = XTENSA_OP_PRIVILEGED,
6151    }, {
6152        .name = "xsr.misc3",
6153        .translate = translate_xsr,
6154        .test_ill = test_ill_sr,
6155        .par = (const uint32_t[]){
6156            MISC + 3,
6157            XTENSA_OPTION_MISC_SR,
6158        },
6159        .op_flags = XTENSA_OP_PRIVILEGED,
6160    }, {
6161        .name = "xsr.mpuenb",
6162        .translate = translate_xsr_mpuenb,
6163        .test_ill = test_ill_sr,
6164        .par = (const uint32_t[]){
6165            MPUENB,
6166            XTENSA_OPTION_MPU,
6167        },
6168        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
6169    }, {
6170        .name = "xsr.prefctl",
6171        .translate = translate_xsr,
6172        .par = (const uint32_t[]){PREFCTL},
6173    }, {
6174        .name = "xsr.prid",
6175        .op_flags = XTENSA_OP_ILL,
6176    }, {
6177        .name = "xsr.ps",
6178        .translate = translate_xsr_ps,
6179        .test_ill = test_ill_sr,
6180        .par = (const uint32_t[]){
6181            PS,
6182            XTENSA_OPTION_EXCEPTION,
6183        },
6184        .op_flags =
6185            XTENSA_OP_PRIVILEGED |
6186            XTENSA_OP_EXIT_TB_M1 |
6187            XTENSA_OP_CHECK_INTERRUPTS,
6188    }, {
6189        .name = "xsr.ptevaddr",
6190        .translate = translate_xsr_mask,
6191        .test_ill = test_ill_sr,
6192        .par = (const uint32_t[]){
6193            PTEVADDR,
6194            XTENSA_OPTION_MMU,
6195            0xffc00000,
6196        },
6197        .op_flags = XTENSA_OP_PRIVILEGED,
6198    }, {
6199        .name = "xsr.rasid",
6200        .translate = translate_xsr_rasid,
6201        .test_ill = test_ill_sr,
6202        .par = (const uint32_t[]){
6203            RASID,
6204            XTENSA_OPTION_MMU,
6205        },
6206        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
6207    }, {
6208        .name = "xsr.sar",
6209        .translate = translate_xsr_sar,
6210        .par = (const uint32_t[]){SAR},
6211    }, {
6212        .name = "xsr.scompare1",
6213        .translate = translate_xsr,
6214        .test_ill = test_ill_sr,
6215        .par = (const uint32_t[]){
6216            SCOMPARE1,
6217            XTENSA_OPTION_CONDITIONAL_STORE,
6218        },
6219    }, {
6220        .name = "xsr.vecbase",
6221        .translate = translate_xsr,
6222        .test_ill = test_ill_sr,
6223        .par = (const uint32_t[]){
6224            VECBASE,
6225            XTENSA_OPTION_RELOCATABLE_VECTOR,
6226        },
6227        .op_flags = XTENSA_OP_PRIVILEGED,
6228    }, {
6229        .name = "xsr.windowbase",
6230        .translate = translate_xsr_windowbase,
6231        .test_ill = test_ill_sr,
6232        .par = (const uint32_t[]){
6233            WINDOW_BASE,
6234            XTENSA_OPTION_WINDOWED_REGISTER,
6235        },
6236        .op_flags = XTENSA_OP_PRIVILEGED |
6237            XTENSA_OP_EXIT_TB_M1 |
6238            XTENSA_OP_SYNC_REGISTER_WINDOW,
6239    }, {
6240        .name = "xsr.windowstart",
6241        .translate = translate_xsr_windowstart,
6242        .test_ill = test_ill_sr,
6243        .par = (const uint32_t[]){
6244            WINDOW_START,
6245            XTENSA_OPTION_WINDOWED_REGISTER,
6246        },
6247        .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
6248    },
6249};
6250
6251const XtensaOpcodeTranslators xtensa_core_opcodes = {
6252    .num_opcodes = ARRAY_SIZE(core_ops),
6253    .opcode = core_ops,
6254};
6255
6256
6257static void translate_abs_s(DisasContext *dc, const OpcodeArg arg[],
6258                            const uint32_t par[])
6259{
6260    gen_helper_abs_s(arg[0].out, arg[1].in);
6261}
6262
6263static void translate_add_s(DisasContext *dc, const OpcodeArg arg[],
6264                            const uint32_t par[])
6265{
6266    gen_helper_add_s(arg[0].out, cpu_env,
6267                     arg[1].in, arg[2].in);
6268}
6269
6270enum {
6271    COMPARE_UN,
6272    COMPARE_OEQ,
6273    COMPARE_UEQ,
6274    COMPARE_OLT,
6275    COMPARE_ULT,
6276    COMPARE_OLE,
6277    COMPARE_ULE,
6278};
6279
6280static void translate_compare_s(DisasContext *dc, const OpcodeArg arg[],
6281                                const uint32_t par[])
6282{
6283    static void (* const helper[])(TCGv_env env, TCGv_i32 bit,
6284                                   TCGv_i32 s, TCGv_i32 t) = {
6285        [COMPARE_UN] = gen_helper_un_s,
6286        [COMPARE_OEQ] = gen_helper_oeq_s,
6287        [COMPARE_UEQ] = gen_helper_ueq_s,
6288        [COMPARE_OLT] = gen_helper_olt_s,
6289        [COMPARE_ULT] = gen_helper_ult_s,
6290        [COMPARE_OLE] = gen_helper_ole_s,
6291        [COMPARE_ULE] = gen_helper_ule_s,
6292    };
6293    TCGv_i32 bit = tcg_const_i32(1 << arg[0].imm);
6294
6295    helper[par[0]](cpu_env, bit, arg[1].in, arg[2].in);
6296    tcg_temp_free(bit);
6297}
6298
6299static void translate_float_s(DisasContext *dc, const OpcodeArg arg[],
6300                              const uint32_t par[])
6301{
6302    TCGv_i32 scale = tcg_const_i32(-arg[2].imm);
6303
6304    if (par[0]) {
6305        gen_helper_uitof(arg[0].out, cpu_env, arg[1].in, scale);
6306    } else {
6307        gen_helper_itof(arg[0].out, cpu_env, arg[1].in, scale);
6308    }
6309    tcg_temp_free(scale);
6310}
6311
6312static void translate_ftoi_s(DisasContext *dc, const OpcodeArg arg[],
6313                             const uint32_t par[])
6314{
6315    TCGv_i32 rounding_mode = tcg_const_i32(par[0]);
6316    TCGv_i32 scale = tcg_const_i32(arg[2].imm);
6317
6318    if (par[1]) {
6319        gen_helper_ftoui(arg[0].out, arg[1].in,
6320                         rounding_mode, scale);
6321    } else {
6322        gen_helper_ftoi(arg[0].out, arg[1].in,
6323                        rounding_mode, scale);
6324    }
6325    tcg_temp_free(rounding_mode);
6326    tcg_temp_free(scale);
6327}
6328
6329static void translate_ldsti(DisasContext *dc, const OpcodeArg arg[],
6330                            const uint32_t par[])
6331{
6332    TCGv_i32 addr = tcg_temp_new_i32();
6333
6334    tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm);
6335    gen_load_store_alignment(dc, 2, addr, false);
6336    if (par[0]) {
6337        tcg_gen_qemu_st32(arg[0].in, addr, dc->cring);
6338    } else {
6339        tcg_gen_qemu_ld32u(arg[0].out, addr, dc->cring);
6340    }
6341    if (par[1]) {
6342        tcg_gen_mov_i32(arg[1].out, addr);
6343    }
6344    tcg_temp_free(addr);
6345}
6346
6347static void translate_ldstx(DisasContext *dc, const OpcodeArg arg[],
6348                            const uint32_t par[])
6349{
6350    TCGv_i32 addr = tcg_temp_new_i32();
6351
6352    tcg_gen_add_i32(addr, arg[1].in, arg[2].in);
6353    gen_load_store_alignment(dc, 2, addr, false);
6354    if (par[0]) {
6355        tcg_gen_qemu_st32(arg[0].in, addr, dc->cring);
6356    } else {
6357        tcg_gen_qemu_ld32u(arg[0].out, addr, dc->cring);
6358    }
6359    if (par[1]) {
6360        tcg_gen_mov_i32(arg[1].out, addr);
6361    }
6362    tcg_temp_free(addr);
6363}
6364
6365static void translate_madd_s(DisasContext *dc, const OpcodeArg arg[],
6366                             const uint32_t par[])
6367{
6368    gen_helper_madd_s(arg[0].out, cpu_env,
6369                      arg[0].in, arg[1].in, arg[2].in);
6370}
6371
6372static void translate_mov_s(DisasContext *dc, const OpcodeArg arg[],
6373                            const uint32_t par[])
6374{
6375    tcg_gen_mov_i32(arg[0].out, arg[1].in);
6376}
6377
6378static void translate_movcond_s(DisasContext *dc, const OpcodeArg arg[],
6379                                const uint32_t par[])
6380{
6381    TCGv_i32 zero = tcg_const_i32(0);
6382
6383    tcg_gen_movcond_i32(par[0], arg[0].out,
6384                        arg[2].in, zero,
6385                        arg[1].in, arg[0].in);
6386    tcg_temp_free(zero);
6387}
6388
6389static void translate_movp_s(DisasContext *dc, const OpcodeArg arg[],
6390                             const uint32_t par[])
6391{
6392    TCGv_i32 zero = tcg_const_i32(0);
6393    TCGv_i32 tmp = tcg_temp_new_i32();
6394
6395    tcg_gen_andi_i32(tmp, arg[2].in, 1 << arg[2].imm);
6396    tcg_gen_movcond_i32(par[0],
6397                        arg[0].out, tmp, zero,
6398                        arg[1].in, arg[0].in);
6399    tcg_temp_free(tmp);
6400    tcg_temp_free(zero);
6401}
6402
6403static void translate_mul_s(DisasContext *dc, const OpcodeArg arg[],
6404                            const uint32_t par[])
6405{
6406    gen_helper_mul_s(arg[0].out, cpu_env,
6407                     arg[1].in, arg[2].in);
6408}
6409
6410static void translate_msub_s(DisasContext *dc, const OpcodeArg arg[],
6411                             const uint32_t par[])
6412{
6413    gen_helper_msub_s(arg[0].out, cpu_env,
6414                      arg[0].in, arg[1].in, arg[2].in);
6415}
6416
6417static void translate_neg_s(DisasContext *dc, const OpcodeArg arg[],
6418                            const uint32_t par[])
6419{
6420    gen_helper_neg_s(arg[0].out, arg[1].in);
6421}
6422
6423static void translate_rfr_s(DisasContext *dc, const OpcodeArg arg[],
6424                            const uint32_t par[])
6425{
6426    tcg_gen_mov_i32(arg[0].out, arg[1].in);
6427}
6428
6429static void translate_sub_s(DisasContext *dc, const OpcodeArg arg[],
6430                            const uint32_t par[])
6431{
6432    gen_helper_sub_s(arg[0].out, cpu_env,
6433                     arg[1].in, arg[2].in);
6434}
6435
6436static void translate_wfr_s(DisasContext *dc, const OpcodeArg arg[],
6437                            const uint32_t par[])
6438{
6439    tcg_gen_mov_i32(arg[0].out, arg[1].in);
6440}
6441
6442static const XtensaOpcodeOps fpu2000_ops[] = {
6443    {
6444        .name = "abs.s",
6445        .translate = translate_abs_s,
6446        .coprocessor = 0x1,
6447    }, {
6448        .name = "add.s",
6449        .translate = translate_add_s,
6450        .coprocessor = 0x1,
6451    }, {
6452        .name = "ceil.s",
6453        .translate = translate_ftoi_s,
6454        .par = (const uint32_t[]){float_round_up, false},
6455        .coprocessor = 0x1,
6456    }, {
6457        .name = "float.s",
6458        .translate = translate_float_s,
6459        .par = (const uint32_t[]){false},
6460        .coprocessor = 0x1,
6461    }, {
6462        .name = "floor.s",
6463        .translate = translate_ftoi_s,
6464        .par = (const uint32_t[]){float_round_down, false},
6465        .coprocessor = 0x1,
6466    }, {
6467        .name = "lsi",
6468        .translate = translate_ldsti,
6469        .par = (const uint32_t[]){false, false},
6470        .op_flags = XTENSA_OP_LOAD,
6471        .coprocessor = 0x1,
6472    }, {
6473        .name = "lsiu",
6474        .translate = translate_ldsti,
6475        .par = (const uint32_t[]){false, true},
6476        .op_flags = XTENSA_OP_LOAD,
6477        .coprocessor = 0x1,
6478    }, {
6479        .name = "lsx",
6480        .translate = translate_ldstx,
6481        .par = (const uint32_t[]){false, false},
6482        .op_flags = XTENSA_OP_LOAD,
6483        .coprocessor = 0x1,
6484    }, {
6485        .name = "lsxu",
6486        .translate = translate_ldstx,
6487        .par = (const uint32_t[]){false, true},
6488        .op_flags = XTENSA_OP_LOAD,
6489        .coprocessor = 0x1,
6490    }, {
6491        .name = "madd.s",
6492        .translate = translate_madd_s,
6493        .coprocessor = 0x1,
6494    }, {
6495        .name = "mov.s",
6496        .translate = translate_mov_s,
6497        .coprocessor = 0x1,
6498    }, {
6499        .name = "moveqz.s",
6500        .translate = translate_movcond_s,
6501        .par = (const uint32_t[]){TCG_COND_EQ},
6502        .coprocessor = 0x1,
6503    }, {
6504        .name = "movf.s",
6505        .translate = translate_movp_s,
6506        .par = (const uint32_t[]){TCG_COND_EQ},
6507        .coprocessor = 0x1,
6508    }, {
6509        .name = "movgez.s",
6510        .translate = translate_movcond_s,
6511        .par = (const uint32_t[]){TCG_COND_GE},
6512        .coprocessor = 0x1,
6513    }, {
6514        .name = "movltz.s",
6515        .translate = translate_movcond_s,
6516        .par = (const uint32_t[]){TCG_COND_LT},
6517        .coprocessor = 0x1,
6518    }, {
6519        .name = "movnez.s",
6520        .translate = translate_movcond_s,
6521        .par = (const uint32_t[]){TCG_COND_NE},
6522        .coprocessor = 0x1,
6523    }, {
6524        .name = "movt.s",
6525        .translate = translate_movp_s,
6526        .par = (const uint32_t[]){TCG_COND_NE},
6527        .coprocessor = 0x1,
6528    }, {
6529        .name = "msub.s",
6530        .translate = translate_msub_s,
6531        .coprocessor = 0x1,
6532    }, {
6533        .name = "mul.s",
6534        .translate = translate_mul_s,
6535        .coprocessor = 0x1,
6536    }, {
6537        .name = "neg.s",
6538        .translate = translate_neg_s,
6539        .coprocessor = 0x1,
6540    }, {
6541        .name = "oeq.s",
6542        .translate = translate_compare_s,
6543        .par = (const uint32_t[]){COMPARE_OEQ},
6544        .coprocessor = 0x1,
6545    }, {
6546        .name = "ole.s",
6547        .translate = translate_compare_s,
6548        .par = (const uint32_t[]){COMPARE_OLE},
6549        .coprocessor = 0x1,
6550    }, {
6551        .name = "olt.s",
6552        .translate = translate_compare_s,
6553        .par = (const uint32_t[]){COMPARE_OLT},
6554        .coprocessor = 0x1,
6555    }, {
6556        .name = "rfr",
6557        .translate = translate_rfr_s,
6558        .coprocessor = 0x1,
6559    }, {
6560        .name = "round.s",
6561        .translate = translate_ftoi_s,
6562        .par = (const uint32_t[]){float_round_nearest_even, false},
6563        .coprocessor = 0x1,
6564    }, {
6565        .name = "ssi",
6566        .translate = translate_ldsti,
6567        .par = (const uint32_t[]){true, false},
6568        .op_flags = XTENSA_OP_STORE,
6569        .coprocessor = 0x1,
6570    }, {
6571        .name = "ssiu",
6572        .translate = translate_ldsti,
6573        .par = (const uint32_t[]){true, true},
6574        .op_flags = XTENSA_OP_STORE,
6575        .coprocessor = 0x1,
6576    }, {
6577        .name = "ssx",
6578        .translate = translate_ldstx,
6579        .par = (const uint32_t[]){true, false},
6580        .op_flags = XTENSA_OP_STORE,
6581        .coprocessor = 0x1,
6582    }, {
6583        .name = "ssxu",
6584        .translate = translate_ldstx,
6585        .par = (const uint32_t[]){true, true},
6586        .op_flags = XTENSA_OP_STORE,
6587        .coprocessor = 0x1,
6588    }, {
6589        .name = "sub.s",
6590        .translate = translate_sub_s,
6591        .coprocessor = 0x1,
6592    }, {
6593        .name = "trunc.s",
6594        .translate = translate_ftoi_s,
6595        .par = (const uint32_t[]){float_round_to_zero, false},
6596        .coprocessor = 0x1,
6597    }, {
6598        .name = "ueq.s",
6599        .translate = translate_compare_s,
6600        .par = (const uint32_t[]){COMPARE_UEQ},
6601        .coprocessor = 0x1,
6602    }, {
6603        .name = "ufloat.s",
6604        .translate = translate_float_s,
6605        .par = (const uint32_t[]){true},
6606        .coprocessor = 0x1,
6607    }, {
6608        .name = "ule.s",
6609        .translate = translate_compare_s,
6610        .par = (const uint32_t[]){COMPARE_ULE},
6611        .coprocessor = 0x1,
6612    }, {
6613        .name = "ult.s",
6614        .translate = translate_compare_s,
6615        .par = (const uint32_t[]){COMPARE_ULT},
6616        .coprocessor = 0x1,
6617    }, {
6618        .name = "un.s",
6619        .translate = translate_compare_s,
6620        .par = (const uint32_t[]){COMPARE_UN},
6621        .coprocessor = 0x1,
6622    }, {
6623        .name = "utrunc.s",
6624        .translate = translate_ftoi_s,
6625        .par = (const uint32_t[]){float_round_to_zero, true},
6626        .coprocessor = 0x1,
6627    }, {
6628        .name = "wfr",
6629        .translate = translate_wfr_s,
6630        .coprocessor = 0x1,
6631    },
6632};
6633
6634const XtensaOpcodeTranslators xtensa_fpu2000_opcodes = {
6635    .num_opcodes = ARRAY_SIZE(fpu2000_ops),
6636    .opcode = fpu2000_ops,
6637};
6638