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