qemu/target/xtensa/translate.c
<<
>>
Prefs
   1/*
   2 * Xtensa ISA:
   3 * http://www.tensilica.com/products/literature-docs/documentation/xtensa-isa-databook.htm
   4 *
   5 * Copyright (c) 2011, Max Filippov, Open Source and Linux Lab.
   6 * All rights reserved.
   7 *
   8 * Redistribution and use in source and binary forms, with or without
   9 * modification, are permitted provided that the following conditions are met:
  10 *     * Redistributions of source code must retain the above copyright
  11 *       notice, this list of conditions and the following disclaimer.
  12 *     * Redistributions in binary form must reproduce the above copyright
  13 *       notice, this list of conditions and the following disclaimer in the
  14 *       documentation and/or other materials provided with the distribution.
  15 *     * Neither the name of the Open Source and Linux Lab nor the
  16 *       names of its contributors may be used to endorse or promote products
  17 *       derived from this software without specific prior written permission.
  18 *
  19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29 */
  30
  31#include "qemu/osdep.h"
  32
  33#include "cpu.h"
  34#include "exec/exec-all.h"
  35#include "disas/disas.h"
  36#include "tcg-op.h"
  37#include "qemu/log.h"
  38#include "sysemu/sysemu.h"
  39#include "exec/cpu_ldst.h"
  40#include "exec/semihost.h"
  41#include "exec/translator.h"
  42
  43#include "exec/helper-proto.h"
  44#include "exec/helper-gen.h"
  45
  46#include "trace-tcg.h"
  47#include "exec/log.h"
  48
  49
  50/* is_jmp field values */
  51#define DISAS_UPDATE  DISAS_TARGET_0 /* cpu state was modified dynamically */
  52
  53struct DisasContext {
  54    const XtensaConfig *config;
  55    TranslationBlock *tb;
  56    uint32_t pc;
  57    uint32_t next_pc;
  58    int cring;
  59    int ring;
  60    uint32_t lbeg;
  61    uint32_t lend;
  62    int is_jmp;
  63    int singlestep_enabled;
  64
  65    bool sar_5bit;
  66    bool sar_m32_5bit;
  67    bool sar_m32_allocated;
  68    TCGv_i32 sar_m32;
  69
  70    unsigned window;
  71
  72    bool debug;
  73    bool icount;
  74    TCGv_i32 next_icount;
  75
  76    unsigned cpenable;
  77
  78    uint32_t *raw_arg;
  79    xtensa_insnbuf insnbuf;
  80    xtensa_insnbuf slotbuf;
  81};
  82
  83static TCGv_i32 cpu_pc;
  84static TCGv_i32 cpu_R[16];
  85static TCGv_i32 cpu_FR[16];
  86static TCGv_i32 cpu_SR[256];
  87static TCGv_i32 cpu_UR[256];
  88
  89#include "exec/gen-icount.h"
  90
  91typedef struct XtensaReg {
  92    const char *name;
  93    uint64_t opt_bits;
  94    enum {
  95        SR_R = 1,
  96        SR_W = 2,
  97        SR_X = 4,
  98        SR_RW = 3,
  99        SR_RWX = 7,
 100    } access;
 101} XtensaReg;
 102
 103#define XTENSA_REG_ACCESS(regname, opt, acc) { \
 104        .name = (regname), \
 105        .opt_bits = XTENSA_OPTION_BIT(opt), \
 106        .access = (acc), \
 107    }
 108
 109#define XTENSA_REG(regname, opt) XTENSA_REG_ACCESS(regname, opt, SR_RWX)
 110
 111#define XTENSA_REG_BITS_ACCESS(regname, opt, acc) { \
 112        .name = (regname), \
 113        .opt_bits = (opt), \
 114        .access = (acc), \
 115    }
 116
 117#define XTENSA_REG_BITS(regname, opt) \
 118    XTENSA_REG_BITS_ACCESS(regname, opt, SR_RWX)
 119
 120static const XtensaReg sregnames[256] = {
 121    [LBEG] = XTENSA_REG("LBEG", XTENSA_OPTION_LOOP),
 122    [LEND] = XTENSA_REG("LEND", XTENSA_OPTION_LOOP),
 123    [LCOUNT] = XTENSA_REG("LCOUNT", XTENSA_OPTION_LOOP),
 124    [SAR] = XTENSA_REG_BITS("SAR", XTENSA_OPTION_ALL),
 125    [BR] = XTENSA_REG("BR", XTENSA_OPTION_BOOLEAN),
 126    [LITBASE] = XTENSA_REG("LITBASE", XTENSA_OPTION_EXTENDED_L32R),
 127    [SCOMPARE1] = XTENSA_REG("SCOMPARE1", XTENSA_OPTION_CONDITIONAL_STORE),
 128    [ACCLO] = XTENSA_REG("ACCLO", XTENSA_OPTION_MAC16),
 129    [ACCHI] = XTENSA_REG("ACCHI", XTENSA_OPTION_MAC16),
 130    [MR] = XTENSA_REG("MR0", XTENSA_OPTION_MAC16),
 131    [MR + 1] = XTENSA_REG("MR1", XTENSA_OPTION_MAC16),
 132    [MR + 2] = XTENSA_REG("MR2", XTENSA_OPTION_MAC16),
 133    [MR + 3] = XTENSA_REG("MR3", XTENSA_OPTION_MAC16),
 134    [WINDOW_BASE] = XTENSA_REG("WINDOW_BASE", XTENSA_OPTION_WINDOWED_REGISTER),
 135    [WINDOW_START] = XTENSA_REG("WINDOW_START",
 136            XTENSA_OPTION_WINDOWED_REGISTER),
 137    [PTEVADDR] = XTENSA_REG("PTEVADDR", XTENSA_OPTION_MMU),
 138    [MMID] = XTENSA_REG_BITS("MMID", XTENSA_OPTION_ALL),
 139    [RASID] = XTENSA_REG("RASID", XTENSA_OPTION_MMU),
 140    [ITLBCFG] = XTENSA_REG("ITLBCFG", XTENSA_OPTION_MMU),
 141    [DTLBCFG] = XTENSA_REG("DTLBCFG", XTENSA_OPTION_MMU),
 142    [IBREAKENABLE] = XTENSA_REG("IBREAKENABLE", XTENSA_OPTION_DEBUG),
 143    [MEMCTL] = XTENSA_REG_BITS("MEMCTL", XTENSA_OPTION_ALL),
 144    [CACHEATTR] = XTENSA_REG("CACHEATTR", XTENSA_OPTION_CACHEATTR),
 145    [ATOMCTL] = XTENSA_REG("ATOMCTL", XTENSA_OPTION_ATOMCTL),
 146    [DDR] = XTENSA_REG("DDR", XTENSA_OPTION_DEBUG),
 147    [IBREAKA] = XTENSA_REG("IBREAKA0", XTENSA_OPTION_DEBUG),
 148    [IBREAKA + 1] = XTENSA_REG("IBREAKA1", XTENSA_OPTION_DEBUG),
 149    [DBREAKA] = XTENSA_REG("DBREAKA0", XTENSA_OPTION_DEBUG),
 150    [DBREAKA + 1] = XTENSA_REG("DBREAKA1", XTENSA_OPTION_DEBUG),
 151    [DBREAKC] = XTENSA_REG("DBREAKC0", XTENSA_OPTION_DEBUG),
 152    [DBREAKC + 1] = XTENSA_REG("DBREAKC1", XTENSA_OPTION_DEBUG),
 153    [CONFIGID0] = XTENSA_REG_BITS_ACCESS("CONFIGID0", XTENSA_OPTION_ALL, SR_R),
 154    [EPC1] = XTENSA_REG("EPC1", XTENSA_OPTION_EXCEPTION),
 155    [EPC1 + 1] = XTENSA_REG("EPC2", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
 156    [EPC1 + 2] = XTENSA_REG("EPC3", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
 157    [EPC1 + 3] = XTENSA_REG("EPC4", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
 158    [EPC1 + 4] = XTENSA_REG("EPC5", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
 159    [EPC1 + 5] = XTENSA_REG("EPC6", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
 160    [EPC1 + 6] = XTENSA_REG("EPC7", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
 161    [DEPC] = XTENSA_REG("DEPC", XTENSA_OPTION_EXCEPTION),
 162    [EPS2] = XTENSA_REG("EPS2", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
 163    [EPS2 + 1] = XTENSA_REG("EPS3", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
 164    [EPS2 + 2] = XTENSA_REG("EPS4", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
 165    [EPS2 + 3] = XTENSA_REG("EPS5", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
 166    [EPS2 + 4] = XTENSA_REG("EPS6", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
 167    [EPS2 + 5] = XTENSA_REG("EPS7", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
 168    [CONFIGID1] = XTENSA_REG_BITS_ACCESS("CONFIGID1", XTENSA_OPTION_ALL, SR_R),
 169    [EXCSAVE1] = XTENSA_REG("EXCSAVE1", XTENSA_OPTION_EXCEPTION),
 170    [EXCSAVE1 + 1] = XTENSA_REG("EXCSAVE2",
 171            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
 172    [EXCSAVE1 + 2] = XTENSA_REG("EXCSAVE3",
 173            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
 174    [EXCSAVE1 + 3] = XTENSA_REG("EXCSAVE4",
 175            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
 176    [EXCSAVE1 + 4] = XTENSA_REG("EXCSAVE5",
 177            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
 178    [EXCSAVE1 + 5] = XTENSA_REG("EXCSAVE6",
 179            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
 180    [EXCSAVE1 + 6] = XTENSA_REG("EXCSAVE7",
 181            XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
 182    [CPENABLE] = XTENSA_REG("CPENABLE", XTENSA_OPTION_COPROCESSOR),
 183    [INTSET] = XTENSA_REG_ACCESS("INTSET", XTENSA_OPTION_INTERRUPT, SR_RW),
 184    [INTCLEAR] = XTENSA_REG_ACCESS("INTCLEAR", XTENSA_OPTION_INTERRUPT, SR_W),
 185    [INTENABLE] = XTENSA_REG("INTENABLE", XTENSA_OPTION_INTERRUPT),
 186    [PS] = XTENSA_REG_BITS("PS", XTENSA_OPTION_ALL),
 187    [VECBASE] = XTENSA_REG("VECBASE", XTENSA_OPTION_RELOCATABLE_VECTOR),
 188    [EXCCAUSE] = XTENSA_REG("EXCCAUSE", XTENSA_OPTION_EXCEPTION),
 189    [DEBUGCAUSE] = XTENSA_REG_ACCESS("DEBUGCAUSE", XTENSA_OPTION_DEBUG, SR_R),
 190    [CCOUNT] = XTENSA_REG("CCOUNT", XTENSA_OPTION_TIMER_INTERRUPT),
 191    [PRID] = XTENSA_REG_ACCESS("PRID", XTENSA_OPTION_PROCESSOR_ID, SR_R),
 192    [ICOUNT] = XTENSA_REG("ICOUNT", XTENSA_OPTION_DEBUG),
 193    [ICOUNTLEVEL] = XTENSA_REG("ICOUNTLEVEL", XTENSA_OPTION_DEBUG),
 194    [EXCVADDR] = XTENSA_REG("EXCVADDR", XTENSA_OPTION_EXCEPTION),
 195    [CCOMPARE] = XTENSA_REG("CCOMPARE0", XTENSA_OPTION_TIMER_INTERRUPT),
 196    [CCOMPARE + 1] = XTENSA_REG("CCOMPARE1",
 197            XTENSA_OPTION_TIMER_INTERRUPT),
 198    [CCOMPARE + 2] = XTENSA_REG("CCOMPARE2",
 199            XTENSA_OPTION_TIMER_INTERRUPT),
 200    [MISC] = XTENSA_REG("MISC0", XTENSA_OPTION_MISC_SR),
 201    [MISC + 1] = XTENSA_REG("MISC1", XTENSA_OPTION_MISC_SR),
 202    [MISC + 2] = XTENSA_REG("MISC2", XTENSA_OPTION_MISC_SR),
 203    [MISC + 3] = XTENSA_REG("MISC3", XTENSA_OPTION_MISC_SR),
 204};
 205
 206static const XtensaReg uregnames[256] = {
 207    [EXPSTATE] = XTENSA_REG_BITS("EXPSTATE", XTENSA_OPTION_ALL),
 208    [THREADPTR] = XTENSA_REG("THREADPTR", XTENSA_OPTION_THREAD_POINTER),
 209    [FCR] = XTENSA_REG("FCR", XTENSA_OPTION_FP_COPROCESSOR),
 210    [FSR] = XTENSA_REG("FSR", XTENSA_OPTION_FP_COPROCESSOR),
 211};
 212
 213void xtensa_translate_init(void)
 214{
 215    static const char * const regnames[] = {
 216        "ar0", "ar1", "ar2", "ar3",
 217        "ar4", "ar5", "ar6", "ar7",
 218        "ar8", "ar9", "ar10", "ar11",
 219        "ar12", "ar13", "ar14", "ar15",
 220    };
 221    static const char * const fregnames[] = {
 222        "f0", "f1", "f2", "f3",
 223        "f4", "f5", "f6", "f7",
 224        "f8", "f9", "f10", "f11",
 225        "f12", "f13", "f14", "f15",
 226    };
 227    int i;
 228
 229    cpu_pc = tcg_global_mem_new_i32(cpu_env,
 230            offsetof(CPUXtensaState, pc), "pc");
 231
 232    for (i = 0; i < 16; i++) {
 233        cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
 234                offsetof(CPUXtensaState, regs[i]),
 235                regnames[i]);
 236    }
 237
 238    for (i = 0; i < 16; i++) {
 239        cpu_FR[i] = tcg_global_mem_new_i32(cpu_env,
 240                offsetof(CPUXtensaState, fregs[i].f32[FP_F32_LOW]),
 241                fregnames[i]);
 242    }
 243
 244    for (i = 0; i < 256; ++i) {
 245        if (sregnames[i].name) {
 246            cpu_SR[i] = tcg_global_mem_new_i32(cpu_env,
 247                    offsetof(CPUXtensaState, sregs[i]),
 248                    sregnames[i].name);
 249        }
 250    }
 251
 252    for (i = 0; i < 256; ++i) {
 253        if (uregnames[i].name) {
 254            cpu_UR[i] = tcg_global_mem_new_i32(cpu_env,
 255                    offsetof(CPUXtensaState, uregs[i]),
 256                    uregnames[i].name);
 257        }
 258    }
 259}
 260
 261static inline bool option_enabled(DisasContext *dc, int opt)
 262{
 263    return xtensa_option_enabled(dc->config, opt);
 264}
 265
 266static void init_sar_tracker(DisasContext *dc)
 267{
 268    dc->sar_5bit = false;
 269    dc->sar_m32_5bit = false;
 270    dc->sar_m32_allocated = false;
 271}
 272
 273static void reset_sar_tracker(DisasContext *dc)
 274{
 275    if (dc->sar_m32_allocated) {
 276        tcg_temp_free(dc->sar_m32);
 277    }
 278}
 279
 280static void gen_right_shift_sar(DisasContext *dc, TCGv_i32 sa)
 281{
 282    tcg_gen_andi_i32(cpu_SR[SAR], sa, 0x1f);
 283    if (dc->sar_m32_5bit) {
 284        tcg_gen_discard_i32(dc->sar_m32);
 285    }
 286    dc->sar_5bit = true;
 287    dc->sar_m32_5bit = false;
 288}
 289
 290static void gen_left_shift_sar(DisasContext *dc, TCGv_i32 sa)
 291{
 292    TCGv_i32 tmp = tcg_const_i32(32);
 293    if (!dc->sar_m32_allocated) {
 294        dc->sar_m32 = tcg_temp_local_new_i32();
 295        dc->sar_m32_allocated = true;
 296    }
 297    tcg_gen_andi_i32(dc->sar_m32, sa, 0x1f);
 298    tcg_gen_sub_i32(cpu_SR[SAR], tmp, dc->sar_m32);
 299    dc->sar_5bit = false;
 300    dc->sar_m32_5bit = true;
 301    tcg_temp_free(tmp);
 302}
 303
 304static void gen_exception(DisasContext *dc, int excp)
 305{
 306    TCGv_i32 tmp = tcg_const_i32(excp);
 307    gen_helper_exception(cpu_env, tmp);
 308    tcg_temp_free(tmp);
 309}
 310
 311static void gen_exception_cause(DisasContext *dc, uint32_t cause)
 312{
 313    TCGv_i32 tpc = tcg_const_i32(dc->pc);
 314    TCGv_i32 tcause = tcg_const_i32(cause);
 315    gen_helper_exception_cause(cpu_env, tpc, tcause);
 316    tcg_temp_free(tpc);
 317    tcg_temp_free(tcause);
 318    if (cause == ILLEGAL_INSTRUCTION_CAUSE ||
 319            cause == SYSCALL_CAUSE) {
 320        dc->is_jmp = DISAS_UPDATE;
 321    }
 322}
 323
 324static void gen_exception_cause_vaddr(DisasContext *dc, uint32_t cause,
 325        TCGv_i32 vaddr)
 326{
 327    TCGv_i32 tpc = tcg_const_i32(dc->pc);
 328    TCGv_i32 tcause = tcg_const_i32(cause);
 329    gen_helper_exception_cause_vaddr(cpu_env, tpc, tcause, vaddr);
 330    tcg_temp_free(tpc);
 331    tcg_temp_free(tcause);
 332}
 333
 334static void gen_debug_exception(DisasContext *dc, uint32_t cause)
 335{
 336    TCGv_i32 tpc = tcg_const_i32(dc->pc);
 337    TCGv_i32 tcause = tcg_const_i32(cause);
 338    gen_helper_debug_exception(cpu_env, tpc, tcause);
 339    tcg_temp_free(tpc);
 340    tcg_temp_free(tcause);
 341    if (cause & (DEBUGCAUSE_IB | DEBUGCAUSE_BI | DEBUGCAUSE_BN)) {
 342        dc->is_jmp = DISAS_UPDATE;
 343    }
 344}
 345
 346static bool gen_check_privilege(DisasContext *dc)
 347{
 348#ifndef CONFIG_USER_ONLY
 349    if (!dc->cring) {
 350        return true;
 351    }
 352#endif
 353    gen_exception_cause(dc, PRIVILEGED_CAUSE);
 354    dc->is_jmp = DISAS_UPDATE;
 355    return false;
 356}
 357
 358static bool gen_check_cpenable(DisasContext *dc, unsigned cp)
 359{
 360    if (option_enabled(dc, XTENSA_OPTION_COPROCESSOR) &&
 361            !(dc->cpenable & (1 << cp))) {
 362        gen_exception_cause(dc, COPROCESSOR0_DISABLED + cp);
 363        dc->is_jmp = DISAS_UPDATE;
 364        return false;
 365    }
 366    return true;
 367}
 368
 369static void gen_jump_slot(DisasContext *dc, TCGv dest, int slot)
 370{
 371    tcg_gen_mov_i32(cpu_pc, dest);
 372    if (dc->icount) {
 373        tcg_gen_mov_i32(cpu_SR[ICOUNT], dc->next_icount);
 374    }
 375    if (dc->singlestep_enabled) {
 376        gen_exception(dc, EXCP_DEBUG);
 377    } else {
 378        if (slot >= 0) {
 379            tcg_gen_goto_tb(slot);
 380            tcg_gen_exit_tb((uintptr_t)dc->tb + slot);
 381        } else {
 382            tcg_gen_exit_tb(0);
 383        }
 384    }
 385    dc->is_jmp = DISAS_UPDATE;
 386}
 387
 388static void gen_jump(DisasContext *dc, TCGv dest)
 389{
 390    gen_jump_slot(dc, dest, -1);
 391}
 392
 393static void gen_jumpi(DisasContext *dc, uint32_t dest, int slot)
 394{
 395    TCGv_i32 tmp = tcg_const_i32(dest);
 396#ifndef CONFIG_USER_ONLY
 397    if (((dc->tb->pc ^ dest) & TARGET_PAGE_MASK) != 0) {
 398        slot = -1;
 399    }
 400#endif
 401    gen_jump_slot(dc, tmp, slot);
 402    tcg_temp_free(tmp);
 403}
 404
 405static void gen_callw_slot(DisasContext *dc, int callinc, TCGv_i32 dest,
 406        int slot)
 407{
 408    TCGv_i32 tcallinc = tcg_const_i32(callinc);
 409
 410    tcg_gen_deposit_i32(cpu_SR[PS], cpu_SR[PS],
 411            tcallinc, PS_CALLINC_SHIFT, PS_CALLINC_LEN);
 412    tcg_temp_free(tcallinc);
 413    tcg_gen_movi_i32(cpu_R[callinc << 2],
 414            (callinc << 30) | (dc->next_pc & 0x3fffffff));
 415    gen_jump_slot(dc, dest, slot);
 416}
 417
 418static void gen_callw(DisasContext *dc, int callinc, TCGv_i32 dest)
 419{
 420    gen_callw_slot(dc, callinc, dest, -1);
 421}
 422
 423static void gen_callwi(DisasContext *dc, int callinc, uint32_t dest, int slot)
 424{
 425    TCGv_i32 tmp = tcg_const_i32(dest);
 426#ifndef CONFIG_USER_ONLY
 427    if (((dc->tb->pc ^ dest) & TARGET_PAGE_MASK) != 0) {
 428        slot = -1;
 429    }
 430#endif
 431    gen_callw_slot(dc, callinc, tmp, slot);
 432    tcg_temp_free(tmp);
 433}
 434
 435static bool gen_check_loop_end(DisasContext *dc, int slot)
 436{
 437    if (option_enabled(dc, XTENSA_OPTION_LOOP) &&
 438            !(dc->tb->flags & XTENSA_TBFLAG_EXCM) &&
 439            dc->next_pc == dc->lend) {
 440        TCGLabel *label = gen_new_label();
 441
 442        tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_SR[LCOUNT], 0, label);
 443        tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_SR[LCOUNT], 1);
 444        gen_jumpi(dc, dc->lbeg, slot);
 445        gen_set_label(label);
 446        gen_jumpi(dc, dc->next_pc, -1);
 447        return true;
 448    }
 449    return false;
 450}
 451
 452static void gen_jumpi_check_loop_end(DisasContext *dc, int slot)
 453{
 454    if (!gen_check_loop_end(dc, slot)) {
 455        gen_jumpi(dc, dc->next_pc, slot);
 456    }
 457}
 458
 459static void gen_brcond(DisasContext *dc, TCGCond cond,
 460                       TCGv_i32 t0, TCGv_i32 t1, uint32_t addr)
 461{
 462    TCGLabel *label = gen_new_label();
 463
 464    tcg_gen_brcond_i32(cond, t0, t1, label);
 465    gen_jumpi_check_loop_end(dc, 0);
 466    gen_set_label(label);
 467    gen_jumpi(dc, addr, 1);
 468}
 469
 470static void gen_brcondi(DisasContext *dc, TCGCond cond,
 471                        TCGv_i32 t0, uint32_t t1, uint32_t addr)
 472{
 473    TCGv_i32 tmp = tcg_const_i32(t1);
 474    gen_brcond(dc, cond, t0, tmp, addr);
 475    tcg_temp_free(tmp);
 476}
 477
 478static bool gen_check_sr(DisasContext *dc, uint32_t sr, unsigned access)
 479{
 480    if (!xtensa_option_bits_enabled(dc->config, sregnames[sr].opt_bits)) {
 481        if (sregnames[sr].name) {
 482            qemu_log_mask(LOG_GUEST_ERROR, "SR %s is not configured\n", sregnames[sr].name);
 483        } else {
 484            qemu_log_mask(LOG_UNIMP, "SR %d is not implemented\n", sr);
 485        }
 486        gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
 487        return false;
 488    } else if (!(sregnames[sr].access & access)) {
 489        static const char * const access_text[] = {
 490            [SR_R] = "rsr",
 491            [SR_W] = "wsr",
 492            [SR_X] = "xsr",
 493        };
 494        assert(access < ARRAY_SIZE(access_text) && access_text[access]);
 495        qemu_log_mask(LOG_GUEST_ERROR, "SR %s is not available for %s\n", sregnames[sr].name,
 496                      access_text[access]);
 497        gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
 498        return false;
 499    }
 500    return true;
 501}
 502
 503#ifndef CONFIG_USER_ONLY
 504static bool gen_rsr_ccount(DisasContext *dc, TCGv_i32 d, uint32_t sr)
 505{
 506    if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
 507        gen_io_start();
 508    }
 509    gen_helper_update_ccount(cpu_env);
 510    tcg_gen_mov_i32(d, cpu_SR[sr]);
 511    if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
 512        gen_io_end();
 513        return true;
 514    }
 515    return false;
 516}
 517
 518static bool gen_rsr_ptevaddr(DisasContext *dc, TCGv_i32 d, uint32_t sr)
 519{
 520    tcg_gen_shri_i32(d, cpu_SR[EXCVADDR], 10);
 521    tcg_gen_or_i32(d, d, cpu_SR[sr]);
 522    tcg_gen_andi_i32(d, d, 0xfffffffc);
 523    return false;
 524}
 525#endif
 526
 527static bool gen_rsr(DisasContext *dc, TCGv_i32 d, uint32_t sr)
 528{
 529    static bool (* const rsr_handler[256])(DisasContext *dc,
 530            TCGv_i32 d, uint32_t sr) = {
 531#ifndef CONFIG_USER_ONLY
 532        [CCOUNT] = gen_rsr_ccount,
 533        [INTSET] = gen_rsr_ccount,
 534        [PTEVADDR] = gen_rsr_ptevaddr,
 535#endif
 536    };
 537
 538    if (rsr_handler[sr]) {
 539        return rsr_handler[sr](dc, d, sr);
 540    } else {
 541        tcg_gen_mov_i32(d, cpu_SR[sr]);
 542        return false;
 543    }
 544}
 545
 546static bool gen_wsr_lbeg(DisasContext *dc, uint32_t sr, TCGv_i32 s)
 547{
 548    gen_helper_wsr_lbeg(cpu_env, s);
 549    gen_jumpi_check_loop_end(dc, 0);
 550    return false;
 551}
 552
 553static bool gen_wsr_lend(DisasContext *dc, uint32_t sr, TCGv_i32 s)
 554{
 555    gen_helper_wsr_lend(cpu_env, s);
 556    gen_jumpi_check_loop_end(dc, 0);
 557    return false;
 558}
 559
 560static bool gen_wsr_sar(DisasContext *dc, uint32_t sr, TCGv_i32 s)
 561{
 562    tcg_gen_andi_i32(cpu_SR[sr], s, 0x3f);
 563    if (dc->sar_m32_5bit) {
 564        tcg_gen_discard_i32(dc->sar_m32);
 565    }
 566    dc->sar_5bit = false;
 567    dc->sar_m32_5bit = false;
 568    return false;
 569}
 570
 571static bool gen_wsr_br(DisasContext *dc, uint32_t sr, TCGv_i32 s)
 572{
 573    tcg_gen_andi_i32(cpu_SR[sr], s, 0xffff);
 574    return false;
 575}
 576
 577static bool gen_wsr_litbase(DisasContext *dc, uint32_t sr, TCGv_i32 s)
 578{
 579    tcg_gen_andi_i32(cpu_SR[sr], s, 0xfffff001);
 580    /* This can change tb->flags, so exit tb */
 581    gen_jumpi_check_loop_end(dc, -1);
 582    return true;
 583}
 584
 585static bool gen_wsr_acchi(DisasContext *dc, uint32_t sr, TCGv_i32 s)
 586{
 587    tcg_gen_ext8s_i32(cpu_SR[sr], s);
 588    return false;
 589}
 590
 591#ifndef CONFIG_USER_ONLY
 592static bool gen_wsr_windowbase(DisasContext *dc, uint32_t sr, TCGv_i32 v)
 593{
 594    gen_helper_wsr_windowbase(cpu_env, v);
 595    /* This can change tb->flags, so exit tb */
 596    gen_jumpi_check_loop_end(dc, -1);
 597    return true;
 598}
 599
 600static bool gen_wsr_windowstart(DisasContext *dc, uint32_t sr, TCGv_i32 v)
 601{
 602    tcg_gen_andi_i32(cpu_SR[sr], v, (1 << dc->config->nareg / 4) - 1);
 603    /* This can change tb->flags, so exit tb */
 604    gen_jumpi_check_loop_end(dc, -1);
 605    return true;
 606}
 607
 608static bool gen_wsr_ptevaddr(DisasContext *dc, uint32_t sr, TCGv_i32 v)
 609{
 610    tcg_gen_andi_i32(cpu_SR[sr], v, 0xffc00000);
 611    return false;
 612}
 613
 614static bool gen_wsr_rasid(DisasContext *dc, uint32_t sr, TCGv_i32 v)
 615{
 616    gen_helper_wsr_rasid(cpu_env, v);
 617    /* This can change tb->flags, so exit tb */
 618    gen_jumpi_check_loop_end(dc, -1);
 619    return true;
 620}
 621
 622static bool gen_wsr_tlbcfg(DisasContext *dc, uint32_t sr, TCGv_i32 v)
 623{
 624    tcg_gen_andi_i32(cpu_SR[sr], v, 0x01130000);
 625    return false;
 626}
 627
 628static bool gen_wsr_ibreakenable(DisasContext *dc, uint32_t sr, TCGv_i32 v)
 629{
 630    gen_helper_wsr_ibreakenable(cpu_env, v);
 631    gen_jumpi_check_loop_end(dc, 0);
 632    return true;
 633}
 634
 635static bool gen_wsr_memctl(DisasContext *dc, uint32_t sr, TCGv_i32 v)
 636{
 637    gen_helper_wsr_memctl(cpu_env, v);
 638    return false;
 639}
 640
 641static bool gen_wsr_atomctl(DisasContext *dc, uint32_t sr, TCGv_i32 v)
 642{
 643    tcg_gen_andi_i32(cpu_SR[sr], v, 0x3f);
 644    return false;
 645}
 646
 647static bool gen_wsr_ibreaka(DisasContext *dc, uint32_t sr, TCGv_i32 v)
 648{
 649    unsigned id = sr - IBREAKA;
 650
 651    if (id < dc->config->nibreak) {
 652        TCGv_i32 tmp = tcg_const_i32(id);
 653        gen_helper_wsr_ibreaka(cpu_env, tmp, v);
 654        tcg_temp_free(tmp);
 655        gen_jumpi_check_loop_end(dc, 0);
 656        return true;
 657    }
 658    return false;
 659}
 660
 661static bool gen_wsr_dbreaka(DisasContext *dc, uint32_t sr, TCGv_i32 v)
 662{
 663    unsigned id = sr - DBREAKA;
 664
 665    if (id < dc->config->ndbreak) {
 666        TCGv_i32 tmp = tcg_const_i32(id);
 667        gen_helper_wsr_dbreaka(cpu_env, tmp, v);
 668        tcg_temp_free(tmp);
 669    }
 670    return false;
 671}
 672
 673static bool gen_wsr_dbreakc(DisasContext *dc, uint32_t sr, TCGv_i32 v)
 674{
 675    unsigned id = sr - DBREAKC;
 676
 677    if (id < dc->config->ndbreak) {
 678        TCGv_i32 tmp = tcg_const_i32(id);
 679        gen_helper_wsr_dbreakc(cpu_env, tmp, v);
 680        tcg_temp_free(tmp);
 681    }
 682    return false;
 683}
 684
 685static bool gen_wsr_cpenable(DisasContext *dc, uint32_t sr, TCGv_i32 v)
 686{
 687    tcg_gen_andi_i32(cpu_SR[sr], v, 0xff);
 688    /* This can change tb->flags, so exit tb */
 689    gen_jumpi_check_loop_end(dc, -1);
 690    return true;
 691}
 692
 693static void gen_check_interrupts(DisasContext *dc)
 694{
 695    if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
 696        gen_io_start();
 697    }
 698    gen_helper_check_interrupts(cpu_env);
 699    if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
 700        gen_io_end();
 701    }
 702}
 703
 704static bool gen_wsr_intset(DisasContext *dc, uint32_t sr, TCGv_i32 v)
 705{
 706    tcg_gen_andi_i32(cpu_SR[sr], v,
 707            dc->config->inttype_mask[INTTYPE_SOFTWARE]);
 708    gen_check_interrupts(dc);
 709    gen_jumpi_check_loop_end(dc, 0);
 710    return true;
 711}
 712
 713static bool gen_wsr_intclear(DisasContext *dc, uint32_t sr, TCGv_i32 v)
 714{
 715    TCGv_i32 tmp = tcg_temp_new_i32();
 716
 717    tcg_gen_andi_i32(tmp, v,
 718            dc->config->inttype_mask[INTTYPE_EDGE] |
 719            dc->config->inttype_mask[INTTYPE_NMI] |
 720            dc->config->inttype_mask[INTTYPE_SOFTWARE]);
 721    tcg_gen_andc_i32(cpu_SR[INTSET], cpu_SR[INTSET], tmp);
 722    tcg_temp_free(tmp);
 723    gen_check_interrupts(dc);
 724    gen_jumpi_check_loop_end(dc, 0);
 725    return true;
 726}
 727
 728static bool gen_wsr_intenable(DisasContext *dc, uint32_t sr, TCGv_i32 v)
 729{
 730    tcg_gen_mov_i32(cpu_SR[sr], v);
 731    gen_check_interrupts(dc);
 732    gen_jumpi_check_loop_end(dc, 0);
 733    return true;
 734}
 735
 736static bool gen_wsr_ps(DisasContext *dc, uint32_t sr, TCGv_i32 v)
 737{
 738    uint32_t mask = PS_WOE | PS_CALLINC | PS_OWB |
 739        PS_UM | PS_EXCM | PS_INTLEVEL;
 740
 741    if (option_enabled(dc, XTENSA_OPTION_MMU)) {
 742        mask |= PS_RING;
 743    }
 744    tcg_gen_andi_i32(cpu_SR[sr], v, mask);
 745    gen_check_interrupts(dc);
 746    /* This can change mmu index and tb->flags, so exit tb */
 747    gen_jumpi_check_loop_end(dc, -1);
 748    return true;
 749}
 750
 751static bool gen_wsr_ccount(DisasContext *dc, uint32_t sr, TCGv_i32 v)
 752{
 753    if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
 754        gen_io_start();
 755    }
 756    gen_helper_wsr_ccount(cpu_env, v);
 757    if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
 758        gen_io_end();
 759        gen_jumpi_check_loop_end(dc, 0);
 760        return true;
 761    }
 762    return false;
 763}
 764
 765static bool gen_wsr_icount(DisasContext *dc, uint32_t sr, TCGv_i32 v)
 766{
 767    if (dc->icount) {
 768        tcg_gen_mov_i32(dc->next_icount, v);
 769    } else {
 770        tcg_gen_mov_i32(cpu_SR[sr], v);
 771    }
 772    return false;
 773}
 774
 775static bool gen_wsr_icountlevel(DisasContext *dc, uint32_t sr, TCGv_i32 v)
 776{
 777    tcg_gen_andi_i32(cpu_SR[sr], v, 0xf);
 778    /* This can change tb->flags, so exit tb */
 779    gen_jumpi_check_loop_end(dc, -1);
 780    return true;
 781}
 782
 783static bool gen_wsr_ccompare(DisasContext *dc, uint32_t sr, TCGv_i32 v)
 784{
 785    uint32_t id = sr - CCOMPARE;
 786    bool ret = false;
 787
 788    if (id < dc->config->nccompare) {
 789        uint32_t int_bit = 1 << dc->config->timerint[id];
 790        TCGv_i32 tmp = tcg_const_i32(id);
 791
 792        tcg_gen_mov_i32(cpu_SR[sr], v);
 793        tcg_gen_andi_i32(cpu_SR[INTSET], cpu_SR[INTSET], ~int_bit);
 794        if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
 795            gen_io_start();
 796        }
 797        gen_helper_update_ccompare(cpu_env, tmp);
 798        if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
 799            gen_io_end();
 800            gen_jumpi_check_loop_end(dc, 0);
 801            ret = true;
 802        }
 803        tcg_temp_free(tmp);
 804    }
 805    return ret;
 806}
 807#else
 808static void gen_check_interrupts(DisasContext *dc)
 809{
 810}
 811#endif
 812
 813static bool gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s)
 814{
 815    static bool (* const wsr_handler[256])(DisasContext *dc,
 816            uint32_t sr, TCGv_i32 v) = {
 817        [LBEG] = gen_wsr_lbeg,
 818        [LEND] = gen_wsr_lend,
 819        [SAR] = gen_wsr_sar,
 820        [BR] = gen_wsr_br,
 821        [LITBASE] = gen_wsr_litbase,
 822        [ACCHI] = gen_wsr_acchi,
 823#ifndef CONFIG_USER_ONLY
 824        [WINDOW_BASE] = gen_wsr_windowbase,
 825        [WINDOW_START] = gen_wsr_windowstart,
 826        [PTEVADDR] = gen_wsr_ptevaddr,
 827        [RASID] = gen_wsr_rasid,
 828        [ITLBCFG] = gen_wsr_tlbcfg,
 829        [DTLBCFG] = gen_wsr_tlbcfg,
 830        [IBREAKENABLE] = gen_wsr_ibreakenable,
 831        [MEMCTL] = gen_wsr_memctl,
 832        [ATOMCTL] = gen_wsr_atomctl,
 833        [IBREAKA] = gen_wsr_ibreaka,
 834        [IBREAKA + 1] = gen_wsr_ibreaka,
 835        [DBREAKA] = gen_wsr_dbreaka,
 836        [DBREAKA + 1] = gen_wsr_dbreaka,
 837        [DBREAKC] = gen_wsr_dbreakc,
 838        [DBREAKC + 1] = gen_wsr_dbreakc,
 839        [CPENABLE] = gen_wsr_cpenable,
 840        [INTSET] = gen_wsr_intset,
 841        [INTCLEAR] = gen_wsr_intclear,
 842        [INTENABLE] = gen_wsr_intenable,
 843        [PS] = gen_wsr_ps,
 844        [CCOUNT] = gen_wsr_ccount,
 845        [ICOUNT] = gen_wsr_icount,
 846        [ICOUNTLEVEL] = gen_wsr_icountlevel,
 847        [CCOMPARE] = gen_wsr_ccompare,
 848        [CCOMPARE + 1] = gen_wsr_ccompare,
 849        [CCOMPARE + 2] = gen_wsr_ccompare,
 850#endif
 851    };
 852
 853    if (wsr_handler[sr]) {
 854        return wsr_handler[sr](dc, sr, s);
 855    } else {
 856        tcg_gen_mov_i32(cpu_SR[sr], s);
 857        return false;
 858    }
 859}
 860
 861static void gen_wur(uint32_t ur, TCGv_i32 s)
 862{
 863    switch (ur) {
 864    case FCR:
 865        gen_helper_wur_fcr(cpu_env, s);
 866        break;
 867
 868    case FSR:
 869        tcg_gen_andi_i32(cpu_UR[ur], s, 0xffffff80);
 870        break;
 871
 872    default:
 873        tcg_gen_mov_i32(cpu_UR[ur], s);
 874        break;
 875    }
 876}
 877
 878static void gen_load_store_alignment(DisasContext *dc, int shift,
 879        TCGv_i32 addr, bool no_hw_alignment)
 880{
 881    if (!option_enabled(dc, XTENSA_OPTION_UNALIGNED_EXCEPTION)) {
 882        tcg_gen_andi_i32(addr, addr, ~0 << shift);
 883    } else if (option_enabled(dc, XTENSA_OPTION_HW_ALIGNMENT) &&
 884            no_hw_alignment) {
 885        TCGLabel *label = gen_new_label();
 886        TCGv_i32 tmp = tcg_temp_new_i32();
 887        tcg_gen_andi_i32(tmp, addr, ~(~0 << shift));
 888        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
 889        gen_exception_cause_vaddr(dc, LOAD_STORE_ALIGNMENT_CAUSE, addr);
 890        gen_set_label(label);
 891        tcg_temp_free(tmp);
 892    }
 893}
 894
 895#ifndef CONFIG_USER_ONLY
 896static void gen_waiti(DisasContext *dc, uint32_t imm4)
 897{
 898    TCGv_i32 pc = tcg_const_i32(dc->next_pc);
 899    TCGv_i32 intlevel = tcg_const_i32(imm4);
 900
 901    if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
 902        gen_io_start();
 903    }
 904    gen_helper_waiti(cpu_env, pc, intlevel);
 905    if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
 906        gen_io_end();
 907    }
 908    tcg_temp_free(pc);
 909    tcg_temp_free(intlevel);
 910    gen_jumpi_check_loop_end(dc, 0);
 911}
 912#endif
 913
 914static bool gen_window_check1(DisasContext *dc, unsigned r1)
 915{
 916    if (r1 / 4 > dc->window) {
 917        TCGv_i32 pc = tcg_const_i32(dc->pc);
 918        TCGv_i32 w = tcg_const_i32(r1 / 4);
 919
 920        gen_helper_window_check(cpu_env, pc, w);
 921        dc->is_jmp = DISAS_UPDATE;
 922        return false;
 923    }
 924    return true;
 925}
 926
 927static bool gen_window_check2(DisasContext *dc, unsigned r1, unsigned r2)
 928{
 929    return gen_window_check1(dc, r1 > r2 ? r1 : r2);
 930}
 931
 932static bool gen_window_check3(DisasContext *dc, unsigned r1, unsigned r2,
 933        unsigned r3)
 934{
 935    return gen_window_check2(dc, r1, r2 > r3 ? r2 : r3);
 936}
 937
 938static TCGv_i32 gen_mac16_m(TCGv_i32 v, bool hi, bool is_unsigned)
 939{
 940    TCGv_i32 m = tcg_temp_new_i32();
 941
 942    if (hi) {
 943        (is_unsigned ? tcg_gen_shri_i32 : tcg_gen_sari_i32)(m, v, 16);
 944    } else {
 945        (is_unsigned ? tcg_gen_ext16u_i32 : tcg_gen_ext16s_i32)(m, v);
 946    }
 947    return m;
 948}
 949
 950static inline unsigned xtensa_op0_insn_len(DisasContext *dc, uint8_t op0)
 951{
 952    return xtensa_isa_length_from_chars(dc->config->isa, &op0);
 953}
 954
 955static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
 956{
 957    xtensa_isa isa = dc->config->isa;
 958    unsigned char b[MAX_INSN_LENGTH] = {cpu_ldub_code(env, dc->pc)};
 959    unsigned len = xtensa_op0_insn_len(dc, b[0]);
 960    xtensa_format fmt;
 961    int slot, slots;
 962    unsigned i;
 963
 964    if (len == XTENSA_UNDEFINED) {
 965        qemu_log_mask(LOG_GUEST_ERROR,
 966                      "unknown instruction length (pc = %08x)\n",
 967                      dc->pc);
 968        gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
 969        return;
 970    }
 971
 972    dc->next_pc = dc->pc + len;
 973    for (i = 1; i < len; ++i) {
 974        b[i] = cpu_ldub_code(env, dc->pc + i);
 975    }
 976    xtensa_insnbuf_from_chars(isa, dc->insnbuf, b, len);
 977    fmt = xtensa_format_decode(isa, dc->insnbuf);
 978    if (fmt == XTENSA_UNDEFINED) {
 979        qemu_log_mask(LOG_GUEST_ERROR,
 980                      "unrecognized instruction format (pc = %08x)\n",
 981                      dc->pc);
 982        gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
 983        return;
 984    }
 985    slots = xtensa_format_num_slots(isa, fmt);
 986    for (slot = 0; slot < slots; ++slot) {
 987        xtensa_opcode opc;
 988        int opnd, vopnd, opnds;
 989        uint32_t raw_arg[MAX_OPCODE_ARGS];
 990        uint32_t arg[MAX_OPCODE_ARGS];
 991        XtensaOpcodeOps *ops;
 992
 993        dc->raw_arg = raw_arg;
 994
 995        xtensa_format_get_slot(isa, fmt, slot, dc->insnbuf, dc->slotbuf);
 996        opc = xtensa_opcode_decode(isa, fmt, slot, dc->slotbuf);
 997        if (opc == XTENSA_UNDEFINED) {
 998            qemu_log_mask(LOG_GUEST_ERROR,
 999                          "unrecognized opcode in slot %d (pc = %08x)\n",
1000                          slot, dc->pc);
1001            gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
1002            return;
1003        }
1004        opnds = xtensa_opcode_num_operands(isa, opc);
1005
1006        for (opnd = vopnd = 0; opnd < opnds; ++opnd) {
1007            if (xtensa_operand_is_visible(isa, opc, opnd)) {
1008                uint32_t v;
1009
1010                xtensa_operand_get_field(isa, opc, opnd, fmt, slot,
1011                                         dc->slotbuf, &v);
1012                xtensa_operand_decode(isa, opc, opnd, &v);
1013                raw_arg[vopnd] = v;
1014                if (xtensa_operand_is_PCrelative(isa, opc, opnd)) {
1015                    xtensa_operand_undo_reloc(isa, opc, opnd, &v, dc->pc);
1016                }
1017                arg[vopnd] = v;
1018                ++vopnd;
1019            }
1020        }
1021        ops = dc->config->opcode_ops[opc];
1022        if (ops) {
1023            ops->translate(dc, arg, ops->par);
1024        } else {
1025            qemu_log_mask(LOG_GUEST_ERROR,
1026                          "unimplemented opcode '%s' in slot %d (pc = %08x)\n",
1027                          xtensa_opcode_name(isa, opc), slot, dc->pc);
1028            gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
1029            return;
1030        }
1031    }
1032    if (dc->is_jmp == DISAS_NEXT) {
1033        gen_check_loop_end(dc, 0);
1034    }
1035    dc->pc = dc->next_pc;
1036}
1037
1038static inline unsigned xtensa_insn_len(CPUXtensaState *env, DisasContext *dc)
1039{
1040    uint8_t b0 = cpu_ldub_code(env, dc->pc);
1041    return xtensa_op0_insn_len(dc, b0);
1042}
1043
1044static void gen_ibreak_check(CPUXtensaState *env, DisasContext *dc)
1045{
1046    unsigned i;
1047
1048    for (i = 0; i < dc->config->nibreak; ++i) {
1049        if ((env->sregs[IBREAKENABLE] & (1 << i)) &&
1050                env->sregs[IBREAKA + i] == dc->pc) {
1051            gen_debug_exception(dc, DEBUGCAUSE_IB);
1052            break;
1053        }
1054    }
1055}
1056
1057void gen_intermediate_code(CPUState *cs, TranslationBlock *tb)
1058{
1059    CPUXtensaState *env = cs->env_ptr;
1060    DisasContext dc;
1061    int insn_count = 0;
1062    int max_insns = tb_cflags(tb) & CF_COUNT_MASK;
1063    uint32_t pc_start = tb->pc;
1064    uint32_t next_page_start =
1065        (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
1066
1067    if (max_insns == 0) {
1068        max_insns = CF_COUNT_MASK;
1069    }
1070    if (max_insns > TCG_MAX_INSNS) {
1071        max_insns = TCG_MAX_INSNS;
1072    }
1073
1074    dc.config = env->config;
1075    dc.singlestep_enabled = cs->singlestep_enabled;
1076    dc.tb = tb;
1077    dc.pc = pc_start;
1078    dc.ring = tb->flags & XTENSA_TBFLAG_RING_MASK;
1079    dc.cring = (tb->flags & XTENSA_TBFLAG_EXCM) ? 0 : dc.ring;
1080    dc.lbeg = env->sregs[LBEG];
1081    dc.lend = env->sregs[LEND];
1082    dc.is_jmp = DISAS_NEXT;
1083    dc.debug = tb->flags & XTENSA_TBFLAG_DEBUG;
1084    dc.icount = tb->flags & XTENSA_TBFLAG_ICOUNT;
1085    dc.cpenable = (tb->flags & XTENSA_TBFLAG_CPENABLE_MASK) >>
1086        XTENSA_TBFLAG_CPENABLE_SHIFT;
1087    dc.window = ((tb->flags & XTENSA_TBFLAG_WINDOW_MASK) >>
1088                 XTENSA_TBFLAG_WINDOW_SHIFT);
1089
1090    if (dc.config->isa) {
1091        dc.insnbuf = xtensa_insnbuf_alloc(dc.config->isa);
1092        dc.slotbuf = xtensa_insnbuf_alloc(dc.config->isa);
1093    }
1094
1095    init_sar_tracker(&dc);
1096    if (dc.icount) {
1097        dc.next_icount = tcg_temp_local_new_i32();
1098    }
1099
1100    gen_tb_start(tb);
1101
1102    if ((tb_cflags(tb) & CF_USE_ICOUNT) &&
1103        (tb->flags & XTENSA_TBFLAG_YIELD)) {
1104        tcg_gen_insn_start(dc.pc);
1105        ++insn_count;
1106        gen_exception(&dc, EXCP_YIELD);
1107        dc.is_jmp = DISAS_UPDATE;
1108        goto done;
1109    }
1110    if (tb->flags & XTENSA_TBFLAG_EXCEPTION) {
1111        tcg_gen_insn_start(dc.pc);
1112        ++insn_count;
1113        gen_exception(&dc, EXCP_DEBUG);
1114        dc.is_jmp = DISAS_UPDATE;
1115        goto done;
1116    }
1117
1118    do {
1119        tcg_gen_insn_start(dc.pc);
1120        ++insn_count;
1121
1122        if (unlikely(cpu_breakpoint_test(cs, dc.pc, BP_ANY))) {
1123            tcg_gen_movi_i32(cpu_pc, dc.pc);
1124            gen_exception(&dc, EXCP_DEBUG);
1125            dc.is_jmp = DISAS_UPDATE;
1126            /* The address covered by the breakpoint must be included in
1127               [tb->pc, tb->pc + tb->size) in order to for it to be
1128               properly cleared -- thus we increment the PC here so that
1129               the logic setting tb->size below does the right thing.  */
1130            dc.pc += 2;
1131            break;
1132        }
1133
1134        if (insn_count == max_insns && (tb_cflags(tb) & CF_LAST_IO)) {
1135            gen_io_start();
1136        }
1137
1138        if (dc.icount) {
1139            TCGLabel *label = gen_new_label();
1140
1141            tcg_gen_addi_i32(dc.next_icount, cpu_SR[ICOUNT], 1);
1142            tcg_gen_brcondi_i32(TCG_COND_NE, dc.next_icount, 0, label);
1143            tcg_gen_mov_i32(dc.next_icount, cpu_SR[ICOUNT]);
1144            if (dc.debug) {
1145                gen_debug_exception(&dc, DEBUGCAUSE_IC);
1146            }
1147            gen_set_label(label);
1148        }
1149
1150        if (dc.debug) {
1151            gen_ibreak_check(env, &dc);
1152        }
1153
1154        disas_xtensa_insn(env, &dc);
1155        if (dc.icount) {
1156            tcg_gen_mov_i32(cpu_SR[ICOUNT], dc.next_icount);
1157        }
1158        if (cs->singlestep_enabled) {
1159            tcg_gen_movi_i32(cpu_pc, dc.pc);
1160            gen_exception(&dc, EXCP_DEBUG);
1161            break;
1162        }
1163    } while (dc.is_jmp == DISAS_NEXT &&
1164            insn_count < max_insns &&
1165            dc.pc < next_page_start &&
1166            dc.pc + xtensa_insn_len(env, &dc) <= next_page_start &&
1167            !tcg_op_buf_full());
1168done:
1169    reset_sar_tracker(&dc);
1170    if (dc.icount) {
1171        tcg_temp_free(dc.next_icount);
1172    }
1173    if (dc.config->isa) {
1174        xtensa_insnbuf_free(dc.config->isa, dc.insnbuf);
1175        xtensa_insnbuf_free(dc.config->isa, dc.slotbuf);
1176    }
1177
1178    if (tb_cflags(tb) & CF_LAST_IO) {
1179        gen_io_end();
1180    }
1181
1182    if (dc.is_jmp == DISAS_NEXT) {
1183        gen_jumpi(&dc, dc.pc, 0);
1184    }
1185    gen_tb_end(tb, insn_count);
1186
1187#ifdef DEBUG_DISAS
1188    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
1189        && qemu_log_in_addr_range(pc_start)) {
1190        qemu_log_lock();
1191        qemu_log("----------------\n");
1192        qemu_log("IN: %s\n", lookup_symbol(pc_start));
1193        log_target_disas(cs, pc_start, dc.pc - pc_start);
1194        qemu_log("\n");
1195        qemu_log_unlock();
1196    }
1197#endif
1198    tb->size = dc.pc - pc_start;
1199    tb->icount = insn_count;
1200}
1201
1202void xtensa_cpu_dump_state(CPUState *cs, FILE *f,
1203                           fprintf_function cpu_fprintf, int flags)
1204{
1205    XtensaCPU *cpu = XTENSA_CPU(cs);
1206    CPUXtensaState *env = &cpu->env;
1207    int i, j;
1208
1209    cpu_fprintf(f, "PC=%08x\n\n", env->pc);
1210
1211    for (i = j = 0; i < 256; ++i) {
1212        if (xtensa_option_bits_enabled(env->config, sregnames[i].opt_bits)) {
1213            cpu_fprintf(f, "%12s=%08x%c", sregnames[i].name, env->sregs[i],
1214                    (j++ % 4) == 3 ? '\n' : ' ');
1215        }
1216    }
1217
1218    cpu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n");
1219
1220    for (i = j = 0; i < 256; ++i) {
1221        if (xtensa_option_bits_enabled(env->config, uregnames[i].opt_bits)) {
1222            cpu_fprintf(f, "%s=%08x%c", uregnames[i].name, env->uregs[i],
1223                    (j++ % 4) == 3 ? '\n' : ' ');
1224        }
1225    }
1226
1227    cpu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n");
1228
1229    for (i = 0; i < 16; ++i) {
1230        cpu_fprintf(f, " A%02d=%08x%c", i, env->regs[i],
1231                (i % 4) == 3 ? '\n' : ' ');
1232    }
1233
1234    xtensa_sync_phys_from_window(env);
1235    cpu_fprintf(f, "\n");
1236
1237    for (i = 0; i < env->config->nareg; ++i) {
1238        cpu_fprintf(f, "AR%02d=%08x ", i, env->phys_regs[i]);
1239        if (i % 4 == 3) {
1240            bool ws = (env->sregs[WINDOW_START] & (1 << (i / 4))) != 0;
1241            bool cw = env->sregs[WINDOW_BASE] == i / 4;
1242
1243            cpu_fprintf(f, "%c%c\n", ws ? '<' : ' ', cw ? '=' : ' ');
1244        }
1245    }
1246
1247    if (xtensa_option_enabled(env->config, XTENSA_OPTION_FP_COPROCESSOR)) {
1248        cpu_fprintf(f, "\n");
1249
1250        for (i = 0; i < 16; ++i) {
1251            cpu_fprintf(f, "F%02d=%08x (%+10.8e)%c", i,
1252                    float32_val(env->fregs[i].f32[FP_F32_LOW]),
1253                    *(float *)(env->fregs[i].f32 + FP_F32_LOW),
1254                    (i % 2) == 1 ? '\n' : ' ');
1255        }
1256    }
1257}
1258
1259void restore_state_to_opc(CPUXtensaState *env, TranslationBlock *tb,
1260                          target_ulong *data)
1261{
1262    env->pc = data[0];
1263}
1264
1265static int compare_opcode_ops(const void *a, const void *b)
1266{
1267    return strcmp((const char *)a,
1268                  ((const XtensaOpcodeOps *)b)->name);
1269}
1270
1271XtensaOpcodeOps *
1272xtensa_find_opcode_ops(const XtensaOpcodeTranslators *t,
1273                       const char *name)
1274{
1275    XtensaOpcodeOps *ops;
1276
1277    ops = bsearch(name, t->opcode, t->num_opcodes,
1278                  sizeof(XtensaOpcodeOps), compare_opcode_ops);
1279    return ops;
1280}
1281
1282static void translate_abs(DisasContext *dc, const uint32_t arg[],
1283                          const uint32_t par[])
1284{
1285    if (gen_window_check2(dc, arg[0], arg[1])) {
1286        TCGv_i32 zero = tcg_const_i32(0);
1287        TCGv_i32 neg = tcg_temp_new_i32();
1288
1289        tcg_gen_neg_i32(neg, cpu_R[arg[1]]);
1290        tcg_gen_movcond_i32(TCG_COND_GE, cpu_R[arg[0]],
1291                            cpu_R[arg[1]], zero, cpu_R[arg[1]], neg);
1292        tcg_temp_free(neg);
1293        tcg_temp_free(zero);
1294    }
1295}
1296
1297static void translate_add(DisasContext *dc, const uint32_t arg[],
1298                          const uint32_t par[])
1299{
1300    if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
1301        tcg_gen_add_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
1302    }
1303}
1304
1305static void translate_addi(DisasContext *dc, const uint32_t arg[],
1306                           const uint32_t par[])
1307{
1308    if (gen_window_check2(dc, arg[0], arg[1])) {
1309        tcg_gen_addi_i32(cpu_R[arg[0]], cpu_R[arg[1]], arg[2]);
1310    }
1311}
1312
1313static void translate_addx(DisasContext *dc, const uint32_t arg[],
1314                           const uint32_t par[])
1315{
1316    if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
1317        TCGv_i32 tmp = tcg_temp_new_i32();
1318        tcg_gen_shli_i32(tmp, cpu_R[arg[1]], par[0]);
1319        tcg_gen_add_i32(cpu_R[arg[0]], tmp, cpu_R[arg[2]]);
1320        tcg_temp_free(tmp);
1321    }
1322}
1323
1324static void translate_all(DisasContext *dc, const uint32_t arg[],
1325                          const uint32_t par[])
1326{
1327    uint32_t shift = par[1];
1328    TCGv_i32 mask = tcg_const_i32(((1 << shift) - 1) << arg[1]);
1329    TCGv_i32 tmp = tcg_temp_new_i32();
1330
1331    tcg_gen_and_i32(tmp, cpu_SR[BR], mask);
1332    if (par[0]) {
1333        tcg_gen_addi_i32(tmp, tmp, 1 << arg[1]);
1334    } else {
1335        tcg_gen_add_i32(tmp, tmp, mask);
1336    }
1337    tcg_gen_shri_i32(tmp, tmp, arg[1] + shift);
1338    tcg_gen_deposit_i32(cpu_SR[BR], cpu_SR[BR],
1339                        tmp, arg[0], 1);
1340    tcg_temp_free(mask);
1341    tcg_temp_free(tmp);
1342}
1343
1344static void translate_and(DisasContext *dc, const uint32_t arg[],
1345                          const uint32_t par[])
1346{
1347    if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
1348        tcg_gen_and_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
1349    }
1350}
1351
1352static void translate_ball(DisasContext *dc, const uint32_t arg[],
1353                           const uint32_t par[])
1354{
1355    if (gen_window_check2(dc, arg[0], arg[1])) {
1356        TCGv_i32 tmp = tcg_temp_new_i32();
1357        tcg_gen_and_i32(tmp, cpu_R[arg[0]], cpu_R[arg[1]]);
1358        gen_brcond(dc, par[0], tmp, cpu_R[arg[1]], arg[2]);
1359        tcg_temp_free(tmp);
1360    }
1361}
1362
1363static void translate_bany(DisasContext *dc, const uint32_t arg[],
1364                           const uint32_t par[])
1365{
1366    if (gen_window_check2(dc, arg[0], arg[1])) {
1367        TCGv_i32 tmp = tcg_temp_new_i32();
1368        tcg_gen_and_i32(tmp, cpu_R[arg[0]], cpu_R[arg[1]]);
1369        gen_brcondi(dc, par[0], tmp, 0, arg[2]);
1370        tcg_temp_free(tmp);
1371    }
1372}
1373
1374static void translate_b(DisasContext *dc, const uint32_t arg[],
1375                        const uint32_t par[])
1376{
1377    if (gen_window_check2(dc, arg[0], arg[1])) {
1378        gen_brcond(dc, par[0], cpu_R[arg[0]], cpu_R[arg[1]], arg[2]);
1379    }
1380}
1381
1382static void translate_bb(DisasContext *dc, const uint32_t arg[],
1383                         const uint32_t par[])
1384{
1385    if (gen_window_check2(dc, arg[0], arg[1])) {
1386#ifdef TARGET_WORDS_BIGENDIAN
1387        TCGv_i32 bit = tcg_const_i32(0x80000000u);
1388#else
1389        TCGv_i32 bit = tcg_const_i32(0x00000001u);
1390#endif
1391        TCGv_i32 tmp = tcg_temp_new_i32();
1392        tcg_gen_andi_i32(tmp, cpu_R[arg[1]], 0x1f);
1393#ifdef TARGET_WORDS_BIGENDIAN
1394        tcg_gen_shr_i32(bit, bit, tmp);
1395#else
1396        tcg_gen_shl_i32(bit, bit, tmp);
1397#endif
1398        tcg_gen_and_i32(tmp, cpu_R[arg[0]], bit);
1399        gen_brcondi(dc, par[0], tmp, 0, arg[2]);
1400        tcg_temp_free(tmp);
1401        tcg_temp_free(bit);
1402    }
1403}
1404
1405static void translate_bbi(DisasContext *dc, const uint32_t arg[],
1406                          const uint32_t par[])
1407{
1408    if (gen_window_check1(dc, arg[0])) {
1409        TCGv_i32 tmp = tcg_temp_new_i32();
1410#ifdef TARGET_WORDS_BIGENDIAN
1411        tcg_gen_andi_i32(tmp, cpu_R[arg[0]], 0x80000000u >> arg[1]);
1412#else
1413        tcg_gen_andi_i32(tmp, cpu_R[arg[0]], 0x00000001u << arg[1]);
1414#endif
1415        gen_brcondi(dc, par[0], tmp, 0, arg[2]);
1416        tcg_temp_free(tmp);
1417    }
1418}
1419
1420static void translate_bi(DisasContext *dc, const uint32_t arg[],
1421                         const uint32_t par[])
1422{
1423    if (gen_window_check1(dc, arg[0])) {
1424        gen_brcondi(dc, par[0], cpu_R[arg[0]], arg[1], arg[2]);
1425    }
1426}
1427
1428static void translate_bz(DisasContext *dc, const uint32_t arg[],
1429                         const uint32_t par[])
1430{
1431    if (gen_window_check1(dc, arg[0])) {
1432        gen_brcondi(dc, par[0], cpu_R[arg[0]], 0, arg[1]);
1433    }
1434}
1435
1436enum {
1437    BOOLEAN_AND,
1438    BOOLEAN_ANDC,
1439    BOOLEAN_OR,
1440    BOOLEAN_ORC,
1441    BOOLEAN_XOR,
1442};
1443
1444static void translate_boolean(DisasContext *dc, const uint32_t arg[],
1445                              const uint32_t par[])
1446{
1447    static void (* const op[])(TCGv_i32, TCGv_i32, TCGv_i32) = {
1448        [BOOLEAN_AND] = tcg_gen_and_i32,
1449        [BOOLEAN_ANDC] = tcg_gen_andc_i32,
1450        [BOOLEAN_OR] = tcg_gen_or_i32,
1451        [BOOLEAN_ORC] = tcg_gen_orc_i32,
1452        [BOOLEAN_XOR] = tcg_gen_xor_i32,
1453    };
1454
1455    TCGv_i32 tmp1 = tcg_temp_new_i32();
1456    TCGv_i32 tmp2 = tcg_temp_new_i32();
1457
1458    tcg_gen_shri_i32(tmp1, cpu_SR[BR], arg[1]);
1459    tcg_gen_shri_i32(tmp2, cpu_SR[BR], arg[2]);
1460    op[par[0]](tmp1, tmp1, tmp2);
1461    tcg_gen_deposit_i32(cpu_SR[BR], cpu_SR[BR], tmp1, arg[0], 1);
1462    tcg_temp_free(tmp1);
1463    tcg_temp_free(tmp2);
1464}
1465
1466static void translate_bp(DisasContext *dc, const uint32_t arg[],
1467                         const uint32_t par[])
1468{
1469    TCGv_i32 tmp = tcg_temp_new_i32();
1470
1471    tcg_gen_andi_i32(tmp, cpu_SR[BR], 1 << arg[0]);
1472    gen_brcondi(dc, par[0], tmp, 0, arg[1]);
1473    tcg_temp_free(tmp);
1474}
1475
1476static void translate_break(DisasContext *dc, const uint32_t arg[],
1477                            const uint32_t par[])
1478{
1479    if (dc->debug) {
1480        gen_debug_exception(dc, par[0]);
1481    }
1482}
1483
1484static void translate_call0(DisasContext *dc, const uint32_t arg[],
1485                            const uint32_t par[])
1486{
1487    tcg_gen_movi_i32(cpu_R[0], dc->next_pc);
1488    gen_jumpi(dc, arg[0], 0);
1489}
1490
1491static void translate_callw(DisasContext *dc, const uint32_t arg[],
1492                            const uint32_t par[])
1493{
1494    if (gen_window_check1(dc, par[0] << 2)) {
1495        gen_callwi(dc, par[0], arg[0], 0);
1496    }
1497}
1498
1499static void translate_callx0(DisasContext *dc, const uint32_t arg[],
1500                             const uint32_t par[])
1501{
1502    if (gen_window_check1(dc, arg[0])) {
1503        TCGv_i32 tmp = tcg_temp_new_i32();
1504        tcg_gen_mov_i32(tmp, cpu_R[arg[0]]);
1505        tcg_gen_movi_i32(cpu_R[0], dc->next_pc);
1506        gen_jump(dc, tmp);
1507        tcg_temp_free(tmp);
1508    }
1509}
1510
1511static void translate_callxw(DisasContext *dc, const uint32_t arg[],
1512                             const uint32_t par[])
1513{
1514    if (gen_window_check2(dc, arg[0], par[0] << 2)) {
1515        TCGv_i32 tmp = tcg_temp_new_i32();
1516
1517        tcg_gen_mov_i32(tmp, cpu_R[arg[0]]);
1518        gen_callw(dc, par[0], tmp);
1519        tcg_temp_free(tmp);
1520    }
1521}
1522
1523static void translate_clamps(DisasContext *dc, const uint32_t arg[],
1524                             const uint32_t par[])
1525{
1526    if (gen_window_check2(dc, arg[0], arg[1])) {
1527        TCGv_i32 tmp1 = tcg_const_i32(-1u << arg[2]);
1528        TCGv_i32 tmp2 = tcg_const_i32((1 << arg[2]) - 1);
1529
1530        tcg_gen_movcond_i32(TCG_COND_GT, tmp1,
1531                            cpu_R[arg[1]], tmp1, cpu_R[arg[1]], tmp1);
1532        tcg_gen_movcond_i32(TCG_COND_LT, cpu_R[arg[0]],
1533                            tmp1, tmp2, tmp1, tmp2);
1534        tcg_temp_free(tmp1);
1535        tcg_temp_free(tmp2);
1536    }
1537}
1538
1539static void translate_clrb_expstate(DisasContext *dc, const uint32_t arg[],
1540                                    const uint32_t par[])
1541{
1542    /* TODO: GPIO32 may be a part of coprocessor */
1543    tcg_gen_andi_i32(cpu_UR[EXPSTATE], cpu_UR[EXPSTATE], ~(1u << arg[0]));
1544}
1545
1546static void translate_const16(DisasContext *dc, const uint32_t arg[],
1547                             const uint32_t par[])
1548{
1549    if (gen_window_check1(dc, arg[0])) {
1550        TCGv_i32 c = tcg_const_i32(arg[1]);
1551
1552        tcg_gen_deposit_i32(cpu_R[arg[0]], c, cpu_R[arg[0]], 16, 16);
1553        tcg_temp_free(c);
1554    }
1555}
1556
1557/* par[0]: privileged, par[1]: check memory access */
1558static void translate_dcache(DisasContext *dc, const uint32_t arg[],
1559                             const uint32_t par[])
1560{
1561    if ((!par[0] || gen_check_privilege(dc)) &&
1562        gen_window_check1(dc, arg[0]) && par[1]) {
1563        TCGv_i32 addr = tcg_temp_new_i32();
1564        TCGv_i32 res = tcg_temp_new_i32();
1565
1566        tcg_gen_addi_i32(addr, cpu_R[arg[0]], arg[1]);
1567        tcg_gen_qemu_ld8u(res, addr, dc->cring);
1568        tcg_temp_free(addr);
1569        tcg_temp_free(res);
1570    }
1571}
1572
1573static void translate_depbits(DisasContext *dc, const uint32_t arg[],
1574                              const uint32_t par[])
1575{
1576    if (gen_window_check2(dc, arg[0], arg[1])) {
1577        tcg_gen_deposit_i32(cpu_R[arg[1]], cpu_R[arg[1]], cpu_R[arg[0]],
1578                            arg[2], arg[3]);
1579    }
1580}
1581
1582static void translate_entry(DisasContext *dc, const uint32_t arg[],
1583                            const uint32_t par[])
1584{
1585    TCGv_i32 pc = tcg_const_i32(dc->pc);
1586    TCGv_i32 s = tcg_const_i32(arg[0]);
1587    TCGv_i32 imm = tcg_const_i32(arg[1]);
1588    gen_helper_entry(cpu_env, pc, s, imm);
1589    tcg_temp_free(imm);
1590    tcg_temp_free(s);
1591    tcg_temp_free(pc);
1592    /* This can change tb->flags, so exit tb */
1593    gen_jumpi_check_loop_end(dc, -1);
1594}
1595
1596static void translate_extui(DisasContext *dc, const uint32_t arg[],
1597                            const uint32_t par[])
1598{
1599    if (gen_window_check2(dc, arg[0], arg[1])) {
1600        int maskimm = (1 << arg[3]) - 1;
1601
1602        TCGv_i32 tmp = tcg_temp_new_i32();
1603        tcg_gen_shri_i32(tmp, cpu_R[arg[1]], arg[2]);
1604        tcg_gen_andi_i32(cpu_R[arg[0]], tmp, maskimm);
1605        tcg_temp_free(tmp);
1606    }
1607}
1608
1609/* par[0]: privileged, par[1]: check memory access */
1610static void translate_icache(DisasContext *dc, const uint32_t arg[],
1611                             const uint32_t par[])
1612{
1613    if ((!par[0] || gen_check_privilege(dc)) &&
1614        gen_window_check1(dc, arg[0]) && par[1]) {
1615#ifndef CONFIG_USER_ONLY
1616        TCGv_i32 addr = tcg_temp_new_i32();
1617
1618        tcg_gen_movi_i32(cpu_pc, dc->pc);
1619        tcg_gen_addi_i32(addr, cpu_R[arg[0]], arg[1]);
1620        gen_helper_itlb_hit_test(cpu_env, addr);
1621        tcg_temp_free(addr);
1622#endif
1623    }
1624}
1625
1626static void translate_itlb(DisasContext *dc, const uint32_t arg[],
1627                           const uint32_t par[])
1628{
1629    if (gen_check_privilege(dc) &&
1630        gen_window_check1(dc, arg[0])) {
1631#ifndef CONFIG_USER_ONLY
1632        TCGv_i32 dtlb = tcg_const_i32(par[0]);
1633
1634        gen_helper_itlb(cpu_env, cpu_R[arg[0]], dtlb);
1635        /* This could change memory mapping, so exit tb */
1636        gen_jumpi_check_loop_end(dc, -1);
1637        tcg_temp_free(dtlb);
1638#endif
1639    }
1640}
1641
1642static void translate_ill(DisasContext *dc, const uint32_t arg[],
1643                          const uint32_t par[])
1644{
1645    gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
1646}
1647
1648static void translate_j(DisasContext *dc, const uint32_t arg[],
1649                        const uint32_t par[])
1650{
1651    gen_jumpi(dc, arg[0], 0);
1652}
1653
1654static void translate_jx(DisasContext *dc, const uint32_t arg[],
1655                         const uint32_t par[])
1656{
1657    if (gen_window_check1(dc, arg[0])) {
1658        gen_jump(dc, cpu_R[arg[0]]);
1659    }
1660}
1661
1662static void translate_l32e(DisasContext *dc, const uint32_t arg[],
1663                           const uint32_t par[])
1664{
1665    if (gen_check_privilege(dc) &&
1666        gen_window_check2(dc, arg[0], arg[1])) {
1667        TCGv_i32 addr = tcg_temp_new_i32();
1668
1669        tcg_gen_addi_i32(addr, cpu_R[arg[1]], arg[2]);
1670        gen_load_store_alignment(dc, 2, addr, false);
1671        tcg_gen_qemu_ld_tl(cpu_R[arg[0]], addr, dc->ring, MO_TEUL);
1672        tcg_temp_free(addr);
1673    }
1674}
1675
1676static void translate_ldst(DisasContext *dc, const uint32_t arg[],
1677                           const uint32_t par[])
1678{
1679    if (gen_window_check2(dc, arg[0], arg[1])) {
1680        TCGv_i32 addr = tcg_temp_new_i32();
1681
1682        tcg_gen_addi_i32(addr, cpu_R[arg[1]], arg[2]);
1683        if (par[0] & MO_SIZE) {
1684            gen_load_store_alignment(dc, par[0] & MO_SIZE, addr, par[1]);
1685        }
1686        if (par[2]) {
1687            if (par[1]) {
1688                tcg_gen_mb(TCG_BAR_STRL | TCG_MO_ALL);
1689            }
1690            tcg_gen_qemu_st_tl(cpu_R[arg[0]], addr, dc->cring, par[0]);
1691        } else {
1692            tcg_gen_qemu_ld_tl(cpu_R[arg[0]], addr, dc->cring, par[0]);
1693            if (par[1]) {
1694                tcg_gen_mb(TCG_BAR_LDAQ | TCG_MO_ALL);
1695            }
1696        }
1697        tcg_temp_free(addr);
1698    }
1699}
1700
1701static void translate_l32r(DisasContext *dc, const uint32_t arg[],
1702                           const uint32_t par[])
1703{
1704    if (gen_window_check1(dc, arg[0])) {
1705        TCGv_i32 tmp;
1706
1707        if (dc->tb->flags & XTENSA_TBFLAG_LITBASE) {
1708            tmp = tcg_const_i32(dc->raw_arg[1] - 1);
1709            tcg_gen_add_i32(tmp, cpu_SR[LITBASE], tmp);
1710        } else {
1711            tmp = tcg_const_i32(arg[1]);
1712        }
1713        tcg_gen_qemu_ld32u(cpu_R[arg[0]], tmp, dc->cring);
1714        tcg_temp_free(tmp);
1715    }
1716}
1717
1718static void translate_loop(DisasContext *dc, const uint32_t arg[],
1719                           const uint32_t par[])
1720{
1721    if (gen_window_check1(dc, arg[0])) {
1722        uint32_t lend = arg[1];
1723        TCGv_i32 tmp = tcg_const_i32(lend);
1724
1725        tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_R[arg[0]], 1);
1726        tcg_gen_movi_i32(cpu_SR[LBEG], dc->next_pc);
1727        gen_helper_wsr_lend(cpu_env, tmp);
1728        tcg_temp_free(tmp);
1729
1730        if (par[0] != TCG_COND_NEVER) {
1731            TCGLabel *label = gen_new_label();
1732            tcg_gen_brcondi_i32(par[0], cpu_R[arg[0]], 0, label);
1733            gen_jumpi(dc, lend, 1);
1734            gen_set_label(label);
1735        }
1736
1737        gen_jumpi(dc, dc->next_pc, 0);
1738    }
1739}
1740
1741enum {
1742    MAC16_UMUL,
1743    MAC16_MUL,
1744    MAC16_MULA,
1745    MAC16_MULS,
1746    MAC16_NONE,
1747};
1748
1749enum {
1750    MAC16_LL,
1751    MAC16_HL,
1752    MAC16_LH,
1753    MAC16_HH,
1754
1755    MAC16_HX = 0x1,
1756    MAC16_XH = 0x2,
1757};
1758
1759enum {
1760    MAC16_AA,
1761    MAC16_AD,
1762    MAC16_DA,
1763    MAC16_DD,
1764
1765    MAC16_XD = 0x1,
1766    MAC16_DX = 0x2,
1767};
1768
1769static void translate_mac16(DisasContext *dc, const uint32_t arg[],
1770                            const uint32_t par[])
1771{
1772    int op = par[0];
1773    bool is_m1_sr = par[1] & MAC16_DX;
1774    bool is_m2_sr = par[1] & MAC16_XD;
1775    unsigned half = par[2];
1776    uint32_t ld_offset = par[3];
1777    unsigned off = ld_offset ? 2 : 0;
1778    uint32_t ar[3] = {0};
1779    unsigned n_ar = 0;
1780
1781    if (op != MAC16_NONE) {
1782        if (!is_m1_sr) {
1783            ar[n_ar++] = arg[off];
1784        }
1785        if (!is_m2_sr) {
1786            ar[n_ar++] = arg[off + 1];
1787        }
1788    }
1789
1790    if (ld_offset) {
1791        ar[n_ar++] = arg[1];
1792    }
1793
1794    if (gen_window_check3(dc, ar[0], ar[1], ar[2])) {
1795        TCGv_i32 vaddr = tcg_temp_new_i32();
1796        TCGv_i32 mem32 = tcg_temp_new_i32();
1797
1798        if (ld_offset) {
1799            tcg_gen_addi_i32(vaddr, cpu_R[arg[1]], ld_offset);
1800            gen_load_store_alignment(dc, 2, vaddr, false);
1801            tcg_gen_qemu_ld32u(mem32, vaddr, dc->cring);
1802        }
1803        if (op != MAC16_NONE) {
1804            TCGv_i32 m1 = gen_mac16_m(is_m1_sr ?
1805                                      cpu_SR[MR + arg[off]] :
1806                                      cpu_R[arg[off]],
1807                                      half & MAC16_HX, op == MAC16_UMUL);
1808            TCGv_i32 m2 = gen_mac16_m(is_m2_sr ?
1809                                      cpu_SR[MR + arg[off + 1]] :
1810                                      cpu_R[arg[off + 1]],
1811                                      half & MAC16_XH, op == MAC16_UMUL);
1812
1813            if (op == MAC16_MUL || op == MAC16_UMUL) {
1814                tcg_gen_mul_i32(cpu_SR[ACCLO], m1, m2);
1815                if (op == MAC16_UMUL) {
1816                    tcg_gen_movi_i32(cpu_SR[ACCHI], 0);
1817                } else {
1818                    tcg_gen_sari_i32(cpu_SR[ACCHI], cpu_SR[ACCLO], 31);
1819                }
1820            } else {
1821                TCGv_i32 lo = tcg_temp_new_i32();
1822                TCGv_i32 hi = tcg_temp_new_i32();
1823
1824                tcg_gen_mul_i32(lo, m1, m2);
1825                tcg_gen_sari_i32(hi, lo, 31);
1826                if (op == MAC16_MULA) {
1827                    tcg_gen_add2_i32(cpu_SR[ACCLO], cpu_SR[ACCHI],
1828                                     cpu_SR[ACCLO], cpu_SR[ACCHI],
1829                                     lo, hi);
1830                } else {
1831                    tcg_gen_sub2_i32(cpu_SR[ACCLO], cpu_SR[ACCHI],
1832                                     cpu_SR[ACCLO], cpu_SR[ACCHI],
1833                                     lo, hi);
1834                }
1835                tcg_gen_ext8s_i32(cpu_SR[ACCHI], cpu_SR[ACCHI]);
1836
1837                tcg_temp_free_i32(lo);
1838                tcg_temp_free_i32(hi);
1839            }
1840            tcg_temp_free(m1);
1841            tcg_temp_free(m2);
1842        }
1843        if (ld_offset) {
1844            tcg_gen_mov_i32(cpu_R[arg[1]], vaddr);
1845            tcg_gen_mov_i32(cpu_SR[MR + arg[0]], mem32);
1846        }
1847        tcg_temp_free(vaddr);
1848        tcg_temp_free(mem32);
1849    }
1850}
1851
1852static void translate_memw(DisasContext *dc, const uint32_t arg[],
1853                           const uint32_t par[])
1854{
1855    tcg_gen_mb(TCG_BAR_SC | TCG_MO_ALL);
1856}
1857
1858static void translate_minmax(DisasContext *dc, const uint32_t arg[],
1859                             const uint32_t par[])
1860{
1861    if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
1862        tcg_gen_movcond_i32(par[0], cpu_R[arg[0]],
1863                            cpu_R[arg[1]], cpu_R[arg[2]],
1864                            cpu_R[arg[1]], cpu_R[arg[2]]);
1865    }
1866}
1867
1868static void translate_mov(DisasContext *dc, const uint32_t arg[],
1869                          const uint32_t par[])
1870{
1871    if (gen_window_check2(dc, arg[0], arg[1])) {
1872        tcg_gen_mov_i32(cpu_R[arg[0]], cpu_R[arg[1]]);
1873    }
1874}
1875
1876static void translate_movcond(DisasContext *dc, const uint32_t arg[],
1877                              const uint32_t par[])
1878{
1879    if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
1880        TCGv_i32 zero = tcg_const_i32(0);
1881
1882        tcg_gen_movcond_i32(par[0], cpu_R[arg[0]],
1883                            cpu_R[arg[2]], zero, cpu_R[arg[1]], cpu_R[arg[0]]);
1884        tcg_temp_free(zero);
1885    }
1886}
1887
1888static void translate_movi(DisasContext *dc, const uint32_t arg[],
1889                           const uint32_t par[])
1890{
1891    if (gen_window_check1(dc, arg[0])) {
1892        tcg_gen_movi_i32(cpu_R[arg[0]], arg[1]);
1893    }
1894}
1895
1896static void translate_movp(DisasContext *dc, const uint32_t arg[],
1897                           const uint32_t par[])
1898{
1899    if (gen_window_check2(dc, arg[0], arg[1])) {
1900        TCGv_i32 zero = tcg_const_i32(0);
1901        TCGv_i32 tmp = tcg_temp_new_i32();
1902
1903        tcg_gen_andi_i32(tmp, cpu_SR[BR], 1 << arg[2]);
1904        tcg_gen_movcond_i32(par[0],
1905                            cpu_R[arg[0]], tmp, zero,
1906                            cpu_R[arg[1]], cpu_R[arg[0]]);
1907        tcg_temp_free(tmp);
1908        tcg_temp_free(zero);
1909    }
1910}
1911
1912static void translate_movsp(DisasContext *dc, const uint32_t arg[],
1913                            const uint32_t par[])
1914{
1915    if (gen_window_check2(dc, arg[0], arg[1])) {
1916        TCGv_i32 pc = tcg_const_i32(dc->pc);
1917        gen_helper_movsp(cpu_env, pc);
1918        tcg_gen_mov_i32(cpu_R[arg[0]], cpu_R[arg[1]]);
1919        tcg_temp_free(pc);
1920    }
1921}
1922
1923static void translate_mul16(DisasContext *dc, const uint32_t arg[],
1924                            const uint32_t par[])
1925{
1926    if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
1927        TCGv_i32 v1 = tcg_temp_new_i32();
1928        TCGv_i32 v2 = tcg_temp_new_i32();
1929
1930        if (par[0]) {
1931            tcg_gen_ext16s_i32(v1, cpu_R[arg[1]]);
1932            tcg_gen_ext16s_i32(v2, cpu_R[arg[2]]);
1933        } else {
1934            tcg_gen_ext16u_i32(v1, cpu_R[arg[1]]);
1935            tcg_gen_ext16u_i32(v2, cpu_R[arg[2]]);
1936        }
1937        tcg_gen_mul_i32(cpu_R[arg[0]], v1, v2);
1938        tcg_temp_free(v2);
1939        tcg_temp_free(v1);
1940    }
1941}
1942
1943static void translate_mull(DisasContext *dc, const uint32_t arg[],
1944                           const uint32_t par[])
1945{
1946    if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
1947        tcg_gen_mul_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
1948    }
1949}
1950
1951static void translate_mulh(DisasContext *dc, const uint32_t arg[],
1952                           const uint32_t par[])
1953{
1954    if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
1955        TCGv_i32 lo = tcg_temp_new();
1956
1957        if (par[0]) {
1958            tcg_gen_muls2_i32(lo, cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
1959        } else {
1960            tcg_gen_mulu2_i32(lo, cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
1961        }
1962        tcg_temp_free(lo);
1963    }
1964}
1965
1966static void translate_neg(DisasContext *dc, const uint32_t arg[],
1967                          const uint32_t par[])
1968{
1969    if (gen_window_check2(dc, arg[0], arg[1])) {
1970        tcg_gen_neg_i32(cpu_R[arg[0]], cpu_R[arg[1]]);
1971    }
1972}
1973
1974static void translate_nop(DisasContext *dc, const uint32_t arg[],
1975                          const uint32_t par[])
1976{
1977}
1978
1979static void translate_nsa(DisasContext *dc, const uint32_t arg[],
1980                          const uint32_t par[])
1981{
1982    if (gen_window_check2(dc, arg[0], arg[1])) {
1983        tcg_gen_clrsb_i32(cpu_R[arg[0]], cpu_R[arg[1]]);
1984    }
1985}
1986
1987static void translate_nsau(DisasContext *dc, const uint32_t arg[],
1988                           const uint32_t par[])
1989{
1990    if (gen_window_check2(dc, arg[0], arg[1])) {
1991        tcg_gen_clzi_i32(cpu_R[arg[0]], cpu_R[arg[1]], 32);
1992    }
1993}
1994
1995static void translate_or(DisasContext *dc, const uint32_t arg[],
1996                         const uint32_t par[])
1997{
1998    if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
1999        tcg_gen_or_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
2000    }
2001}
2002
2003static void translate_ptlb(DisasContext *dc, const uint32_t arg[],
2004                           const uint32_t par[])
2005{
2006    if (gen_check_privilege(dc) &&
2007        gen_window_check2(dc, arg[0], arg[1])) {
2008#ifndef CONFIG_USER_ONLY
2009        TCGv_i32 dtlb = tcg_const_i32(par[0]);
2010
2011        tcg_gen_movi_i32(cpu_pc, dc->pc);
2012        gen_helper_ptlb(cpu_R[arg[0]], cpu_env, cpu_R[arg[1]], dtlb);
2013        tcg_temp_free(dtlb);
2014#endif
2015    }
2016}
2017
2018static void gen_zero_check(DisasContext *dc, const uint32_t arg[])
2019{
2020    TCGLabel *label = gen_new_label();
2021
2022    tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[arg[2]], 0, label);
2023    gen_exception_cause(dc, INTEGER_DIVIDE_BY_ZERO_CAUSE);
2024    gen_set_label(label);
2025}
2026
2027static void translate_quos(DisasContext *dc, const uint32_t arg[],
2028                           const uint32_t par[])
2029{
2030    if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
2031        TCGLabel *label1 = gen_new_label();
2032        TCGLabel *label2 = gen_new_label();
2033
2034        gen_zero_check(dc, arg);
2035
2036        tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[arg[1]], 0x80000000,
2037                            label1);
2038        tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[arg[2]], 0xffffffff,
2039                            label1);
2040        tcg_gen_movi_i32(cpu_R[arg[0]],
2041                         par[0] ? 0x80000000 : 0);
2042        tcg_gen_br(label2);
2043        gen_set_label(label1);
2044        if (par[0]) {
2045            tcg_gen_div_i32(cpu_R[arg[0]],
2046                            cpu_R[arg[1]], cpu_R[arg[2]]);
2047        } else {
2048            tcg_gen_rem_i32(cpu_R[arg[0]],
2049                            cpu_R[arg[1]], cpu_R[arg[2]]);
2050        }
2051        gen_set_label(label2);
2052    }
2053}
2054
2055static void translate_quou(DisasContext *dc, const uint32_t arg[],
2056                           const uint32_t par[])
2057{
2058    if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
2059        gen_zero_check(dc, arg);
2060        if (par[0]) {
2061            tcg_gen_divu_i32(cpu_R[arg[0]],
2062                             cpu_R[arg[1]], cpu_R[arg[2]]);
2063        } else {
2064            tcg_gen_remu_i32(cpu_R[arg[0]],
2065                             cpu_R[arg[1]], cpu_R[arg[2]]);
2066        }
2067    }
2068}
2069
2070static void translate_read_impwire(DisasContext *dc, const uint32_t arg[],
2071                                   const uint32_t par[])
2072{
2073    if (gen_window_check1(dc, arg[0])) {
2074        /* TODO: GPIO32 may be a part of coprocessor */
2075        tcg_gen_movi_i32(cpu_R[arg[0]], 0);
2076    }
2077}
2078
2079static void translate_rer(DisasContext *dc, const uint32_t arg[],
2080                          const uint32_t par[])
2081{
2082    if (gen_check_privilege(dc) &&
2083        gen_window_check2(dc, arg[0], arg[1])) {
2084        gen_helper_rer(cpu_R[arg[0]], cpu_env, cpu_R[arg[1]]);
2085    }
2086}
2087
2088static void translate_ret(DisasContext *dc, const uint32_t arg[],
2089                          const uint32_t par[])
2090{
2091    gen_jump(dc, cpu_R[0]);
2092}
2093
2094static void translate_retw(DisasContext *dc, const uint32_t arg[],
2095                           const uint32_t par[])
2096{
2097    TCGv_i32 tmp = tcg_const_i32(dc->pc);
2098    gen_helper_retw(tmp, cpu_env, tmp);
2099    gen_jump(dc, tmp);
2100    tcg_temp_free(tmp);
2101}
2102
2103static void translate_rfde(DisasContext *dc, const uint32_t arg[],
2104                           const uint32_t par[])
2105{
2106    if (gen_check_privilege(dc)) {
2107        gen_jump(dc, cpu_SR[dc->config->ndepc ? DEPC : EPC1]);
2108    }
2109}
2110
2111static void translate_rfe(DisasContext *dc, const uint32_t arg[],
2112                          const uint32_t par[])
2113{
2114    if (gen_check_privilege(dc)) {
2115        tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_EXCM);
2116        gen_check_interrupts(dc);
2117        gen_jump(dc, cpu_SR[EPC1]);
2118    }
2119}
2120
2121static void translate_rfi(DisasContext *dc, const uint32_t arg[],
2122                          const uint32_t par[])
2123{
2124    if (gen_check_privilege(dc)) {
2125        tcg_gen_mov_i32(cpu_SR[PS], cpu_SR[EPS2 + arg[0] - 2]);
2126        gen_check_interrupts(dc);
2127        gen_jump(dc, cpu_SR[EPC1 + arg[0] - 1]);
2128    }
2129}
2130
2131static void translate_rfw(DisasContext *dc, const uint32_t arg[],
2132                          const uint32_t par[])
2133{
2134    if (gen_check_privilege(dc)) {
2135        TCGv_i32 tmp = tcg_const_i32(1);
2136
2137        tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_EXCM);
2138        tcg_gen_shl_i32(tmp, tmp, cpu_SR[WINDOW_BASE]);
2139
2140        if (par[0]) {
2141            tcg_gen_andc_i32(cpu_SR[WINDOW_START],
2142                             cpu_SR[WINDOW_START], tmp);
2143        } else {
2144            tcg_gen_or_i32(cpu_SR[WINDOW_START],
2145                           cpu_SR[WINDOW_START], tmp);
2146        }
2147
2148        gen_helper_restore_owb(cpu_env);
2149        gen_check_interrupts(dc);
2150        gen_jump(dc, cpu_SR[EPC1]);
2151
2152        tcg_temp_free(tmp);
2153    }
2154}
2155
2156static void translate_rotw(DisasContext *dc, const uint32_t arg[],
2157                           const uint32_t par[])
2158{
2159    if (gen_check_privilege(dc)) {
2160        TCGv_i32 tmp = tcg_const_i32(arg[0]);
2161        gen_helper_rotw(cpu_env, tmp);
2162        tcg_temp_free(tmp);
2163        /* This can change tb->flags, so exit tb */
2164        gen_jumpi_check_loop_end(dc, -1);
2165    }
2166}
2167
2168static void translate_rsil(DisasContext *dc, const uint32_t arg[],
2169                           const uint32_t par[])
2170{
2171    if (gen_check_privilege(dc) &&
2172        gen_window_check1(dc, arg[0])) {
2173        tcg_gen_mov_i32(cpu_R[arg[0]], cpu_SR[PS]);
2174        tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_INTLEVEL);
2175        tcg_gen_ori_i32(cpu_SR[PS], cpu_SR[PS], arg[1]);
2176        gen_check_interrupts(dc);
2177        gen_jumpi_check_loop_end(dc, 0);
2178    }
2179}
2180
2181static void translate_rsr(DisasContext *dc, const uint32_t arg[],
2182                          const uint32_t par[])
2183{
2184    if (gen_check_sr(dc, par[0], SR_R) &&
2185        (par[0] < 64 || gen_check_privilege(dc)) &&
2186        gen_window_check1(dc, arg[0])) {
2187        if (gen_rsr(dc, cpu_R[arg[0]], par[0])) {
2188            gen_jumpi_check_loop_end(dc, 0);
2189        }
2190    }
2191}
2192
2193static void translate_rtlb(DisasContext *dc, const uint32_t arg[],
2194                           const uint32_t par[])
2195{
2196    static void (* const helper[])(TCGv_i32 r, TCGv_env env, TCGv_i32 a1,
2197                                   TCGv_i32 a2) = {
2198#ifndef CONFIG_USER_ONLY
2199        gen_helper_rtlb0,
2200        gen_helper_rtlb1,
2201#endif
2202    };
2203
2204    if (gen_check_privilege(dc) &&
2205        gen_window_check2(dc, arg[0], arg[1])) {
2206        TCGv_i32 dtlb = tcg_const_i32(par[0]);
2207
2208        helper[par[1]](cpu_R[arg[0]], cpu_env, cpu_R[arg[1]], dtlb);
2209        tcg_temp_free(dtlb);
2210    }
2211}
2212
2213static void translate_rur(DisasContext *dc, const uint32_t arg[],
2214                          const uint32_t par[])
2215{
2216    if (gen_window_check1(dc, arg[0])) {
2217        if (uregnames[par[0]].name) {
2218            tcg_gen_mov_i32(cpu_R[arg[0]], cpu_UR[par[0]]);
2219        } else {
2220            qemu_log_mask(LOG_UNIMP, "RUR %d not implemented, ", par[0]);
2221        }
2222    }
2223}
2224
2225static void translate_setb_expstate(DisasContext *dc, const uint32_t arg[],
2226                                    const uint32_t par[])
2227{
2228    /* TODO: GPIO32 may be a part of coprocessor */
2229    tcg_gen_ori_i32(cpu_UR[EXPSTATE], cpu_UR[EXPSTATE], 1u << arg[0]);
2230}
2231
2232#ifdef CONFIG_USER_ONLY
2233static void gen_check_atomctl(DisasContext *dc, TCGv_i32 addr)
2234{
2235}
2236#else
2237static void gen_check_atomctl(DisasContext *dc, TCGv_i32 addr)
2238{
2239    TCGv_i32 tpc = tcg_const_i32(dc->pc);
2240
2241    gen_helper_check_atomctl(cpu_env, tpc, addr);
2242    tcg_temp_free(tpc);
2243}
2244#endif
2245
2246static void translate_s32c1i(DisasContext *dc, const uint32_t arg[],
2247                             const uint32_t par[])
2248{
2249    if (gen_window_check2(dc, arg[0], arg[1])) {
2250        TCGv_i32 tmp = tcg_temp_local_new_i32();
2251        TCGv_i32 addr = tcg_temp_local_new_i32();
2252
2253        tcg_gen_mov_i32(tmp, cpu_R[arg[0]]);
2254        tcg_gen_addi_i32(addr, cpu_R[arg[1]], arg[2]);
2255        gen_load_store_alignment(dc, 2, addr, true);
2256        gen_check_atomctl(dc, addr);
2257        tcg_gen_atomic_cmpxchg_i32(cpu_R[arg[0]], addr, cpu_SR[SCOMPARE1],
2258                                   tmp, dc->cring, MO_32);
2259        tcg_temp_free(addr);
2260        tcg_temp_free(tmp);
2261    }
2262}
2263
2264static void translate_s32e(DisasContext *dc, const uint32_t arg[],
2265                           const uint32_t par[])
2266{
2267    if (gen_check_privilege(dc) &&
2268        gen_window_check2(dc, arg[0], arg[1])) {
2269        TCGv_i32 addr = tcg_temp_new_i32();
2270
2271        tcg_gen_addi_i32(addr, cpu_R[arg[1]], arg[2]);
2272        gen_load_store_alignment(dc, 2, addr, false);
2273        tcg_gen_qemu_st_tl(cpu_R[arg[0]], addr, dc->ring, MO_TEUL);
2274        tcg_temp_free(addr);
2275    }
2276}
2277
2278static void translate_salt(DisasContext *dc, const uint32_t arg[],
2279                           const uint32_t par[])
2280{
2281    if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
2282        tcg_gen_setcond_i32(par[0],
2283                            cpu_R[arg[0]],
2284                            cpu_R[arg[1]], cpu_R[arg[2]]);
2285    }
2286}
2287
2288static void translate_sext(DisasContext *dc, const uint32_t arg[],
2289                           const uint32_t par[])
2290{
2291    if (gen_window_check2(dc, arg[0], arg[1])) {
2292        int shift = 31 - arg[2];
2293
2294        if (shift == 24) {
2295            tcg_gen_ext8s_i32(cpu_R[arg[0]], cpu_R[arg[1]]);
2296        } else if (shift == 16) {
2297            tcg_gen_ext16s_i32(cpu_R[arg[0]], cpu_R[arg[1]]);
2298        } else {
2299            TCGv_i32 tmp = tcg_temp_new_i32();
2300            tcg_gen_shli_i32(tmp, cpu_R[arg[1]], shift);
2301            tcg_gen_sari_i32(cpu_R[arg[0]], tmp, shift);
2302            tcg_temp_free(tmp);
2303        }
2304    }
2305}
2306
2307static void translate_simcall(DisasContext *dc, const uint32_t arg[],
2308                              const uint32_t par[])
2309{
2310#ifndef CONFIG_USER_ONLY
2311    if (semihosting_enabled()) {
2312        if (gen_check_privilege(dc)) {
2313            gen_helper_simcall(cpu_env);
2314        }
2315    } else
2316#endif
2317    {
2318        qemu_log_mask(LOG_GUEST_ERROR, "SIMCALL but semihosting is disabled\n");
2319        gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
2320    }
2321}
2322
2323/*
2324 * Note: 64 bit ops are used here solely because SAR values
2325 * have range 0..63
2326 */
2327#define gen_shift_reg(cmd, reg) do { \
2328                    TCGv_i64 tmp = tcg_temp_new_i64(); \
2329                    tcg_gen_extu_i32_i64(tmp, reg); \
2330                    tcg_gen_##cmd##_i64(v, v, tmp); \
2331                    tcg_gen_extrl_i64_i32(cpu_R[arg[0]], v); \
2332                    tcg_temp_free_i64(v); \
2333                    tcg_temp_free_i64(tmp); \
2334                } while (0)
2335
2336#define gen_shift(cmd) gen_shift_reg(cmd, cpu_SR[SAR])
2337
2338static void translate_sll(DisasContext *dc, const uint32_t arg[],
2339                          const uint32_t par[])
2340{
2341    if (gen_window_check2(dc, arg[0], arg[1])) {
2342        if (dc->sar_m32_5bit) {
2343            tcg_gen_shl_i32(cpu_R[arg[0]], cpu_R[arg[1]], dc->sar_m32);
2344        } else {
2345            TCGv_i64 v = tcg_temp_new_i64();
2346            TCGv_i32 s = tcg_const_i32(32);
2347            tcg_gen_sub_i32(s, s, cpu_SR[SAR]);
2348            tcg_gen_andi_i32(s, s, 0x3f);
2349            tcg_gen_extu_i32_i64(v, cpu_R[arg[1]]);
2350            gen_shift_reg(shl, s);
2351            tcg_temp_free(s);
2352        }
2353    }
2354}
2355
2356static void translate_slli(DisasContext *dc, const uint32_t arg[],
2357                           const uint32_t par[])
2358{
2359    if (gen_window_check2(dc, arg[0], arg[1])) {
2360        if (arg[2] == 32) {
2361            qemu_log_mask(LOG_GUEST_ERROR, "slli a%d, a%d, 32 is undefined",
2362                          arg[0], arg[1]);
2363        }
2364        tcg_gen_shli_i32(cpu_R[arg[0]], cpu_R[arg[1]], arg[2] & 0x1f);
2365    }
2366}
2367
2368static void translate_sra(DisasContext *dc, const uint32_t arg[],
2369                          const uint32_t par[])
2370{
2371    if (gen_window_check2(dc, arg[0], arg[1])) {
2372        if (dc->sar_m32_5bit) {
2373            tcg_gen_sar_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_SR[SAR]);
2374        } else {
2375            TCGv_i64 v = tcg_temp_new_i64();
2376            tcg_gen_ext_i32_i64(v, cpu_R[arg[1]]);
2377            gen_shift(sar);
2378        }
2379    }
2380}
2381
2382static void translate_srai(DisasContext *dc, const uint32_t arg[],
2383                           const uint32_t par[])
2384{
2385    if (gen_window_check2(dc, arg[0], arg[1])) {
2386        tcg_gen_sari_i32(cpu_R[arg[0]], cpu_R[arg[1]], arg[2]);
2387    }
2388}
2389
2390static void translate_src(DisasContext *dc, const uint32_t arg[],
2391                          const uint32_t par[])
2392{
2393    if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
2394        TCGv_i64 v = tcg_temp_new_i64();
2395        tcg_gen_concat_i32_i64(v, cpu_R[arg[2]], cpu_R[arg[1]]);
2396        gen_shift(shr);
2397    }
2398}
2399
2400static void translate_srl(DisasContext *dc, const uint32_t arg[],
2401                          const uint32_t par[])
2402{
2403    if (gen_window_check2(dc, arg[0], arg[1])) {
2404        if (dc->sar_m32_5bit) {
2405            tcg_gen_shr_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_SR[SAR]);
2406        } else {
2407            TCGv_i64 v = tcg_temp_new_i64();
2408            tcg_gen_extu_i32_i64(v, cpu_R[arg[1]]);
2409            gen_shift(shr);
2410        }
2411    }
2412}
2413
2414#undef gen_shift
2415#undef gen_shift_reg
2416
2417static void translate_srli(DisasContext *dc, const uint32_t arg[],
2418                           const uint32_t par[])
2419{
2420    if (gen_window_check2(dc, arg[0], arg[1])) {
2421        tcg_gen_shri_i32(cpu_R[arg[0]], cpu_R[arg[1]], arg[2]);
2422    }
2423}
2424
2425static void translate_ssa8b(DisasContext *dc, const uint32_t arg[],
2426                            const uint32_t par[])
2427{
2428    if (gen_window_check1(dc, arg[0])) {
2429        TCGv_i32 tmp = tcg_temp_new_i32();
2430        tcg_gen_shli_i32(tmp, cpu_R[arg[0]], 3);
2431        gen_left_shift_sar(dc, tmp);
2432        tcg_temp_free(tmp);
2433    }
2434}
2435
2436static void translate_ssa8l(DisasContext *dc, const uint32_t arg[],
2437                            const uint32_t par[])
2438{
2439    if (gen_window_check1(dc, arg[0])) {
2440        TCGv_i32 tmp = tcg_temp_new_i32();
2441        tcg_gen_shli_i32(tmp, cpu_R[arg[0]], 3);
2442        gen_right_shift_sar(dc, tmp);
2443        tcg_temp_free(tmp);
2444    }
2445}
2446
2447static void translate_ssai(DisasContext *dc, const uint32_t arg[],
2448                           const uint32_t par[])
2449{
2450    TCGv_i32 tmp = tcg_const_i32(arg[0]);
2451    gen_right_shift_sar(dc, tmp);
2452    tcg_temp_free(tmp);
2453}
2454
2455static void translate_ssl(DisasContext *dc, const uint32_t arg[],
2456                          const uint32_t par[])
2457{
2458    if (gen_window_check1(dc, arg[0])) {
2459        gen_left_shift_sar(dc, cpu_R[arg[0]]);
2460    }
2461}
2462
2463static void translate_ssr(DisasContext *dc, const uint32_t arg[],
2464                          const uint32_t par[])
2465{
2466    if (gen_window_check1(dc, arg[0])) {
2467        gen_right_shift_sar(dc, cpu_R[arg[0]]);
2468    }
2469}
2470
2471static void translate_sub(DisasContext *dc, const uint32_t arg[],
2472                          const uint32_t par[])
2473{
2474    if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
2475        tcg_gen_sub_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
2476    }
2477}
2478
2479static void translate_subx(DisasContext *dc, const uint32_t arg[],
2480                           const uint32_t par[])
2481{
2482    if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
2483        TCGv_i32 tmp = tcg_temp_new_i32();
2484        tcg_gen_shli_i32(tmp, cpu_R[arg[1]], par[0]);
2485        tcg_gen_sub_i32(cpu_R[arg[0]], tmp, cpu_R[arg[2]]);
2486        tcg_temp_free(tmp);
2487    }
2488}
2489
2490static void translate_syscall(DisasContext *dc, const uint32_t arg[],
2491                              const uint32_t par[])
2492{
2493    gen_exception_cause(dc, SYSCALL_CAUSE);
2494}
2495
2496static void translate_waiti(DisasContext *dc, const uint32_t arg[],
2497                            const uint32_t par[])
2498{
2499    if (gen_check_privilege(dc)) {
2500#ifndef CONFIG_USER_ONLY
2501        gen_waiti(dc, arg[0]);
2502#endif
2503    }
2504}
2505
2506static void translate_wtlb(DisasContext *dc, const uint32_t arg[],
2507                           const uint32_t par[])
2508{
2509    if (gen_check_privilege(dc) &&
2510        gen_window_check2(dc, arg[0], arg[1])) {
2511#ifndef CONFIG_USER_ONLY
2512        TCGv_i32 dtlb = tcg_const_i32(par[0]);
2513
2514        gen_helper_wtlb(cpu_env, cpu_R[arg[0]], cpu_R[arg[1]], dtlb);
2515        /* This could change memory mapping, so exit tb */
2516        gen_jumpi_check_loop_end(dc, -1);
2517        tcg_temp_free(dtlb);
2518#endif
2519    }
2520}
2521
2522static void translate_wer(DisasContext *dc, const uint32_t arg[],
2523                          const uint32_t par[])
2524{
2525    if (gen_check_privilege(dc) &&
2526        gen_window_check2(dc, arg[0], arg[1])) {
2527        gen_helper_wer(cpu_env, cpu_R[arg[0]], cpu_R[arg[1]]);
2528    }
2529}
2530
2531static void translate_wrmsk_expstate(DisasContext *dc, const uint32_t arg[],
2532                                     const uint32_t par[])
2533{
2534    if (gen_window_check2(dc, arg[0], arg[1])) {
2535        /* TODO: GPIO32 may be a part of coprocessor */
2536        tcg_gen_and_i32(cpu_UR[EXPSTATE], cpu_R[arg[0]], cpu_R[arg[1]]);
2537    }
2538}
2539
2540static void translate_wsr(DisasContext *dc, const uint32_t arg[],
2541                          const uint32_t par[])
2542{
2543    if (gen_check_sr(dc, par[0], SR_W) &&
2544        (par[0] < 64 || gen_check_privilege(dc)) &&
2545        gen_window_check1(dc, arg[0])) {
2546        gen_wsr(dc, par[0], cpu_R[arg[0]]);
2547    }
2548}
2549
2550static void translate_wur(DisasContext *dc, const uint32_t arg[],
2551                          const uint32_t par[])
2552{
2553    if (gen_window_check1(dc, arg[0])) {
2554        if (uregnames[par[0]].name) {
2555            gen_wur(par[0], cpu_R[arg[0]]);
2556        } else {
2557            qemu_log_mask(LOG_UNIMP, "WUR %d not implemented, ", par[0]);
2558        }
2559    }
2560}
2561
2562static void translate_xor(DisasContext *dc, const uint32_t arg[],
2563                          const uint32_t par[])
2564{
2565    if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
2566        tcg_gen_xor_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
2567    }
2568}
2569
2570static void translate_xsr(DisasContext *dc, const uint32_t arg[],
2571                          const uint32_t par[])
2572{
2573    if (gen_check_sr(dc, par[0], SR_X) &&
2574        (par[0] < 64 || gen_check_privilege(dc)) &&
2575        gen_window_check1(dc, arg[0])) {
2576        TCGv_i32 tmp = tcg_temp_new_i32();
2577        bool rsr_end, wsr_end;
2578
2579        tcg_gen_mov_i32(tmp, cpu_R[arg[0]]);
2580        rsr_end = gen_rsr(dc, cpu_R[arg[0]], par[0]);
2581        wsr_end = gen_wsr(dc, par[0], tmp);
2582        tcg_temp_free(tmp);
2583        if (rsr_end && !wsr_end) {
2584            gen_jumpi_check_loop_end(dc, 0);
2585        }
2586    }
2587}
2588
2589static const XtensaOpcodeOps core_ops[] = {
2590    {
2591        .name = "abs",
2592        .translate = translate_abs,
2593    }, {
2594        .name = "add",
2595        .translate = translate_add,
2596    }, {
2597        .name = "add.n",
2598        .translate = translate_add,
2599    }, {
2600        .name = "addi",
2601        .translate = translate_addi,
2602    }, {
2603        .name = "addi.n",
2604        .translate = translate_addi,
2605    }, {
2606        .name = "addmi",
2607        .translate = translate_addi,
2608    }, {
2609        .name = "addx2",
2610        .translate = translate_addx,
2611        .par = (const uint32_t[]){1},
2612    }, {
2613        .name = "addx4",
2614        .translate = translate_addx,
2615        .par = (const uint32_t[]){2},
2616    }, {
2617        .name = "addx8",
2618        .translate = translate_addx,
2619        .par = (const uint32_t[]){3},
2620    }, {
2621        .name = "all4",
2622        .translate = translate_all,
2623        .par = (const uint32_t[]){true, 4},
2624    }, {
2625        .name = "all8",
2626        .translate = translate_all,
2627        .par = (const uint32_t[]){true, 8},
2628    }, {
2629        .name = "and",
2630        .translate = translate_and,
2631    }, {
2632        .name = "andb",
2633        .translate = translate_boolean,
2634        .par = (const uint32_t[]){BOOLEAN_AND},
2635    }, {
2636        .name = "andbc",
2637        .translate = translate_boolean,
2638        .par = (const uint32_t[]){BOOLEAN_ANDC},
2639    }, {
2640        .name = "any4",
2641        .translate = translate_all,
2642        .par = (const uint32_t[]){false, 4},
2643    }, {
2644        .name = "any8",
2645        .translate = translate_all,
2646        .par = (const uint32_t[]){false, 8},
2647    }, {
2648        .name = "ball",
2649        .translate = translate_ball,
2650        .par = (const uint32_t[]){TCG_COND_EQ},
2651    }, {
2652        .name = "bany",
2653        .translate = translate_bany,
2654        .par = (const uint32_t[]){TCG_COND_NE},
2655    }, {
2656        .name = "bbc",
2657        .translate = translate_bb,
2658        .par = (const uint32_t[]){TCG_COND_EQ},
2659    }, {
2660        .name = "bbci",
2661        .translate = translate_bbi,
2662        .par = (const uint32_t[]){TCG_COND_EQ},
2663    }, {
2664        .name = "bbs",
2665        .translate = translate_bb,
2666        .par = (const uint32_t[]){TCG_COND_NE},
2667    }, {
2668        .name = "bbsi",
2669        .translate = translate_bbi,
2670        .par = (const uint32_t[]){TCG_COND_NE},
2671    }, {
2672        .name = "beq",
2673        .translate = translate_b,
2674        .par = (const uint32_t[]){TCG_COND_EQ},
2675    }, {
2676        .name = "beqi",
2677        .translate = translate_bi,
2678        .par = (const uint32_t[]){TCG_COND_EQ},
2679    }, {
2680        .name = "beqz",
2681        .translate = translate_bz,
2682        .par = (const uint32_t[]){TCG_COND_EQ},
2683    }, {
2684        .name = "beqz.n",
2685        .translate = translate_bz,
2686        .par = (const uint32_t[]){TCG_COND_EQ},
2687    }, {
2688        .name = "bf",
2689        .translate = translate_bp,
2690        .par = (const uint32_t[]){TCG_COND_EQ},
2691    }, {
2692        .name = "bge",
2693        .translate = translate_b,
2694        .par = (const uint32_t[]){TCG_COND_GE},
2695    }, {
2696        .name = "bgei",
2697        .translate = translate_bi,
2698        .par = (const uint32_t[]){TCG_COND_GE},
2699    }, {
2700        .name = "bgeu",
2701        .translate = translate_b,
2702        .par = (const uint32_t[]){TCG_COND_GEU},
2703    }, {
2704        .name = "bgeui",
2705        .translate = translate_bi,
2706        .par = (const uint32_t[]){TCG_COND_GEU},
2707    }, {
2708        .name = "bgez",
2709        .translate = translate_bz,
2710        .par = (const uint32_t[]){TCG_COND_GE},
2711    }, {
2712        .name = "blt",
2713        .translate = translate_b,
2714        .par = (const uint32_t[]){TCG_COND_LT},
2715    }, {
2716        .name = "blti",
2717        .translate = translate_bi,
2718        .par = (const uint32_t[]){TCG_COND_LT},
2719    }, {
2720        .name = "bltu",
2721        .translate = translate_b,
2722        .par = (const uint32_t[]){TCG_COND_LTU},
2723    }, {
2724        .name = "bltui",
2725        .translate = translate_bi,
2726        .par = (const uint32_t[]){TCG_COND_LTU},
2727    }, {
2728        .name = "bltz",
2729        .translate = translate_bz,
2730        .par = (const uint32_t[]){TCG_COND_LT},
2731    }, {
2732        .name = "bnall",
2733        .translate = translate_ball,
2734        .par = (const uint32_t[]){TCG_COND_NE},
2735    }, {
2736        .name = "bne",
2737        .translate = translate_b,
2738        .par = (const uint32_t[]){TCG_COND_NE},
2739    }, {
2740        .name = "bnei",
2741        .translate = translate_bi,
2742        .par = (const uint32_t[]){TCG_COND_NE},
2743    }, {
2744        .name = "bnez",
2745        .translate = translate_bz,
2746        .par = (const uint32_t[]){TCG_COND_NE},
2747    }, {
2748        .name = "bnez.n",
2749        .translate = translate_bz,
2750        .par = (const uint32_t[]){TCG_COND_NE},
2751    }, {
2752        .name = "bnone",
2753        .translate = translate_bany,
2754        .par = (const uint32_t[]){TCG_COND_EQ},
2755    }, {
2756        .name = "break",
2757        .translate = translate_break,
2758        .par = (const uint32_t[]){DEBUGCAUSE_BI},
2759    }, {
2760        .name = "break.n",
2761        .translate = translate_break,
2762        .par = (const uint32_t[]){DEBUGCAUSE_BN},
2763    }, {
2764        .name = "bt",
2765        .translate = translate_bp,
2766        .par = (const uint32_t[]){TCG_COND_NE},
2767    }, {
2768        .name = "call0",
2769        .translate = translate_call0,
2770    }, {
2771        .name = "call12",
2772        .translate = translate_callw,
2773        .par = (const uint32_t[]){3},
2774    }, {
2775        .name = "call4",
2776        .translate = translate_callw,
2777        .par = (const uint32_t[]){1},
2778    }, {
2779        .name = "call8",
2780        .translate = translate_callw,
2781        .par = (const uint32_t[]){2},
2782    }, {
2783        .name = "callx0",
2784        .translate = translate_callx0,
2785    }, {
2786        .name = "callx12",
2787        .translate = translate_callxw,
2788        .par = (const uint32_t[]){3},
2789    }, {
2790        .name = "callx4",
2791        .translate = translate_callxw,
2792        .par = (const uint32_t[]){1},
2793    }, {
2794        .name = "callx8",
2795        .translate = translate_callxw,
2796        .par = (const uint32_t[]){2},
2797    }, {
2798        .name = "clamps",
2799        .translate = translate_clamps,
2800    }, {
2801        .name = "clrb_expstate",
2802        .translate = translate_clrb_expstate,
2803    }, {
2804        .name = "const16",
2805        .translate = translate_const16,
2806    }, {
2807        .name = "depbits",
2808        .translate = translate_depbits,
2809    }, {
2810        .name = "dhi",
2811        .translate = translate_dcache,
2812        .par = (const uint32_t[]){true, true},
2813    }, {
2814        .name = "dhu",
2815        .translate = translate_dcache,
2816        .par = (const uint32_t[]){true, true},
2817    }, {
2818        .name = "dhwb",
2819        .translate = translate_dcache,
2820        .par = (const uint32_t[]){false, true},
2821    }, {
2822        .name = "dhwbi",
2823        .translate = translate_dcache,
2824        .par = (const uint32_t[]){false, true},
2825    }, {
2826        .name = "dii",
2827        .translate = translate_dcache,
2828        .par = (const uint32_t[]){true, false},
2829    }, {
2830        .name = "diu",
2831        .translate = translate_dcache,
2832        .par = (const uint32_t[]){true, false},
2833    }, {
2834        .name = "diwb",
2835        .translate = translate_dcache,
2836        .par = (const uint32_t[]){true, false},
2837    }, {
2838        .name = "diwbi",
2839        .translate = translate_dcache,
2840        .par = (const uint32_t[]){true, false},
2841    }, {
2842        .name = "dpfl",
2843        .translate = translate_dcache,
2844        .par = (const uint32_t[]){true, true},
2845    }, {
2846        .name = "dpfr",
2847        .translate = translate_dcache,
2848        .par = (const uint32_t[]){false, false},
2849    }, {
2850        .name = "dpfro",
2851        .translate = translate_dcache,
2852        .par = (const uint32_t[]){false, false},
2853    }, {
2854        .name = "dpfw",
2855        .translate = translate_dcache,
2856        .par = (const uint32_t[]){false, false},
2857    }, {
2858        .name = "dpfwo",
2859        .translate = translate_dcache,
2860        .par = (const uint32_t[]){false, false},
2861    }, {
2862        .name = "dsync",
2863        .translate = translate_nop,
2864    }, {
2865        .name = "entry",
2866        .translate = translate_entry,
2867    }, {
2868        .name = "esync",
2869        .translate = translate_nop,
2870    }, {
2871        .name = "excw",
2872        .translate = translate_nop,
2873    }, {
2874        .name = "extui",
2875        .translate = translate_extui,
2876    }, {
2877        .name = "extw",
2878        .translate = translate_memw,
2879    }, {
2880        .name = "hwwdtlba",
2881        .translate = translate_ill,
2882    }, {
2883        .name = "hwwitlba",
2884        .translate = translate_ill,
2885    }, {
2886        .name = "idtlb",
2887        .translate = translate_itlb,
2888        .par = (const uint32_t[]){true},
2889    }, {
2890        .name = "ihi",
2891        .translate = translate_icache,
2892        .par = (const uint32_t[]){false, true},
2893    }, {
2894        .name = "ihu",
2895        .translate = translate_icache,
2896        .par = (const uint32_t[]){true, true},
2897    }, {
2898        .name = "iii",
2899        .translate = translate_icache,
2900        .par = (const uint32_t[]){true, false},
2901    }, {
2902        .name = "iitlb",
2903        .translate = translate_itlb,
2904        .par = (const uint32_t[]){false},
2905    }, {
2906        .name = "iiu",
2907        .translate = translate_icache,
2908        .par = (const uint32_t[]){true, false},
2909    }, {
2910        .name = "ill",
2911        .translate = translate_ill,
2912    }, {
2913        .name = "ill.n",
2914        .translate = translate_ill,
2915    }, {
2916        .name = "ipf",
2917        .translate = translate_icache,
2918        .par = (const uint32_t[]){false, false},
2919    }, {
2920        .name = "ipfl",
2921        .translate = translate_icache,
2922        .par = (const uint32_t[]){true, true},
2923    }, {
2924        .name = "isync",
2925        .translate = translate_nop,
2926    }, {
2927        .name = "j",
2928        .translate = translate_j,
2929    }, {
2930        .name = "jx",
2931        .translate = translate_jx,
2932    }, {
2933        .name = "l16si",
2934        .translate = translate_ldst,
2935        .par = (const uint32_t[]){MO_TESW, false, false},
2936    }, {
2937        .name = "l16ui",
2938        .translate = translate_ldst,
2939        .par = (const uint32_t[]){MO_TEUW, false, false},
2940    }, {
2941        .name = "l32ai",
2942        .translate = translate_ldst,
2943        .par = (const uint32_t[]){MO_TEUL, true, false},
2944    }, {
2945        .name = "l32e",
2946        .translate = translate_l32e,
2947    }, {
2948        .name = "l32i",
2949        .translate = translate_ldst,
2950        .par = (const uint32_t[]){MO_TEUL, false, false},
2951    }, {
2952        .name = "l32i.n",
2953        .translate = translate_ldst,
2954        .par = (const uint32_t[]){MO_TEUL, false, false},
2955    }, {
2956        .name = "l32r",
2957        .translate = translate_l32r,
2958    }, {
2959        .name = "l8ui",
2960        .translate = translate_ldst,
2961        .par = (const uint32_t[]){MO_UB, false, false},
2962    }, {
2963        .name = "lddec",
2964        .translate = translate_mac16,
2965        .par = (const uint32_t[]){MAC16_NONE, 0, 0, -4},
2966    }, {
2967        .name = "ldinc",
2968        .translate = translate_mac16,
2969        .par = (const uint32_t[]){MAC16_NONE, 0, 0, 4},
2970    }, {
2971        .name = "ldpte",
2972        .translate = translate_ill,
2973    }, {
2974        .name = "loop",
2975        .translate = translate_loop,
2976        .par = (const uint32_t[]){TCG_COND_NEVER},
2977    }, {
2978        .name = "loopgtz",
2979        .translate = translate_loop,
2980        .par = (const uint32_t[]){TCG_COND_GT},
2981    }, {
2982        .name = "loopnez",
2983        .translate = translate_loop,
2984        .par = (const uint32_t[]){TCG_COND_NE},
2985    }, {
2986        .name = "max",
2987        .translate = translate_minmax,
2988        .par = (const uint32_t[]){TCG_COND_GE},
2989    }, {
2990        .name = "maxu",
2991        .translate = translate_minmax,
2992        .par = (const uint32_t[]){TCG_COND_GEU},
2993    }, {
2994        .name = "memw",
2995        .translate = translate_memw,
2996    }, {
2997        .name = "min",
2998        .translate = translate_minmax,
2999        .par = (const uint32_t[]){TCG_COND_LT},
3000    }, {
3001        .name = "minu",
3002        .translate = translate_minmax,
3003        .par = (const uint32_t[]){TCG_COND_LTU},
3004    }, {
3005        .name = "mov",
3006        .translate = translate_mov,
3007    }, {
3008        .name = "mov.n",
3009        .translate = translate_mov,
3010    }, {
3011        .name = "moveqz",
3012        .translate = translate_movcond,
3013        .par = (const uint32_t[]){TCG_COND_EQ},
3014    }, {
3015        .name = "movf",
3016        .translate = translate_movp,
3017        .par = (const uint32_t[]){TCG_COND_EQ},
3018    }, {
3019        .name = "movgez",
3020        .translate = translate_movcond,
3021        .par = (const uint32_t[]){TCG_COND_GE},
3022    }, {
3023        .name = "movi",
3024        .translate = translate_movi,
3025    }, {
3026        .name = "movi.n",
3027        .translate = translate_movi,
3028    }, {
3029        .name = "movltz",
3030        .translate = translate_movcond,
3031        .par = (const uint32_t[]){TCG_COND_LT},
3032    }, {
3033        .name = "movnez",
3034        .translate = translate_movcond,
3035        .par = (const uint32_t[]){TCG_COND_NE},
3036    }, {
3037        .name = "movsp",
3038        .translate = translate_movsp,
3039    }, {
3040        .name = "movt",
3041        .translate = translate_movp,
3042        .par = (const uint32_t[]){TCG_COND_NE},
3043    }, {
3044        .name = "mul.aa.hh",
3045        .translate = translate_mac16,
3046        .par = (const uint32_t[]){MAC16_MUL, MAC16_AA, MAC16_HH, 0},
3047    }, {
3048        .name = "mul.aa.hl",
3049        .translate = translate_mac16,
3050        .par = (const uint32_t[]){MAC16_MUL, MAC16_AA, MAC16_HL, 0},
3051    }, {
3052        .name = "mul.aa.lh",
3053        .translate = translate_mac16,
3054        .par = (const uint32_t[]){MAC16_MUL, MAC16_AA, MAC16_LH, 0},
3055    }, {
3056        .name = "mul.aa.ll",
3057        .translate = translate_mac16,
3058        .par = (const uint32_t[]){MAC16_MUL, MAC16_AA, MAC16_LL, 0},
3059    }, {
3060        .name = "mul.ad.hh",
3061        .translate = translate_mac16,
3062        .par = (const uint32_t[]){MAC16_MUL, MAC16_AD, MAC16_HH, 0},
3063    }, {
3064        .name = "mul.ad.hl",
3065        .translate = translate_mac16,
3066        .par = (const uint32_t[]){MAC16_MUL, MAC16_AD, MAC16_HL, 0},
3067    }, {
3068        .name = "mul.ad.lh",
3069        .translate = translate_mac16,
3070        .par = (const uint32_t[]){MAC16_MUL, MAC16_AD, MAC16_LH, 0},
3071    }, {
3072        .name = "mul.ad.ll",
3073        .translate = translate_mac16,
3074        .par = (const uint32_t[]){MAC16_MUL, MAC16_AD, MAC16_LL, 0},
3075    }, {
3076        .name = "mul.da.hh",
3077        .translate = translate_mac16,
3078        .par = (const uint32_t[]){MAC16_MUL, MAC16_DA, MAC16_HH, 0},
3079    }, {
3080        .name = "mul.da.hl",
3081        .translate = translate_mac16,
3082        .par = (const uint32_t[]){MAC16_MUL, MAC16_DA, MAC16_HL, 0},
3083    }, {
3084        .name = "mul.da.lh",
3085        .translate = translate_mac16,
3086        .par = (const uint32_t[]){MAC16_MUL, MAC16_DA, MAC16_LH, 0},
3087    }, {
3088        .name = "mul.da.ll",
3089        .translate = translate_mac16,
3090        .par = (const uint32_t[]){MAC16_MUL, MAC16_DA, MAC16_LL, 0},
3091    }, {
3092        .name = "mul.dd.hh",
3093        .translate = translate_mac16,
3094        .par = (const uint32_t[]){MAC16_MUL, MAC16_DD, MAC16_HH, 0},
3095    }, {
3096        .name = "mul.dd.hl",
3097        .translate = translate_mac16,
3098        .par = (const uint32_t[]){MAC16_MUL, MAC16_DD, MAC16_HL, 0},
3099    }, {
3100        .name = "mul.dd.lh",
3101        .translate = translate_mac16,
3102        .par = (const uint32_t[]){MAC16_MUL, MAC16_DD, MAC16_LH, 0},
3103    }, {
3104        .name = "mul.dd.ll",
3105        .translate = translate_mac16,
3106        .par = (const uint32_t[]){MAC16_MUL, MAC16_DD, MAC16_LL, 0},
3107    }, {
3108        .name = "mul16s",
3109        .translate = translate_mul16,
3110        .par = (const uint32_t[]){true},
3111    }, {
3112        .name = "mul16u",
3113        .translate = translate_mul16,
3114        .par = (const uint32_t[]){false},
3115    }, {
3116        .name = "mula.aa.hh",
3117        .translate = translate_mac16,
3118        .par = (const uint32_t[]){MAC16_MULA, MAC16_AA, MAC16_HH, 0},
3119    }, {
3120        .name = "mula.aa.hl",
3121        .translate = translate_mac16,
3122        .par = (const uint32_t[]){MAC16_MULA, MAC16_AA, MAC16_HL, 0},
3123    }, {
3124        .name = "mula.aa.lh",
3125        .translate = translate_mac16,
3126        .par = (const uint32_t[]){MAC16_MULA, MAC16_AA, MAC16_LH, 0},
3127    }, {
3128        .name = "mula.aa.ll",
3129        .translate = translate_mac16,
3130        .par = (const uint32_t[]){MAC16_MULA, MAC16_AA, MAC16_LL, 0},
3131    }, {
3132        .name = "mula.ad.hh",
3133        .translate = translate_mac16,
3134        .par = (const uint32_t[]){MAC16_MULA, MAC16_AD, MAC16_HH, 0},
3135    }, {
3136        .name = "mula.ad.hl",
3137        .translate = translate_mac16,
3138        .par = (const uint32_t[]){MAC16_MULA, MAC16_AD, MAC16_HL, 0},
3139    }, {
3140        .name = "mula.ad.lh",
3141        .translate = translate_mac16,
3142        .par = (const uint32_t[]){MAC16_MULA, MAC16_AD, MAC16_LH, 0},
3143    }, {
3144        .name = "mula.ad.ll",
3145        .translate = translate_mac16,
3146        .par = (const uint32_t[]){MAC16_MULA, MAC16_AD, MAC16_LL, 0},
3147    }, {
3148        .name = "mula.da.hh",
3149        .translate = translate_mac16,
3150        .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_HH, 0},
3151    }, {
3152        .name = "mula.da.hh.lddec",
3153        .translate = translate_mac16,
3154        .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_HH, -4},
3155    }, {
3156        .name = "mula.da.hh.ldinc",
3157        .translate = translate_mac16,
3158        .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_HH, 4},
3159    }, {
3160        .name = "mula.da.hl",
3161        .translate = translate_mac16,
3162        .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_HL, 0},
3163    }, {
3164        .name = "mula.da.hl.lddec",
3165        .translate = translate_mac16,
3166        .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_HL, -4},
3167    }, {
3168        .name = "mula.da.hl.ldinc",
3169        .translate = translate_mac16,
3170        .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_HL, 4},
3171    }, {
3172        .name = "mula.da.lh",
3173        .translate = translate_mac16,
3174        .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_LH, 0},
3175    }, {
3176        .name = "mula.da.lh.lddec",
3177        .translate = translate_mac16,
3178        .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_LH, -4},
3179    }, {
3180        .name = "mula.da.lh.ldinc",
3181        .translate = translate_mac16,
3182        .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_LH, 4},
3183    }, {
3184        .name = "mula.da.ll",
3185        .translate = translate_mac16,
3186        .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_LL, 0},
3187    }, {
3188        .name = "mula.da.ll.lddec",
3189        .translate = translate_mac16,
3190        .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_LL, -4},
3191    }, {
3192        .name = "mula.da.ll.ldinc",
3193        .translate = translate_mac16,
3194        .par = (const uint32_t[]){MAC16_MULA, MAC16_DA, MAC16_LL, 4},
3195    }, {
3196        .name = "mula.dd.hh",
3197        .translate = translate_mac16,
3198        .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_HH, 0},
3199    }, {
3200        .name = "mula.dd.hh.lddec",
3201        .translate = translate_mac16,
3202        .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_HH, -4},
3203    }, {
3204        .name = "mula.dd.hh.ldinc",
3205        .translate = translate_mac16,
3206        .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_HH, 4},
3207    }, {
3208        .name = "mula.dd.hl",
3209        .translate = translate_mac16,
3210        .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_HL, 0},
3211    }, {
3212        .name = "mula.dd.hl.lddec",
3213        .translate = translate_mac16,
3214        .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_HL, -4},
3215    }, {
3216        .name = "mula.dd.hl.ldinc",
3217        .translate = translate_mac16,
3218        .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_HL, 4},
3219    }, {
3220        .name = "mula.dd.lh",
3221        .translate = translate_mac16,
3222        .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_LH, 0},
3223    }, {
3224        .name = "mula.dd.lh.lddec",
3225        .translate = translate_mac16,
3226        .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_LH, -4},
3227    }, {
3228        .name = "mula.dd.lh.ldinc",
3229        .translate = translate_mac16,
3230        .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_LH, 4},
3231    }, {
3232        .name = "mula.dd.ll",
3233        .translate = translate_mac16,
3234        .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_LL, 0},
3235    }, {
3236        .name = "mula.dd.ll.lddec",
3237        .translate = translate_mac16,
3238        .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_LL, -4},
3239    }, {
3240        .name = "mula.dd.ll.ldinc",
3241        .translate = translate_mac16,
3242        .par = (const uint32_t[]){MAC16_MULA, MAC16_DD, MAC16_LL, 4},
3243    }, {
3244        .name = "mull",
3245        .translate = translate_mull,
3246    }, {
3247        .name = "muls.aa.hh",
3248        .translate = translate_mac16,
3249        .par = (const uint32_t[]){MAC16_MULS, MAC16_AA, MAC16_HH, 0},
3250    }, {
3251        .name = "muls.aa.hl",
3252        .translate = translate_mac16,
3253        .par = (const uint32_t[]){MAC16_MULS, MAC16_AA, MAC16_HL, 0},
3254    }, {
3255        .name = "muls.aa.lh",
3256        .translate = translate_mac16,
3257        .par = (const uint32_t[]){MAC16_MULS, MAC16_AA, MAC16_LH, 0},
3258    }, {
3259        .name = "muls.aa.ll",
3260        .translate = translate_mac16,
3261        .par = (const uint32_t[]){MAC16_MULS, MAC16_AA, MAC16_LL, 0},
3262    }, {
3263        .name = "muls.ad.hh",
3264        .translate = translate_mac16,
3265        .par = (const uint32_t[]){MAC16_MULS, MAC16_AD, MAC16_HH, 0},
3266    }, {
3267        .name = "muls.ad.hl",
3268        .translate = translate_mac16,
3269        .par = (const uint32_t[]){MAC16_MULS, MAC16_AD, MAC16_HL, 0},
3270    }, {
3271        .name = "muls.ad.lh",
3272        .translate = translate_mac16,
3273        .par = (const uint32_t[]){MAC16_MULS, MAC16_AD, MAC16_LH, 0},
3274    }, {
3275        .name = "muls.ad.ll",
3276        .translate = translate_mac16,
3277        .par = (const uint32_t[]){MAC16_MULS, MAC16_AD, MAC16_LL, 0},
3278    }, {
3279        .name = "muls.da.hh",
3280        .translate = translate_mac16,
3281        .par = (const uint32_t[]){MAC16_MULS, MAC16_DA, MAC16_HH, 0},
3282    }, {
3283        .name = "muls.da.hl",
3284        .translate = translate_mac16,
3285        .par = (const uint32_t[]){MAC16_MULS, MAC16_DA, MAC16_HL, 0},
3286    }, {
3287        .name = "muls.da.lh",
3288        .translate = translate_mac16,
3289        .par = (const uint32_t[]){MAC16_MULS, MAC16_DA, MAC16_LH, 0},
3290    }, {
3291        .name = "muls.da.ll",
3292        .translate = translate_mac16,
3293        .par = (const uint32_t[]){MAC16_MULS, MAC16_DA, MAC16_LL, 0},
3294    }, {
3295        .name = "muls.dd.hh",
3296        .translate = translate_mac16,
3297        .par = (const uint32_t[]){MAC16_MULS, MAC16_DD, MAC16_HH, 0},
3298    }, {
3299        .name = "muls.dd.hl",
3300        .translate = translate_mac16,
3301        .par = (const uint32_t[]){MAC16_MULS, MAC16_DD, MAC16_HL, 0},
3302    }, {
3303        .name = "muls.dd.lh",
3304        .translate = translate_mac16,
3305        .par = (const uint32_t[]){MAC16_MULS, MAC16_DD, MAC16_LH, 0},
3306    }, {
3307        .name = "muls.dd.ll",
3308        .translate = translate_mac16,
3309        .par = (const uint32_t[]){MAC16_MULS, MAC16_DD, MAC16_LL, 0},
3310    }, {
3311        .name = "mulsh",
3312        .translate = translate_mulh,
3313        .par = (const uint32_t[]){true},
3314    }, {
3315        .name = "muluh",
3316        .translate = translate_mulh,
3317        .par = (const uint32_t[]){false},
3318    }, {
3319        .name = "neg",
3320        .translate = translate_neg,
3321    }, {
3322        .name = "nop",
3323        .translate = translate_nop,
3324    }, {
3325        .name = "nop.n",
3326        .translate = translate_nop,
3327    }, {
3328        .name = "nsa",
3329        .translate = translate_nsa,
3330    }, {
3331        .name = "nsau",
3332        .translate = translate_nsau,
3333    }, {
3334        .name = "or",
3335        .translate = translate_or,
3336    }, {
3337        .name = "orb",
3338        .translate = translate_boolean,
3339        .par = (const uint32_t[]){BOOLEAN_OR},
3340    }, {
3341        .name = "orbc",
3342        .translate = translate_boolean,
3343        .par = (const uint32_t[]){BOOLEAN_ORC},
3344    }, {
3345        .name = "pdtlb",
3346        .translate = translate_ptlb,
3347        .par = (const uint32_t[]){true},
3348    }, {
3349        .name = "pitlb",
3350        .translate = translate_ptlb,
3351        .par = (const uint32_t[]){false},
3352    }, {
3353        .name = "quos",
3354        .translate = translate_quos,
3355        .par = (const uint32_t[]){true},
3356    }, {
3357        .name = "quou",
3358        .translate = translate_quou,
3359        .par = (const uint32_t[]){true},
3360    }, {
3361        .name = "rdtlb0",
3362        .translate = translate_rtlb,
3363        .par = (const uint32_t[]){true, 0},
3364    }, {
3365        .name = "rdtlb1",
3366        .translate = translate_rtlb,
3367        .par = (const uint32_t[]){true, 1},
3368    }, {
3369        .name = "read_impwire",
3370        .translate = translate_read_impwire,
3371    }, {
3372        .name = "rems",
3373        .translate = translate_quos,
3374        .par = (const uint32_t[]){false},
3375    }, {
3376        .name = "remu",
3377        .translate = translate_quou,
3378        .par = (const uint32_t[]){false},
3379    }, {
3380        .name = "rer",
3381        .translate = translate_rer,
3382    }, {
3383        .name = "ret",
3384        .translate = translate_ret,
3385    }, {
3386        .name = "ret.n",
3387        .translate = translate_ret,
3388    }, {
3389        .name = "retw",
3390        .translate = translate_retw,
3391    }, {
3392        .name = "retw.n",
3393        .translate = translate_retw,
3394    }, {
3395        .name = "rfdd",
3396        .translate = translate_ill,
3397    }, {
3398        .name = "rfde",
3399        .translate = translate_rfde,
3400    }, {
3401        .name = "rfdo",
3402        .translate = translate_ill,
3403    }, {
3404        .name = "rfe",
3405        .translate = translate_rfe,
3406    }, {
3407        .name = "rfi",
3408        .translate = translate_rfi,
3409    }, {
3410        .name = "rfwo",
3411        .translate = translate_rfw,
3412        .par = (const uint32_t[]){true},
3413    }, {
3414        .name = "rfwu",
3415        .translate = translate_rfw,
3416        .par = (const uint32_t[]){false},
3417    }, {
3418        .name = "ritlb0",
3419        .translate = translate_rtlb,
3420        .par = (const uint32_t[]){false, 0},
3421    }, {
3422        .name = "ritlb1",
3423        .translate = translate_rtlb,
3424        .par = (const uint32_t[]){false, 1},
3425    }, {
3426        .name = "rotw",
3427        .translate = translate_rotw,
3428    }, {
3429        .name = "rsil",
3430        .translate = translate_rsil,
3431    }, {
3432        .name = "rsr.176",
3433        .translate = translate_rsr,
3434        .par = (const uint32_t[]){176},
3435    }, {
3436        .name = "rsr.208",
3437        .translate = translate_rsr,
3438        .par = (const uint32_t[]){208},
3439    }, {
3440        .name = "rsr.acchi",
3441        .translate = translate_rsr,
3442        .par = (const uint32_t[]){ACCHI},
3443    }, {
3444        .name = "rsr.acclo",
3445        .translate = translate_rsr,
3446        .par = (const uint32_t[]){ACCLO},
3447    }, {
3448        .name = "rsr.atomctl",
3449        .translate = translate_rsr,
3450        .par = (const uint32_t[]){ATOMCTL},
3451    }, {
3452        .name = "rsr.br",
3453        .translate = translate_rsr,
3454        .par = (const uint32_t[]){BR},
3455    }, {
3456        .name = "rsr.cacheattr",
3457        .translate = translate_rsr,
3458        .par = (const uint32_t[]){CACHEATTR},
3459    }, {
3460        .name = "rsr.ccompare0",
3461        .translate = translate_rsr,
3462        .par = (const uint32_t[]){CCOMPARE},
3463    }, {
3464        .name = "rsr.ccompare1",
3465        .translate = translate_rsr,
3466        .par = (const uint32_t[]){CCOMPARE + 1},
3467    }, {
3468        .name = "rsr.ccompare2",
3469        .translate = translate_rsr,
3470        .par = (const uint32_t[]){CCOMPARE + 2},
3471    }, {
3472        .name = "rsr.ccount",
3473        .translate = translate_rsr,
3474        .par = (const uint32_t[]){CCOUNT},
3475    }, {
3476        .name = "rsr.configid0",
3477        .translate = translate_rsr,
3478        .par = (const uint32_t[]){CONFIGID0},
3479    }, {
3480        .name = "rsr.configid1",
3481        .translate = translate_rsr,
3482        .par = (const uint32_t[]){CONFIGID1},
3483    }, {
3484        .name = "rsr.cpenable",
3485        .translate = translate_rsr,
3486        .par = (const uint32_t[]){CPENABLE},
3487    }, {
3488        .name = "rsr.dbreaka0",
3489        .translate = translate_rsr,
3490        .par = (const uint32_t[]){DBREAKA},
3491    }, {
3492        .name = "rsr.dbreaka1",
3493        .translate = translate_rsr,
3494        .par = (const uint32_t[]){DBREAKA + 1},
3495    }, {
3496        .name = "rsr.dbreakc0",
3497        .translate = translate_rsr,
3498        .par = (const uint32_t[]){DBREAKC},
3499    }, {
3500        .name = "rsr.dbreakc1",
3501        .translate = translate_rsr,
3502        .par = (const uint32_t[]){DBREAKC + 1},
3503    }, {
3504        .name = "rsr.ddr",
3505        .translate = translate_rsr,
3506        .par = (const uint32_t[]){DDR},
3507    }, {
3508        .name = "rsr.debugcause",
3509        .translate = translate_rsr,
3510        .par = (const uint32_t[]){DEBUGCAUSE},
3511    }, {
3512        .name = "rsr.depc",
3513        .translate = translate_rsr,
3514        .par = (const uint32_t[]){DEPC},
3515    }, {
3516        .name = "rsr.dtlbcfg",
3517        .translate = translate_rsr,
3518        .par = (const uint32_t[]){DTLBCFG},
3519    }, {
3520        .name = "rsr.epc1",
3521        .translate = translate_rsr,
3522        .par = (const uint32_t[]){EPC1},
3523    }, {
3524        .name = "rsr.epc2",
3525        .translate = translate_rsr,
3526        .par = (const uint32_t[]){EPC1 + 1},
3527    }, {
3528        .name = "rsr.epc3",
3529        .translate = translate_rsr,
3530        .par = (const uint32_t[]){EPC1 + 2},
3531    }, {
3532        .name = "rsr.epc4",
3533        .translate = translate_rsr,
3534        .par = (const uint32_t[]){EPC1 + 3},
3535    }, {
3536        .name = "rsr.epc5",
3537        .translate = translate_rsr,
3538        .par = (const uint32_t[]){EPC1 + 4},
3539    }, {
3540        .name = "rsr.epc6",
3541        .translate = translate_rsr,
3542        .par = (const uint32_t[]){EPC1 + 5},
3543    }, {
3544        .name = "rsr.epc7",
3545        .translate = translate_rsr,
3546        .par = (const uint32_t[]){EPC1 + 6},
3547    }, {
3548        .name = "rsr.eps2",
3549        .translate = translate_rsr,
3550        .par = (const uint32_t[]){EPS2},
3551    }, {
3552        .name = "rsr.eps3",
3553        .translate = translate_rsr,
3554        .par = (const uint32_t[]){EPS2 + 1},
3555    }, {
3556        .name = "rsr.eps4",
3557        .translate = translate_rsr,
3558        .par = (const uint32_t[]){EPS2 + 2},
3559    }, {
3560        .name = "rsr.eps5",
3561        .translate = translate_rsr,
3562        .par = (const uint32_t[]){EPS2 + 3},
3563    }, {
3564        .name = "rsr.eps6",
3565        .translate = translate_rsr,
3566        .par = (const uint32_t[]){EPS2 + 4},
3567    }, {
3568        .name = "rsr.eps7",
3569        .translate = translate_rsr,
3570        .par = (const uint32_t[]){EPS2 + 5},
3571    }, {
3572        .name = "rsr.exccause",
3573        .translate = translate_rsr,
3574        .par = (const uint32_t[]){EXCCAUSE},
3575    }, {
3576        .name = "rsr.excsave1",
3577        .translate = translate_rsr,
3578        .par = (const uint32_t[]){EXCSAVE1},
3579    }, {
3580        .name = "rsr.excsave2",
3581        .translate = translate_rsr,
3582        .par = (const uint32_t[]){EXCSAVE1 + 1},
3583    }, {
3584        .name = "rsr.excsave3",
3585        .translate = translate_rsr,
3586        .par = (const uint32_t[]){EXCSAVE1 + 2},
3587    }, {
3588        .name = "rsr.excsave4",
3589        .translate = translate_rsr,
3590        .par = (const uint32_t[]){EXCSAVE1 + 3},
3591    }, {
3592        .name = "rsr.excsave5",
3593        .translate = translate_rsr,
3594        .par = (const uint32_t[]){EXCSAVE1 + 4},
3595    }, {
3596        .name = "rsr.excsave6",
3597        .translate = translate_rsr,
3598        .par = (const uint32_t[]){EXCSAVE1 + 5},
3599    }, {
3600        .name = "rsr.excsave7",
3601        .translate = translate_rsr,
3602        .par = (const uint32_t[]){EXCSAVE1 + 6},
3603    }, {
3604        .name = "rsr.excvaddr",
3605        .translate = translate_rsr,
3606        .par = (const uint32_t[]){EXCVADDR},
3607    }, {
3608        .name = "rsr.ibreaka0",
3609        .translate = translate_rsr,
3610        .par = (const uint32_t[]){IBREAKA},
3611    }, {
3612        .name = "rsr.ibreaka1",
3613        .translate = translate_rsr,
3614        .par = (const uint32_t[]){IBREAKA + 1},
3615    }, {
3616        .name = "rsr.ibreakenable",
3617        .translate = translate_rsr,
3618        .par = (const uint32_t[]){IBREAKENABLE},
3619    }, {
3620        .name = "rsr.icount",
3621        .translate = translate_rsr,
3622        .par = (const uint32_t[]){ICOUNT},
3623    }, {
3624        .name = "rsr.icountlevel",
3625        .translate = translate_rsr,
3626        .par = (const uint32_t[]){ICOUNTLEVEL},
3627    }, {
3628        .name = "rsr.intclear",
3629        .translate = translate_rsr,
3630        .par = (const uint32_t[]){INTCLEAR},
3631    }, {
3632        .name = "rsr.intenable",
3633        .translate = translate_rsr,
3634        .par = (const uint32_t[]){INTENABLE},
3635    }, {
3636        .name = "rsr.interrupt",
3637        .translate = translate_rsr,
3638        .par = (const uint32_t[]){INTSET},
3639    }, {
3640        .name = "rsr.intset",
3641        .translate = translate_rsr,
3642        .par = (const uint32_t[]){INTSET},
3643    }, {
3644        .name = "rsr.itlbcfg",
3645        .translate = translate_rsr,
3646        .par = (const uint32_t[]){ITLBCFG},
3647    }, {
3648        .name = "rsr.lbeg",
3649        .translate = translate_rsr,
3650        .par = (const uint32_t[]){LBEG},
3651    }, {
3652        .name = "rsr.lcount",
3653        .translate = translate_rsr,
3654        .par = (const uint32_t[]){LCOUNT},
3655    }, {
3656        .name = "rsr.lend",
3657        .translate = translate_rsr,
3658        .par = (const uint32_t[]){LEND},
3659    }, {
3660        .name = "rsr.litbase",
3661        .translate = translate_rsr,
3662        .par = (const uint32_t[]){LITBASE},
3663    }, {
3664        .name = "rsr.m0",
3665        .translate = translate_rsr,
3666        .par = (const uint32_t[]){MR},
3667    }, {
3668        .name = "rsr.m1",
3669        .translate = translate_rsr,
3670        .par = (const uint32_t[]){MR + 1},
3671    }, {
3672        .name = "rsr.m2",
3673        .translate = translate_rsr,
3674        .par = (const uint32_t[]){MR + 2},
3675    }, {
3676        .name = "rsr.m3",
3677        .translate = translate_rsr,
3678        .par = (const uint32_t[]){MR + 3},
3679    }, {
3680        .name = "rsr.memctl",
3681        .translate = translate_rsr,
3682        .par = (const uint32_t[]){MEMCTL},
3683    }, {
3684        .name = "rsr.misc0",
3685        .translate = translate_rsr,
3686        .par = (const uint32_t[]){MISC},
3687    }, {
3688        .name = "rsr.misc1",
3689        .translate = translate_rsr,
3690        .par = (const uint32_t[]){MISC + 1},
3691    }, {
3692        .name = "rsr.misc2",
3693        .translate = translate_rsr,
3694        .par = (const uint32_t[]){MISC + 2},
3695    }, {
3696        .name = "rsr.misc3",
3697        .translate = translate_rsr,
3698        .par = (const uint32_t[]){MISC + 3},
3699    }, {
3700        .name = "rsr.prid",
3701        .translate = translate_rsr,
3702        .par = (const uint32_t[]){PRID},
3703    }, {
3704        .name = "rsr.ps",
3705        .translate = translate_rsr,
3706        .par = (const uint32_t[]){PS},
3707    }, {
3708        .name = "rsr.ptevaddr",
3709        .translate = translate_rsr,
3710        .par = (const uint32_t[]){PTEVADDR},
3711    }, {
3712        .name = "rsr.rasid",
3713        .translate = translate_rsr,
3714        .par = (const uint32_t[]){RASID},
3715    }, {
3716        .name = "rsr.sar",
3717        .translate = translate_rsr,
3718        .par = (const uint32_t[]){SAR},
3719    }, {
3720        .name = "rsr.scompare1",
3721        .translate = translate_rsr,
3722        .par = (const uint32_t[]){SCOMPARE1},
3723    }, {
3724        .name = "rsr.vecbase",
3725        .translate = translate_rsr,
3726        .par = (const uint32_t[]){VECBASE},
3727    }, {
3728        .name = "rsr.windowbase",
3729        .translate = translate_rsr,
3730        .par = (const uint32_t[]){WINDOW_BASE},
3731    }, {
3732        .name = "rsr.windowstart",
3733        .translate = translate_rsr,
3734        .par = (const uint32_t[]){WINDOW_START},
3735    }, {
3736        .name = "rsync",
3737        .translate = translate_nop,
3738    }, {
3739        .name = "rur.expstate",
3740        .translate = translate_rur,
3741        .par = (const uint32_t[]){EXPSTATE},
3742    }, {
3743        .name = "rur.fcr",
3744        .translate = translate_rur,
3745        .par = (const uint32_t[]){FCR},
3746    }, {
3747        .name = "rur.fsr",
3748        .translate = translate_rur,
3749        .par = (const uint32_t[]){FSR},
3750    }, {
3751        .name = "rur.threadptr",
3752        .translate = translate_rur,
3753        .par = (const uint32_t[]){THREADPTR},
3754    }, {
3755        .name = "s16i",
3756        .translate = translate_ldst,
3757        .par = (const uint32_t[]){MO_TEUW, false, true},
3758    }, {
3759        .name = "s32c1i",
3760        .translate = translate_s32c1i,
3761    }, {
3762        .name = "s32e",
3763        .translate = translate_s32e,
3764    }, {
3765        .name = "s32i",
3766        .translate = translate_ldst,
3767        .par = (const uint32_t[]){MO_TEUL, false, true},
3768    }, {
3769        .name = "s32i.n",
3770        .translate = translate_ldst,
3771        .par = (const uint32_t[]){MO_TEUL, false, true},
3772    }, {
3773        .name = "s32nb",
3774        .translate = translate_ldst,
3775        .par = (const uint32_t[]){MO_TEUL, false, true},
3776    }, {
3777        .name = "s32ri",
3778        .translate = translate_ldst,
3779        .par = (const uint32_t[]){MO_TEUL, true, true},
3780    }, {
3781        .name = "s8i",
3782        .translate = translate_ldst,
3783        .par = (const uint32_t[]){MO_UB, false, true},
3784    }, {
3785        .name = "salt",
3786        .translate = translate_salt,
3787        .par = (const uint32_t[]){TCG_COND_LT},
3788    }, {
3789        .name = "saltu",
3790        .translate = translate_salt,
3791        .par = (const uint32_t[]){TCG_COND_LTU},
3792    }, {
3793        .name = "setb_expstate",
3794        .translate = translate_setb_expstate,
3795    }, {
3796        .name = "sext",
3797        .translate = translate_sext,
3798    }, {
3799        .name = "simcall",
3800        .translate = translate_simcall,
3801    }, {
3802        .name = "sll",
3803        .translate = translate_sll,
3804    }, {
3805        .name = "slli",
3806        .translate = translate_slli,
3807    }, {
3808        .name = "sra",
3809        .translate = translate_sra,
3810    }, {
3811        .name = "srai",
3812        .translate = translate_srai,
3813    }, {
3814        .name = "src",
3815        .translate = translate_src,
3816    }, {
3817        .name = "srl",
3818        .translate = translate_srl,
3819    }, {
3820        .name = "srli",
3821        .translate = translate_srli,
3822    }, {
3823        .name = "ssa8b",
3824        .translate = translate_ssa8b,
3825    }, {
3826        .name = "ssa8l",
3827        .translate = translate_ssa8l,
3828    }, {
3829        .name = "ssai",
3830        .translate = translate_ssai,
3831    }, {
3832        .name = "ssl",
3833        .translate = translate_ssl,
3834    }, {
3835        .name = "ssr",
3836        .translate = translate_ssr,
3837    }, {
3838        .name = "sub",
3839        .translate = translate_sub,
3840    }, {
3841        .name = "subx2",
3842        .translate = translate_subx,
3843        .par = (const uint32_t[]){1},
3844    }, {
3845        .name = "subx4",
3846        .translate = translate_subx,
3847        .par = (const uint32_t[]){2},
3848    }, {
3849        .name = "subx8",
3850        .translate = translate_subx,
3851        .par = (const uint32_t[]){3},
3852    }, {
3853        .name = "syscall",
3854        .translate = translate_syscall,
3855    }, {
3856        .name = "umul.aa.hh",
3857        .translate = translate_mac16,
3858        .par = (const uint32_t[]){MAC16_UMUL, MAC16_AA, MAC16_HH, 0},
3859    }, {
3860        .name = "umul.aa.hl",
3861        .translate = translate_mac16,
3862        .par = (const uint32_t[]){MAC16_UMUL, MAC16_AA, MAC16_HL, 0},
3863    }, {
3864        .name = "umul.aa.lh",
3865        .translate = translate_mac16,
3866        .par = (const uint32_t[]){MAC16_UMUL, MAC16_AA, MAC16_LH, 0},
3867    }, {
3868        .name = "umul.aa.ll",
3869        .translate = translate_mac16,
3870        .par = (const uint32_t[]){MAC16_UMUL, MAC16_AA, MAC16_LL, 0},
3871    }, {
3872        .name = "waiti",
3873        .translate = translate_waiti,
3874    }, {
3875        .name = "wdtlb",
3876        .translate = translate_wtlb,
3877        .par = (const uint32_t[]){true},
3878    }, {
3879        .name = "wer",
3880        .translate = translate_wer,
3881    }, {
3882        .name = "witlb",
3883        .translate = translate_wtlb,
3884        .par = (const uint32_t[]){false},
3885    }, {
3886        .name = "wrmsk_expstate",
3887        .translate = translate_wrmsk_expstate,
3888    }, {
3889        .name = "wsr.176",
3890        .translate = translate_wsr,
3891        .par = (const uint32_t[]){176},
3892    }, {
3893        .name = "wsr.208",
3894        .translate = translate_wsr,
3895        .par = (const uint32_t[]){208},
3896    }, {
3897        .name = "wsr.acchi",
3898        .translate = translate_wsr,
3899        .par = (const uint32_t[]){ACCHI},
3900    }, {
3901        .name = "wsr.acclo",
3902        .translate = translate_wsr,
3903        .par = (const uint32_t[]){ACCLO},
3904    }, {
3905        .name = "wsr.atomctl",
3906        .translate = translate_wsr,
3907        .par = (const uint32_t[]){ATOMCTL},
3908    }, {
3909        .name = "wsr.br",
3910        .translate = translate_wsr,
3911        .par = (const uint32_t[]){BR},
3912    }, {
3913        .name = "wsr.cacheattr",
3914        .translate = translate_wsr,
3915        .par = (const uint32_t[]){CACHEATTR},
3916    }, {
3917        .name = "wsr.ccompare0",
3918        .translate = translate_wsr,
3919        .par = (const uint32_t[]){CCOMPARE},
3920    }, {
3921        .name = "wsr.ccompare1",
3922        .translate = translate_wsr,
3923        .par = (const uint32_t[]){CCOMPARE + 1},
3924    }, {
3925        .name = "wsr.ccompare2",
3926        .translate = translate_wsr,
3927        .par = (const uint32_t[]){CCOMPARE + 2},
3928    }, {
3929        .name = "wsr.ccount",
3930        .translate = translate_wsr,
3931        .par = (const uint32_t[]){CCOUNT},
3932    }, {
3933        .name = "wsr.configid0",
3934        .translate = translate_wsr,
3935        .par = (const uint32_t[]){CONFIGID0},
3936    }, {
3937        .name = "wsr.configid1",
3938        .translate = translate_wsr,
3939        .par = (const uint32_t[]){CONFIGID1},
3940    }, {
3941        .name = "wsr.cpenable",
3942        .translate = translate_wsr,
3943        .par = (const uint32_t[]){CPENABLE},
3944    }, {
3945        .name = "wsr.dbreaka0",
3946        .translate = translate_wsr,
3947        .par = (const uint32_t[]){DBREAKA},
3948    }, {
3949        .name = "wsr.dbreaka1",
3950        .translate = translate_wsr,
3951        .par = (const uint32_t[]){DBREAKA + 1},
3952    }, {
3953        .name = "wsr.dbreakc0",
3954        .translate = translate_wsr,
3955        .par = (const uint32_t[]){DBREAKC},
3956    }, {
3957        .name = "wsr.dbreakc1",
3958        .translate = translate_wsr,
3959        .par = (const uint32_t[]){DBREAKC + 1},
3960    }, {
3961        .name = "wsr.ddr",
3962        .translate = translate_wsr,
3963        .par = (const uint32_t[]){DDR},
3964    }, {
3965        .name = "wsr.debugcause",
3966        .translate = translate_wsr,
3967        .par = (const uint32_t[]){DEBUGCAUSE},
3968    }, {
3969        .name = "wsr.depc",
3970        .translate = translate_wsr,
3971        .par = (const uint32_t[]){DEPC},
3972    }, {
3973        .name = "wsr.dtlbcfg",
3974        .translate = translate_wsr,
3975        .par = (const uint32_t[]){DTLBCFG},
3976    }, {
3977        .name = "wsr.epc1",
3978        .translate = translate_wsr,
3979        .par = (const uint32_t[]){EPC1},
3980    }, {
3981        .name = "wsr.epc2",
3982        .translate = translate_wsr,
3983        .par = (const uint32_t[]){EPC1 + 1},
3984    }, {
3985        .name = "wsr.epc3",
3986        .translate = translate_wsr,
3987        .par = (const uint32_t[]){EPC1 + 2},
3988    }, {
3989        .name = "wsr.epc4",
3990        .translate = translate_wsr,
3991        .par = (const uint32_t[]){EPC1 + 3},
3992    }, {
3993        .name = "wsr.epc5",
3994        .translate = translate_wsr,
3995        .par = (const uint32_t[]){EPC1 + 4},
3996    }, {
3997        .name = "wsr.epc6",
3998        .translate = translate_wsr,
3999        .par = (const uint32_t[]){EPC1 + 5},
4000    }, {
4001        .name = "wsr.epc7",
4002        .translate = translate_wsr,
4003        .par = (const uint32_t[]){EPC1 + 6},
4004    }, {
4005        .name = "wsr.eps2",
4006        .translate = translate_wsr,
4007        .par = (const uint32_t[]){EPS2},
4008    }, {
4009        .name = "wsr.eps3",
4010        .translate = translate_wsr,
4011        .par = (const uint32_t[]){EPS2 + 1},
4012    }, {
4013        .name = "wsr.eps4",
4014        .translate = translate_wsr,
4015        .par = (const uint32_t[]){EPS2 + 2},
4016    }, {
4017        .name = "wsr.eps5",
4018        .translate = translate_wsr,
4019        .par = (const uint32_t[]){EPS2 + 3},
4020    }, {
4021        .name = "wsr.eps6",
4022        .translate = translate_wsr,
4023        .par = (const uint32_t[]){EPS2 + 4},
4024    }, {
4025        .name = "wsr.eps7",
4026        .translate = translate_wsr,
4027        .par = (const uint32_t[]){EPS2 + 5},
4028    }, {
4029        .name = "wsr.exccause",
4030        .translate = translate_wsr,
4031        .par = (const uint32_t[]){EXCCAUSE},
4032    }, {
4033        .name = "wsr.excsave1",
4034        .translate = translate_wsr,
4035        .par = (const uint32_t[]){EXCSAVE1},
4036    }, {
4037        .name = "wsr.excsave2",
4038        .translate = translate_wsr,
4039        .par = (const uint32_t[]){EXCSAVE1 + 1},
4040    }, {
4041        .name = "wsr.excsave3",
4042        .translate = translate_wsr,
4043        .par = (const uint32_t[]){EXCSAVE1 + 2},
4044    }, {
4045        .name = "wsr.excsave4",
4046        .translate = translate_wsr,
4047        .par = (const uint32_t[]){EXCSAVE1 + 3},
4048    }, {
4049        .name = "wsr.excsave5",
4050        .translate = translate_wsr,
4051        .par = (const uint32_t[]){EXCSAVE1 + 4},
4052    }, {
4053        .name = "wsr.excsave6",
4054        .translate = translate_wsr,
4055        .par = (const uint32_t[]){EXCSAVE1 + 5},
4056    }, {
4057        .name = "wsr.excsave7",
4058        .translate = translate_wsr,
4059        .par = (const uint32_t[]){EXCSAVE1 + 6},
4060    }, {
4061        .name = "wsr.excvaddr",
4062        .translate = translate_wsr,
4063        .par = (const uint32_t[]){EXCVADDR},
4064    }, {
4065        .name = "wsr.ibreaka0",
4066        .translate = translate_wsr,
4067        .par = (const uint32_t[]){IBREAKA},
4068    }, {
4069        .name = "wsr.ibreaka1",
4070        .translate = translate_wsr,
4071        .par = (const uint32_t[]){IBREAKA + 1},
4072    }, {
4073        .name = "wsr.ibreakenable",
4074        .translate = translate_wsr,
4075        .par = (const uint32_t[]){IBREAKENABLE},
4076    }, {
4077        .name = "wsr.icount",
4078        .translate = translate_wsr,
4079        .par = (const uint32_t[]){ICOUNT},
4080    }, {
4081        .name = "wsr.icountlevel",
4082        .translate = translate_wsr,
4083        .par = (const uint32_t[]){ICOUNTLEVEL},
4084    }, {
4085        .name = "wsr.intclear",
4086        .translate = translate_wsr,
4087        .par = (const uint32_t[]){INTCLEAR},
4088    }, {
4089        .name = "wsr.intenable",
4090        .translate = translate_wsr,
4091        .par = (const uint32_t[]){INTENABLE},
4092    }, {
4093        .name = "wsr.interrupt",
4094        .translate = translate_wsr,
4095        .par = (const uint32_t[]){INTSET},
4096    }, {
4097        .name = "wsr.intset",
4098        .translate = translate_wsr,
4099        .par = (const uint32_t[]){INTSET},
4100    }, {
4101        .name = "wsr.itlbcfg",
4102        .translate = translate_wsr,
4103        .par = (const uint32_t[]){ITLBCFG},
4104    }, {
4105        .name = "wsr.lbeg",
4106        .translate = translate_wsr,
4107        .par = (const uint32_t[]){LBEG},
4108    }, {
4109        .name = "wsr.lcount",
4110        .translate = translate_wsr,
4111        .par = (const uint32_t[]){LCOUNT},
4112    }, {
4113        .name = "wsr.lend",
4114        .translate = translate_wsr,
4115        .par = (const uint32_t[]){LEND},
4116    }, {
4117        .name = "wsr.litbase",
4118        .translate = translate_wsr,
4119        .par = (const uint32_t[]){LITBASE},
4120    }, {
4121        .name = "wsr.m0",
4122        .translate = translate_wsr,
4123        .par = (const uint32_t[]){MR},
4124    }, {
4125        .name = "wsr.m1",
4126        .translate = translate_wsr,
4127        .par = (const uint32_t[]){MR + 1},
4128    }, {
4129        .name = "wsr.m2",
4130        .translate = translate_wsr,
4131        .par = (const uint32_t[]){MR + 2},
4132    }, {
4133        .name = "wsr.m3",
4134        .translate = translate_wsr,
4135        .par = (const uint32_t[]){MR + 3},
4136    }, {
4137        .name = "wsr.memctl",
4138        .translate = translate_wsr,
4139        .par = (const uint32_t[]){MEMCTL},
4140    }, {
4141        .name = "wsr.misc0",
4142        .translate = translate_wsr,
4143        .par = (const uint32_t[]){MISC},
4144    }, {
4145        .name = "wsr.misc1",
4146        .translate = translate_wsr,
4147        .par = (const uint32_t[]){MISC + 1},
4148    }, {
4149        .name = "wsr.misc2",
4150        .translate = translate_wsr,
4151        .par = (const uint32_t[]){MISC + 2},
4152    }, {
4153        .name = "wsr.misc3",
4154        .translate = translate_wsr,
4155        .par = (const uint32_t[]){MISC + 3},
4156    }, {
4157        .name = "wsr.mmid",
4158        .translate = translate_wsr,
4159        .par = (const uint32_t[]){MMID},
4160    }, {
4161        .name = "wsr.prid",
4162        .translate = translate_wsr,
4163        .par = (const uint32_t[]){PRID},
4164    }, {
4165        .name = "wsr.ps",
4166        .translate = translate_wsr,
4167        .par = (const uint32_t[]){PS},
4168    }, {
4169        .name = "wsr.ptevaddr",
4170        .translate = translate_wsr,
4171        .par = (const uint32_t[]){PTEVADDR},
4172    }, {
4173        .name = "wsr.rasid",
4174        .translate = translate_wsr,
4175        .par = (const uint32_t[]){RASID},
4176    }, {
4177        .name = "wsr.sar",
4178        .translate = translate_wsr,
4179        .par = (const uint32_t[]){SAR},
4180    }, {
4181        .name = "wsr.scompare1",
4182        .translate = translate_wsr,
4183        .par = (const uint32_t[]){SCOMPARE1},
4184    }, {
4185        .name = "wsr.vecbase",
4186        .translate = translate_wsr,
4187        .par = (const uint32_t[]){VECBASE},
4188    }, {
4189        .name = "wsr.windowbase",
4190        .translate = translate_wsr,
4191        .par = (const uint32_t[]){WINDOW_BASE},
4192    }, {
4193        .name = "wsr.windowstart",
4194        .translate = translate_wsr,
4195        .par = (const uint32_t[]){WINDOW_START},
4196    }, {
4197        .name = "wur.expstate",
4198        .translate = translate_wur,
4199        .par = (const uint32_t[]){EXPSTATE},
4200    }, {
4201        .name = "wur.fcr",
4202        .translate = translate_wur,
4203        .par = (const uint32_t[]){FCR},
4204    }, {
4205        .name = "wur.fsr",
4206        .translate = translate_wur,
4207        .par = (const uint32_t[]){FSR},
4208    }, {
4209        .name = "wur.threadptr",
4210        .translate = translate_wur,
4211        .par = (const uint32_t[]){THREADPTR},
4212    }, {
4213        .name = "xor",
4214        .translate = translate_xor,
4215    }, {
4216        .name = "xorb",
4217        .translate = translate_boolean,
4218        .par = (const uint32_t[]){BOOLEAN_XOR},
4219    }, {
4220        .name = "xsr.176",
4221        .translate = translate_xsr,
4222        .par = (const uint32_t[]){176},
4223    }, {
4224        .name = "xsr.208",
4225        .translate = translate_xsr,
4226        .par = (const uint32_t[]){208},
4227    }, {
4228        .name = "xsr.acchi",
4229        .translate = translate_xsr,
4230        .par = (const uint32_t[]){ACCHI},
4231    }, {
4232        .name = "xsr.acclo",
4233        .translate = translate_xsr,
4234        .par = (const uint32_t[]){ACCLO},
4235    }, {
4236        .name = "xsr.atomctl",
4237        .translate = translate_xsr,
4238        .par = (const uint32_t[]){ATOMCTL},
4239    }, {
4240        .name = "xsr.br",
4241        .translate = translate_xsr,
4242        .par = (const uint32_t[]){BR},
4243    }, {
4244        .name = "xsr.cacheattr",
4245        .translate = translate_xsr,
4246        .par = (const uint32_t[]){CACHEATTR},
4247    }, {
4248        .name = "xsr.ccompare0",
4249        .translate = translate_xsr,
4250        .par = (const uint32_t[]){CCOMPARE},
4251    }, {
4252        .name = "xsr.ccompare1",
4253        .translate = translate_xsr,
4254        .par = (const uint32_t[]){CCOMPARE + 1},
4255    }, {
4256        .name = "xsr.ccompare2",
4257        .translate = translate_xsr,
4258        .par = (const uint32_t[]){CCOMPARE + 2},
4259    }, {
4260        .name = "xsr.ccount",
4261        .translate = translate_xsr,
4262        .par = (const uint32_t[]){CCOUNT},
4263    }, {
4264        .name = "xsr.configid0",
4265        .translate = translate_xsr,
4266        .par = (const uint32_t[]){CONFIGID0},
4267    }, {
4268        .name = "xsr.configid1",
4269        .translate = translate_xsr,
4270        .par = (const uint32_t[]){CONFIGID1},
4271    }, {
4272        .name = "xsr.cpenable",
4273        .translate = translate_xsr,
4274        .par = (const uint32_t[]){CPENABLE},
4275    }, {
4276        .name = "xsr.dbreaka0",
4277        .translate = translate_xsr,
4278        .par = (const uint32_t[]){DBREAKA},
4279    }, {
4280        .name = "xsr.dbreaka1",
4281        .translate = translate_xsr,
4282        .par = (const uint32_t[]){DBREAKA + 1},
4283    }, {
4284        .name = "xsr.dbreakc0",
4285        .translate = translate_xsr,
4286        .par = (const uint32_t[]){DBREAKC},
4287    }, {
4288        .name = "xsr.dbreakc1",
4289        .translate = translate_xsr,
4290        .par = (const uint32_t[]){DBREAKC + 1},
4291    }, {
4292        .name = "xsr.ddr",
4293        .translate = translate_xsr,
4294        .par = (const uint32_t[]){DDR},
4295    }, {
4296        .name = "xsr.debugcause",
4297        .translate = translate_xsr,
4298        .par = (const uint32_t[]){DEBUGCAUSE},
4299    }, {
4300        .name = "xsr.depc",
4301        .translate = translate_xsr,
4302        .par = (const uint32_t[]){DEPC},
4303    }, {
4304        .name = "xsr.dtlbcfg",
4305        .translate = translate_xsr,
4306        .par = (const uint32_t[]){DTLBCFG},
4307    }, {
4308        .name = "xsr.epc1",
4309        .translate = translate_xsr,
4310        .par = (const uint32_t[]){EPC1},
4311    }, {
4312        .name = "xsr.epc2",
4313        .translate = translate_xsr,
4314        .par = (const uint32_t[]){EPC1 + 1},
4315    }, {
4316        .name = "xsr.epc3",
4317        .translate = translate_xsr,
4318        .par = (const uint32_t[]){EPC1 + 2},
4319    }, {
4320        .name = "xsr.epc4",
4321        .translate = translate_xsr,
4322        .par = (const uint32_t[]){EPC1 + 3},
4323    }, {
4324        .name = "xsr.epc5",
4325        .translate = translate_xsr,
4326        .par = (const uint32_t[]){EPC1 + 4},
4327    }, {
4328        .name = "xsr.epc6",
4329        .translate = translate_xsr,
4330        .par = (const uint32_t[]){EPC1 + 5},
4331    }, {
4332        .name = "xsr.epc7",
4333        .translate = translate_xsr,
4334        .par = (const uint32_t[]){EPC1 + 6},
4335    }, {
4336        .name = "xsr.eps2",
4337        .translate = translate_xsr,
4338        .par = (const uint32_t[]){EPS2},
4339    }, {
4340        .name = "xsr.eps3",
4341        .translate = translate_xsr,
4342        .par = (const uint32_t[]){EPS2 + 1},
4343    }, {
4344        .name = "xsr.eps4",
4345        .translate = translate_xsr,
4346        .par = (const uint32_t[]){EPS2 + 2},
4347    }, {
4348        .name = "xsr.eps5",
4349        .translate = translate_xsr,
4350        .par = (const uint32_t[]){EPS2 + 3},
4351    }, {
4352        .name = "xsr.eps6",
4353        .translate = translate_xsr,
4354        .par = (const uint32_t[]){EPS2 + 4},
4355    }, {
4356        .name = "xsr.eps7",
4357        .translate = translate_xsr,
4358        .par = (const uint32_t[]){EPS2 + 5},
4359    }, {
4360        .name = "xsr.exccause",
4361        .translate = translate_xsr,
4362        .par = (const uint32_t[]){EXCCAUSE},
4363    }, {
4364        .name = "xsr.excsave1",
4365        .translate = translate_xsr,
4366        .par = (const uint32_t[]){EXCSAVE1},
4367    }, {
4368        .name = "xsr.excsave2",
4369        .translate = translate_xsr,
4370        .par = (const uint32_t[]){EXCSAVE1 + 1},
4371    }, {
4372        .name = "xsr.excsave3",
4373        .translate = translate_xsr,
4374        .par = (const uint32_t[]){EXCSAVE1 + 2},
4375    }, {
4376        .name = "xsr.excsave4",
4377        .translate = translate_xsr,
4378        .par = (const uint32_t[]){EXCSAVE1 + 3},
4379    }, {
4380        .name = "xsr.excsave5",
4381        .translate = translate_xsr,
4382        .par = (const uint32_t[]){EXCSAVE1 + 4},
4383    }, {
4384        .name = "xsr.excsave6",
4385        .translate = translate_xsr,
4386        .par = (const uint32_t[]){EXCSAVE1 + 5},
4387    }, {
4388        .name = "xsr.excsave7",
4389        .translate = translate_xsr,
4390        .par = (const uint32_t[]){EXCSAVE1 + 6},
4391    }, {
4392        .name = "xsr.excvaddr",
4393        .translate = translate_xsr,
4394        .par = (const uint32_t[]){EXCVADDR},
4395    }, {
4396        .name = "xsr.ibreaka0",
4397        .translate = translate_xsr,
4398        .par = (const uint32_t[]){IBREAKA},
4399    }, {
4400        .name = "xsr.ibreaka1",
4401        .translate = translate_xsr,
4402        .par = (const uint32_t[]){IBREAKA + 1},
4403    }, {
4404        .name = "xsr.ibreakenable",
4405        .translate = translate_xsr,
4406        .par = (const uint32_t[]){IBREAKENABLE},
4407    }, {
4408        .name = "xsr.icount",
4409        .translate = translate_xsr,
4410        .par = (const uint32_t[]){ICOUNT},
4411    }, {
4412        .name = "xsr.icountlevel",
4413        .translate = translate_xsr,
4414        .par = (const uint32_t[]){ICOUNTLEVEL},
4415    }, {
4416        .name = "xsr.intclear",
4417        .translate = translate_xsr,
4418        .par = (const uint32_t[]){INTCLEAR},
4419    }, {
4420        .name = "xsr.intenable",
4421        .translate = translate_xsr,
4422        .par = (const uint32_t[]){INTENABLE},
4423    }, {
4424        .name = "xsr.interrupt",
4425        .translate = translate_xsr,
4426        .par = (const uint32_t[]){INTSET},
4427    }, {
4428        .name = "xsr.intset",
4429        .translate = translate_xsr,
4430        .par = (const uint32_t[]){INTSET},
4431    }, {
4432        .name = "xsr.itlbcfg",
4433        .translate = translate_xsr,
4434        .par = (const uint32_t[]){ITLBCFG},
4435    }, {
4436        .name = "xsr.lbeg",
4437        .translate = translate_xsr,
4438        .par = (const uint32_t[]){LBEG},
4439    }, {
4440        .name = "xsr.lcount",
4441        .translate = translate_xsr,
4442        .par = (const uint32_t[]){LCOUNT},
4443    }, {
4444        .name = "xsr.lend",
4445        .translate = translate_xsr,
4446        .par = (const uint32_t[]){LEND},
4447    }, {
4448        .name = "xsr.litbase",
4449        .translate = translate_xsr,
4450        .par = (const uint32_t[]){LITBASE},
4451    }, {
4452        .name = "xsr.m0",
4453        .translate = translate_xsr,
4454        .par = (const uint32_t[]){MR},
4455    }, {
4456        .name = "xsr.m1",
4457        .translate = translate_xsr,
4458        .par = (const uint32_t[]){MR + 1},
4459    }, {
4460        .name = "xsr.m2",
4461        .translate = translate_xsr,
4462        .par = (const uint32_t[]){MR + 2},
4463    }, {
4464        .name = "xsr.m3",
4465        .translate = translate_xsr,
4466        .par = (const uint32_t[]){MR + 3},
4467    }, {
4468        .name = "xsr.memctl",
4469        .translate = translate_xsr,
4470        .par = (const uint32_t[]){MEMCTL},
4471    }, {
4472        .name = "xsr.misc0",
4473        .translate = translate_xsr,
4474        .par = (const uint32_t[]){MISC},
4475    }, {
4476        .name = "xsr.misc1",
4477        .translate = translate_xsr,
4478        .par = (const uint32_t[]){MISC + 1},
4479    }, {
4480        .name = "xsr.misc2",
4481        .translate = translate_xsr,
4482        .par = (const uint32_t[]){MISC + 2},
4483    }, {
4484        .name = "xsr.misc3",
4485        .translate = translate_xsr,
4486        .par = (const uint32_t[]){MISC + 3},
4487    }, {
4488        .name = "xsr.prid",
4489        .translate = translate_xsr,
4490        .par = (const uint32_t[]){PRID},
4491    }, {
4492        .name = "xsr.ps",
4493        .translate = translate_xsr,
4494        .par = (const uint32_t[]){PS},
4495    }, {
4496        .name = "xsr.ptevaddr",
4497        .translate = translate_xsr,
4498        .par = (const uint32_t[]){PTEVADDR},
4499    }, {
4500        .name = "xsr.rasid",
4501        .translate = translate_xsr,
4502        .par = (const uint32_t[]){RASID},
4503    }, {
4504        .name = "xsr.sar",
4505        .translate = translate_xsr,
4506        .par = (const uint32_t[]){SAR},
4507    }, {
4508        .name = "xsr.scompare1",
4509        .translate = translate_xsr,
4510        .par = (const uint32_t[]){SCOMPARE1},
4511    }, {
4512        .name = "xsr.vecbase",
4513        .translate = translate_xsr,
4514        .par = (const uint32_t[]){VECBASE},
4515    }, {
4516        .name = "xsr.windowbase",
4517        .translate = translate_xsr,
4518        .par = (const uint32_t[]){WINDOW_BASE},
4519    }, {
4520        .name = "xsr.windowstart",
4521        .translate = translate_xsr,
4522        .par = (const uint32_t[]){WINDOW_START},
4523    },
4524};
4525
4526const XtensaOpcodeTranslators xtensa_core_opcodes = {
4527    .num_opcodes = ARRAY_SIZE(core_ops),
4528    .opcode = core_ops,
4529};
4530
4531
4532static void translate_abs_s(DisasContext *dc, const uint32_t arg[],
4533                            const uint32_t par[])
4534{
4535    if (gen_check_cpenable(dc, 0)) {
4536        gen_helper_abs_s(cpu_FR[arg[0]], cpu_FR[arg[1]]);
4537    }
4538}
4539
4540static void translate_add_s(DisasContext *dc, const uint32_t arg[],
4541                            const uint32_t par[])
4542{
4543    if (gen_check_cpenable(dc, 0)) {
4544        gen_helper_add_s(cpu_FR[arg[0]], cpu_env,
4545                         cpu_FR[arg[1]], cpu_FR[arg[2]]);
4546    }
4547}
4548
4549enum {
4550    COMPARE_UN,
4551    COMPARE_OEQ,
4552    COMPARE_UEQ,
4553    COMPARE_OLT,
4554    COMPARE_ULT,
4555    COMPARE_OLE,
4556    COMPARE_ULE,
4557};
4558
4559static void translate_compare_s(DisasContext *dc, const uint32_t arg[],
4560                                const uint32_t par[])
4561{
4562    static void (* const helper[])(TCGv_env env, TCGv_i32 bit,
4563                                   TCGv_i32 s, TCGv_i32 t) = {
4564        [COMPARE_UN] = gen_helper_un_s,
4565        [COMPARE_OEQ] = gen_helper_oeq_s,
4566        [COMPARE_UEQ] = gen_helper_ueq_s,
4567        [COMPARE_OLT] = gen_helper_olt_s,
4568        [COMPARE_ULT] = gen_helper_ult_s,
4569        [COMPARE_OLE] = gen_helper_ole_s,
4570        [COMPARE_ULE] = gen_helper_ule_s,
4571    };
4572
4573    if (gen_check_cpenable(dc, 0)) {
4574        TCGv_i32 bit = tcg_const_i32(1 << arg[0]);
4575
4576        helper[par[0]](cpu_env, bit, cpu_FR[arg[1]], cpu_FR[arg[2]]);
4577        tcg_temp_free(bit);
4578    }
4579}
4580
4581static void translate_float_s(DisasContext *dc, const uint32_t arg[],
4582                              const uint32_t par[])
4583{
4584    if (gen_window_check1(dc, arg[1]) && gen_check_cpenable(dc, 0)) {
4585        TCGv_i32 scale = tcg_const_i32(-arg[2]);
4586
4587        if (par[0]) {
4588            gen_helper_uitof(cpu_FR[arg[0]], cpu_env, cpu_R[arg[1]], scale);
4589        } else {
4590            gen_helper_itof(cpu_FR[arg[0]], cpu_env, cpu_R[arg[1]], scale);
4591        }
4592        tcg_temp_free(scale);
4593    }
4594}
4595
4596static void translate_ftoi_s(DisasContext *dc, const uint32_t arg[],
4597                             const uint32_t par[])
4598{
4599    if (gen_window_check1(dc, arg[0]) && gen_check_cpenable(dc, 0)) {
4600        TCGv_i32 rounding_mode = tcg_const_i32(par[0]);
4601        TCGv_i32 scale = tcg_const_i32(arg[2]);
4602
4603        if (par[1]) {
4604            gen_helper_ftoui(cpu_R[arg[0]], cpu_FR[arg[1]],
4605                             rounding_mode, scale);
4606        } else {
4607            gen_helper_ftoi(cpu_R[arg[0]], cpu_FR[arg[1]],
4608                            rounding_mode, scale);
4609        }
4610        tcg_temp_free(rounding_mode);
4611        tcg_temp_free(scale);
4612    }
4613}
4614
4615static void translate_ldsti(DisasContext *dc, const uint32_t arg[],
4616                            const uint32_t par[])
4617{
4618    if (gen_window_check1(dc, arg[1]) && gen_check_cpenable(dc, 0)) {
4619        TCGv_i32 addr = tcg_temp_new_i32();
4620
4621        tcg_gen_addi_i32(addr, cpu_R[arg[1]], arg[2]);
4622        gen_load_store_alignment(dc, 2, addr, false);
4623        if (par[0]) {
4624            tcg_gen_qemu_st32(cpu_FR[arg[0]], addr, dc->cring);
4625        } else {
4626            tcg_gen_qemu_ld32u(cpu_FR[arg[0]], addr, dc->cring);
4627        }
4628        if (par[1]) {
4629            tcg_gen_mov_i32(cpu_R[arg[1]], addr);
4630        }
4631        tcg_temp_free(addr);
4632    }
4633}
4634
4635static void translate_ldstx(DisasContext *dc, const uint32_t arg[],
4636                            const uint32_t par[])
4637{
4638    if (gen_window_check2(dc, arg[1], arg[2]) && gen_check_cpenable(dc, 0)) {
4639        TCGv_i32 addr = tcg_temp_new_i32();
4640
4641        tcg_gen_add_i32(addr, cpu_R[arg[1]], cpu_R[arg[2]]);
4642        gen_load_store_alignment(dc, 2, addr, false);
4643        if (par[0]) {
4644            tcg_gen_qemu_st32(cpu_FR[arg[0]], addr, dc->cring);
4645        } else {
4646            tcg_gen_qemu_ld32u(cpu_FR[arg[0]], addr, dc->cring);
4647        }
4648        if (par[1]) {
4649            tcg_gen_mov_i32(cpu_R[arg[1]], addr);
4650        }
4651        tcg_temp_free(addr);
4652    }
4653}
4654
4655static void translate_madd_s(DisasContext *dc, const uint32_t arg[],
4656                             const uint32_t par[])
4657{
4658    if (gen_check_cpenable(dc, 0)) {
4659        gen_helper_madd_s(cpu_FR[arg[0]], cpu_env,
4660                          cpu_FR[arg[0]], cpu_FR[arg[1]], cpu_FR[arg[2]]);
4661    }
4662}
4663
4664static void translate_mov_s(DisasContext *dc, const uint32_t arg[],
4665                            const uint32_t par[])
4666{
4667    if (gen_check_cpenable(dc, 0)) {
4668        tcg_gen_mov_i32(cpu_FR[arg[0]], cpu_FR[arg[1]]);
4669    }
4670}
4671
4672static void translate_movcond_s(DisasContext *dc, const uint32_t arg[],
4673                                const uint32_t par[])
4674{
4675    if (gen_window_check1(dc, arg[2]) && gen_check_cpenable(dc, 0)) {
4676        TCGv_i32 zero = tcg_const_i32(0);
4677
4678        tcg_gen_movcond_i32(par[0], cpu_FR[arg[0]],
4679                            cpu_R[arg[2]], zero,
4680                            cpu_FR[arg[1]], cpu_FR[arg[2]]);
4681        tcg_temp_free(zero);
4682    }
4683}
4684
4685static void translate_movp_s(DisasContext *dc, const uint32_t arg[],
4686                             const uint32_t par[])
4687{
4688    if (gen_check_cpenable(dc, 0)) {
4689        TCGv_i32 zero = tcg_const_i32(0);
4690        TCGv_i32 tmp = tcg_temp_new_i32();
4691
4692        tcg_gen_andi_i32(tmp, cpu_SR[BR], 1 << arg[2]);
4693        tcg_gen_movcond_i32(par[0],
4694                            cpu_FR[arg[0]], tmp, zero,
4695                            cpu_FR[arg[1]], cpu_FR[arg[0]]);
4696        tcg_temp_free(tmp);
4697        tcg_temp_free(zero);
4698    }
4699}
4700
4701static void translate_mul_s(DisasContext *dc, const uint32_t arg[],
4702                            const uint32_t par[])
4703{
4704    if (gen_check_cpenable(dc, 0)) {
4705        gen_helper_mul_s(cpu_FR[arg[0]], cpu_env,
4706                         cpu_FR[arg[1]], cpu_FR[arg[2]]);
4707    }
4708}
4709
4710static void translate_msub_s(DisasContext *dc, const uint32_t arg[],
4711                             const uint32_t par[])
4712{
4713    if (gen_check_cpenable(dc, 0)) {
4714        gen_helper_msub_s(cpu_FR[arg[0]], cpu_env,
4715                          cpu_FR[arg[0]], cpu_FR[arg[1]], cpu_FR[arg[2]]);
4716    }
4717}
4718
4719static void translate_neg_s(DisasContext *dc, const uint32_t arg[],
4720                            const uint32_t par[])
4721{
4722    if (gen_check_cpenable(dc, 0)) {
4723        gen_helper_neg_s(cpu_FR[arg[0]], cpu_FR[arg[1]]);
4724    }
4725}
4726
4727static void translate_rfr_s(DisasContext *dc, const uint32_t arg[],
4728                            const uint32_t par[])
4729{
4730    if (gen_window_check1(dc, arg[0]) &&
4731        gen_check_cpenable(dc, 0)) {
4732        tcg_gen_mov_i32(cpu_R[arg[0]], cpu_FR[arg[1]]);
4733    }
4734}
4735
4736static void translate_sub_s(DisasContext *dc, const uint32_t arg[],
4737                            const uint32_t par[])
4738{
4739    if (gen_check_cpenable(dc, 0)) {
4740        gen_helper_sub_s(cpu_FR[arg[0]], cpu_env,
4741                         cpu_FR[arg[1]], cpu_FR[arg[2]]);
4742    }
4743}
4744
4745static void translate_wfr_s(DisasContext *dc, const uint32_t arg[],
4746                            const uint32_t par[])
4747{
4748    if (gen_window_check1(dc, arg[1]) &&
4749        gen_check_cpenable(dc, 0)) {
4750        tcg_gen_mov_i32(cpu_FR[arg[0]], cpu_R[arg[1]]);
4751    }
4752}
4753
4754static const XtensaOpcodeOps fpu2000_ops[] = {
4755    {
4756        .name = "abs.s",
4757        .translate = translate_abs_s,
4758    }, {
4759        .name = "add.s",
4760        .translate = translate_add_s,
4761    }, {
4762        .name = "ceil.s",
4763        .translate = translate_ftoi_s,
4764        .par = (const uint32_t[]){float_round_up, false},
4765    }, {
4766        .name = "float.s",
4767        .translate = translate_float_s,
4768        .par = (const uint32_t[]){false},
4769    }, {
4770        .name = "floor.s",
4771        .translate = translate_ftoi_s,
4772        .par = (const uint32_t[]){float_round_down, false},
4773    }, {
4774        .name = "lsi",
4775        .translate = translate_ldsti,
4776        .par = (const uint32_t[]){false, false},
4777    }, {
4778        .name = "lsiu",
4779        .translate = translate_ldsti,
4780        .par = (const uint32_t[]){false, true},
4781    }, {
4782        .name = "lsx",
4783        .translate = translate_ldstx,
4784        .par = (const uint32_t[]){false, false},
4785    }, {
4786        .name = "lsxu",
4787        .translate = translate_ldstx,
4788        .par = (const uint32_t[]){false, true},
4789    }, {
4790        .name = "madd.s",
4791        .translate = translate_madd_s,
4792    }, {
4793        .name = "mov.s",
4794        .translate = translate_mov_s,
4795    }, {
4796        .name = "moveqz.s",
4797        .translate = translate_movcond_s,
4798        .par = (const uint32_t[]){TCG_COND_EQ},
4799    }, {
4800        .name = "movf.s",
4801        .translate = translate_movp_s,
4802        .par = (const uint32_t[]){TCG_COND_EQ},
4803    }, {
4804        .name = "movgez.s",
4805        .translate = translate_movcond_s,
4806        .par = (const uint32_t[]){TCG_COND_GE},
4807    }, {
4808        .name = "movltz.s",
4809        .translate = translate_movcond_s,
4810        .par = (const uint32_t[]){TCG_COND_LT},
4811    }, {
4812        .name = "movnez.s",
4813        .translate = translate_movcond_s,
4814        .par = (const uint32_t[]){TCG_COND_NE},
4815    }, {
4816        .name = "movt.s",
4817        .translate = translate_movp_s,
4818        .par = (const uint32_t[]){TCG_COND_NE},
4819    }, {
4820        .name = "msub.s",
4821        .translate = translate_msub_s,
4822    }, {
4823        .name = "mul.s",
4824        .translate = translate_mul_s,
4825    }, {
4826        .name = "neg.s",
4827        .translate = translate_neg_s,
4828    }, {
4829        .name = "oeq.s",
4830        .translate = translate_compare_s,
4831        .par = (const uint32_t[]){COMPARE_OEQ},
4832    }, {
4833        .name = "ole.s",
4834        .translate = translate_compare_s,
4835        .par = (const uint32_t[]){COMPARE_OLE},
4836    }, {
4837        .name = "olt.s",
4838        .translate = translate_compare_s,
4839        .par = (const uint32_t[]){COMPARE_OLT},
4840    }, {
4841        .name = "rfr.s",
4842        .translate = translate_rfr_s,
4843    }, {
4844        .name = "round.s",
4845        .translate = translate_ftoi_s,
4846        .par = (const uint32_t[]){float_round_nearest_even, false},
4847    }, {
4848        .name = "ssi",
4849        .translate = translate_ldsti,
4850        .par = (const uint32_t[]){true, false},
4851    }, {
4852        .name = "ssiu",
4853        .translate = translate_ldsti,
4854        .par = (const uint32_t[]){true, true},
4855    }, {
4856        .name = "ssx",
4857        .translate = translate_ldstx,
4858        .par = (const uint32_t[]){true, false},
4859    }, {
4860        .name = "ssxu",
4861        .translate = translate_ldstx,
4862        .par = (const uint32_t[]){true, true},
4863    }, {
4864        .name = "sub.s",
4865        .translate = translate_sub_s,
4866    }, {
4867        .name = "trunc.s",
4868        .translate = translate_ftoi_s,
4869        .par = (const uint32_t[]){float_round_to_zero, false},
4870    }, {
4871        .name = "ueq.s",
4872        .translate = translate_compare_s,
4873        .par = (const uint32_t[]){COMPARE_UEQ},
4874    }, {
4875        .name = "ufloat.s",
4876        .translate = translate_float_s,
4877        .par = (const uint32_t[]){true},
4878    }, {
4879        .name = "ule.s",
4880        .translate = translate_compare_s,
4881        .par = (const uint32_t[]){COMPARE_ULE},
4882    }, {
4883        .name = "ult.s",
4884        .translate = translate_compare_s,
4885        .par = (const uint32_t[]){COMPARE_ULT},
4886    }, {
4887        .name = "un.s",
4888        .translate = translate_compare_s,
4889        .par = (const uint32_t[]){COMPARE_UN},
4890    }, {
4891        .name = "utrunc.s",
4892        .translate = translate_ftoi_s,
4893        .par = (const uint32_t[]){float_round_to_zero, true},
4894    }, {
4895        .name = "wfr.s",
4896        .translate = translate_wfr_s,
4897    },
4898};
4899
4900const XtensaOpcodeTranslators xtensa_fpu2000_opcodes = {
4901    .num_opcodes = ARRAY_SIZE(fpu2000_ops),
4902    .opcode = fpu2000_ops,
4903};
4904