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