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