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