1*e5918d7dSYoshinori Sato /* 2*e5918d7dSYoshinori Sato * RX translation 3*e5918d7dSYoshinori Sato * 4*e5918d7dSYoshinori Sato * Copyright (c) 2019 Yoshinori Sato 5*e5918d7dSYoshinori Sato * 6*e5918d7dSYoshinori Sato * This program is free software; you can redistribute it and/or modify it 7*e5918d7dSYoshinori Sato * under the terms and conditions of the GNU General Public License, 8*e5918d7dSYoshinori Sato * version 2 or later, as published by the Free Software Foundation. 9*e5918d7dSYoshinori Sato * 10*e5918d7dSYoshinori Sato * This program is distributed in the hope it will be useful, but WITHOUT 11*e5918d7dSYoshinori Sato * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12*e5918d7dSYoshinori Sato * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13*e5918d7dSYoshinori Sato * more details. 14*e5918d7dSYoshinori Sato * 15*e5918d7dSYoshinori Sato * You should have received a copy of the GNU General Public License along with 16*e5918d7dSYoshinori Sato * this program. If not, see <http://www.gnu.org/licenses/>. 17*e5918d7dSYoshinori Sato */ 18*e5918d7dSYoshinori Sato 19*e5918d7dSYoshinori Sato #include "qemu/osdep.h" 20*e5918d7dSYoshinori Sato #include "qemu/bswap.h" 21*e5918d7dSYoshinori Sato #include "qemu/qemu-print.h" 22*e5918d7dSYoshinori Sato #include "cpu.h" 23*e5918d7dSYoshinori Sato #include "exec/exec-all.h" 24*e5918d7dSYoshinori Sato #include "tcg/tcg-op.h" 25*e5918d7dSYoshinori Sato #include "exec/cpu_ldst.h" 26*e5918d7dSYoshinori Sato #include "exec/helper-proto.h" 27*e5918d7dSYoshinori Sato #include "exec/helper-gen.h" 28*e5918d7dSYoshinori Sato #include "exec/translator.h" 29*e5918d7dSYoshinori Sato #include "trace-tcg.h" 30*e5918d7dSYoshinori Sato #include "exec/log.h" 31*e5918d7dSYoshinori Sato 32*e5918d7dSYoshinori Sato typedef struct DisasContext { 33*e5918d7dSYoshinori Sato DisasContextBase base; 34*e5918d7dSYoshinori Sato CPURXState *env; 35*e5918d7dSYoshinori Sato uint32_t pc; 36*e5918d7dSYoshinori Sato } DisasContext; 37*e5918d7dSYoshinori Sato 38*e5918d7dSYoshinori Sato typedef struct DisasCompare { 39*e5918d7dSYoshinori Sato TCGv value; 40*e5918d7dSYoshinori Sato TCGv temp; 41*e5918d7dSYoshinori Sato TCGCond cond; 42*e5918d7dSYoshinori Sato } DisasCompare; 43*e5918d7dSYoshinori Sato 44*e5918d7dSYoshinori Sato const char rx_crname[][6] = { 45*e5918d7dSYoshinori Sato "psw", "pc", "usp", "fpsw", "", "", "", "", 46*e5918d7dSYoshinori Sato "bpsw", "bpc", "isp", "fintv", "intb", "", "", "", 47*e5918d7dSYoshinori Sato }; 48*e5918d7dSYoshinori Sato 49*e5918d7dSYoshinori Sato /* Target-specific values for dc->base.is_jmp. */ 50*e5918d7dSYoshinori Sato #define DISAS_JUMP DISAS_TARGET_0 51*e5918d7dSYoshinori Sato #define DISAS_UPDATE DISAS_TARGET_1 52*e5918d7dSYoshinori Sato #define DISAS_EXIT DISAS_TARGET_2 53*e5918d7dSYoshinori Sato 54*e5918d7dSYoshinori Sato /* global register indexes */ 55*e5918d7dSYoshinori Sato static TCGv cpu_regs[16]; 56*e5918d7dSYoshinori Sato static TCGv cpu_psw_o, cpu_psw_s, cpu_psw_z, cpu_psw_c; 57*e5918d7dSYoshinori Sato static TCGv cpu_psw_i, cpu_psw_pm, cpu_psw_u, cpu_psw_ipl; 58*e5918d7dSYoshinori Sato static TCGv cpu_usp, cpu_fpsw, cpu_bpsw, cpu_bpc, cpu_isp; 59*e5918d7dSYoshinori Sato static TCGv cpu_fintv, cpu_intb, cpu_pc; 60*e5918d7dSYoshinori Sato static TCGv_i64 cpu_acc; 61*e5918d7dSYoshinori Sato 62*e5918d7dSYoshinori Sato #define cpu_sp cpu_regs[0] 63*e5918d7dSYoshinori Sato 64*e5918d7dSYoshinori Sato #include "exec/gen-icount.h" 65*e5918d7dSYoshinori Sato 66*e5918d7dSYoshinori Sato /* decoder helper */ 67*e5918d7dSYoshinori Sato static uint32_t decode_load_bytes(DisasContext *ctx, uint32_t insn, 68*e5918d7dSYoshinori Sato int i, int n) 69*e5918d7dSYoshinori Sato { 70*e5918d7dSYoshinori Sato while (++i <= n) { 71*e5918d7dSYoshinori Sato uint8_t b = cpu_ldub_code(ctx->env, ctx->base.pc_next++); 72*e5918d7dSYoshinori Sato insn |= b << (32 - i * 8); 73*e5918d7dSYoshinori Sato } 74*e5918d7dSYoshinori Sato return insn; 75*e5918d7dSYoshinori Sato } 76*e5918d7dSYoshinori Sato 77*e5918d7dSYoshinori Sato static uint32_t li(DisasContext *ctx, int sz) 78*e5918d7dSYoshinori Sato { 79*e5918d7dSYoshinori Sato int32_t tmp, addr; 80*e5918d7dSYoshinori Sato CPURXState *env = ctx->env; 81*e5918d7dSYoshinori Sato addr = ctx->base.pc_next; 82*e5918d7dSYoshinori Sato 83*e5918d7dSYoshinori Sato tcg_debug_assert(sz < 4); 84*e5918d7dSYoshinori Sato switch (sz) { 85*e5918d7dSYoshinori Sato case 1: 86*e5918d7dSYoshinori Sato ctx->base.pc_next += 1; 87*e5918d7dSYoshinori Sato return cpu_ldsb_code(env, addr); 88*e5918d7dSYoshinori Sato case 2: 89*e5918d7dSYoshinori Sato ctx->base.pc_next += 2; 90*e5918d7dSYoshinori Sato return cpu_ldsw_code(env, addr); 91*e5918d7dSYoshinori Sato case 3: 92*e5918d7dSYoshinori Sato ctx->base.pc_next += 3; 93*e5918d7dSYoshinori Sato tmp = cpu_ldsb_code(env, addr + 2) << 16; 94*e5918d7dSYoshinori Sato tmp |= cpu_lduw_code(env, addr) & 0xffff; 95*e5918d7dSYoshinori Sato return tmp; 96*e5918d7dSYoshinori Sato case 0: 97*e5918d7dSYoshinori Sato ctx->base.pc_next += 4; 98*e5918d7dSYoshinori Sato return cpu_ldl_code(env, addr); 99*e5918d7dSYoshinori Sato } 100*e5918d7dSYoshinori Sato return 0; 101*e5918d7dSYoshinori Sato } 102*e5918d7dSYoshinori Sato 103*e5918d7dSYoshinori Sato static int bdsp_s(DisasContext *ctx, int d) 104*e5918d7dSYoshinori Sato { 105*e5918d7dSYoshinori Sato /* 106*e5918d7dSYoshinori Sato * 0 -> 8 107*e5918d7dSYoshinori Sato * 1 -> 9 108*e5918d7dSYoshinori Sato * 2 -> 10 109*e5918d7dSYoshinori Sato * 3 -> 3 110*e5918d7dSYoshinori Sato * : 111*e5918d7dSYoshinori Sato * 7 -> 7 112*e5918d7dSYoshinori Sato */ 113*e5918d7dSYoshinori Sato if (d < 3) { 114*e5918d7dSYoshinori Sato d += 8; 115*e5918d7dSYoshinori Sato } 116*e5918d7dSYoshinori Sato return d; 117*e5918d7dSYoshinori Sato } 118*e5918d7dSYoshinori Sato 119*e5918d7dSYoshinori Sato /* Include the auto-generated decoder. */ 120*e5918d7dSYoshinori Sato #include "decode.inc.c" 121*e5918d7dSYoshinori Sato 122*e5918d7dSYoshinori Sato void rx_cpu_dump_state(CPUState *cs, FILE *f, int flags) 123*e5918d7dSYoshinori Sato { 124*e5918d7dSYoshinori Sato RXCPU *cpu = RXCPU(cs); 125*e5918d7dSYoshinori Sato CPURXState *env = &cpu->env; 126*e5918d7dSYoshinori Sato int i; 127*e5918d7dSYoshinori Sato uint32_t psw; 128*e5918d7dSYoshinori Sato 129*e5918d7dSYoshinori Sato psw = rx_cpu_pack_psw(env); 130*e5918d7dSYoshinori Sato qemu_fprintf(f, "pc=0x%08x psw=0x%08x\n", 131*e5918d7dSYoshinori Sato env->pc, psw); 132*e5918d7dSYoshinori Sato for (i = 0; i < 16; i += 4) { 133*e5918d7dSYoshinori Sato qemu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n", 134*e5918d7dSYoshinori Sato i, env->regs[i], i + 1, env->regs[i + 1], 135*e5918d7dSYoshinori Sato i + 2, env->regs[i + 2], i + 3, env->regs[i + 3]); 136*e5918d7dSYoshinori Sato } 137*e5918d7dSYoshinori Sato } 138*e5918d7dSYoshinori Sato 139*e5918d7dSYoshinori Sato static bool use_goto_tb(DisasContext *dc, target_ulong dest) 140*e5918d7dSYoshinori Sato { 141*e5918d7dSYoshinori Sato if (unlikely(dc->base.singlestep_enabled)) { 142*e5918d7dSYoshinori Sato return false; 143*e5918d7dSYoshinori Sato } else { 144*e5918d7dSYoshinori Sato return true; 145*e5918d7dSYoshinori Sato } 146*e5918d7dSYoshinori Sato } 147*e5918d7dSYoshinori Sato 148*e5918d7dSYoshinori Sato static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest) 149*e5918d7dSYoshinori Sato { 150*e5918d7dSYoshinori Sato if (use_goto_tb(dc, dest)) { 151*e5918d7dSYoshinori Sato tcg_gen_goto_tb(n); 152*e5918d7dSYoshinori Sato tcg_gen_movi_i32(cpu_pc, dest); 153*e5918d7dSYoshinori Sato tcg_gen_exit_tb(dc->base.tb, n); 154*e5918d7dSYoshinori Sato } else { 155*e5918d7dSYoshinori Sato tcg_gen_movi_i32(cpu_pc, dest); 156*e5918d7dSYoshinori Sato if (dc->base.singlestep_enabled) { 157*e5918d7dSYoshinori Sato gen_helper_debug(cpu_env); 158*e5918d7dSYoshinori Sato } else { 159*e5918d7dSYoshinori Sato tcg_gen_lookup_and_goto_ptr(); 160*e5918d7dSYoshinori Sato } 161*e5918d7dSYoshinori Sato } 162*e5918d7dSYoshinori Sato dc->base.is_jmp = DISAS_NORETURN; 163*e5918d7dSYoshinori Sato } 164*e5918d7dSYoshinori Sato 165*e5918d7dSYoshinori Sato /* generic load wrapper */ 166*e5918d7dSYoshinori Sato static inline void rx_gen_ld(unsigned int size, TCGv reg, TCGv mem) 167*e5918d7dSYoshinori Sato { 168*e5918d7dSYoshinori Sato tcg_gen_qemu_ld_i32(reg, mem, 0, size | MO_SIGN | MO_TE); 169*e5918d7dSYoshinori Sato } 170*e5918d7dSYoshinori Sato 171*e5918d7dSYoshinori Sato /* unsigned load wrapper */ 172*e5918d7dSYoshinori Sato static inline void rx_gen_ldu(unsigned int size, TCGv reg, TCGv mem) 173*e5918d7dSYoshinori Sato { 174*e5918d7dSYoshinori Sato tcg_gen_qemu_ld_i32(reg, mem, 0, size | MO_TE); 175*e5918d7dSYoshinori Sato } 176*e5918d7dSYoshinori Sato 177*e5918d7dSYoshinori Sato /* generic store wrapper */ 178*e5918d7dSYoshinori Sato static inline void rx_gen_st(unsigned int size, TCGv reg, TCGv mem) 179*e5918d7dSYoshinori Sato { 180*e5918d7dSYoshinori Sato tcg_gen_qemu_st_i32(reg, mem, 0, size | MO_TE); 181*e5918d7dSYoshinori Sato } 182*e5918d7dSYoshinori Sato 183*e5918d7dSYoshinori Sato /* [ri, rb] */ 184*e5918d7dSYoshinori Sato static inline void rx_gen_regindex(DisasContext *ctx, TCGv mem, 185*e5918d7dSYoshinori Sato int size, int ri, int rb) 186*e5918d7dSYoshinori Sato { 187*e5918d7dSYoshinori Sato tcg_gen_shli_i32(mem, cpu_regs[ri], size); 188*e5918d7dSYoshinori Sato tcg_gen_add_i32(mem, mem, cpu_regs[rb]); 189*e5918d7dSYoshinori Sato } 190*e5918d7dSYoshinori Sato 191*e5918d7dSYoshinori Sato /* dsp[reg] */ 192*e5918d7dSYoshinori Sato static inline TCGv rx_index_addr(DisasContext *ctx, TCGv mem, 193*e5918d7dSYoshinori Sato int ld, int size, int reg) 194*e5918d7dSYoshinori Sato { 195*e5918d7dSYoshinori Sato uint32_t dsp; 196*e5918d7dSYoshinori Sato 197*e5918d7dSYoshinori Sato tcg_debug_assert(ld < 3); 198*e5918d7dSYoshinori Sato switch (ld) { 199*e5918d7dSYoshinori Sato case 0: 200*e5918d7dSYoshinori Sato return cpu_regs[reg]; 201*e5918d7dSYoshinori Sato case 1: 202*e5918d7dSYoshinori Sato dsp = cpu_ldub_code(ctx->env, ctx->base.pc_next) << size; 203*e5918d7dSYoshinori Sato tcg_gen_addi_i32(mem, cpu_regs[reg], dsp); 204*e5918d7dSYoshinori Sato ctx->base.pc_next += 1; 205*e5918d7dSYoshinori Sato return mem; 206*e5918d7dSYoshinori Sato case 2: 207*e5918d7dSYoshinori Sato dsp = cpu_lduw_code(ctx->env, ctx->base.pc_next) << size; 208*e5918d7dSYoshinori Sato tcg_gen_addi_i32(mem, cpu_regs[reg], dsp); 209*e5918d7dSYoshinori Sato ctx->base.pc_next += 2; 210*e5918d7dSYoshinori Sato return mem; 211*e5918d7dSYoshinori Sato } 212*e5918d7dSYoshinori Sato return NULL; 213*e5918d7dSYoshinori Sato } 214*e5918d7dSYoshinori Sato 215*e5918d7dSYoshinori Sato static inline MemOp mi_to_mop(unsigned mi) 216*e5918d7dSYoshinori Sato { 217*e5918d7dSYoshinori Sato static const MemOp mop[5] = { MO_SB, MO_SW, MO_UL, MO_UW, MO_UB }; 218*e5918d7dSYoshinori Sato tcg_debug_assert(mi < 5); 219*e5918d7dSYoshinori Sato return mop[mi]; 220*e5918d7dSYoshinori Sato } 221*e5918d7dSYoshinori Sato 222*e5918d7dSYoshinori Sato /* load source operand */ 223*e5918d7dSYoshinori Sato static inline TCGv rx_load_source(DisasContext *ctx, TCGv mem, 224*e5918d7dSYoshinori Sato int ld, int mi, int rs) 225*e5918d7dSYoshinori Sato { 226*e5918d7dSYoshinori Sato TCGv addr; 227*e5918d7dSYoshinori Sato MemOp mop; 228*e5918d7dSYoshinori Sato if (ld < 3) { 229*e5918d7dSYoshinori Sato mop = mi_to_mop(mi); 230*e5918d7dSYoshinori Sato addr = rx_index_addr(ctx, mem, ld, mop & MO_SIZE, rs); 231*e5918d7dSYoshinori Sato tcg_gen_qemu_ld_i32(mem, addr, 0, mop | MO_TE); 232*e5918d7dSYoshinori Sato return mem; 233*e5918d7dSYoshinori Sato } else { 234*e5918d7dSYoshinori Sato return cpu_regs[rs]; 235*e5918d7dSYoshinori Sato } 236*e5918d7dSYoshinori Sato } 237*e5918d7dSYoshinori Sato 238*e5918d7dSYoshinori Sato /* Processor mode check */ 239*e5918d7dSYoshinori Sato static int is_privileged(DisasContext *ctx, int is_exception) 240*e5918d7dSYoshinori Sato { 241*e5918d7dSYoshinori Sato if (FIELD_EX32(ctx->base.tb->flags, PSW, PM)) { 242*e5918d7dSYoshinori Sato if (is_exception) { 243*e5918d7dSYoshinori Sato gen_helper_raise_privilege_violation(cpu_env); 244*e5918d7dSYoshinori Sato } 245*e5918d7dSYoshinori Sato return 0; 246*e5918d7dSYoshinori Sato } else { 247*e5918d7dSYoshinori Sato return 1; 248*e5918d7dSYoshinori Sato } 249*e5918d7dSYoshinori Sato } 250*e5918d7dSYoshinori Sato 251*e5918d7dSYoshinori Sato /* generate QEMU condition */ 252*e5918d7dSYoshinori Sato static void psw_cond(DisasCompare *dc, uint32_t cond) 253*e5918d7dSYoshinori Sato { 254*e5918d7dSYoshinori Sato tcg_debug_assert(cond < 16); 255*e5918d7dSYoshinori Sato switch (cond) { 256*e5918d7dSYoshinori Sato case 0: /* z */ 257*e5918d7dSYoshinori Sato dc->cond = TCG_COND_EQ; 258*e5918d7dSYoshinori Sato dc->value = cpu_psw_z; 259*e5918d7dSYoshinori Sato break; 260*e5918d7dSYoshinori Sato case 1: /* nz */ 261*e5918d7dSYoshinori Sato dc->cond = TCG_COND_NE; 262*e5918d7dSYoshinori Sato dc->value = cpu_psw_z; 263*e5918d7dSYoshinori Sato break; 264*e5918d7dSYoshinori Sato case 2: /* c */ 265*e5918d7dSYoshinori Sato dc->cond = TCG_COND_NE; 266*e5918d7dSYoshinori Sato dc->value = cpu_psw_c; 267*e5918d7dSYoshinori Sato break; 268*e5918d7dSYoshinori Sato case 3: /* nc */ 269*e5918d7dSYoshinori Sato dc->cond = TCG_COND_EQ; 270*e5918d7dSYoshinori Sato dc->value = cpu_psw_c; 271*e5918d7dSYoshinori Sato break; 272*e5918d7dSYoshinori Sato case 4: /* gtu (C& ~Z) == 1 */ 273*e5918d7dSYoshinori Sato case 5: /* leu (C& ~Z) == 0 */ 274*e5918d7dSYoshinori Sato tcg_gen_setcondi_i32(TCG_COND_NE, dc->temp, cpu_psw_z, 0); 275*e5918d7dSYoshinori Sato tcg_gen_and_i32(dc->temp, dc->temp, cpu_psw_c); 276*e5918d7dSYoshinori Sato dc->cond = (cond == 4) ? TCG_COND_NE : TCG_COND_EQ; 277*e5918d7dSYoshinori Sato dc->value = dc->temp; 278*e5918d7dSYoshinori Sato break; 279*e5918d7dSYoshinori Sato case 6: /* pz (S == 0) */ 280*e5918d7dSYoshinori Sato dc->cond = TCG_COND_GE; 281*e5918d7dSYoshinori Sato dc->value = cpu_psw_s; 282*e5918d7dSYoshinori Sato break; 283*e5918d7dSYoshinori Sato case 7: /* n (S == 1) */ 284*e5918d7dSYoshinori Sato dc->cond = TCG_COND_LT; 285*e5918d7dSYoshinori Sato dc->value = cpu_psw_s; 286*e5918d7dSYoshinori Sato break; 287*e5918d7dSYoshinori Sato case 8: /* ge (S^O)==0 */ 288*e5918d7dSYoshinori Sato case 9: /* lt (S^O)==1 */ 289*e5918d7dSYoshinori Sato tcg_gen_xor_i32(dc->temp, cpu_psw_o, cpu_psw_s); 290*e5918d7dSYoshinori Sato dc->cond = (cond == 8) ? TCG_COND_GE : TCG_COND_LT; 291*e5918d7dSYoshinori Sato dc->value = dc->temp; 292*e5918d7dSYoshinori Sato break; 293*e5918d7dSYoshinori Sato case 10: /* gt ((S^O)|Z)==0 */ 294*e5918d7dSYoshinori Sato case 11: /* le ((S^O)|Z)==1 */ 295*e5918d7dSYoshinori Sato tcg_gen_xor_i32(dc->temp, cpu_psw_o, cpu_psw_s); 296*e5918d7dSYoshinori Sato tcg_gen_sari_i32(dc->temp, dc->temp, 31); 297*e5918d7dSYoshinori Sato tcg_gen_andc_i32(dc->temp, cpu_psw_z, dc->temp); 298*e5918d7dSYoshinori Sato dc->cond = (cond == 10) ? TCG_COND_NE : TCG_COND_EQ; 299*e5918d7dSYoshinori Sato dc->value = dc->temp; 300*e5918d7dSYoshinori Sato break; 301*e5918d7dSYoshinori Sato case 12: /* o */ 302*e5918d7dSYoshinori Sato dc->cond = TCG_COND_LT; 303*e5918d7dSYoshinori Sato dc->value = cpu_psw_o; 304*e5918d7dSYoshinori Sato break; 305*e5918d7dSYoshinori Sato case 13: /* no */ 306*e5918d7dSYoshinori Sato dc->cond = TCG_COND_GE; 307*e5918d7dSYoshinori Sato dc->value = cpu_psw_o; 308*e5918d7dSYoshinori Sato break; 309*e5918d7dSYoshinori Sato case 14: /* always true */ 310*e5918d7dSYoshinori Sato dc->cond = TCG_COND_ALWAYS; 311*e5918d7dSYoshinori Sato dc->value = dc->temp; 312*e5918d7dSYoshinori Sato break; 313*e5918d7dSYoshinori Sato case 15: /* always false */ 314*e5918d7dSYoshinori Sato dc->cond = TCG_COND_NEVER; 315*e5918d7dSYoshinori Sato dc->value = dc->temp; 316*e5918d7dSYoshinori Sato break; 317*e5918d7dSYoshinori Sato } 318*e5918d7dSYoshinori Sato } 319*e5918d7dSYoshinori Sato 320*e5918d7dSYoshinori Sato static void move_from_cr(TCGv ret, int cr, uint32_t pc) 321*e5918d7dSYoshinori Sato { 322*e5918d7dSYoshinori Sato TCGv z = tcg_const_i32(0); 323*e5918d7dSYoshinori Sato switch (cr) { 324*e5918d7dSYoshinori Sato case 0: /* PSW */ 325*e5918d7dSYoshinori Sato gen_helper_pack_psw(ret, cpu_env); 326*e5918d7dSYoshinori Sato break; 327*e5918d7dSYoshinori Sato case 1: /* PC */ 328*e5918d7dSYoshinori Sato tcg_gen_movi_i32(ret, pc); 329*e5918d7dSYoshinori Sato break; 330*e5918d7dSYoshinori Sato case 2: /* USP */ 331*e5918d7dSYoshinori Sato tcg_gen_movcond_i32(TCG_COND_NE, ret, 332*e5918d7dSYoshinori Sato cpu_psw_u, z, cpu_sp, cpu_usp); 333*e5918d7dSYoshinori Sato break; 334*e5918d7dSYoshinori Sato case 3: /* FPSW */ 335*e5918d7dSYoshinori Sato tcg_gen_mov_i32(ret, cpu_fpsw); 336*e5918d7dSYoshinori Sato break; 337*e5918d7dSYoshinori Sato case 8: /* BPSW */ 338*e5918d7dSYoshinori Sato tcg_gen_mov_i32(ret, cpu_bpsw); 339*e5918d7dSYoshinori Sato break; 340*e5918d7dSYoshinori Sato case 9: /* BPC */ 341*e5918d7dSYoshinori Sato tcg_gen_mov_i32(ret, cpu_bpc); 342*e5918d7dSYoshinori Sato break; 343*e5918d7dSYoshinori Sato case 10: /* ISP */ 344*e5918d7dSYoshinori Sato tcg_gen_movcond_i32(TCG_COND_EQ, ret, 345*e5918d7dSYoshinori Sato cpu_psw_u, z, cpu_sp, cpu_isp); 346*e5918d7dSYoshinori Sato break; 347*e5918d7dSYoshinori Sato case 11: /* FINTV */ 348*e5918d7dSYoshinori Sato tcg_gen_mov_i32(ret, cpu_fintv); 349*e5918d7dSYoshinori Sato break; 350*e5918d7dSYoshinori Sato case 12: /* INTB */ 351*e5918d7dSYoshinori Sato tcg_gen_mov_i32(ret, cpu_intb); 352*e5918d7dSYoshinori Sato break; 353*e5918d7dSYoshinori Sato default: 354*e5918d7dSYoshinori Sato qemu_log_mask(LOG_GUEST_ERROR, "Unimplement control register %d", cr); 355*e5918d7dSYoshinori Sato /* Unimplement registers return 0 */ 356*e5918d7dSYoshinori Sato tcg_gen_movi_i32(ret, 0); 357*e5918d7dSYoshinori Sato break; 358*e5918d7dSYoshinori Sato } 359*e5918d7dSYoshinori Sato tcg_temp_free(z); 360*e5918d7dSYoshinori Sato } 361*e5918d7dSYoshinori Sato 362*e5918d7dSYoshinori Sato static void move_to_cr(DisasContext *ctx, TCGv val, int cr) 363*e5918d7dSYoshinori Sato { 364*e5918d7dSYoshinori Sato TCGv z; 365*e5918d7dSYoshinori Sato if (cr >= 8 && !is_privileged(ctx, 0)) { 366*e5918d7dSYoshinori Sato /* Some control registers can only be written in privileged mode. */ 367*e5918d7dSYoshinori Sato qemu_log_mask(LOG_GUEST_ERROR, 368*e5918d7dSYoshinori Sato "disallow control register write %s", rx_crname[cr]); 369*e5918d7dSYoshinori Sato return; 370*e5918d7dSYoshinori Sato } 371*e5918d7dSYoshinori Sato z = tcg_const_i32(0); 372*e5918d7dSYoshinori Sato switch (cr) { 373*e5918d7dSYoshinori Sato case 0: /* PSW */ 374*e5918d7dSYoshinori Sato gen_helper_set_psw(cpu_env, val); 375*e5918d7dSYoshinori Sato break; 376*e5918d7dSYoshinori Sato /* case 1: to PC not supported */ 377*e5918d7dSYoshinori Sato case 2: /* USP */ 378*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_usp, val); 379*e5918d7dSYoshinori Sato tcg_gen_movcond_i32(TCG_COND_NE, cpu_sp, 380*e5918d7dSYoshinori Sato cpu_psw_u, z, cpu_usp, cpu_sp); 381*e5918d7dSYoshinori Sato break; 382*e5918d7dSYoshinori Sato case 3: /* FPSW */ 383*e5918d7dSYoshinori Sato gen_helper_set_fpsw(cpu_env, val); 384*e5918d7dSYoshinori Sato break; 385*e5918d7dSYoshinori Sato case 8: /* BPSW */ 386*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_bpsw, val); 387*e5918d7dSYoshinori Sato break; 388*e5918d7dSYoshinori Sato case 9: /* BPC */ 389*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_bpc, val); 390*e5918d7dSYoshinori Sato break; 391*e5918d7dSYoshinori Sato case 10: /* ISP */ 392*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_isp, val); 393*e5918d7dSYoshinori Sato /* if PSW.U is 0, copy isp to r0 */ 394*e5918d7dSYoshinori Sato tcg_gen_movcond_i32(TCG_COND_EQ, cpu_sp, 395*e5918d7dSYoshinori Sato cpu_psw_u, z, cpu_isp, cpu_sp); 396*e5918d7dSYoshinori Sato break; 397*e5918d7dSYoshinori Sato case 11: /* FINTV */ 398*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_fintv, val); 399*e5918d7dSYoshinori Sato break; 400*e5918d7dSYoshinori Sato case 12: /* INTB */ 401*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_intb, val); 402*e5918d7dSYoshinori Sato break; 403*e5918d7dSYoshinori Sato default: 404*e5918d7dSYoshinori Sato qemu_log_mask(LOG_GUEST_ERROR, 405*e5918d7dSYoshinori Sato "Unimplement control register %d", cr); 406*e5918d7dSYoshinori Sato break; 407*e5918d7dSYoshinori Sato } 408*e5918d7dSYoshinori Sato tcg_temp_free(z); 409*e5918d7dSYoshinori Sato } 410*e5918d7dSYoshinori Sato 411*e5918d7dSYoshinori Sato static void push(TCGv val) 412*e5918d7dSYoshinori Sato { 413*e5918d7dSYoshinori Sato tcg_gen_subi_i32(cpu_sp, cpu_sp, 4); 414*e5918d7dSYoshinori Sato rx_gen_st(MO_32, val, cpu_sp); 415*e5918d7dSYoshinori Sato } 416*e5918d7dSYoshinori Sato 417*e5918d7dSYoshinori Sato static void pop(TCGv ret) 418*e5918d7dSYoshinori Sato { 419*e5918d7dSYoshinori Sato rx_gen_ld(MO_32, ret, cpu_sp); 420*e5918d7dSYoshinori Sato tcg_gen_addi_i32(cpu_sp, cpu_sp, 4); 421*e5918d7dSYoshinori Sato } 422*e5918d7dSYoshinori Sato 423*e5918d7dSYoshinori Sato /* mov.<bwl> rs,dsp5[rd] */ 424*e5918d7dSYoshinori Sato static bool trans_MOV_rm(DisasContext *ctx, arg_MOV_rm *a) 425*e5918d7dSYoshinori Sato { 426*e5918d7dSYoshinori Sato TCGv mem; 427*e5918d7dSYoshinori Sato mem = tcg_temp_new(); 428*e5918d7dSYoshinori Sato tcg_gen_addi_i32(mem, cpu_regs[a->rd], a->dsp << a->sz); 429*e5918d7dSYoshinori Sato rx_gen_st(a->sz, cpu_regs[a->rs], mem); 430*e5918d7dSYoshinori Sato tcg_temp_free(mem); 431*e5918d7dSYoshinori Sato return true; 432*e5918d7dSYoshinori Sato } 433*e5918d7dSYoshinori Sato 434*e5918d7dSYoshinori Sato /* mov.<bwl> dsp5[rs],rd */ 435*e5918d7dSYoshinori Sato static bool trans_MOV_mr(DisasContext *ctx, arg_MOV_mr *a) 436*e5918d7dSYoshinori Sato { 437*e5918d7dSYoshinori Sato TCGv mem; 438*e5918d7dSYoshinori Sato mem = tcg_temp_new(); 439*e5918d7dSYoshinori Sato tcg_gen_addi_i32(mem, cpu_regs[a->rs], a->dsp << a->sz); 440*e5918d7dSYoshinori Sato rx_gen_ld(a->sz, cpu_regs[a->rd], mem); 441*e5918d7dSYoshinori Sato tcg_temp_free(mem); 442*e5918d7dSYoshinori Sato return true; 443*e5918d7dSYoshinori Sato } 444*e5918d7dSYoshinori Sato 445*e5918d7dSYoshinori Sato /* mov.l #uimm4,rd */ 446*e5918d7dSYoshinori Sato /* mov.l #uimm8,rd */ 447*e5918d7dSYoshinori Sato /* mov.l #imm,rd */ 448*e5918d7dSYoshinori Sato static bool trans_MOV_ir(DisasContext *ctx, arg_MOV_ir *a) 449*e5918d7dSYoshinori Sato { 450*e5918d7dSYoshinori Sato tcg_gen_movi_i32(cpu_regs[a->rd], a->imm); 451*e5918d7dSYoshinori Sato return true; 452*e5918d7dSYoshinori Sato } 453*e5918d7dSYoshinori Sato 454*e5918d7dSYoshinori Sato /* mov.<bwl> #uimm8,dsp[rd] */ 455*e5918d7dSYoshinori Sato /* mov.<bwl> #imm, dsp[rd] */ 456*e5918d7dSYoshinori Sato static bool trans_MOV_im(DisasContext *ctx, arg_MOV_im *a) 457*e5918d7dSYoshinori Sato { 458*e5918d7dSYoshinori Sato TCGv imm, mem; 459*e5918d7dSYoshinori Sato imm = tcg_const_i32(a->imm); 460*e5918d7dSYoshinori Sato mem = tcg_temp_new(); 461*e5918d7dSYoshinori Sato tcg_gen_addi_i32(mem, cpu_regs[a->rd], a->dsp << a->sz); 462*e5918d7dSYoshinori Sato rx_gen_st(a->sz, imm, mem); 463*e5918d7dSYoshinori Sato tcg_temp_free(imm); 464*e5918d7dSYoshinori Sato tcg_temp_free(mem); 465*e5918d7dSYoshinori Sato return true; 466*e5918d7dSYoshinori Sato } 467*e5918d7dSYoshinori Sato 468*e5918d7dSYoshinori Sato /* mov.<bwl> [ri,rb],rd */ 469*e5918d7dSYoshinori Sato static bool trans_MOV_ar(DisasContext *ctx, arg_MOV_ar *a) 470*e5918d7dSYoshinori Sato { 471*e5918d7dSYoshinori Sato TCGv mem; 472*e5918d7dSYoshinori Sato mem = tcg_temp_new(); 473*e5918d7dSYoshinori Sato rx_gen_regindex(ctx, mem, a->sz, a->ri, a->rb); 474*e5918d7dSYoshinori Sato rx_gen_ld(a->sz, cpu_regs[a->rd], mem); 475*e5918d7dSYoshinori Sato tcg_temp_free(mem); 476*e5918d7dSYoshinori Sato return true; 477*e5918d7dSYoshinori Sato } 478*e5918d7dSYoshinori Sato 479*e5918d7dSYoshinori Sato /* mov.<bwl> rd,[ri,rb] */ 480*e5918d7dSYoshinori Sato static bool trans_MOV_ra(DisasContext *ctx, arg_MOV_ra *a) 481*e5918d7dSYoshinori Sato { 482*e5918d7dSYoshinori Sato TCGv mem; 483*e5918d7dSYoshinori Sato mem = tcg_temp_new(); 484*e5918d7dSYoshinori Sato rx_gen_regindex(ctx, mem, a->sz, a->ri, a->rb); 485*e5918d7dSYoshinori Sato rx_gen_st(a->sz, cpu_regs[a->rs], mem); 486*e5918d7dSYoshinori Sato tcg_temp_free(mem); 487*e5918d7dSYoshinori Sato return true; 488*e5918d7dSYoshinori Sato } 489*e5918d7dSYoshinori Sato 490*e5918d7dSYoshinori Sato /* mov.<bwl> dsp[rs],dsp[rd] */ 491*e5918d7dSYoshinori Sato /* mov.<bwl> rs,dsp[rd] */ 492*e5918d7dSYoshinori Sato /* mov.<bwl> dsp[rs],rd */ 493*e5918d7dSYoshinori Sato /* mov.<bwl> rs,rd */ 494*e5918d7dSYoshinori Sato static bool trans_MOV_mm(DisasContext *ctx, arg_MOV_mm *a) 495*e5918d7dSYoshinori Sato { 496*e5918d7dSYoshinori Sato static void (* const mov[])(TCGv ret, TCGv arg) = { 497*e5918d7dSYoshinori Sato tcg_gen_ext8s_i32, tcg_gen_ext16s_i32, tcg_gen_mov_i32, 498*e5918d7dSYoshinori Sato }; 499*e5918d7dSYoshinori Sato TCGv tmp, mem, addr; 500*e5918d7dSYoshinori Sato if (a->lds == 3 && a->ldd == 3) { 501*e5918d7dSYoshinori Sato /* mov.<bwl> rs,rd */ 502*e5918d7dSYoshinori Sato mov[a->sz](cpu_regs[a->rd], cpu_regs[a->rs]); 503*e5918d7dSYoshinori Sato return true; 504*e5918d7dSYoshinori Sato } 505*e5918d7dSYoshinori Sato 506*e5918d7dSYoshinori Sato mem = tcg_temp_new(); 507*e5918d7dSYoshinori Sato if (a->lds == 3) { 508*e5918d7dSYoshinori Sato /* mov.<bwl> rs,dsp[rd] */ 509*e5918d7dSYoshinori Sato addr = rx_index_addr(ctx, mem, a->ldd, a->sz, a->rs); 510*e5918d7dSYoshinori Sato rx_gen_st(a->sz, cpu_regs[a->rd], addr); 511*e5918d7dSYoshinori Sato } else if (a->ldd == 3) { 512*e5918d7dSYoshinori Sato /* mov.<bwl> dsp[rs],rd */ 513*e5918d7dSYoshinori Sato addr = rx_index_addr(ctx, mem, a->lds, a->sz, a->rs); 514*e5918d7dSYoshinori Sato rx_gen_ld(a->sz, cpu_regs[a->rd], addr); 515*e5918d7dSYoshinori Sato } else { 516*e5918d7dSYoshinori Sato /* mov.<bwl> dsp[rs],dsp[rd] */ 517*e5918d7dSYoshinori Sato tmp = tcg_temp_new(); 518*e5918d7dSYoshinori Sato addr = rx_index_addr(ctx, mem, a->lds, a->sz, a->rs); 519*e5918d7dSYoshinori Sato rx_gen_ld(a->sz, tmp, addr); 520*e5918d7dSYoshinori Sato addr = rx_index_addr(ctx, mem, a->ldd, a->sz, a->rd); 521*e5918d7dSYoshinori Sato rx_gen_st(a->sz, tmp, addr); 522*e5918d7dSYoshinori Sato tcg_temp_free(tmp); 523*e5918d7dSYoshinori Sato } 524*e5918d7dSYoshinori Sato tcg_temp_free(mem); 525*e5918d7dSYoshinori Sato return true; 526*e5918d7dSYoshinori Sato } 527*e5918d7dSYoshinori Sato 528*e5918d7dSYoshinori Sato /* mov.<bwl> rs,[rd+] */ 529*e5918d7dSYoshinori Sato /* mov.<bwl> rs,[-rd] */ 530*e5918d7dSYoshinori Sato static bool trans_MOV_rp(DisasContext *ctx, arg_MOV_rp *a) 531*e5918d7dSYoshinori Sato { 532*e5918d7dSYoshinori Sato TCGv val; 533*e5918d7dSYoshinori Sato val = tcg_temp_new(); 534*e5918d7dSYoshinori Sato tcg_gen_mov_i32(val, cpu_regs[a->rs]); 535*e5918d7dSYoshinori Sato if (a->ad == 1) { 536*e5918d7dSYoshinori Sato tcg_gen_subi_i32(cpu_regs[a->rd], cpu_regs[a->rd], 1 << a->sz); 537*e5918d7dSYoshinori Sato } 538*e5918d7dSYoshinori Sato rx_gen_st(a->sz, val, cpu_regs[a->rd]); 539*e5918d7dSYoshinori Sato if (a->ad == 0) { 540*e5918d7dSYoshinori Sato tcg_gen_addi_i32(cpu_regs[a->rd], cpu_regs[a->rd], 1 << a->sz); 541*e5918d7dSYoshinori Sato } 542*e5918d7dSYoshinori Sato tcg_temp_free(val); 543*e5918d7dSYoshinori Sato return true; 544*e5918d7dSYoshinori Sato } 545*e5918d7dSYoshinori Sato 546*e5918d7dSYoshinori Sato /* mov.<bwl> [rd+],rs */ 547*e5918d7dSYoshinori Sato /* mov.<bwl> [-rd],rs */ 548*e5918d7dSYoshinori Sato static bool trans_MOV_pr(DisasContext *ctx, arg_MOV_pr *a) 549*e5918d7dSYoshinori Sato { 550*e5918d7dSYoshinori Sato TCGv val; 551*e5918d7dSYoshinori Sato val = tcg_temp_new(); 552*e5918d7dSYoshinori Sato if (a->ad == 1) { 553*e5918d7dSYoshinori Sato tcg_gen_subi_i32(cpu_regs[a->rd], cpu_regs[a->rd], 1 << a->sz); 554*e5918d7dSYoshinori Sato } 555*e5918d7dSYoshinori Sato rx_gen_ld(a->sz, val, cpu_regs[a->rd]); 556*e5918d7dSYoshinori Sato if (a->ad == 0) { 557*e5918d7dSYoshinori Sato tcg_gen_addi_i32(cpu_regs[a->rd], cpu_regs[a->rd], 1 << a->sz); 558*e5918d7dSYoshinori Sato } 559*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_regs[a->rs], val); 560*e5918d7dSYoshinori Sato tcg_temp_free(val); 561*e5918d7dSYoshinori Sato return true; 562*e5918d7dSYoshinori Sato } 563*e5918d7dSYoshinori Sato 564*e5918d7dSYoshinori Sato /* movu.<bw> dsp5[rs],rd */ 565*e5918d7dSYoshinori Sato /* movu.<bw> dsp[rs],rd */ 566*e5918d7dSYoshinori Sato static bool trans_MOVU_mr(DisasContext *ctx, arg_MOVU_mr *a) 567*e5918d7dSYoshinori Sato { 568*e5918d7dSYoshinori Sato TCGv mem; 569*e5918d7dSYoshinori Sato mem = tcg_temp_new(); 570*e5918d7dSYoshinori Sato tcg_gen_addi_i32(mem, cpu_regs[a->rs], a->dsp << a->sz); 571*e5918d7dSYoshinori Sato rx_gen_ldu(a->sz, cpu_regs[a->rd], mem); 572*e5918d7dSYoshinori Sato tcg_temp_free(mem); 573*e5918d7dSYoshinori Sato return true; 574*e5918d7dSYoshinori Sato } 575*e5918d7dSYoshinori Sato 576*e5918d7dSYoshinori Sato /* movu.<bw> rs,rd */ 577*e5918d7dSYoshinori Sato static bool trans_MOVU_rr(DisasContext *ctx, arg_MOVU_rr *a) 578*e5918d7dSYoshinori Sato { 579*e5918d7dSYoshinori Sato static void (* const ext[])(TCGv ret, TCGv arg) = { 580*e5918d7dSYoshinori Sato tcg_gen_ext8u_i32, tcg_gen_ext16u_i32, 581*e5918d7dSYoshinori Sato }; 582*e5918d7dSYoshinori Sato ext[a->sz](cpu_regs[a->rd], cpu_regs[a->rs]); 583*e5918d7dSYoshinori Sato return true; 584*e5918d7dSYoshinori Sato } 585*e5918d7dSYoshinori Sato 586*e5918d7dSYoshinori Sato /* movu.<bw> [ri,rb],rd */ 587*e5918d7dSYoshinori Sato static bool trans_MOVU_ar(DisasContext *ctx, arg_MOVU_ar *a) 588*e5918d7dSYoshinori Sato { 589*e5918d7dSYoshinori Sato TCGv mem; 590*e5918d7dSYoshinori Sato mem = tcg_temp_new(); 591*e5918d7dSYoshinori Sato rx_gen_regindex(ctx, mem, a->sz, a->ri, a->rb); 592*e5918d7dSYoshinori Sato rx_gen_ldu(a->sz, cpu_regs[a->rd], mem); 593*e5918d7dSYoshinori Sato tcg_temp_free(mem); 594*e5918d7dSYoshinori Sato return true; 595*e5918d7dSYoshinori Sato } 596*e5918d7dSYoshinori Sato 597*e5918d7dSYoshinori Sato /* movu.<bw> [rd+],rs */ 598*e5918d7dSYoshinori Sato /* mov.<bw> [-rd],rs */ 599*e5918d7dSYoshinori Sato static bool trans_MOVU_pr(DisasContext *ctx, arg_MOVU_pr *a) 600*e5918d7dSYoshinori Sato { 601*e5918d7dSYoshinori Sato TCGv val; 602*e5918d7dSYoshinori Sato val = tcg_temp_new(); 603*e5918d7dSYoshinori Sato if (a->ad == 1) { 604*e5918d7dSYoshinori Sato tcg_gen_subi_i32(cpu_regs[a->rd], cpu_regs[a->rd], 1 << a->sz); 605*e5918d7dSYoshinori Sato } 606*e5918d7dSYoshinori Sato rx_gen_ldu(a->sz, val, cpu_regs[a->rd]); 607*e5918d7dSYoshinori Sato if (a->ad == 0) { 608*e5918d7dSYoshinori Sato tcg_gen_addi_i32(cpu_regs[a->rd], cpu_regs[a->rd], 1 << a->sz); 609*e5918d7dSYoshinori Sato } 610*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_regs[a->rs], val); 611*e5918d7dSYoshinori Sato tcg_temp_free(val); 612*e5918d7dSYoshinori Sato return true; 613*e5918d7dSYoshinori Sato } 614*e5918d7dSYoshinori Sato 615*e5918d7dSYoshinori Sato 616*e5918d7dSYoshinori Sato /* pop rd */ 617*e5918d7dSYoshinori Sato static bool trans_POP(DisasContext *ctx, arg_POP *a) 618*e5918d7dSYoshinori Sato { 619*e5918d7dSYoshinori Sato /* mov.l [r0+], rd */ 620*e5918d7dSYoshinori Sato arg_MOV_rp mov_a; 621*e5918d7dSYoshinori Sato mov_a.rd = 0; 622*e5918d7dSYoshinori Sato mov_a.rs = a->rd; 623*e5918d7dSYoshinori Sato mov_a.ad = 0; 624*e5918d7dSYoshinori Sato mov_a.sz = MO_32; 625*e5918d7dSYoshinori Sato trans_MOV_pr(ctx, &mov_a); 626*e5918d7dSYoshinori Sato return true; 627*e5918d7dSYoshinori Sato } 628*e5918d7dSYoshinori Sato 629*e5918d7dSYoshinori Sato /* popc cr */ 630*e5918d7dSYoshinori Sato static bool trans_POPC(DisasContext *ctx, arg_POPC *a) 631*e5918d7dSYoshinori Sato { 632*e5918d7dSYoshinori Sato TCGv val; 633*e5918d7dSYoshinori Sato val = tcg_temp_new(); 634*e5918d7dSYoshinori Sato pop(val); 635*e5918d7dSYoshinori Sato move_to_cr(ctx, val, a->cr); 636*e5918d7dSYoshinori Sato if (a->cr == 0 && is_privileged(ctx, 0)) { 637*e5918d7dSYoshinori Sato /* PSW.I may be updated here. exit TB. */ 638*e5918d7dSYoshinori Sato ctx->base.is_jmp = DISAS_UPDATE; 639*e5918d7dSYoshinori Sato } 640*e5918d7dSYoshinori Sato tcg_temp_free(val); 641*e5918d7dSYoshinori Sato return true; 642*e5918d7dSYoshinori Sato } 643*e5918d7dSYoshinori Sato 644*e5918d7dSYoshinori Sato /* popm rd-rd2 */ 645*e5918d7dSYoshinori Sato static bool trans_POPM(DisasContext *ctx, arg_POPM *a) 646*e5918d7dSYoshinori Sato { 647*e5918d7dSYoshinori Sato int r; 648*e5918d7dSYoshinori Sato if (a->rd == 0 || a->rd >= a->rd2) { 649*e5918d7dSYoshinori Sato qemu_log_mask(LOG_GUEST_ERROR, 650*e5918d7dSYoshinori Sato "Invalid register ranges r%d-r%d", a->rd, a->rd2); 651*e5918d7dSYoshinori Sato } 652*e5918d7dSYoshinori Sato r = a->rd; 653*e5918d7dSYoshinori Sato while (r <= a->rd2 && r < 16) { 654*e5918d7dSYoshinori Sato pop(cpu_regs[r++]); 655*e5918d7dSYoshinori Sato } 656*e5918d7dSYoshinori Sato return true; 657*e5918d7dSYoshinori Sato } 658*e5918d7dSYoshinori Sato 659*e5918d7dSYoshinori Sato 660*e5918d7dSYoshinori Sato /* push.<bwl> rs */ 661*e5918d7dSYoshinori Sato static bool trans_PUSH_r(DisasContext *ctx, arg_PUSH_r *a) 662*e5918d7dSYoshinori Sato { 663*e5918d7dSYoshinori Sato TCGv val; 664*e5918d7dSYoshinori Sato val = tcg_temp_new(); 665*e5918d7dSYoshinori Sato tcg_gen_mov_i32(val, cpu_regs[a->rs]); 666*e5918d7dSYoshinori Sato tcg_gen_subi_i32(cpu_sp, cpu_sp, 4); 667*e5918d7dSYoshinori Sato rx_gen_st(a->sz, val, cpu_sp); 668*e5918d7dSYoshinori Sato tcg_temp_free(val); 669*e5918d7dSYoshinori Sato return true; 670*e5918d7dSYoshinori Sato } 671*e5918d7dSYoshinori Sato 672*e5918d7dSYoshinori Sato /* push.<bwl> dsp[rs] */ 673*e5918d7dSYoshinori Sato static bool trans_PUSH_m(DisasContext *ctx, arg_PUSH_m *a) 674*e5918d7dSYoshinori Sato { 675*e5918d7dSYoshinori Sato TCGv mem, val, addr; 676*e5918d7dSYoshinori Sato mem = tcg_temp_new(); 677*e5918d7dSYoshinori Sato val = tcg_temp_new(); 678*e5918d7dSYoshinori Sato addr = rx_index_addr(ctx, mem, a->ld, a->sz, a->rs); 679*e5918d7dSYoshinori Sato rx_gen_ld(a->sz, val, addr); 680*e5918d7dSYoshinori Sato tcg_gen_subi_i32(cpu_sp, cpu_sp, 4); 681*e5918d7dSYoshinori Sato rx_gen_st(a->sz, val, cpu_sp); 682*e5918d7dSYoshinori Sato tcg_temp_free(mem); 683*e5918d7dSYoshinori Sato tcg_temp_free(val); 684*e5918d7dSYoshinori Sato return true; 685*e5918d7dSYoshinori Sato } 686*e5918d7dSYoshinori Sato 687*e5918d7dSYoshinori Sato /* pushc rx */ 688*e5918d7dSYoshinori Sato static bool trans_PUSHC(DisasContext *ctx, arg_PUSHC *a) 689*e5918d7dSYoshinori Sato { 690*e5918d7dSYoshinori Sato TCGv val; 691*e5918d7dSYoshinori Sato val = tcg_temp_new(); 692*e5918d7dSYoshinori Sato move_from_cr(val, a->cr, ctx->pc); 693*e5918d7dSYoshinori Sato push(val); 694*e5918d7dSYoshinori Sato tcg_temp_free(val); 695*e5918d7dSYoshinori Sato return true; 696*e5918d7dSYoshinori Sato } 697*e5918d7dSYoshinori Sato 698*e5918d7dSYoshinori Sato /* pushm rs-rs2 */ 699*e5918d7dSYoshinori Sato static bool trans_PUSHM(DisasContext *ctx, arg_PUSHM *a) 700*e5918d7dSYoshinori Sato { 701*e5918d7dSYoshinori Sato int r; 702*e5918d7dSYoshinori Sato 703*e5918d7dSYoshinori Sato if (a->rs == 0 || a->rs >= a->rs2) { 704*e5918d7dSYoshinori Sato qemu_log_mask(LOG_GUEST_ERROR, 705*e5918d7dSYoshinori Sato "Invalid register ranges r%d-r%d", a->rs, a->rs2); 706*e5918d7dSYoshinori Sato } 707*e5918d7dSYoshinori Sato r = a->rs2; 708*e5918d7dSYoshinori Sato while (r >= a->rs && r >= 0) { 709*e5918d7dSYoshinori Sato push(cpu_regs[r--]); 710*e5918d7dSYoshinori Sato } 711*e5918d7dSYoshinori Sato return true; 712*e5918d7dSYoshinori Sato } 713*e5918d7dSYoshinori Sato 714*e5918d7dSYoshinori Sato /* xchg rs,rd */ 715*e5918d7dSYoshinori Sato static bool trans_XCHG_rr(DisasContext *ctx, arg_XCHG_rr *a) 716*e5918d7dSYoshinori Sato { 717*e5918d7dSYoshinori Sato TCGv tmp; 718*e5918d7dSYoshinori Sato tmp = tcg_temp_new(); 719*e5918d7dSYoshinori Sato tcg_gen_mov_i32(tmp, cpu_regs[a->rs]); 720*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_regs[a->rs], cpu_regs[a->rd]); 721*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_regs[a->rd], tmp); 722*e5918d7dSYoshinori Sato tcg_temp_free(tmp); 723*e5918d7dSYoshinori Sato return true; 724*e5918d7dSYoshinori Sato } 725*e5918d7dSYoshinori Sato 726*e5918d7dSYoshinori Sato /* xchg dsp[rs].<mi>,rd */ 727*e5918d7dSYoshinori Sato static bool trans_XCHG_mr(DisasContext *ctx, arg_XCHG_mr *a) 728*e5918d7dSYoshinori Sato { 729*e5918d7dSYoshinori Sato TCGv mem, addr; 730*e5918d7dSYoshinori Sato mem = tcg_temp_new(); 731*e5918d7dSYoshinori Sato switch (a->mi) { 732*e5918d7dSYoshinori Sato case 0: /* dsp[rs].b */ 733*e5918d7dSYoshinori Sato case 1: /* dsp[rs].w */ 734*e5918d7dSYoshinori Sato case 2: /* dsp[rs].l */ 735*e5918d7dSYoshinori Sato addr = rx_index_addr(ctx, mem, a->ld, a->mi, a->rs); 736*e5918d7dSYoshinori Sato break; 737*e5918d7dSYoshinori Sato case 3: /* dsp[rs].uw */ 738*e5918d7dSYoshinori Sato case 4: /* dsp[rs].ub */ 739*e5918d7dSYoshinori Sato addr = rx_index_addr(ctx, mem, a->ld, 4 - a->mi, a->rs); 740*e5918d7dSYoshinori Sato break; 741*e5918d7dSYoshinori Sato default: 742*e5918d7dSYoshinori Sato g_assert_not_reached(); 743*e5918d7dSYoshinori Sato } 744*e5918d7dSYoshinori Sato tcg_gen_atomic_xchg_i32(cpu_regs[a->rd], addr, cpu_regs[a->rd], 745*e5918d7dSYoshinori Sato 0, mi_to_mop(a->mi)); 746*e5918d7dSYoshinori Sato tcg_temp_free(mem); 747*e5918d7dSYoshinori Sato return true; 748*e5918d7dSYoshinori Sato } 749*e5918d7dSYoshinori Sato 750*e5918d7dSYoshinori Sato static inline void stcond(TCGCond cond, int rd, int imm) 751*e5918d7dSYoshinori Sato { 752*e5918d7dSYoshinori Sato TCGv z; 753*e5918d7dSYoshinori Sato TCGv _imm; 754*e5918d7dSYoshinori Sato z = tcg_const_i32(0); 755*e5918d7dSYoshinori Sato _imm = tcg_const_i32(imm); 756*e5918d7dSYoshinori Sato tcg_gen_movcond_i32(cond, cpu_regs[rd], cpu_psw_z, z, 757*e5918d7dSYoshinori Sato _imm, cpu_regs[rd]); 758*e5918d7dSYoshinori Sato tcg_temp_free(z); 759*e5918d7dSYoshinori Sato tcg_temp_free(_imm); 760*e5918d7dSYoshinori Sato } 761*e5918d7dSYoshinori Sato 762*e5918d7dSYoshinori Sato /* stz #imm,rd */ 763*e5918d7dSYoshinori Sato static bool trans_STZ(DisasContext *ctx, arg_STZ *a) 764*e5918d7dSYoshinori Sato { 765*e5918d7dSYoshinori Sato stcond(TCG_COND_EQ, a->rd, a->imm); 766*e5918d7dSYoshinori Sato return true; 767*e5918d7dSYoshinori Sato } 768*e5918d7dSYoshinori Sato 769*e5918d7dSYoshinori Sato /* stnz #imm,rd */ 770*e5918d7dSYoshinori Sato static bool trans_STNZ(DisasContext *ctx, arg_STNZ *a) 771*e5918d7dSYoshinori Sato { 772*e5918d7dSYoshinori Sato stcond(TCG_COND_NE, a->rd, a->imm); 773*e5918d7dSYoshinori Sato return true; 774*e5918d7dSYoshinori Sato } 775*e5918d7dSYoshinori Sato 776*e5918d7dSYoshinori Sato /* sccnd.<bwl> rd */ 777*e5918d7dSYoshinori Sato /* sccnd.<bwl> dsp:[rd] */ 778*e5918d7dSYoshinori Sato static bool trans_SCCnd(DisasContext *ctx, arg_SCCnd *a) 779*e5918d7dSYoshinori Sato { 780*e5918d7dSYoshinori Sato DisasCompare dc; 781*e5918d7dSYoshinori Sato TCGv val, mem, addr; 782*e5918d7dSYoshinori Sato dc.temp = tcg_temp_new(); 783*e5918d7dSYoshinori Sato psw_cond(&dc, a->cd); 784*e5918d7dSYoshinori Sato if (a->ld < 3) { 785*e5918d7dSYoshinori Sato val = tcg_temp_new(); 786*e5918d7dSYoshinori Sato mem = tcg_temp_new(); 787*e5918d7dSYoshinori Sato tcg_gen_setcondi_i32(dc.cond, val, dc.value, 0); 788*e5918d7dSYoshinori Sato addr = rx_index_addr(ctx, mem, a->sz, a->ld, a->rd); 789*e5918d7dSYoshinori Sato rx_gen_st(a->sz, val, addr); 790*e5918d7dSYoshinori Sato tcg_temp_free(val); 791*e5918d7dSYoshinori Sato tcg_temp_free(mem); 792*e5918d7dSYoshinori Sato } else { 793*e5918d7dSYoshinori Sato tcg_gen_setcondi_i32(dc.cond, cpu_regs[a->rd], dc.value, 0); 794*e5918d7dSYoshinori Sato } 795*e5918d7dSYoshinori Sato tcg_temp_free(dc.temp); 796*e5918d7dSYoshinori Sato return true; 797*e5918d7dSYoshinori Sato } 798*e5918d7dSYoshinori Sato 799*e5918d7dSYoshinori Sato /* rtsd #imm */ 800*e5918d7dSYoshinori Sato static bool trans_RTSD_i(DisasContext *ctx, arg_RTSD_i *a) 801*e5918d7dSYoshinori Sato { 802*e5918d7dSYoshinori Sato tcg_gen_addi_i32(cpu_sp, cpu_sp, a->imm << 2); 803*e5918d7dSYoshinori Sato pop(cpu_pc); 804*e5918d7dSYoshinori Sato ctx->base.is_jmp = DISAS_JUMP; 805*e5918d7dSYoshinori Sato return true; 806*e5918d7dSYoshinori Sato } 807*e5918d7dSYoshinori Sato 808*e5918d7dSYoshinori Sato /* rtsd #imm, rd-rd2 */ 809*e5918d7dSYoshinori Sato static bool trans_RTSD_irr(DisasContext *ctx, arg_RTSD_irr *a) 810*e5918d7dSYoshinori Sato { 811*e5918d7dSYoshinori Sato int dst; 812*e5918d7dSYoshinori Sato int adj; 813*e5918d7dSYoshinori Sato 814*e5918d7dSYoshinori Sato if (a->rd2 >= a->rd) { 815*e5918d7dSYoshinori Sato adj = a->imm - (a->rd2 - a->rd + 1); 816*e5918d7dSYoshinori Sato } else { 817*e5918d7dSYoshinori Sato adj = a->imm - (15 - a->rd + 1); 818*e5918d7dSYoshinori Sato } 819*e5918d7dSYoshinori Sato 820*e5918d7dSYoshinori Sato tcg_gen_addi_i32(cpu_sp, cpu_sp, adj << 2); 821*e5918d7dSYoshinori Sato dst = a->rd; 822*e5918d7dSYoshinori Sato while (dst <= a->rd2 && dst < 16) { 823*e5918d7dSYoshinori Sato pop(cpu_regs[dst++]); 824*e5918d7dSYoshinori Sato } 825*e5918d7dSYoshinori Sato pop(cpu_pc); 826*e5918d7dSYoshinori Sato ctx->base.is_jmp = DISAS_JUMP; 827*e5918d7dSYoshinori Sato return true; 828*e5918d7dSYoshinori Sato } 829*e5918d7dSYoshinori Sato 830*e5918d7dSYoshinori Sato typedef void (*op2fn)(TCGv ret, TCGv arg1); 831*e5918d7dSYoshinori Sato typedef void (*op3fn)(TCGv ret, TCGv arg1, TCGv arg2); 832*e5918d7dSYoshinori Sato 833*e5918d7dSYoshinori Sato static inline void rx_gen_op_rr(op2fn opr, int dst, int src) 834*e5918d7dSYoshinori Sato { 835*e5918d7dSYoshinori Sato opr(cpu_regs[dst], cpu_regs[src]); 836*e5918d7dSYoshinori Sato } 837*e5918d7dSYoshinori Sato 838*e5918d7dSYoshinori Sato static inline void rx_gen_op_rrr(op3fn opr, int dst, int src, int src2) 839*e5918d7dSYoshinori Sato { 840*e5918d7dSYoshinori Sato opr(cpu_regs[dst], cpu_regs[src], cpu_regs[src2]); 841*e5918d7dSYoshinori Sato } 842*e5918d7dSYoshinori Sato 843*e5918d7dSYoshinori Sato static inline void rx_gen_op_irr(op3fn opr, int dst, int src, uint32_t src2) 844*e5918d7dSYoshinori Sato { 845*e5918d7dSYoshinori Sato TCGv imm = tcg_const_i32(src2); 846*e5918d7dSYoshinori Sato opr(cpu_regs[dst], cpu_regs[src], imm); 847*e5918d7dSYoshinori Sato tcg_temp_free(imm); 848*e5918d7dSYoshinori Sato } 849*e5918d7dSYoshinori Sato 850*e5918d7dSYoshinori Sato static inline void rx_gen_op_mr(op3fn opr, DisasContext *ctx, 851*e5918d7dSYoshinori Sato int dst, int src, int ld, int mi) 852*e5918d7dSYoshinori Sato { 853*e5918d7dSYoshinori Sato TCGv val, mem; 854*e5918d7dSYoshinori Sato mem = tcg_temp_new(); 855*e5918d7dSYoshinori Sato val = rx_load_source(ctx, mem, ld, mi, src); 856*e5918d7dSYoshinori Sato opr(cpu_regs[dst], cpu_regs[dst], val); 857*e5918d7dSYoshinori Sato tcg_temp_free(mem); 858*e5918d7dSYoshinori Sato } 859*e5918d7dSYoshinori Sato 860*e5918d7dSYoshinori Sato static void rx_and(TCGv ret, TCGv arg1, TCGv arg2) 861*e5918d7dSYoshinori Sato { 862*e5918d7dSYoshinori Sato tcg_gen_and_i32(cpu_psw_s, arg1, arg2); 863*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_psw_z, cpu_psw_s); 864*e5918d7dSYoshinori Sato tcg_gen_mov_i32(ret, cpu_psw_s); 865*e5918d7dSYoshinori Sato } 866*e5918d7dSYoshinori Sato 867*e5918d7dSYoshinori Sato /* and #uimm:4, rd */ 868*e5918d7dSYoshinori Sato /* and #imm, rd */ 869*e5918d7dSYoshinori Sato static bool trans_AND_ir(DisasContext *ctx, arg_AND_ir *a) 870*e5918d7dSYoshinori Sato { 871*e5918d7dSYoshinori Sato rx_gen_op_irr(rx_and, a->rd, a->rd, a->imm); 872*e5918d7dSYoshinori Sato return true; 873*e5918d7dSYoshinori Sato } 874*e5918d7dSYoshinori Sato 875*e5918d7dSYoshinori Sato /* and dsp[rs], rd */ 876*e5918d7dSYoshinori Sato /* and rs,rd */ 877*e5918d7dSYoshinori Sato static bool trans_AND_mr(DisasContext *ctx, arg_AND_mr *a) 878*e5918d7dSYoshinori Sato { 879*e5918d7dSYoshinori Sato rx_gen_op_mr(rx_and, ctx, a->rd, a->rs, a->ld, a->mi); 880*e5918d7dSYoshinori Sato return true; 881*e5918d7dSYoshinori Sato } 882*e5918d7dSYoshinori Sato 883*e5918d7dSYoshinori Sato /* and rs,rs2,rd */ 884*e5918d7dSYoshinori Sato static bool trans_AND_rrr(DisasContext *ctx, arg_AND_rrr *a) 885*e5918d7dSYoshinori Sato { 886*e5918d7dSYoshinori Sato rx_gen_op_rrr(rx_and, a->rd, a->rs, a->rs2); 887*e5918d7dSYoshinori Sato return true; 888*e5918d7dSYoshinori Sato } 889*e5918d7dSYoshinori Sato 890*e5918d7dSYoshinori Sato static void rx_or(TCGv ret, TCGv arg1, TCGv arg2) 891*e5918d7dSYoshinori Sato { 892*e5918d7dSYoshinori Sato tcg_gen_or_i32(cpu_psw_s, arg1, arg2); 893*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_psw_z, cpu_psw_s); 894*e5918d7dSYoshinori Sato tcg_gen_mov_i32(ret, cpu_psw_s); 895*e5918d7dSYoshinori Sato } 896*e5918d7dSYoshinori Sato 897*e5918d7dSYoshinori Sato /* or #uimm:4, rd */ 898*e5918d7dSYoshinori Sato /* or #imm, rd */ 899*e5918d7dSYoshinori Sato static bool trans_OR_ir(DisasContext *ctx, arg_OR_ir *a) 900*e5918d7dSYoshinori Sato { 901*e5918d7dSYoshinori Sato rx_gen_op_irr(rx_or, a->rd, a->rd, a->imm); 902*e5918d7dSYoshinori Sato return true; 903*e5918d7dSYoshinori Sato } 904*e5918d7dSYoshinori Sato 905*e5918d7dSYoshinori Sato /* or dsp[rs], rd */ 906*e5918d7dSYoshinori Sato /* or rs,rd */ 907*e5918d7dSYoshinori Sato static bool trans_OR_mr(DisasContext *ctx, arg_OR_mr *a) 908*e5918d7dSYoshinori Sato { 909*e5918d7dSYoshinori Sato rx_gen_op_mr(rx_or, ctx, a->rd, a->rs, a->ld, a->mi); 910*e5918d7dSYoshinori Sato return true; 911*e5918d7dSYoshinori Sato } 912*e5918d7dSYoshinori Sato 913*e5918d7dSYoshinori Sato /* or rs,rs2,rd */ 914*e5918d7dSYoshinori Sato static bool trans_OR_rrr(DisasContext *ctx, arg_OR_rrr *a) 915*e5918d7dSYoshinori Sato { 916*e5918d7dSYoshinori Sato rx_gen_op_rrr(rx_or, a->rd, a->rs, a->rs2); 917*e5918d7dSYoshinori Sato return true; 918*e5918d7dSYoshinori Sato } 919*e5918d7dSYoshinori Sato 920*e5918d7dSYoshinori Sato static void rx_xor(TCGv ret, TCGv arg1, TCGv arg2) 921*e5918d7dSYoshinori Sato { 922*e5918d7dSYoshinori Sato tcg_gen_xor_i32(cpu_psw_s, arg1, arg2); 923*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_psw_z, cpu_psw_s); 924*e5918d7dSYoshinori Sato tcg_gen_mov_i32(ret, cpu_psw_s); 925*e5918d7dSYoshinori Sato } 926*e5918d7dSYoshinori Sato 927*e5918d7dSYoshinori Sato /* xor #imm, rd */ 928*e5918d7dSYoshinori Sato static bool trans_XOR_ir(DisasContext *ctx, arg_XOR_ir *a) 929*e5918d7dSYoshinori Sato { 930*e5918d7dSYoshinori Sato rx_gen_op_irr(rx_xor, a->rd, a->rd, a->imm); 931*e5918d7dSYoshinori Sato return true; 932*e5918d7dSYoshinori Sato } 933*e5918d7dSYoshinori Sato 934*e5918d7dSYoshinori Sato /* xor dsp[rs], rd */ 935*e5918d7dSYoshinori Sato /* xor rs,rd */ 936*e5918d7dSYoshinori Sato static bool trans_XOR_mr(DisasContext *ctx, arg_XOR_mr *a) 937*e5918d7dSYoshinori Sato { 938*e5918d7dSYoshinori Sato rx_gen_op_mr(rx_xor, ctx, a->rd, a->rs, a->ld, a->mi); 939*e5918d7dSYoshinori Sato return true; 940*e5918d7dSYoshinori Sato } 941*e5918d7dSYoshinori Sato 942*e5918d7dSYoshinori Sato static void rx_tst(TCGv ret, TCGv arg1, TCGv arg2) 943*e5918d7dSYoshinori Sato { 944*e5918d7dSYoshinori Sato tcg_gen_and_i32(cpu_psw_s, arg1, arg2); 945*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_psw_z, cpu_psw_s); 946*e5918d7dSYoshinori Sato } 947*e5918d7dSYoshinori Sato 948*e5918d7dSYoshinori Sato /* tst #imm, rd */ 949*e5918d7dSYoshinori Sato static bool trans_TST_ir(DisasContext *ctx, arg_TST_ir *a) 950*e5918d7dSYoshinori Sato { 951*e5918d7dSYoshinori Sato rx_gen_op_irr(rx_tst, a->rd, a->rd, a->imm); 952*e5918d7dSYoshinori Sato return true; 953*e5918d7dSYoshinori Sato } 954*e5918d7dSYoshinori Sato 955*e5918d7dSYoshinori Sato /* tst dsp[rs], rd */ 956*e5918d7dSYoshinori Sato /* tst rs, rd */ 957*e5918d7dSYoshinori Sato static bool trans_TST_mr(DisasContext *ctx, arg_TST_mr *a) 958*e5918d7dSYoshinori Sato { 959*e5918d7dSYoshinori Sato rx_gen_op_mr(rx_tst, ctx, a->rd, a->rs, a->ld, a->mi); 960*e5918d7dSYoshinori Sato return true; 961*e5918d7dSYoshinori Sato } 962*e5918d7dSYoshinori Sato 963*e5918d7dSYoshinori Sato static void rx_not(TCGv ret, TCGv arg1) 964*e5918d7dSYoshinori Sato { 965*e5918d7dSYoshinori Sato tcg_gen_not_i32(ret, arg1); 966*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_psw_z, ret); 967*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_psw_s, ret); 968*e5918d7dSYoshinori Sato } 969*e5918d7dSYoshinori Sato 970*e5918d7dSYoshinori Sato /* not rd */ 971*e5918d7dSYoshinori Sato /* not rs, rd */ 972*e5918d7dSYoshinori Sato static bool trans_NOT_rr(DisasContext *ctx, arg_NOT_rr *a) 973*e5918d7dSYoshinori Sato { 974*e5918d7dSYoshinori Sato rx_gen_op_rr(rx_not, a->rd, a->rs); 975*e5918d7dSYoshinori Sato return true; 976*e5918d7dSYoshinori Sato } 977*e5918d7dSYoshinori Sato 978*e5918d7dSYoshinori Sato static void rx_neg(TCGv ret, TCGv arg1) 979*e5918d7dSYoshinori Sato { 980*e5918d7dSYoshinori Sato tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_psw_o, arg1, 0x80000000); 981*e5918d7dSYoshinori Sato tcg_gen_neg_i32(ret, arg1); 982*e5918d7dSYoshinori Sato tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_psw_c, ret, 0); 983*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_psw_z, ret); 984*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_psw_s, ret); 985*e5918d7dSYoshinori Sato } 986*e5918d7dSYoshinori Sato 987*e5918d7dSYoshinori Sato 988*e5918d7dSYoshinori Sato /* neg rd */ 989*e5918d7dSYoshinori Sato /* neg rs, rd */ 990*e5918d7dSYoshinori Sato static bool trans_NEG_rr(DisasContext *ctx, arg_NEG_rr *a) 991*e5918d7dSYoshinori Sato { 992*e5918d7dSYoshinori Sato rx_gen_op_rr(rx_neg, a->rd, a->rs); 993*e5918d7dSYoshinori Sato return true; 994*e5918d7dSYoshinori Sato } 995*e5918d7dSYoshinori Sato 996*e5918d7dSYoshinori Sato /* ret = arg1 + arg2 + psw_c */ 997*e5918d7dSYoshinori Sato static void rx_adc(TCGv ret, TCGv arg1, TCGv arg2) 998*e5918d7dSYoshinori Sato { 999*e5918d7dSYoshinori Sato TCGv z; 1000*e5918d7dSYoshinori Sato z = tcg_const_i32(0); 1001*e5918d7dSYoshinori Sato tcg_gen_add2_i32(cpu_psw_s, cpu_psw_c, arg1, z, cpu_psw_c, z); 1002*e5918d7dSYoshinori Sato tcg_gen_add2_i32(cpu_psw_s, cpu_psw_c, cpu_psw_s, cpu_psw_c, arg2, z); 1003*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_psw_z, cpu_psw_s); 1004*e5918d7dSYoshinori Sato tcg_gen_xor_i32(cpu_psw_o, cpu_psw_s, arg1); 1005*e5918d7dSYoshinori Sato tcg_gen_xor_i32(z, arg1, arg2); 1006*e5918d7dSYoshinori Sato tcg_gen_andc_i32(cpu_psw_o, cpu_psw_o, z); 1007*e5918d7dSYoshinori Sato tcg_gen_mov_i32(ret, cpu_psw_s); 1008*e5918d7dSYoshinori Sato tcg_temp_free(z); 1009*e5918d7dSYoshinori Sato } 1010*e5918d7dSYoshinori Sato 1011*e5918d7dSYoshinori Sato /* adc #imm, rd */ 1012*e5918d7dSYoshinori Sato static bool trans_ADC_ir(DisasContext *ctx, arg_ADC_ir *a) 1013*e5918d7dSYoshinori Sato { 1014*e5918d7dSYoshinori Sato rx_gen_op_irr(rx_adc, a->rd, a->rd, a->imm); 1015*e5918d7dSYoshinori Sato return true; 1016*e5918d7dSYoshinori Sato } 1017*e5918d7dSYoshinori Sato 1018*e5918d7dSYoshinori Sato /* adc rs, rd */ 1019*e5918d7dSYoshinori Sato static bool trans_ADC_rr(DisasContext *ctx, arg_ADC_rr *a) 1020*e5918d7dSYoshinori Sato { 1021*e5918d7dSYoshinori Sato rx_gen_op_rrr(rx_adc, a->rd, a->rd, a->rs); 1022*e5918d7dSYoshinori Sato return true; 1023*e5918d7dSYoshinori Sato } 1024*e5918d7dSYoshinori Sato 1025*e5918d7dSYoshinori Sato /* adc dsp[rs], rd */ 1026*e5918d7dSYoshinori Sato static bool trans_ADC_mr(DisasContext *ctx, arg_ADC_mr *a) 1027*e5918d7dSYoshinori Sato { 1028*e5918d7dSYoshinori Sato /* mi only 2 */ 1029*e5918d7dSYoshinori Sato if (a->mi != 2) { 1030*e5918d7dSYoshinori Sato return false; 1031*e5918d7dSYoshinori Sato } 1032*e5918d7dSYoshinori Sato rx_gen_op_mr(rx_adc, ctx, a->rd, a->rs, a->ld, a->mi); 1033*e5918d7dSYoshinori Sato return true; 1034*e5918d7dSYoshinori Sato } 1035*e5918d7dSYoshinori Sato 1036*e5918d7dSYoshinori Sato /* ret = arg1 + arg2 */ 1037*e5918d7dSYoshinori Sato static void rx_add(TCGv ret, TCGv arg1, TCGv arg2) 1038*e5918d7dSYoshinori Sato { 1039*e5918d7dSYoshinori Sato TCGv z; 1040*e5918d7dSYoshinori Sato z = tcg_const_i32(0); 1041*e5918d7dSYoshinori Sato tcg_gen_add2_i32(cpu_psw_s, cpu_psw_c, arg1, z, arg2, z); 1042*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_psw_z, cpu_psw_s); 1043*e5918d7dSYoshinori Sato tcg_gen_xor_i32(cpu_psw_o, cpu_psw_s, arg1); 1044*e5918d7dSYoshinori Sato tcg_gen_xor_i32(z, arg1, arg2); 1045*e5918d7dSYoshinori Sato tcg_gen_andc_i32(cpu_psw_o, cpu_psw_o, z); 1046*e5918d7dSYoshinori Sato tcg_gen_mov_i32(ret, cpu_psw_s); 1047*e5918d7dSYoshinori Sato tcg_temp_free(z); 1048*e5918d7dSYoshinori Sato } 1049*e5918d7dSYoshinori Sato 1050*e5918d7dSYoshinori Sato /* add #uimm4, rd */ 1051*e5918d7dSYoshinori Sato /* add #imm, rs, rd */ 1052*e5918d7dSYoshinori Sato static bool trans_ADD_irr(DisasContext *ctx, arg_ADD_irr *a) 1053*e5918d7dSYoshinori Sato { 1054*e5918d7dSYoshinori Sato rx_gen_op_irr(rx_add, a->rd, a->rs2, a->imm); 1055*e5918d7dSYoshinori Sato return true; 1056*e5918d7dSYoshinori Sato } 1057*e5918d7dSYoshinori Sato 1058*e5918d7dSYoshinori Sato /* add rs, rd */ 1059*e5918d7dSYoshinori Sato /* add dsp[rs], rd */ 1060*e5918d7dSYoshinori Sato static bool trans_ADD_mr(DisasContext *ctx, arg_ADD_mr *a) 1061*e5918d7dSYoshinori Sato { 1062*e5918d7dSYoshinori Sato rx_gen_op_mr(rx_add, ctx, a->rd, a->rs, a->ld, a->mi); 1063*e5918d7dSYoshinori Sato return true; 1064*e5918d7dSYoshinori Sato } 1065*e5918d7dSYoshinori Sato 1066*e5918d7dSYoshinori Sato /* add rs, rs2, rd */ 1067*e5918d7dSYoshinori Sato static bool trans_ADD_rrr(DisasContext *ctx, arg_ADD_rrr *a) 1068*e5918d7dSYoshinori Sato { 1069*e5918d7dSYoshinori Sato rx_gen_op_rrr(rx_add, a->rd, a->rs, a->rs2); 1070*e5918d7dSYoshinori Sato return true; 1071*e5918d7dSYoshinori Sato } 1072*e5918d7dSYoshinori Sato 1073*e5918d7dSYoshinori Sato /* ret = arg1 - arg2 */ 1074*e5918d7dSYoshinori Sato static void rx_sub(TCGv ret, TCGv arg1, TCGv arg2) 1075*e5918d7dSYoshinori Sato { 1076*e5918d7dSYoshinori Sato TCGv temp; 1077*e5918d7dSYoshinori Sato tcg_gen_sub_i32(cpu_psw_s, arg1, arg2); 1078*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_psw_z, cpu_psw_s); 1079*e5918d7dSYoshinori Sato tcg_gen_setcond_i32(TCG_COND_GEU, cpu_psw_c, arg1, arg2); 1080*e5918d7dSYoshinori Sato tcg_gen_xor_i32(cpu_psw_o, cpu_psw_s, arg1); 1081*e5918d7dSYoshinori Sato temp = tcg_temp_new_i32(); 1082*e5918d7dSYoshinori Sato tcg_gen_xor_i32(temp, arg1, arg2); 1083*e5918d7dSYoshinori Sato tcg_gen_and_i32(cpu_psw_o, cpu_psw_o, temp); 1084*e5918d7dSYoshinori Sato tcg_temp_free_i32(temp); 1085*e5918d7dSYoshinori Sato /* CMP not requred return */ 1086*e5918d7dSYoshinori Sato if (ret) { 1087*e5918d7dSYoshinori Sato tcg_gen_mov_i32(ret, cpu_psw_s); 1088*e5918d7dSYoshinori Sato } 1089*e5918d7dSYoshinori Sato } 1090*e5918d7dSYoshinori Sato static void rx_cmp(TCGv dummy, TCGv arg1, TCGv arg2) 1091*e5918d7dSYoshinori Sato { 1092*e5918d7dSYoshinori Sato rx_sub(NULL, arg1, arg2); 1093*e5918d7dSYoshinori Sato } 1094*e5918d7dSYoshinori Sato /* ret = arg1 - arg2 - !psw_c */ 1095*e5918d7dSYoshinori Sato /* -> ret = arg1 + ~arg2 + psw_c */ 1096*e5918d7dSYoshinori Sato static void rx_sbb(TCGv ret, TCGv arg1, TCGv arg2) 1097*e5918d7dSYoshinori Sato { 1098*e5918d7dSYoshinori Sato TCGv temp; 1099*e5918d7dSYoshinori Sato temp = tcg_temp_new(); 1100*e5918d7dSYoshinori Sato tcg_gen_not_i32(temp, arg2); 1101*e5918d7dSYoshinori Sato rx_adc(ret, arg1, temp); 1102*e5918d7dSYoshinori Sato tcg_temp_free(temp); 1103*e5918d7dSYoshinori Sato } 1104*e5918d7dSYoshinori Sato 1105*e5918d7dSYoshinori Sato /* cmp #imm4, rs2 */ 1106*e5918d7dSYoshinori Sato /* cmp #imm8, rs2 */ 1107*e5918d7dSYoshinori Sato /* cmp #imm, rs2 */ 1108*e5918d7dSYoshinori Sato static bool trans_CMP_ir(DisasContext *ctx, arg_CMP_ir *a) 1109*e5918d7dSYoshinori Sato { 1110*e5918d7dSYoshinori Sato rx_gen_op_irr(rx_cmp, 0, a->rs2, a->imm); 1111*e5918d7dSYoshinori Sato return true; 1112*e5918d7dSYoshinori Sato } 1113*e5918d7dSYoshinori Sato 1114*e5918d7dSYoshinori Sato /* cmp rs, rs2 */ 1115*e5918d7dSYoshinori Sato /* cmp dsp[rs], rs2 */ 1116*e5918d7dSYoshinori Sato static bool trans_CMP_mr(DisasContext *ctx, arg_CMP_mr *a) 1117*e5918d7dSYoshinori Sato { 1118*e5918d7dSYoshinori Sato rx_gen_op_mr(rx_cmp, ctx, a->rd, a->rs, a->ld, a->mi); 1119*e5918d7dSYoshinori Sato return true; 1120*e5918d7dSYoshinori Sato } 1121*e5918d7dSYoshinori Sato 1122*e5918d7dSYoshinori Sato /* sub #imm4, rd */ 1123*e5918d7dSYoshinori Sato static bool trans_SUB_ir(DisasContext *ctx, arg_SUB_ir *a) 1124*e5918d7dSYoshinori Sato { 1125*e5918d7dSYoshinori Sato rx_gen_op_irr(rx_sub, a->rd, a->rd, a->imm); 1126*e5918d7dSYoshinori Sato return true; 1127*e5918d7dSYoshinori Sato } 1128*e5918d7dSYoshinori Sato 1129*e5918d7dSYoshinori Sato /* sub rs, rd */ 1130*e5918d7dSYoshinori Sato /* sub dsp[rs], rd */ 1131*e5918d7dSYoshinori Sato static bool trans_SUB_mr(DisasContext *ctx, arg_SUB_mr *a) 1132*e5918d7dSYoshinori Sato { 1133*e5918d7dSYoshinori Sato rx_gen_op_mr(rx_sub, ctx, a->rd, a->rs, a->ld, a->mi); 1134*e5918d7dSYoshinori Sato return true; 1135*e5918d7dSYoshinori Sato } 1136*e5918d7dSYoshinori Sato 1137*e5918d7dSYoshinori Sato /* sub rs2, rs, rd */ 1138*e5918d7dSYoshinori Sato static bool trans_SUB_rrr(DisasContext *ctx, arg_SUB_rrr *a) 1139*e5918d7dSYoshinori Sato { 1140*e5918d7dSYoshinori Sato rx_gen_op_rrr(rx_sub, a->rd, a->rs2, a->rs); 1141*e5918d7dSYoshinori Sato return true; 1142*e5918d7dSYoshinori Sato } 1143*e5918d7dSYoshinori Sato 1144*e5918d7dSYoshinori Sato /* sbb rs, rd */ 1145*e5918d7dSYoshinori Sato static bool trans_SBB_rr(DisasContext *ctx, arg_SBB_rr *a) 1146*e5918d7dSYoshinori Sato { 1147*e5918d7dSYoshinori Sato rx_gen_op_rrr(rx_sbb, a->rd, a->rd, a->rs); 1148*e5918d7dSYoshinori Sato return true; 1149*e5918d7dSYoshinori Sato } 1150*e5918d7dSYoshinori Sato 1151*e5918d7dSYoshinori Sato /* sbb dsp[rs], rd */ 1152*e5918d7dSYoshinori Sato static bool trans_SBB_mr(DisasContext *ctx, arg_SBB_mr *a) 1153*e5918d7dSYoshinori Sato { 1154*e5918d7dSYoshinori Sato /* mi only 2 */ 1155*e5918d7dSYoshinori Sato if (a->mi != 2) { 1156*e5918d7dSYoshinori Sato return false; 1157*e5918d7dSYoshinori Sato } 1158*e5918d7dSYoshinori Sato rx_gen_op_mr(rx_sbb, ctx, a->rd, a->rs, a->ld, a->mi); 1159*e5918d7dSYoshinori Sato return true; 1160*e5918d7dSYoshinori Sato } 1161*e5918d7dSYoshinori Sato 1162*e5918d7dSYoshinori Sato static void rx_abs(TCGv ret, TCGv arg1) 1163*e5918d7dSYoshinori Sato { 1164*e5918d7dSYoshinori Sato TCGv neg; 1165*e5918d7dSYoshinori Sato TCGv zero; 1166*e5918d7dSYoshinori Sato neg = tcg_temp_new(); 1167*e5918d7dSYoshinori Sato zero = tcg_const_i32(0); 1168*e5918d7dSYoshinori Sato tcg_gen_neg_i32(neg, arg1); 1169*e5918d7dSYoshinori Sato tcg_gen_movcond_i32(TCG_COND_LT, ret, arg1, zero, neg, arg1); 1170*e5918d7dSYoshinori Sato tcg_temp_free(neg); 1171*e5918d7dSYoshinori Sato tcg_temp_free(zero); 1172*e5918d7dSYoshinori Sato } 1173*e5918d7dSYoshinori Sato 1174*e5918d7dSYoshinori Sato /* abs rd */ 1175*e5918d7dSYoshinori Sato /* abs rs, rd */ 1176*e5918d7dSYoshinori Sato static bool trans_ABS_rr(DisasContext *ctx, arg_ABS_rr *a) 1177*e5918d7dSYoshinori Sato { 1178*e5918d7dSYoshinori Sato rx_gen_op_rr(rx_abs, a->rd, a->rs); 1179*e5918d7dSYoshinori Sato return true; 1180*e5918d7dSYoshinori Sato } 1181*e5918d7dSYoshinori Sato 1182*e5918d7dSYoshinori Sato /* max #imm, rd */ 1183*e5918d7dSYoshinori Sato static bool trans_MAX_ir(DisasContext *ctx, arg_MAX_ir *a) 1184*e5918d7dSYoshinori Sato { 1185*e5918d7dSYoshinori Sato rx_gen_op_irr(tcg_gen_smax_i32, a->rd, a->rd, a->imm); 1186*e5918d7dSYoshinori Sato return true; 1187*e5918d7dSYoshinori Sato } 1188*e5918d7dSYoshinori Sato 1189*e5918d7dSYoshinori Sato /* max rs, rd */ 1190*e5918d7dSYoshinori Sato /* max dsp[rs], rd */ 1191*e5918d7dSYoshinori Sato static bool trans_MAX_mr(DisasContext *ctx, arg_MAX_mr *a) 1192*e5918d7dSYoshinori Sato { 1193*e5918d7dSYoshinori Sato rx_gen_op_mr(tcg_gen_smax_i32, ctx, a->rd, a->rs, a->ld, a->mi); 1194*e5918d7dSYoshinori Sato return true; 1195*e5918d7dSYoshinori Sato } 1196*e5918d7dSYoshinori Sato 1197*e5918d7dSYoshinori Sato /* min #imm, rd */ 1198*e5918d7dSYoshinori Sato static bool trans_MIN_ir(DisasContext *ctx, arg_MIN_ir *a) 1199*e5918d7dSYoshinori Sato { 1200*e5918d7dSYoshinori Sato rx_gen_op_irr(tcg_gen_smin_i32, a->rd, a->rd, a->imm); 1201*e5918d7dSYoshinori Sato return true; 1202*e5918d7dSYoshinori Sato } 1203*e5918d7dSYoshinori Sato 1204*e5918d7dSYoshinori Sato /* min rs, rd */ 1205*e5918d7dSYoshinori Sato /* min dsp[rs], rd */ 1206*e5918d7dSYoshinori Sato static bool trans_MIN_mr(DisasContext *ctx, arg_MIN_mr *a) 1207*e5918d7dSYoshinori Sato { 1208*e5918d7dSYoshinori Sato rx_gen_op_mr(tcg_gen_smin_i32, ctx, a->rd, a->rs, a->ld, a->mi); 1209*e5918d7dSYoshinori Sato return true; 1210*e5918d7dSYoshinori Sato } 1211*e5918d7dSYoshinori Sato 1212*e5918d7dSYoshinori Sato /* mul #uimm4, rd */ 1213*e5918d7dSYoshinori Sato /* mul #imm, rd */ 1214*e5918d7dSYoshinori Sato static bool trans_MUL_ir(DisasContext *ctx, arg_MUL_ir *a) 1215*e5918d7dSYoshinori Sato { 1216*e5918d7dSYoshinori Sato rx_gen_op_irr(tcg_gen_mul_i32, a->rd, a->rd, a->imm); 1217*e5918d7dSYoshinori Sato return true; 1218*e5918d7dSYoshinori Sato } 1219*e5918d7dSYoshinori Sato 1220*e5918d7dSYoshinori Sato /* mul rs, rd */ 1221*e5918d7dSYoshinori Sato /* mul dsp[rs], rd */ 1222*e5918d7dSYoshinori Sato static bool trans_MUL_mr(DisasContext *ctx, arg_MUL_mr *a) 1223*e5918d7dSYoshinori Sato { 1224*e5918d7dSYoshinori Sato rx_gen_op_mr(tcg_gen_mul_i32, ctx, a->rd, a->rs, a->ld, a->mi); 1225*e5918d7dSYoshinori Sato return true; 1226*e5918d7dSYoshinori Sato } 1227*e5918d7dSYoshinori Sato 1228*e5918d7dSYoshinori Sato /* mul rs, rs2, rd */ 1229*e5918d7dSYoshinori Sato static bool trans_MUL_rrr(DisasContext *ctx, arg_MUL_rrr *a) 1230*e5918d7dSYoshinori Sato { 1231*e5918d7dSYoshinori Sato rx_gen_op_rrr(tcg_gen_mul_i32, a->rd, a->rs, a->rs2); 1232*e5918d7dSYoshinori Sato return true; 1233*e5918d7dSYoshinori Sato } 1234*e5918d7dSYoshinori Sato 1235*e5918d7dSYoshinori Sato /* emul #imm, rd */ 1236*e5918d7dSYoshinori Sato static bool trans_EMUL_ir(DisasContext *ctx, arg_EMUL_ir *a) 1237*e5918d7dSYoshinori Sato { 1238*e5918d7dSYoshinori Sato TCGv imm = tcg_const_i32(a->imm); 1239*e5918d7dSYoshinori Sato if (a->rd > 14) { 1240*e5918d7dSYoshinori Sato qemu_log_mask(LOG_GUEST_ERROR, "rd too large %d", a->rd); 1241*e5918d7dSYoshinori Sato } 1242*e5918d7dSYoshinori Sato tcg_gen_muls2_i32(cpu_regs[a->rd], cpu_regs[(a->rd + 1) & 15], 1243*e5918d7dSYoshinori Sato cpu_regs[a->rd], imm); 1244*e5918d7dSYoshinori Sato tcg_temp_free(imm); 1245*e5918d7dSYoshinori Sato return true; 1246*e5918d7dSYoshinori Sato } 1247*e5918d7dSYoshinori Sato 1248*e5918d7dSYoshinori Sato /* emul rs, rd */ 1249*e5918d7dSYoshinori Sato /* emul dsp[rs], rd */ 1250*e5918d7dSYoshinori Sato static bool trans_EMUL_mr(DisasContext *ctx, arg_EMUL_mr *a) 1251*e5918d7dSYoshinori Sato { 1252*e5918d7dSYoshinori Sato TCGv val, mem; 1253*e5918d7dSYoshinori Sato if (a->rd > 14) { 1254*e5918d7dSYoshinori Sato qemu_log_mask(LOG_GUEST_ERROR, "rd too large %d", a->rd); 1255*e5918d7dSYoshinori Sato } 1256*e5918d7dSYoshinori Sato mem = tcg_temp_new(); 1257*e5918d7dSYoshinori Sato val = rx_load_source(ctx, mem, a->ld, a->mi, a->rs); 1258*e5918d7dSYoshinori Sato tcg_gen_muls2_i32(cpu_regs[a->rd], cpu_regs[(a->rd + 1) & 15], 1259*e5918d7dSYoshinori Sato cpu_regs[a->rd], val); 1260*e5918d7dSYoshinori Sato tcg_temp_free(mem); 1261*e5918d7dSYoshinori Sato return true; 1262*e5918d7dSYoshinori Sato } 1263*e5918d7dSYoshinori Sato 1264*e5918d7dSYoshinori Sato /* emulu #imm, rd */ 1265*e5918d7dSYoshinori Sato static bool trans_EMULU_ir(DisasContext *ctx, arg_EMULU_ir *a) 1266*e5918d7dSYoshinori Sato { 1267*e5918d7dSYoshinori Sato TCGv imm = tcg_const_i32(a->imm); 1268*e5918d7dSYoshinori Sato if (a->rd > 14) { 1269*e5918d7dSYoshinori Sato qemu_log_mask(LOG_GUEST_ERROR, "rd too large %d", a->rd); 1270*e5918d7dSYoshinori Sato } 1271*e5918d7dSYoshinori Sato tcg_gen_mulu2_i32(cpu_regs[a->rd], cpu_regs[(a->rd + 1) & 15], 1272*e5918d7dSYoshinori Sato cpu_regs[a->rd], imm); 1273*e5918d7dSYoshinori Sato tcg_temp_free(imm); 1274*e5918d7dSYoshinori Sato return true; 1275*e5918d7dSYoshinori Sato } 1276*e5918d7dSYoshinori Sato 1277*e5918d7dSYoshinori Sato /* emulu rs, rd */ 1278*e5918d7dSYoshinori Sato /* emulu dsp[rs], rd */ 1279*e5918d7dSYoshinori Sato static bool trans_EMULU_mr(DisasContext *ctx, arg_EMULU_mr *a) 1280*e5918d7dSYoshinori Sato { 1281*e5918d7dSYoshinori Sato TCGv val, mem; 1282*e5918d7dSYoshinori Sato if (a->rd > 14) { 1283*e5918d7dSYoshinori Sato qemu_log_mask(LOG_GUEST_ERROR, "rd too large %d", a->rd); 1284*e5918d7dSYoshinori Sato } 1285*e5918d7dSYoshinori Sato mem = tcg_temp_new(); 1286*e5918d7dSYoshinori Sato val = rx_load_source(ctx, mem, a->ld, a->mi, a->rs); 1287*e5918d7dSYoshinori Sato tcg_gen_mulu2_i32(cpu_regs[a->rd], cpu_regs[(a->rd + 1) & 15], 1288*e5918d7dSYoshinori Sato cpu_regs[a->rd], val); 1289*e5918d7dSYoshinori Sato tcg_temp_free(mem); 1290*e5918d7dSYoshinori Sato return true; 1291*e5918d7dSYoshinori Sato } 1292*e5918d7dSYoshinori Sato 1293*e5918d7dSYoshinori Sato static void rx_div(TCGv ret, TCGv arg1, TCGv arg2) 1294*e5918d7dSYoshinori Sato { 1295*e5918d7dSYoshinori Sato gen_helper_div(ret, cpu_env, arg1, arg2); 1296*e5918d7dSYoshinori Sato } 1297*e5918d7dSYoshinori Sato 1298*e5918d7dSYoshinori Sato static void rx_divu(TCGv ret, TCGv arg1, TCGv arg2) 1299*e5918d7dSYoshinori Sato { 1300*e5918d7dSYoshinori Sato gen_helper_divu(ret, cpu_env, arg1, arg2); 1301*e5918d7dSYoshinori Sato } 1302*e5918d7dSYoshinori Sato 1303*e5918d7dSYoshinori Sato /* div #imm, rd */ 1304*e5918d7dSYoshinori Sato static bool trans_DIV_ir(DisasContext *ctx, arg_DIV_ir *a) 1305*e5918d7dSYoshinori Sato { 1306*e5918d7dSYoshinori Sato rx_gen_op_irr(rx_div, a->rd, a->rd, a->imm); 1307*e5918d7dSYoshinori Sato return true; 1308*e5918d7dSYoshinori Sato } 1309*e5918d7dSYoshinori Sato 1310*e5918d7dSYoshinori Sato /* div rs, rd */ 1311*e5918d7dSYoshinori Sato /* div dsp[rs], rd */ 1312*e5918d7dSYoshinori Sato static bool trans_DIV_mr(DisasContext *ctx, arg_DIV_mr *a) 1313*e5918d7dSYoshinori Sato { 1314*e5918d7dSYoshinori Sato rx_gen_op_mr(rx_div, ctx, a->rd, a->rs, a->ld, a->mi); 1315*e5918d7dSYoshinori Sato return true; 1316*e5918d7dSYoshinori Sato } 1317*e5918d7dSYoshinori Sato 1318*e5918d7dSYoshinori Sato /* divu #imm, rd */ 1319*e5918d7dSYoshinori Sato static bool trans_DIVU_ir(DisasContext *ctx, arg_DIVU_ir *a) 1320*e5918d7dSYoshinori Sato { 1321*e5918d7dSYoshinori Sato rx_gen_op_irr(rx_divu, a->rd, a->rd, a->imm); 1322*e5918d7dSYoshinori Sato return true; 1323*e5918d7dSYoshinori Sato } 1324*e5918d7dSYoshinori Sato 1325*e5918d7dSYoshinori Sato /* divu rs, rd */ 1326*e5918d7dSYoshinori Sato /* divu dsp[rs], rd */ 1327*e5918d7dSYoshinori Sato static bool trans_DIVU_mr(DisasContext *ctx, arg_DIVU_mr *a) 1328*e5918d7dSYoshinori Sato { 1329*e5918d7dSYoshinori Sato rx_gen_op_mr(rx_divu, ctx, a->rd, a->rs, a->ld, a->mi); 1330*e5918d7dSYoshinori Sato return true; 1331*e5918d7dSYoshinori Sato } 1332*e5918d7dSYoshinori Sato 1333*e5918d7dSYoshinori Sato 1334*e5918d7dSYoshinori Sato /* shll #imm:5, rd */ 1335*e5918d7dSYoshinori Sato /* shll #imm:5, rs2, rd */ 1336*e5918d7dSYoshinori Sato static bool trans_SHLL_irr(DisasContext *ctx, arg_SHLL_irr *a) 1337*e5918d7dSYoshinori Sato { 1338*e5918d7dSYoshinori Sato TCGv tmp; 1339*e5918d7dSYoshinori Sato tmp = tcg_temp_new(); 1340*e5918d7dSYoshinori Sato if (a->imm) { 1341*e5918d7dSYoshinori Sato tcg_gen_sari_i32(cpu_psw_c, cpu_regs[a->rs2], 32 - a->imm); 1342*e5918d7dSYoshinori Sato tcg_gen_shli_i32(cpu_regs[a->rd], cpu_regs[a->rs2], a->imm); 1343*e5918d7dSYoshinori Sato tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_psw_o, cpu_psw_c, 0); 1344*e5918d7dSYoshinori Sato tcg_gen_setcondi_i32(TCG_COND_EQ, tmp, cpu_psw_c, 0xffffffff); 1345*e5918d7dSYoshinori Sato tcg_gen_or_i32(cpu_psw_o, cpu_psw_o, tmp); 1346*e5918d7dSYoshinori Sato tcg_gen_setcondi_i32(TCG_COND_NE, cpu_psw_c, cpu_psw_c, 0); 1347*e5918d7dSYoshinori Sato } else { 1348*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_regs[a->rd], cpu_regs[a->rs2]); 1349*e5918d7dSYoshinori Sato tcg_gen_movi_i32(cpu_psw_c, 0); 1350*e5918d7dSYoshinori Sato tcg_gen_movi_i32(cpu_psw_o, 0); 1351*e5918d7dSYoshinori Sato } 1352*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_psw_z, cpu_regs[a->rd]); 1353*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_psw_s, cpu_regs[a->rd]); 1354*e5918d7dSYoshinori Sato return true; 1355*e5918d7dSYoshinori Sato } 1356*e5918d7dSYoshinori Sato 1357*e5918d7dSYoshinori Sato /* shll rs, rd */ 1358*e5918d7dSYoshinori Sato static bool trans_SHLL_rr(DisasContext *ctx, arg_SHLL_rr *a) 1359*e5918d7dSYoshinori Sato { 1360*e5918d7dSYoshinori Sato TCGLabel *noshift, *done; 1361*e5918d7dSYoshinori Sato TCGv count, tmp; 1362*e5918d7dSYoshinori Sato 1363*e5918d7dSYoshinori Sato noshift = gen_new_label(); 1364*e5918d7dSYoshinori Sato done = gen_new_label(); 1365*e5918d7dSYoshinori Sato /* if (cpu_regs[a->rs]) { */ 1366*e5918d7dSYoshinori Sato tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_regs[a->rs], 0, noshift); 1367*e5918d7dSYoshinori Sato count = tcg_const_i32(32); 1368*e5918d7dSYoshinori Sato tmp = tcg_temp_new(); 1369*e5918d7dSYoshinori Sato tcg_gen_andi_i32(tmp, cpu_regs[a->rs], 31); 1370*e5918d7dSYoshinori Sato tcg_gen_sub_i32(count, count, tmp); 1371*e5918d7dSYoshinori Sato tcg_gen_sar_i32(cpu_psw_c, cpu_regs[a->rd], count); 1372*e5918d7dSYoshinori Sato tcg_gen_shl_i32(cpu_regs[a->rd], cpu_regs[a->rd], tmp); 1373*e5918d7dSYoshinori Sato tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_psw_o, cpu_psw_c, 0); 1374*e5918d7dSYoshinori Sato tcg_gen_setcondi_i32(TCG_COND_EQ, tmp, cpu_psw_c, 0xffffffff); 1375*e5918d7dSYoshinori Sato tcg_gen_or_i32(cpu_psw_o, cpu_psw_o, tmp); 1376*e5918d7dSYoshinori Sato tcg_gen_setcondi_i32(TCG_COND_NE, cpu_psw_c, cpu_psw_c, 0); 1377*e5918d7dSYoshinori Sato tcg_gen_br(done); 1378*e5918d7dSYoshinori Sato /* } else { */ 1379*e5918d7dSYoshinori Sato gen_set_label(noshift); 1380*e5918d7dSYoshinori Sato tcg_gen_movi_i32(cpu_psw_c, 0); 1381*e5918d7dSYoshinori Sato tcg_gen_movi_i32(cpu_psw_o, 0); 1382*e5918d7dSYoshinori Sato /* } */ 1383*e5918d7dSYoshinori Sato gen_set_label(done); 1384*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_psw_z, cpu_regs[a->rd]); 1385*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_psw_s, cpu_regs[a->rd]); 1386*e5918d7dSYoshinori Sato tcg_temp_free(count); 1387*e5918d7dSYoshinori Sato tcg_temp_free(tmp); 1388*e5918d7dSYoshinori Sato return true; 1389*e5918d7dSYoshinori Sato } 1390*e5918d7dSYoshinori Sato 1391*e5918d7dSYoshinori Sato static inline void shiftr_imm(uint32_t rd, uint32_t rs, uint32_t imm, 1392*e5918d7dSYoshinori Sato unsigned int alith) 1393*e5918d7dSYoshinori Sato { 1394*e5918d7dSYoshinori Sato static void (* const gen_sXri[])(TCGv ret, TCGv arg1, int arg2) = { 1395*e5918d7dSYoshinori Sato tcg_gen_shri_i32, tcg_gen_sari_i32, 1396*e5918d7dSYoshinori Sato }; 1397*e5918d7dSYoshinori Sato tcg_debug_assert(alith < 2); 1398*e5918d7dSYoshinori Sato if (imm) { 1399*e5918d7dSYoshinori Sato gen_sXri[alith](cpu_regs[rd], cpu_regs[rs], imm - 1); 1400*e5918d7dSYoshinori Sato tcg_gen_andi_i32(cpu_psw_c, cpu_regs[rd], 0x00000001); 1401*e5918d7dSYoshinori Sato gen_sXri[alith](cpu_regs[rd], cpu_regs[rd], 1); 1402*e5918d7dSYoshinori Sato } else { 1403*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_regs[rd], cpu_regs[rs]); 1404*e5918d7dSYoshinori Sato tcg_gen_movi_i32(cpu_psw_c, 0); 1405*e5918d7dSYoshinori Sato } 1406*e5918d7dSYoshinori Sato tcg_gen_movi_i32(cpu_psw_o, 0); 1407*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_psw_z, cpu_regs[rd]); 1408*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_psw_s, cpu_regs[rd]); 1409*e5918d7dSYoshinori Sato } 1410*e5918d7dSYoshinori Sato 1411*e5918d7dSYoshinori Sato static inline void shiftr_reg(uint32_t rd, uint32_t rs, unsigned int alith) 1412*e5918d7dSYoshinori Sato { 1413*e5918d7dSYoshinori Sato TCGLabel *noshift, *done; 1414*e5918d7dSYoshinori Sato TCGv count; 1415*e5918d7dSYoshinori Sato static void (* const gen_sXri[])(TCGv ret, TCGv arg1, int arg2) = { 1416*e5918d7dSYoshinori Sato tcg_gen_shri_i32, tcg_gen_sari_i32, 1417*e5918d7dSYoshinori Sato }; 1418*e5918d7dSYoshinori Sato static void (* const gen_sXr[])(TCGv ret, TCGv arg1, TCGv arg2) = { 1419*e5918d7dSYoshinori Sato tcg_gen_shr_i32, tcg_gen_sar_i32, 1420*e5918d7dSYoshinori Sato }; 1421*e5918d7dSYoshinori Sato tcg_debug_assert(alith < 2); 1422*e5918d7dSYoshinori Sato noshift = gen_new_label(); 1423*e5918d7dSYoshinori Sato done = gen_new_label(); 1424*e5918d7dSYoshinori Sato count = tcg_temp_new(); 1425*e5918d7dSYoshinori Sato /* if (cpu_regs[rs]) { */ 1426*e5918d7dSYoshinori Sato tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_regs[rs], 0, noshift); 1427*e5918d7dSYoshinori Sato tcg_gen_andi_i32(count, cpu_regs[rs], 31); 1428*e5918d7dSYoshinori Sato tcg_gen_subi_i32(count, count, 1); 1429*e5918d7dSYoshinori Sato gen_sXr[alith](cpu_regs[rd], cpu_regs[rd], count); 1430*e5918d7dSYoshinori Sato tcg_gen_andi_i32(cpu_psw_c, cpu_regs[rd], 0x00000001); 1431*e5918d7dSYoshinori Sato gen_sXri[alith](cpu_regs[rd], cpu_regs[rd], 1); 1432*e5918d7dSYoshinori Sato tcg_gen_br(done); 1433*e5918d7dSYoshinori Sato /* } else { */ 1434*e5918d7dSYoshinori Sato gen_set_label(noshift); 1435*e5918d7dSYoshinori Sato tcg_gen_movi_i32(cpu_psw_c, 0); 1436*e5918d7dSYoshinori Sato /* } */ 1437*e5918d7dSYoshinori Sato gen_set_label(done); 1438*e5918d7dSYoshinori Sato tcg_gen_movi_i32(cpu_psw_o, 0); 1439*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_psw_z, cpu_regs[rd]); 1440*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_psw_s, cpu_regs[rd]); 1441*e5918d7dSYoshinori Sato tcg_temp_free(count); 1442*e5918d7dSYoshinori Sato } 1443*e5918d7dSYoshinori Sato 1444*e5918d7dSYoshinori Sato /* shar #imm:5, rd */ 1445*e5918d7dSYoshinori Sato /* shar #imm:5, rs2, rd */ 1446*e5918d7dSYoshinori Sato static bool trans_SHAR_irr(DisasContext *ctx, arg_SHAR_irr *a) 1447*e5918d7dSYoshinori Sato { 1448*e5918d7dSYoshinori Sato shiftr_imm(a->rd, a->rs2, a->imm, 1); 1449*e5918d7dSYoshinori Sato return true; 1450*e5918d7dSYoshinori Sato } 1451*e5918d7dSYoshinori Sato 1452*e5918d7dSYoshinori Sato /* shar rs, rd */ 1453*e5918d7dSYoshinori Sato static bool trans_SHAR_rr(DisasContext *ctx, arg_SHAR_rr *a) 1454*e5918d7dSYoshinori Sato { 1455*e5918d7dSYoshinori Sato shiftr_reg(a->rd, a->rs, 1); 1456*e5918d7dSYoshinori Sato return true; 1457*e5918d7dSYoshinori Sato } 1458*e5918d7dSYoshinori Sato 1459*e5918d7dSYoshinori Sato /* shlr #imm:5, rd */ 1460*e5918d7dSYoshinori Sato /* shlr #imm:5, rs2, rd */ 1461*e5918d7dSYoshinori Sato static bool trans_SHLR_irr(DisasContext *ctx, arg_SHLR_irr *a) 1462*e5918d7dSYoshinori Sato { 1463*e5918d7dSYoshinori Sato shiftr_imm(a->rd, a->rs2, a->imm, 0); 1464*e5918d7dSYoshinori Sato return true; 1465*e5918d7dSYoshinori Sato } 1466*e5918d7dSYoshinori Sato 1467*e5918d7dSYoshinori Sato /* shlr rs, rd */ 1468*e5918d7dSYoshinori Sato static bool trans_SHLR_rr(DisasContext *ctx, arg_SHLR_rr *a) 1469*e5918d7dSYoshinori Sato { 1470*e5918d7dSYoshinori Sato shiftr_reg(a->rd, a->rs, 0); 1471*e5918d7dSYoshinori Sato return true; 1472*e5918d7dSYoshinori Sato } 1473*e5918d7dSYoshinori Sato 1474*e5918d7dSYoshinori Sato /* rolc rd */ 1475*e5918d7dSYoshinori Sato static bool trans_ROLC(DisasContext *ctx, arg_ROLC *a) 1476*e5918d7dSYoshinori Sato { 1477*e5918d7dSYoshinori Sato TCGv tmp; 1478*e5918d7dSYoshinori Sato tmp = tcg_temp_new(); 1479*e5918d7dSYoshinori Sato tcg_gen_shri_i32(tmp, cpu_regs[a->rd], 31); 1480*e5918d7dSYoshinori Sato tcg_gen_shli_i32(cpu_regs[a->rd], cpu_regs[a->rd], 1); 1481*e5918d7dSYoshinori Sato tcg_gen_or_i32(cpu_regs[a->rd], cpu_regs[a->rd], cpu_psw_c); 1482*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_psw_c, tmp); 1483*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_psw_z, cpu_regs[a->rd]); 1484*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_psw_s, cpu_regs[a->rd]); 1485*e5918d7dSYoshinori Sato tcg_temp_free(tmp); 1486*e5918d7dSYoshinori Sato return true; 1487*e5918d7dSYoshinori Sato } 1488*e5918d7dSYoshinori Sato 1489*e5918d7dSYoshinori Sato /* rorc rd */ 1490*e5918d7dSYoshinori Sato static bool trans_RORC(DisasContext *ctx, arg_RORC *a) 1491*e5918d7dSYoshinori Sato { 1492*e5918d7dSYoshinori Sato TCGv tmp; 1493*e5918d7dSYoshinori Sato tmp = tcg_temp_new(); 1494*e5918d7dSYoshinori Sato tcg_gen_andi_i32(tmp, cpu_regs[a->rd], 0x00000001); 1495*e5918d7dSYoshinori Sato tcg_gen_shri_i32(cpu_regs[a->rd], cpu_regs[a->rd], 1); 1496*e5918d7dSYoshinori Sato tcg_gen_shli_i32(cpu_psw_c, cpu_psw_c, 31); 1497*e5918d7dSYoshinori Sato tcg_gen_or_i32(cpu_regs[a->rd], cpu_regs[a->rd], cpu_psw_c); 1498*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_psw_c, tmp); 1499*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_psw_z, cpu_regs[a->rd]); 1500*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_psw_s, cpu_regs[a->rd]); 1501*e5918d7dSYoshinori Sato return true; 1502*e5918d7dSYoshinori Sato } 1503*e5918d7dSYoshinori Sato 1504*e5918d7dSYoshinori Sato enum {ROTR = 0, ROTL = 1}; 1505*e5918d7dSYoshinori Sato enum {ROT_IMM = 0, ROT_REG = 1}; 1506*e5918d7dSYoshinori Sato static inline void rx_rot(int ir, int dir, int rd, int src) 1507*e5918d7dSYoshinori Sato { 1508*e5918d7dSYoshinori Sato switch (dir) { 1509*e5918d7dSYoshinori Sato case ROTL: 1510*e5918d7dSYoshinori Sato if (ir == ROT_IMM) { 1511*e5918d7dSYoshinori Sato tcg_gen_rotli_i32(cpu_regs[rd], cpu_regs[rd], src); 1512*e5918d7dSYoshinori Sato } else { 1513*e5918d7dSYoshinori Sato tcg_gen_rotl_i32(cpu_regs[rd], cpu_regs[rd], cpu_regs[src]); 1514*e5918d7dSYoshinori Sato } 1515*e5918d7dSYoshinori Sato tcg_gen_andi_i32(cpu_psw_c, cpu_regs[rd], 0x00000001); 1516*e5918d7dSYoshinori Sato break; 1517*e5918d7dSYoshinori Sato case ROTR: 1518*e5918d7dSYoshinori Sato if (ir == ROT_IMM) { 1519*e5918d7dSYoshinori Sato tcg_gen_rotri_i32(cpu_regs[rd], cpu_regs[rd], src); 1520*e5918d7dSYoshinori Sato } else { 1521*e5918d7dSYoshinori Sato tcg_gen_rotr_i32(cpu_regs[rd], cpu_regs[rd], cpu_regs[src]); 1522*e5918d7dSYoshinori Sato } 1523*e5918d7dSYoshinori Sato tcg_gen_shri_i32(cpu_psw_c, cpu_regs[rd], 31); 1524*e5918d7dSYoshinori Sato break; 1525*e5918d7dSYoshinori Sato } 1526*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_psw_z, cpu_regs[rd]); 1527*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_psw_s, cpu_regs[rd]); 1528*e5918d7dSYoshinori Sato } 1529*e5918d7dSYoshinori Sato 1530*e5918d7dSYoshinori Sato /* rotl #imm, rd */ 1531*e5918d7dSYoshinori Sato static bool trans_ROTL_ir(DisasContext *ctx, arg_ROTL_ir *a) 1532*e5918d7dSYoshinori Sato { 1533*e5918d7dSYoshinori Sato rx_rot(ROT_IMM, ROTL, a->rd, a->imm); 1534*e5918d7dSYoshinori Sato return true; 1535*e5918d7dSYoshinori Sato } 1536*e5918d7dSYoshinori Sato 1537*e5918d7dSYoshinori Sato /* rotl rs, rd */ 1538*e5918d7dSYoshinori Sato static bool trans_ROTL_rr(DisasContext *ctx, arg_ROTL_rr *a) 1539*e5918d7dSYoshinori Sato { 1540*e5918d7dSYoshinori Sato rx_rot(ROT_REG, ROTL, a->rd, a->rs); 1541*e5918d7dSYoshinori Sato return true; 1542*e5918d7dSYoshinori Sato } 1543*e5918d7dSYoshinori Sato 1544*e5918d7dSYoshinori Sato /* rotr #imm, rd */ 1545*e5918d7dSYoshinori Sato static bool trans_ROTR_ir(DisasContext *ctx, arg_ROTR_ir *a) 1546*e5918d7dSYoshinori Sato { 1547*e5918d7dSYoshinori Sato rx_rot(ROT_IMM, ROTR, a->rd, a->imm); 1548*e5918d7dSYoshinori Sato return true; 1549*e5918d7dSYoshinori Sato } 1550*e5918d7dSYoshinori Sato 1551*e5918d7dSYoshinori Sato /* rotr rs, rd */ 1552*e5918d7dSYoshinori Sato static bool trans_ROTR_rr(DisasContext *ctx, arg_ROTR_rr *a) 1553*e5918d7dSYoshinori Sato { 1554*e5918d7dSYoshinori Sato rx_rot(ROT_REG, ROTR, a->rd, a->rs); 1555*e5918d7dSYoshinori Sato return true; 1556*e5918d7dSYoshinori Sato } 1557*e5918d7dSYoshinori Sato 1558*e5918d7dSYoshinori Sato /* revl rs, rd */ 1559*e5918d7dSYoshinori Sato static bool trans_REVL(DisasContext *ctx, arg_REVL *a) 1560*e5918d7dSYoshinori Sato { 1561*e5918d7dSYoshinori Sato tcg_gen_bswap32_i32(cpu_regs[a->rd], cpu_regs[a->rs]); 1562*e5918d7dSYoshinori Sato return true; 1563*e5918d7dSYoshinori Sato } 1564*e5918d7dSYoshinori Sato 1565*e5918d7dSYoshinori Sato /* revw rs, rd */ 1566*e5918d7dSYoshinori Sato static bool trans_REVW(DisasContext *ctx, arg_REVW *a) 1567*e5918d7dSYoshinori Sato { 1568*e5918d7dSYoshinori Sato TCGv tmp; 1569*e5918d7dSYoshinori Sato tmp = tcg_temp_new(); 1570*e5918d7dSYoshinori Sato tcg_gen_andi_i32(tmp, cpu_regs[a->rs], 0x00ff00ff); 1571*e5918d7dSYoshinori Sato tcg_gen_shli_i32(tmp, tmp, 8); 1572*e5918d7dSYoshinori Sato tcg_gen_shri_i32(cpu_regs[a->rd], cpu_regs[a->rs], 8); 1573*e5918d7dSYoshinori Sato tcg_gen_andi_i32(cpu_regs[a->rd], cpu_regs[a->rd], 0x00ff00ff); 1574*e5918d7dSYoshinori Sato tcg_gen_or_i32(cpu_regs[a->rd], cpu_regs[a->rd], tmp); 1575*e5918d7dSYoshinori Sato tcg_temp_free(tmp); 1576*e5918d7dSYoshinori Sato return true; 1577*e5918d7dSYoshinori Sato } 1578*e5918d7dSYoshinori Sato 1579*e5918d7dSYoshinori Sato /* conditional branch helper */ 1580*e5918d7dSYoshinori Sato static void rx_bcnd_main(DisasContext *ctx, int cd, int dst) 1581*e5918d7dSYoshinori Sato { 1582*e5918d7dSYoshinori Sato DisasCompare dc; 1583*e5918d7dSYoshinori Sato TCGLabel *t, *done; 1584*e5918d7dSYoshinori Sato 1585*e5918d7dSYoshinori Sato switch (cd) { 1586*e5918d7dSYoshinori Sato case 0 ... 13: 1587*e5918d7dSYoshinori Sato dc.temp = tcg_temp_new(); 1588*e5918d7dSYoshinori Sato psw_cond(&dc, cd); 1589*e5918d7dSYoshinori Sato t = gen_new_label(); 1590*e5918d7dSYoshinori Sato done = gen_new_label(); 1591*e5918d7dSYoshinori Sato tcg_gen_brcondi_i32(dc.cond, dc.value, 0, t); 1592*e5918d7dSYoshinori Sato gen_goto_tb(ctx, 0, ctx->base.pc_next); 1593*e5918d7dSYoshinori Sato tcg_gen_br(done); 1594*e5918d7dSYoshinori Sato gen_set_label(t); 1595*e5918d7dSYoshinori Sato gen_goto_tb(ctx, 1, ctx->pc + dst); 1596*e5918d7dSYoshinori Sato gen_set_label(done); 1597*e5918d7dSYoshinori Sato tcg_temp_free(dc.temp); 1598*e5918d7dSYoshinori Sato break; 1599*e5918d7dSYoshinori Sato case 14: 1600*e5918d7dSYoshinori Sato /* always true case */ 1601*e5918d7dSYoshinori Sato gen_goto_tb(ctx, 0, ctx->pc + dst); 1602*e5918d7dSYoshinori Sato break; 1603*e5918d7dSYoshinori Sato case 15: 1604*e5918d7dSYoshinori Sato /* always false case */ 1605*e5918d7dSYoshinori Sato /* Nothing do */ 1606*e5918d7dSYoshinori Sato break; 1607*e5918d7dSYoshinori Sato } 1608*e5918d7dSYoshinori Sato } 1609*e5918d7dSYoshinori Sato 1610*e5918d7dSYoshinori Sato /* beq dsp:3 / bne dsp:3 */ 1611*e5918d7dSYoshinori Sato /* beq dsp:8 / bne dsp:8 */ 1612*e5918d7dSYoshinori Sato /* bc dsp:8 / bnc dsp:8 */ 1613*e5918d7dSYoshinori Sato /* bgtu dsp:8 / bleu dsp:8 */ 1614*e5918d7dSYoshinori Sato /* bpz dsp:8 / bn dsp:8 */ 1615*e5918d7dSYoshinori Sato /* bge dsp:8 / blt dsp:8 */ 1616*e5918d7dSYoshinori Sato /* bgt dsp:8 / ble dsp:8 */ 1617*e5918d7dSYoshinori Sato /* bo dsp:8 / bno dsp:8 */ 1618*e5918d7dSYoshinori Sato /* beq dsp:16 / bne dsp:16 */ 1619*e5918d7dSYoshinori Sato static bool trans_BCnd(DisasContext *ctx, arg_BCnd *a) 1620*e5918d7dSYoshinori Sato { 1621*e5918d7dSYoshinori Sato rx_bcnd_main(ctx, a->cd, a->dsp); 1622*e5918d7dSYoshinori Sato return true; 1623*e5918d7dSYoshinori Sato } 1624*e5918d7dSYoshinori Sato 1625*e5918d7dSYoshinori Sato /* bra dsp:3 */ 1626*e5918d7dSYoshinori Sato /* bra dsp:8 */ 1627*e5918d7dSYoshinori Sato /* bra dsp:16 */ 1628*e5918d7dSYoshinori Sato /* bra dsp:24 */ 1629*e5918d7dSYoshinori Sato static bool trans_BRA(DisasContext *ctx, arg_BRA *a) 1630*e5918d7dSYoshinori Sato { 1631*e5918d7dSYoshinori Sato rx_bcnd_main(ctx, 14, a->dsp); 1632*e5918d7dSYoshinori Sato return true; 1633*e5918d7dSYoshinori Sato } 1634*e5918d7dSYoshinori Sato 1635*e5918d7dSYoshinori Sato /* bra rs */ 1636*e5918d7dSYoshinori Sato static bool trans_BRA_l(DisasContext *ctx, arg_BRA_l *a) 1637*e5918d7dSYoshinori Sato { 1638*e5918d7dSYoshinori Sato tcg_gen_addi_i32(cpu_pc, cpu_regs[a->rd], ctx->pc); 1639*e5918d7dSYoshinori Sato ctx->base.is_jmp = DISAS_JUMP; 1640*e5918d7dSYoshinori Sato return true; 1641*e5918d7dSYoshinori Sato } 1642*e5918d7dSYoshinori Sato 1643*e5918d7dSYoshinori Sato static inline void rx_save_pc(DisasContext *ctx) 1644*e5918d7dSYoshinori Sato { 1645*e5918d7dSYoshinori Sato TCGv pc = tcg_const_i32(ctx->base.pc_next); 1646*e5918d7dSYoshinori Sato push(pc); 1647*e5918d7dSYoshinori Sato tcg_temp_free(pc); 1648*e5918d7dSYoshinori Sato } 1649*e5918d7dSYoshinori Sato 1650*e5918d7dSYoshinori Sato /* jmp rs */ 1651*e5918d7dSYoshinori Sato static bool trans_JMP(DisasContext *ctx, arg_JMP *a) 1652*e5918d7dSYoshinori Sato { 1653*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_pc, cpu_regs[a->rs]); 1654*e5918d7dSYoshinori Sato ctx->base.is_jmp = DISAS_JUMP; 1655*e5918d7dSYoshinori Sato return true; 1656*e5918d7dSYoshinori Sato } 1657*e5918d7dSYoshinori Sato 1658*e5918d7dSYoshinori Sato /* jsr rs */ 1659*e5918d7dSYoshinori Sato static bool trans_JSR(DisasContext *ctx, arg_JSR *a) 1660*e5918d7dSYoshinori Sato { 1661*e5918d7dSYoshinori Sato rx_save_pc(ctx); 1662*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_pc, cpu_regs[a->rs]); 1663*e5918d7dSYoshinori Sato ctx->base.is_jmp = DISAS_JUMP; 1664*e5918d7dSYoshinori Sato return true; 1665*e5918d7dSYoshinori Sato } 1666*e5918d7dSYoshinori Sato 1667*e5918d7dSYoshinori Sato /* bsr dsp:16 */ 1668*e5918d7dSYoshinori Sato /* bsr dsp:24 */ 1669*e5918d7dSYoshinori Sato static bool trans_BSR(DisasContext *ctx, arg_BSR *a) 1670*e5918d7dSYoshinori Sato { 1671*e5918d7dSYoshinori Sato rx_save_pc(ctx); 1672*e5918d7dSYoshinori Sato rx_bcnd_main(ctx, 14, a->dsp); 1673*e5918d7dSYoshinori Sato return true; 1674*e5918d7dSYoshinori Sato } 1675*e5918d7dSYoshinori Sato 1676*e5918d7dSYoshinori Sato /* bsr rs */ 1677*e5918d7dSYoshinori Sato static bool trans_BSR_l(DisasContext *ctx, arg_BSR_l *a) 1678*e5918d7dSYoshinori Sato { 1679*e5918d7dSYoshinori Sato rx_save_pc(ctx); 1680*e5918d7dSYoshinori Sato tcg_gen_addi_i32(cpu_pc, cpu_regs[a->rd], ctx->pc); 1681*e5918d7dSYoshinori Sato ctx->base.is_jmp = DISAS_JUMP; 1682*e5918d7dSYoshinori Sato return true; 1683*e5918d7dSYoshinori Sato } 1684*e5918d7dSYoshinori Sato 1685*e5918d7dSYoshinori Sato /* rts */ 1686*e5918d7dSYoshinori Sato static bool trans_RTS(DisasContext *ctx, arg_RTS *a) 1687*e5918d7dSYoshinori Sato { 1688*e5918d7dSYoshinori Sato pop(cpu_pc); 1689*e5918d7dSYoshinori Sato ctx->base.is_jmp = DISAS_JUMP; 1690*e5918d7dSYoshinori Sato return true; 1691*e5918d7dSYoshinori Sato } 1692*e5918d7dSYoshinori Sato 1693*e5918d7dSYoshinori Sato /* nop */ 1694*e5918d7dSYoshinori Sato static bool trans_NOP(DisasContext *ctx, arg_NOP *a) 1695*e5918d7dSYoshinori Sato { 1696*e5918d7dSYoshinori Sato return true; 1697*e5918d7dSYoshinori Sato } 1698*e5918d7dSYoshinori Sato 1699*e5918d7dSYoshinori Sato /* scmpu */ 1700*e5918d7dSYoshinori Sato static bool trans_SCMPU(DisasContext *ctx, arg_SCMPU *a) 1701*e5918d7dSYoshinori Sato { 1702*e5918d7dSYoshinori Sato gen_helper_scmpu(cpu_env); 1703*e5918d7dSYoshinori Sato return true; 1704*e5918d7dSYoshinori Sato } 1705*e5918d7dSYoshinori Sato 1706*e5918d7dSYoshinori Sato /* smovu */ 1707*e5918d7dSYoshinori Sato static bool trans_SMOVU(DisasContext *ctx, arg_SMOVU *a) 1708*e5918d7dSYoshinori Sato { 1709*e5918d7dSYoshinori Sato gen_helper_smovu(cpu_env); 1710*e5918d7dSYoshinori Sato return true; 1711*e5918d7dSYoshinori Sato } 1712*e5918d7dSYoshinori Sato 1713*e5918d7dSYoshinori Sato /* smovf */ 1714*e5918d7dSYoshinori Sato static bool trans_SMOVF(DisasContext *ctx, arg_SMOVF *a) 1715*e5918d7dSYoshinori Sato { 1716*e5918d7dSYoshinori Sato gen_helper_smovf(cpu_env); 1717*e5918d7dSYoshinori Sato return true; 1718*e5918d7dSYoshinori Sato } 1719*e5918d7dSYoshinori Sato 1720*e5918d7dSYoshinori Sato /* smovb */ 1721*e5918d7dSYoshinori Sato static bool trans_SMOVB(DisasContext *ctx, arg_SMOVB *a) 1722*e5918d7dSYoshinori Sato { 1723*e5918d7dSYoshinori Sato gen_helper_smovb(cpu_env); 1724*e5918d7dSYoshinori Sato return true; 1725*e5918d7dSYoshinori Sato } 1726*e5918d7dSYoshinori Sato 1727*e5918d7dSYoshinori Sato #define STRING(op) \ 1728*e5918d7dSYoshinori Sato do { \ 1729*e5918d7dSYoshinori Sato TCGv size = tcg_const_i32(a->sz); \ 1730*e5918d7dSYoshinori Sato gen_helper_##op(cpu_env, size); \ 1731*e5918d7dSYoshinori Sato tcg_temp_free(size); \ 1732*e5918d7dSYoshinori Sato } while (0) 1733*e5918d7dSYoshinori Sato 1734*e5918d7dSYoshinori Sato /* suntile.<bwl> */ 1735*e5918d7dSYoshinori Sato static bool trans_SUNTIL(DisasContext *ctx, arg_SUNTIL *a) 1736*e5918d7dSYoshinori Sato { 1737*e5918d7dSYoshinori Sato STRING(suntil); 1738*e5918d7dSYoshinori Sato return true; 1739*e5918d7dSYoshinori Sato } 1740*e5918d7dSYoshinori Sato 1741*e5918d7dSYoshinori Sato /* swhile.<bwl> */ 1742*e5918d7dSYoshinori Sato static bool trans_SWHILE(DisasContext *ctx, arg_SWHILE *a) 1743*e5918d7dSYoshinori Sato { 1744*e5918d7dSYoshinori Sato STRING(swhile); 1745*e5918d7dSYoshinori Sato return true; 1746*e5918d7dSYoshinori Sato } 1747*e5918d7dSYoshinori Sato /* sstr.<bwl> */ 1748*e5918d7dSYoshinori Sato static bool trans_SSTR(DisasContext *ctx, arg_SSTR *a) 1749*e5918d7dSYoshinori Sato { 1750*e5918d7dSYoshinori Sato STRING(sstr); 1751*e5918d7dSYoshinori Sato return true; 1752*e5918d7dSYoshinori Sato } 1753*e5918d7dSYoshinori Sato 1754*e5918d7dSYoshinori Sato /* rmpa.<bwl> */ 1755*e5918d7dSYoshinori Sato static bool trans_RMPA(DisasContext *ctx, arg_RMPA *a) 1756*e5918d7dSYoshinori Sato { 1757*e5918d7dSYoshinori Sato STRING(rmpa); 1758*e5918d7dSYoshinori Sato return true; 1759*e5918d7dSYoshinori Sato } 1760*e5918d7dSYoshinori Sato 1761*e5918d7dSYoshinori Sato static void rx_mul64hi(TCGv_i64 ret, int rs, int rs2) 1762*e5918d7dSYoshinori Sato { 1763*e5918d7dSYoshinori Sato TCGv_i64 tmp0, tmp1; 1764*e5918d7dSYoshinori Sato tmp0 = tcg_temp_new_i64(); 1765*e5918d7dSYoshinori Sato tmp1 = tcg_temp_new_i64(); 1766*e5918d7dSYoshinori Sato tcg_gen_ext_i32_i64(tmp0, cpu_regs[rs]); 1767*e5918d7dSYoshinori Sato tcg_gen_sari_i64(tmp0, tmp0, 16); 1768*e5918d7dSYoshinori Sato tcg_gen_ext_i32_i64(tmp1, cpu_regs[rs2]); 1769*e5918d7dSYoshinori Sato tcg_gen_sari_i64(tmp1, tmp1, 16); 1770*e5918d7dSYoshinori Sato tcg_gen_mul_i64(ret, tmp0, tmp1); 1771*e5918d7dSYoshinori Sato tcg_gen_shli_i64(ret, ret, 16); 1772*e5918d7dSYoshinori Sato tcg_temp_free_i64(tmp0); 1773*e5918d7dSYoshinori Sato tcg_temp_free_i64(tmp1); 1774*e5918d7dSYoshinori Sato } 1775*e5918d7dSYoshinori Sato 1776*e5918d7dSYoshinori Sato static void rx_mul64lo(TCGv_i64 ret, int rs, int rs2) 1777*e5918d7dSYoshinori Sato { 1778*e5918d7dSYoshinori Sato TCGv_i64 tmp0, tmp1; 1779*e5918d7dSYoshinori Sato tmp0 = tcg_temp_new_i64(); 1780*e5918d7dSYoshinori Sato tmp1 = tcg_temp_new_i64(); 1781*e5918d7dSYoshinori Sato tcg_gen_ext_i32_i64(tmp0, cpu_regs[rs]); 1782*e5918d7dSYoshinori Sato tcg_gen_ext16s_i64(tmp0, tmp0); 1783*e5918d7dSYoshinori Sato tcg_gen_ext_i32_i64(tmp1, cpu_regs[rs2]); 1784*e5918d7dSYoshinori Sato tcg_gen_ext16s_i64(tmp1, tmp1); 1785*e5918d7dSYoshinori Sato tcg_gen_mul_i64(ret, tmp0, tmp1); 1786*e5918d7dSYoshinori Sato tcg_gen_shli_i64(ret, ret, 16); 1787*e5918d7dSYoshinori Sato tcg_temp_free_i64(tmp0); 1788*e5918d7dSYoshinori Sato tcg_temp_free_i64(tmp1); 1789*e5918d7dSYoshinori Sato } 1790*e5918d7dSYoshinori Sato 1791*e5918d7dSYoshinori Sato /* mulhi rs,rs2 */ 1792*e5918d7dSYoshinori Sato static bool trans_MULHI(DisasContext *ctx, arg_MULHI *a) 1793*e5918d7dSYoshinori Sato { 1794*e5918d7dSYoshinori Sato rx_mul64hi(cpu_acc, a->rs, a->rs2); 1795*e5918d7dSYoshinori Sato return true; 1796*e5918d7dSYoshinori Sato } 1797*e5918d7dSYoshinori Sato 1798*e5918d7dSYoshinori Sato /* mullo rs,rs2 */ 1799*e5918d7dSYoshinori Sato static bool trans_MULLO(DisasContext *ctx, arg_MULLO *a) 1800*e5918d7dSYoshinori Sato { 1801*e5918d7dSYoshinori Sato rx_mul64lo(cpu_acc, a->rs, a->rs2); 1802*e5918d7dSYoshinori Sato return true; 1803*e5918d7dSYoshinori Sato } 1804*e5918d7dSYoshinori Sato 1805*e5918d7dSYoshinori Sato /* machi rs,rs2 */ 1806*e5918d7dSYoshinori Sato static bool trans_MACHI(DisasContext *ctx, arg_MACHI *a) 1807*e5918d7dSYoshinori Sato { 1808*e5918d7dSYoshinori Sato TCGv_i64 tmp; 1809*e5918d7dSYoshinori Sato tmp = tcg_temp_new_i64(); 1810*e5918d7dSYoshinori Sato rx_mul64hi(tmp, a->rs, a->rs2); 1811*e5918d7dSYoshinori Sato tcg_gen_add_i64(cpu_acc, cpu_acc, tmp); 1812*e5918d7dSYoshinori Sato tcg_temp_free_i64(tmp); 1813*e5918d7dSYoshinori Sato return true; 1814*e5918d7dSYoshinori Sato } 1815*e5918d7dSYoshinori Sato 1816*e5918d7dSYoshinori Sato /* maclo rs,rs2 */ 1817*e5918d7dSYoshinori Sato static bool trans_MACLO(DisasContext *ctx, arg_MACLO *a) 1818*e5918d7dSYoshinori Sato { 1819*e5918d7dSYoshinori Sato TCGv_i64 tmp; 1820*e5918d7dSYoshinori Sato tmp = tcg_temp_new_i64(); 1821*e5918d7dSYoshinori Sato rx_mul64lo(tmp, a->rs, a->rs2); 1822*e5918d7dSYoshinori Sato tcg_gen_add_i64(cpu_acc, cpu_acc, tmp); 1823*e5918d7dSYoshinori Sato tcg_temp_free_i64(tmp); 1824*e5918d7dSYoshinori Sato return true; 1825*e5918d7dSYoshinori Sato } 1826*e5918d7dSYoshinori Sato 1827*e5918d7dSYoshinori Sato /* mvfachi rd */ 1828*e5918d7dSYoshinori Sato static bool trans_MVFACHI(DisasContext *ctx, arg_MVFACHI *a) 1829*e5918d7dSYoshinori Sato { 1830*e5918d7dSYoshinori Sato tcg_gen_extrh_i64_i32(cpu_regs[a->rd], cpu_acc); 1831*e5918d7dSYoshinori Sato return true; 1832*e5918d7dSYoshinori Sato } 1833*e5918d7dSYoshinori Sato 1834*e5918d7dSYoshinori Sato /* mvfacmi rd */ 1835*e5918d7dSYoshinori Sato static bool trans_MVFACMI(DisasContext *ctx, arg_MVFACMI *a) 1836*e5918d7dSYoshinori Sato { 1837*e5918d7dSYoshinori Sato TCGv_i64 rd64; 1838*e5918d7dSYoshinori Sato rd64 = tcg_temp_new_i64(); 1839*e5918d7dSYoshinori Sato tcg_gen_extract_i64(rd64, cpu_acc, 16, 32); 1840*e5918d7dSYoshinori Sato tcg_gen_extrl_i64_i32(cpu_regs[a->rd], rd64); 1841*e5918d7dSYoshinori Sato tcg_temp_free_i64(rd64); 1842*e5918d7dSYoshinori Sato return true; 1843*e5918d7dSYoshinori Sato } 1844*e5918d7dSYoshinori Sato 1845*e5918d7dSYoshinori Sato /* mvtachi rs */ 1846*e5918d7dSYoshinori Sato static bool trans_MVTACHI(DisasContext *ctx, arg_MVTACHI *a) 1847*e5918d7dSYoshinori Sato { 1848*e5918d7dSYoshinori Sato TCGv_i64 rs64; 1849*e5918d7dSYoshinori Sato rs64 = tcg_temp_new_i64(); 1850*e5918d7dSYoshinori Sato tcg_gen_extu_i32_i64(rs64, cpu_regs[a->rs]); 1851*e5918d7dSYoshinori Sato tcg_gen_deposit_i64(cpu_acc, cpu_acc, rs64, 32, 32); 1852*e5918d7dSYoshinori Sato tcg_temp_free_i64(rs64); 1853*e5918d7dSYoshinori Sato return true; 1854*e5918d7dSYoshinori Sato } 1855*e5918d7dSYoshinori Sato 1856*e5918d7dSYoshinori Sato /* mvtaclo rs */ 1857*e5918d7dSYoshinori Sato static bool trans_MVTACLO(DisasContext *ctx, arg_MVTACLO *a) 1858*e5918d7dSYoshinori Sato { 1859*e5918d7dSYoshinori Sato TCGv_i64 rs64; 1860*e5918d7dSYoshinori Sato rs64 = tcg_temp_new_i64(); 1861*e5918d7dSYoshinori Sato tcg_gen_extu_i32_i64(rs64, cpu_regs[a->rs]); 1862*e5918d7dSYoshinori Sato tcg_gen_deposit_i64(cpu_acc, cpu_acc, rs64, 0, 32); 1863*e5918d7dSYoshinori Sato tcg_temp_free_i64(rs64); 1864*e5918d7dSYoshinori Sato return true; 1865*e5918d7dSYoshinori Sato } 1866*e5918d7dSYoshinori Sato 1867*e5918d7dSYoshinori Sato /* racw #imm */ 1868*e5918d7dSYoshinori Sato static bool trans_RACW(DisasContext *ctx, arg_RACW *a) 1869*e5918d7dSYoshinori Sato { 1870*e5918d7dSYoshinori Sato TCGv imm = tcg_const_i32(a->imm + 1); 1871*e5918d7dSYoshinori Sato gen_helper_racw(cpu_env, imm); 1872*e5918d7dSYoshinori Sato tcg_temp_free(imm); 1873*e5918d7dSYoshinori Sato return true; 1874*e5918d7dSYoshinori Sato } 1875*e5918d7dSYoshinori Sato 1876*e5918d7dSYoshinori Sato /* sat rd */ 1877*e5918d7dSYoshinori Sato static bool trans_SAT(DisasContext *ctx, arg_SAT *a) 1878*e5918d7dSYoshinori Sato { 1879*e5918d7dSYoshinori Sato TCGv tmp, z; 1880*e5918d7dSYoshinori Sato tmp = tcg_temp_new(); 1881*e5918d7dSYoshinori Sato z = tcg_const_i32(0); 1882*e5918d7dSYoshinori Sato /* S == 1 -> 0xffffffff / S == 0 -> 0x00000000 */ 1883*e5918d7dSYoshinori Sato tcg_gen_sari_i32(tmp, cpu_psw_s, 31); 1884*e5918d7dSYoshinori Sato /* S == 1 -> 0x7fffffff / S == 0 -> 0x80000000 */ 1885*e5918d7dSYoshinori Sato tcg_gen_xori_i32(tmp, tmp, 0x80000000); 1886*e5918d7dSYoshinori Sato tcg_gen_movcond_i32(TCG_COND_LT, cpu_regs[a->rd], 1887*e5918d7dSYoshinori Sato cpu_psw_o, z, tmp, cpu_regs[a->rd]); 1888*e5918d7dSYoshinori Sato tcg_temp_free(tmp); 1889*e5918d7dSYoshinori Sato tcg_temp_free(z); 1890*e5918d7dSYoshinori Sato return true; 1891*e5918d7dSYoshinori Sato } 1892*e5918d7dSYoshinori Sato 1893*e5918d7dSYoshinori Sato /* satr */ 1894*e5918d7dSYoshinori Sato static bool trans_SATR(DisasContext *ctx, arg_SATR *a) 1895*e5918d7dSYoshinori Sato { 1896*e5918d7dSYoshinori Sato gen_helper_satr(cpu_env); 1897*e5918d7dSYoshinori Sato return true; 1898*e5918d7dSYoshinori Sato } 1899*e5918d7dSYoshinori Sato 1900*e5918d7dSYoshinori Sato #define cat3(a, b, c) a##b##c 1901*e5918d7dSYoshinori Sato #define FOP(name, op) \ 1902*e5918d7dSYoshinori Sato static bool cat3(trans_, name, _ir)(DisasContext *ctx, \ 1903*e5918d7dSYoshinori Sato cat3(arg_, name, _ir) * a) \ 1904*e5918d7dSYoshinori Sato { \ 1905*e5918d7dSYoshinori Sato TCGv imm = tcg_const_i32(li(ctx, 0)); \ 1906*e5918d7dSYoshinori Sato gen_helper_##op(cpu_regs[a->rd], cpu_env, \ 1907*e5918d7dSYoshinori Sato cpu_regs[a->rd], imm); \ 1908*e5918d7dSYoshinori Sato tcg_temp_free(imm); \ 1909*e5918d7dSYoshinori Sato return true; \ 1910*e5918d7dSYoshinori Sato } \ 1911*e5918d7dSYoshinori Sato static bool cat3(trans_, name, _mr)(DisasContext *ctx, \ 1912*e5918d7dSYoshinori Sato cat3(arg_, name, _mr) * a) \ 1913*e5918d7dSYoshinori Sato { \ 1914*e5918d7dSYoshinori Sato TCGv val, mem; \ 1915*e5918d7dSYoshinori Sato mem = tcg_temp_new(); \ 1916*e5918d7dSYoshinori Sato val = rx_load_source(ctx, mem, a->ld, MO_32, a->rs); \ 1917*e5918d7dSYoshinori Sato gen_helper_##op(cpu_regs[a->rd], cpu_env, \ 1918*e5918d7dSYoshinori Sato cpu_regs[a->rd], val); \ 1919*e5918d7dSYoshinori Sato tcg_temp_free(mem); \ 1920*e5918d7dSYoshinori Sato return true; \ 1921*e5918d7dSYoshinori Sato } 1922*e5918d7dSYoshinori Sato 1923*e5918d7dSYoshinori Sato #define FCONVOP(name, op) \ 1924*e5918d7dSYoshinori Sato static bool trans_##name(DisasContext *ctx, arg_##name * a) \ 1925*e5918d7dSYoshinori Sato { \ 1926*e5918d7dSYoshinori Sato TCGv val, mem; \ 1927*e5918d7dSYoshinori Sato mem = tcg_temp_new(); \ 1928*e5918d7dSYoshinori Sato val = rx_load_source(ctx, mem, a->ld, MO_32, a->rs); \ 1929*e5918d7dSYoshinori Sato gen_helper_##op(cpu_regs[a->rd], cpu_env, val); \ 1930*e5918d7dSYoshinori Sato tcg_temp_free(mem); \ 1931*e5918d7dSYoshinori Sato return true; \ 1932*e5918d7dSYoshinori Sato } 1933*e5918d7dSYoshinori Sato 1934*e5918d7dSYoshinori Sato FOP(FADD, fadd) 1935*e5918d7dSYoshinori Sato FOP(FSUB, fsub) 1936*e5918d7dSYoshinori Sato FOP(FMUL, fmul) 1937*e5918d7dSYoshinori Sato FOP(FDIV, fdiv) 1938*e5918d7dSYoshinori Sato 1939*e5918d7dSYoshinori Sato /* fcmp #imm, rd */ 1940*e5918d7dSYoshinori Sato static bool trans_FCMP_ir(DisasContext *ctx, arg_FCMP_ir * a) 1941*e5918d7dSYoshinori Sato { 1942*e5918d7dSYoshinori Sato TCGv imm = tcg_const_i32(li(ctx, 0)); 1943*e5918d7dSYoshinori Sato gen_helper_fcmp(cpu_env, cpu_regs[a->rd], imm); 1944*e5918d7dSYoshinori Sato tcg_temp_free(imm); 1945*e5918d7dSYoshinori Sato return true; 1946*e5918d7dSYoshinori Sato } 1947*e5918d7dSYoshinori Sato 1948*e5918d7dSYoshinori Sato /* fcmp dsp[rs], rd */ 1949*e5918d7dSYoshinori Sato /* fcmp rs, rd */ 1950*e5918d7dSYoshinori Sato static bool trans_FCMP_mr(DisasContext *ctx, arg_FCMP_mr *a) 1951*e5918d7dSYoshinori Sato { 1952*e5918d7dSYoshinori Sato TCGv val, mem; 1953*e5918d7dSYoshinori Sato mem = tcg_temp_new(); 1954*e5918d7dSYoshinori Sato val = rx_load_source(ctx, mem, a->ld, MO_32, a->rs); 1955*e5918d7dSYoshinori Sato gen_helper_fcmp(cpu_env, cpu_regs[a->rd], val); 1956*e5918d7dSYoshinori Sato tcg_temp_free(mem); 1957*e5918d7dSYoshinori Sato return true; 1958*e5918d7dSYoshinori Sato } 1959*e5918d7dSYoshinori Sato 1960*e5918d7dSYoshinori Sato FCONVOP(FTOI, ftoi) 1961*e5918d7dSYoshinori Sato FCONVOP(ROUND, round) 1962*e5918d7dSYoshinori Sato 1963*e5918d7dSYoshinori Sato /* itof rs, rd */ 1964*e5918d7dSYoshinori Sato /* itof dsp[rs], rd */ 1965*e5918d7dSYoshinori Sato static bool trans_ITOF(DisasContext *ctx, arg_ITOF * a) 1966*e5918d7dSYoshinori Sato { 1967*e5918d7dSYoshinori Sato TCGv val, mem; 1968*e5918d7dSYoshinori Sato mem = tcg_temp_new(); 1969*e5918d7dSYoshinori Sato val = rx_load_source(ctx, mem, a->ld, a->mi, a->rs); 1970*e5918d7dSYoshinori Sato gen_helper_itof(cpu_regs[a->rd], cpu_env, val); 1971*e5918d7dSYoshinori Sato tcg_temp_free(mem); 1972*e5918d7dSYoshinori Sato return true; 1973*e5918d7dSYoshinori Sato } 1974*e5918d7dSYoshinori Sato 1975*e5918d7dSYoshinori Sato static void rx_bsetm(TCGv mem, TCGv mask) 1976*e5918d7dSYoshinori Sato { 1977*e5918d7dSYoshinori Sato TCGv val; 1978*e5918d7dSYoshinori Sato val = tcg_temp_new(); 1979*e5918d7dSYoshinori Sato rx_gen_ld(MO_8, val, mem); 1980*e5918d7dSYoshinori Sato tcg_gen_or_i32(val, val, mask); 1981*e5918d7dSYoshinori Sato rx_gen_st(MO_8, val, mem); 1982*e5918d7dSYoshinori Sato tcg_temp_free(val); 1983*e5918d7dSYoshinori Sato } 1984*e5918d7dSYoshinori Sato 1985*e5918d7dSYoshinori Sato static void rx_bclrm(TCGv mem, TCGv mask) 1986*e5918d7dSYoshinori Sato { 1987*e5918d7dSYoshinori Sato TCGv val; 1988*e5918d7dSYoshinori Sato val = tcg_temp_new(); 1989*e5918d7dSYoshinori Sato rx_gen_ld(MO_8, val, mem); 1990*e5918d7dSYoshinori Sato tcg_gen_andc_i32(val, val, mask); 1991*e5918d7dSYoshinori Sato rx_gen_st(MO_8, val, mem); 1992*e5918d7dSYoshinori Sato tcg_temp_free(val); 1993*e5918d7dSYoshinori Sato } 1994*e5918d7dSYoshinori Sato 1995*e5918d7dSYoshinori Sato static void rx_btstm(TCGv mem, TCGv mask) 1996*e5918d7dSYoshinori Sato { 1997*e5918d7dSYoshinori Sato TCGv val; 1998*e5918d7dSYoshinori Sato val = tcg_temp_new(); 1999*e5918d7dSYoshinori Sato rx_gen_ld(MO_8, val, mem); 2000*e5918d7dSYoshinori Sato tcg_gen_and_i32(val, val, mask); 2001*e5918d7dSYoshinori Sato tcg_gen_setcondi_i32(TCG_COND_NE, cpu_psw_c, val, 0); 2002*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_psw_z, cpu_psw_c); 2003*e5918d7dSYoshinori Sato tcg_temp_free(val); 2004*e5918d7dSYoshinori Sato } 2005*e5918d7dSYoshinori Sato 2006*e5918d7dSYoshinori Sato static void rx_bnotm(TCGv mem, TCGv mask) 2007*e5918d7dSYoshinori Sato { 2008*e5918d7dSYoshinori Sato TCGv val; 2009*e5918d7dSYoshinori Sato val = tcg_temp_new(); 2010*e5918d7dSYoshinori Sato rx_gen_ld(MO_8, val, mem); 2011*e5918d7dSYoshinori Sato tcg_gen_xor_i32(val, val, mask); 2012*e5918d7dSYoshinori Sato rx_gen_st(MO_8, val, mem); 2013*e5918d7dSYoshinori Sato tcg_temp_free(val); 2014*e5918d7dSYoshinori Sato } 2015*e5918d7dSYoshinori Sato 2016*e5918d7dSYoshinori Sato static void rx_bsetr(TCGv reg, TCGv mask) 2017*e5918d7dSYoshinori Sato { 2018*e5918d7dSYoshinori Sato tcg_gen_or_i32(reg, reg, mask); 2019*e5918d7dSYoshinori Sato } 2020*e5918d7dSYoshinori Sato 2021*e5918d7dSYoshinori Sato static void rx_bclrr(TCGv reg, TCGv mask) 2022*e5918d7dSYoshinori Sato { 2023*e5918d7dSYoshinori Sato tcg_gen_andc_i32(reg, reg, mask); 2024*e5918d7dSYoshinori Sato } 2025*e5918d7dSYoshinori Sato 2026*e5918d7dSYoshinori Sato static inline void rx_btstr(TCGv reg, TCGv mask) 2027*e5918d7dSYoshinori Sato { 2028*e5918d7dSYoshinori Sato TCGv t0; 2029*e5918d7dSYoshinori Sato t0 = tcg_temp_new(); 2030*e5918d7dSYoshinori Sato tcg_gen_and_i32(t0, reg, mask); 2031*e5918d7dSYoshinori Sato tcg_gen_setcondi_i32(TCG_COND_NE, cpu_psw_c, t0, 0); 2032*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_psw_z, cpu_psw_c); 2033*e5918d7dSYoshinori Sato tcg_temp_free(t0); 2034*e5918d7dSYoshinori Sato } 2035*e5918d7dSYoshinori Sato 2036*e5918d7dSYoshinori Sato static inline void rx_bnotr(TCGv reg, TCGv mask) 2037*e5918d7dSYoshinori Sato { 2038*e5918d7dSYoshinori Sato tcg_gen_xor_i32(reg, reg, mask); 2039*e5918d7dSYoshinori Sato } 2040*e5918d7dSYoshinori Sato 2041*e5918d7dSYoshinori Sato #define BITOP(name, op) \ 2042*e5918d7dSYoshinori Sato static bool cat3(trans_, name, _im)(DisasContext *ctx, \ 2043*e5918d7dSYoshinori Sato cat3(arg_, name, _im) * a) \ 2044*e5918d7dSYoshinori Sato { \ 2045*e5918d7dSYoshinori Sato TCGv mask, mem, addr; \ 2046*e5918d7dSYoshinori Sato mem = tcg_temp_new(); \ 2047*e5918d7dSYoshinori Sato mask = tcg_const_i32(1 << a->imm); \ 2048*e5918d7dSYoshinori Sato addr = rx_index_addr(ctx, mem, a->ld, MO_8, a->rs); \ 2049*e5918d7dSYoshinori Sato cat3(rx_, op, m)(addr, mask); \ 2050*e5918d7dSYoshinori Sato tcg_temp_free(mask); \ 2051*e5918d7dSYoshinori Sato tcg_temp_free(mem); \ 2052*e5918d7dSYoshinori Sato return true; \ 2053*e5918d7dSYoshinori Sato } \ 2054*e5918d7dSYoshinori Sato static bool cat3(trans_, name, _ir)(DisasContext *ctx, \ 2055*e5918d7dSYoshinori Sato cat3(arg_, name, _ir) * a) \ 2056*e5918d7dSYoshinori Sato { \ 2057*e5918d7dSYoshinori Sato TCGv mask; \ 2058*e5918d7dSYoshinori Sato mask = tcg_const_i32(1 << a->imm); \ 2059*e5918d7dSYoshinori Sato cat3(rx_, op, r)(cpu_regs[a->rd], mask); \ 2060*e5918d7dSYoshinori Sato tcg_temp_free(mask); \ 2061*e5918d7dSYoshinori Sato return true; \ 2062*e5918d7dSYoshinori Sato } \ 2063*e5918d7dSYoshinori Sato static bool cat3(trans_, name, _rr)(DisasContext *ctx, \ 2064*e5918d7dSYoshinori Sato cat3(arg_, name, _rr) * a) \ 2065*e5918d7dSYoshinori Sato { \ 2066*e5918d7dSYoshinori Sato TCGv mask, b; \ 2067*e5918d7dSYoshinori Sato mask = tcg_const_i32(1); \ 2068*e5918d7dSYoshinori Sato b = tcg_temp_new(); \ 2069*e5918d7dSYoshinori Sato tcg_gen_andi_i32(b, cpu_regs[a->rs], 31); \ 2070*e5918d7dSYoshinori Sato tcg_gen_shl_i32(mask, mask, b); \ 2071*e5918d7dSYoshinori Sato cat3(rx_, op, r)(cpu_regs[a->rd], mask); \ 2072*e5918d7dSYoshinori Sato tcg_temp_free(mask); \ 2073*e5918d7dSYoshinori Sato tcg_temp_free(b); \ 2074*e5918d7dSYoshinori Sato return true; \ 2075*e5918d7dSYoshinori Sato } \ 2076*e5918d7dSYoshinori Sato static bool cat3(trans_, name, _rm)(DisasContext *ctx, \ 2077*e5918d7dSYoshinori Sato cat3(arg_, name, _rm) * a) \ 2078*e5918d7dSYoshinori Sato { \ 2079*e5918d7dSYoshinori Sato TCGv mask, mem, addr, b; \ 2080*e5918d7dSYoshinori Sato mask = tcg_const_i32(1); \ 2081*e5918d7dSYoshinori Sato b = tcg_temp_new(); \ 2082*e5918d7dSYoshinori Sato tcg_gen_andi_i32(b, cpu_regs[a->rd], 7); \ 2083*e5918d7dSYoshinori Sato tcg_gen_shl_i32(mask, mask, b); \ 2084*e5918d7dSYoshinori Sato mem = tcg_temp_new(); \ 2085*e5918d7dSYoshinori Sato addr = rx_index_addr(ctx, mem, a->ld, MO_8, a->rs); \ 2086*e5918d7dSYoshinori Sato cat3(rx_, op, m)(addr, mask); \ 2087*e5918d7dSYoshinori Sato tcg_temp_free(mem); \ 2088*e5918d7dSYoshinori Sato tcg_temp_free(mask); \ 2089*e5918d7dSYoshinori Sato tcg_temp_free(b); \ 2090*e5918d7dSYoshinori Sato return true; \ 2091*e5918d7dSYoshinori Sato } 2092*e5918d7dSYoshinori Sato 2093*e5918d7dSYoshinori Sato BITOP(BSET, bset) 2094*e5918d7dSYoshinori Sato BITOP(BCLR, bclr) 2095*e5918d7dSYoshinori Sato BITOP(BTST, btst) 2096*e5918d7dSYoshinori Sato BITOP(BNOT, bnot) 2097*e5918d7dSYoshinori Sato 2098*e5918d7dSYoshinori Sato static inline void bmcnd_op(TCGv val, TCGCond cond, int pos) 2099*e5918d7dSYoshinori Sato { 2100*e5918d7dSYoshinori Sato TCGv bit; 2101*e5918d7dSYoshinori Sato DisasCompare dc; 2102*e5918d7dSYoshinori Sato dc.temp = tcg_temp_new(); 2103*e5918d7dSYoshinori Sato bit = tcg_temp_new(); 2104*e5918d7dSYoshinori Sato psw_cond(&dc, cond); 2105*e5918d7dSYoshinori Sato tcg_gen_andi_i32(val, val, ~(1 << pos)); 2106*e5918d7dSYoshinori Sato tcg_gen_setcondi_i32(dc.cond, bit, dc.value, 0); 2107*e5918d7dSYoshinori Sato tcg_gen_deposit_i32(val, val, bit, pos, 1); 2108*e5918d7dSYoshinori Sato tcg_temp_free(bit); 2109*e5918d7dSYoshinori Sato tcg_temp_free(dc.temp); 2110*e5918d7dSYoshinori Sato } 2111*e5918d7dSYoshinori Sato 2112*e5918d7dSYoshinori Sato /* bmcnd #imm, dsp[rd] */ 2113*e5918d7dSYoshinori Sato static bool trans_BMCnd_im(DisasContext *ctx, arg_BMCnd_im *a) 2114*e5918d7dSYoshinori Sato { 2115*e5918d7dSYoshinori Sato TCGv val, mem, addr; 2116*e5918d7dSYoshinori Sato val = tcg_temp_new(); 2117*e5918d7dSYoshinori Sato mem = tcg_temp_new(); 2118*e5918d7dSYoshinori Sato addr = rx_index_addr(ctx, mem, a->ld, MO_8, a->rd); 2119*e5918d7dSYoshinori Sato rx_gen_ld(MO_8, val, addr); 2120*e5918d7dSYoshinori Sato bmcnd_op(val, a->cd, a->imm); 2121*e5918d7dSYoshinori Sato rx_gen_st(MO_8, val, addr); 2122*e5918d7dSYoshinori Sato tcg_temp_free(val); 2123*e5918d7dSYoshinori Sato tcg_temp_free(mem); 2124*e5918d7dSYoshinori Sato return true; 2125*e5918d7dSYoshinori Sato } 2126*e5918d7dSYoshinori Sato 2127*e5918d7dSYoshinori Sato /* bmcond #imm, rd */ 2128*e5918d7dSYoshinori Sato static bool trans_BMCnd_ir(DisasContext *ctx, arg_BMCnd_ir *a) 2129*e5918d7dSYoshinori Sato { 2130*e5918d7dSYoshinori Sato bmcnd_op(cpu_regs[a->rd], a->cd, a->imm); 2131*e5918d7dSYoshinori Sato return true; 2132*e5918d7dSYoshinori Sato } 2133*e5918d7dSYoshinori Sato 2134*e5918d7dSYoshinori Sato enum { 2135*e5918d7dSYoshinori Sato PSW_C = 0, 2136*e5918d7dSYoshinori Sato PSW_Z = 1, 2137*e5918d7dSYoshinori Sato PSW_S = 2, 2138*e5918d7dSYoshinori Sato PSW_O = 3, 2139*e5918d7dSYoshinori Sato PSW_I = 8, 2140*e5918d7dSYoshinori Sato PSW_U = 9, 2141*e5918d7dSYoshinori Sato }; 2142*e5918d7dSYoshinori Sato 2143*e5918d7dSYoshinori Sato static inline void clrsetpsw(DisasContext *ctx, int cb, int val) 2144*e5918d7dSYoshinori Sato { 2145*e5918d7dSYoshinori Sato if (cb < 8) { 2146*e5918d7dSYoshinori Sato switch (cb) { 2147*e5918d7dSYoshinori Sato case PSW_C: 2148*e5918d7dSYoshinori Sato tcg_gen_movi_i32(cpu_psw_c, val); 2149*e5918d7dSYoshinori Sato break; 2150*e5918d7dSYoshinori Sato case PSW_Z: 2151*e5918d7dSYoshinori Sato tcg_gen_movi_i32(cpu_psw_z, val == 0); 2152*e5918d7dSYoshinori Sato break; 2153*e5918d7dSYoshinori Sato case PSW_S: 2154*e5918d7dSYoshinori Sato tcg_gen_movi_i32(cpu_psw_s, val ? -1 : 0); 2155*e5918d7dSYoshinori Sato break; 2156*e5918d7dSYoshinori Sato case PSW_O: 2157*e5918d7dSYoshinori Sato tcg_gen_movi_i32(cpu_psw_o, val << 31); 2158*e5918d7dSYoshinori Sato break; 2159*e5918d7dSYoshinori Sato default: 2160*e5918d7dSYoshinori Sato qemu_log_mask(LOG_GUEST_ERROR, "Invalid distination %d", cb); 2161*e5918d7dSYoshinori Sato break; 2162*e5918d7dSYoshinori Sato } 2163*e5918d7dSYoshinori Sato } else if (is_privileged(ctx, 0)) { 2164*e5918d7dSYoshinori Sato switch (cb) { 2165*e5918d7dSYoshinori Sato case PSW_I: 2166*e5918d7dSYoshinori Sato tcg_gen_movi_i32(cpu_psw_i, val); 2167*e5918d7dSYoshinori Sato ctx->base.is_jmp = DISAS_UPDATE; 2168*e5918d7dSYoshinori Sato break; 2169*e5918d7dSYoshinori Sato case PSW_U: 2170*e5918d7dSYoshinori Sato tcg_gen_movi_i32(cpu_psw_u, val); 2171*e5918d7dSYoshinori Sato break; 2172*e5918d7dSYoshinori Sato default: 2173*e5918d7dSYoshinori Sato qemu_log_mask(LOG_GUEST_ERROR, "Invalid distination %d", cb); 2174*e5918d7dSYoshinori Sato break; 2175*e5918d7dSYoshinori Sato } 2176*e5918d7dSYoshinori Sato } 2177*e5918d7dSYoshinori Sato } 2178*e5918d7dSYoshinori Sato 2179*e5918d7dSYoshinori Sato /* clrpsw psw */ 2180*e5918d7dSYoshinori Sato static bool trans_CLRPSW(DisasContext *ctx, arg_CLRPSW *a) 2181*e5918d7dSYoshinori Sato { 2182*e5918d7dSYoshinori Sato clrsetpsw(ctx, a->cb, 0); 2183*e5918d7dSYoshinori Sato return true; 2184*e5918d7dSYoshinori Sato } 2185*e5918d7dSYoshinori Sato 2186*e5918d7dSYoshinori Sato /* setpsw psw */ 2187*e5918d7dSYoshinori Sato static bool trans_SETPSW(DisasContext *ctx, arg_SETPSW *a) 2188*e5918d7dSYoshinori Sato { 2189*e5918d7dSYoshinori Sato clrsetpsw(ctx, a->cb, 1); 2190*e5918d7dSYoshinori Sato return true; 2191*e5918d7dSYoshinori Sato } 2192*e5918d7dSYoshinori Sato 2193*e5918d7dSYoshinori Sato /* mvtipl #imm */ 2194*e5918d7dSYoshinori Sato static bool trans_MVTIPL(DisasContext *ctx, arg_MVTIPL *a) 2195*e5918d7dSYoshinori Sato { 2196*e5918d7dSYoshinori Sato if (is_privileged(ctx, 1)) { 2197*e5918d7dSYoshinori Sato tcg_gen_movi_i32(cpu_psw_ipl, a->imm); 2198*e5918d7dSYoshinori Sato ctx->base.is_jmp = DISAS_UPDATE; 2199*e5918d7dSYoshinori Sato } 2200*e5918d7dSYoshinori Sato return true; 2201*e5918d7dSYoshinori Sato } 2202*e5918d7dSYoshinori Sato 2203*e5918d7dSYoshinori Sato /* mvtc #imm, rd */ 2204*e5918d7dSYoshinori Sato static bool trans_MVTC_i(DisasContext *ctx, arg_MVTC_i *a) 2205*e5918d7dSYoshinori Sato { 2206*e5918d7dSYoshinori Sato TCGv imm; 2207*e5918d7dSYoshinori Sato 2208*e5918d7dSYoshinori Sato imm = tcg_const_i32(a->imm); 2209*e5918d7dSYoshinori Sato move_to_cr(ctx, imm, a->cr); 2210*e5918d7dSYoshinori Sato if (a->cr == 0 && is_privileged(ctx, 0)) { 2211*e5918d7dSYoshinori Sato ctx->base.is_jmp = DISAS_UPDATE; 2212*e5918d7dSYoshinori Sato } 2213*e5918d7dSYoshinori Sato tcg_temp_free(imm); 2214*e5918d7dSYoshinori Sato return true; 2215*e5918d7dSYoshinori Sato } 2216*e5918d7dSYoshinori Sato 2217*e5918d7dSYoshinori Sato /* mvtc rs, rd */ 2218*e5918d7dSYoshinori Sato static bool trans_MVTC_r(DisasContext *ctx, arg_MVTC_r *a) 2219*e5918d7dSYoshinori Sato { 2220*e5918d7dSYoshinori Sato move_to_cr(ctx, cpu_regs[a->rs], a->cr); 2221*e5918d7dSYoshinori Sato if (a->cr == 0 && is_privileged(ctx, 0)) { 2222*e5918d7dSYoshinori Sato ctx->base.is_jmp = DISAS_UPDATE; 2223*e5918d7dSYoshinori Sato } 2224*e5918d7dSYoshinori Sato return true; 2225*e5918d7dSYoshinori Sato } 2226*e5918d7dSYoshinori Sato 2227*e5918d7dSYoshinori Sato /* mvfc rs, rd */ 2228*e5918d7dSYoshinori Sato static bool trans_MVFC(DisasContext *ctx, arg_MVFC *a) 2229*e5918d7dSYoshinori Sato { 2230*e5918d7dSYoshinori Sato move_from_cr(cpu_regs[a->rd], a->cr, ctx->pc); 2231*e5918d7dSYoshinori Sato return true; 2232*e5918d7dSYoshinori Sato } 2233*e5918d7dSYoshinori Sato 2234*e5918d7dSYoshinori Sato /* rtfi */ 2235*e5918d7dSYoshinori Sato static bool trans_RTFI(DisasContext *ctx, arg_RTFI *a) 2236*e5918d7dSYoshinori Sato { 2237*e5918d7dSYoshinori Sato TCGv psw; 2238*e5918d7dSYoshinori Sato if (is_privileged(ctx, 1)) { 2239*e5918d7dSYoshinori Sato psw = tcg_temp_new(); 2240*e5918d7dSYoshinori Sato tcg_gen_mov_i32(cpu_pc, cpu_bpc); 2241*e5918d7dSYoshinori Sato tcg_gen_mov_i32(psw, cpu_bpsw); 2242*e5918d7dSYoshinori Sato gen_helper_set_psw_rte(cpu_env, psw); 2243*e5918d7dSYoshinori Sato ctx->base.is_jmp = DISAS_EXIT; 2244*e5918d7dSYoshinori Sato tcg_temp_free(psw); 2245*e5918d7dSYoshinori Sato } 2246*e5918d7dSYoshinori Sato return true; 2247*e5918d7dSYoshinori Sato } 2248*e5918d7dSYoshinori Sato 2249*e5918d7dSYoshinori Sato /* rte */ 2250*e5918d7dSYoshinori Sato static bool trans_RTE(DisasContext *ctx, arg_RTE *a) 2251*e5918d7dSYoshinori Sato { 2252*e5918d7dSYoshinori Sato TCGv psw; 2253*e5918d7dSYoshinori Sato if (is_privileged(ctx, 1)) { 2254*e5918d7dSYoshinori Sato psw = tcg_temp_new(); 2255*e5918d7dSYoshinori Sato pop(cpu_pc); 2256*e5918d7dSYoshinori Sato pop(psw); 2257*e5918d7dSYoshinori Sato gen_helper_set_psw_rte(cpu_env, psw); 2258*e5918d7dSYoshinori Sato ctx->base.is_jmp = DISAS_EXIT; 2259*e5918d7dSYoshinori Sato tcg_temp_free(psw); 2260*e5918d7dSYoshinori Sato } 2261*e5918d7dSYoshinori Sato return true; 2262*e5918d7dSYoshinori Sato } 2263*e5918d7dSYoshinori Sato 2264*e5918d7dSYoshinori Sato /* brk */ 2265*e5918d7dSYoshinori Sato static bool trans_BRK(DisasContext *ctx, arg_BRK *a) 2266*e5918d7dSYoshinori Sato { 2267*e5918d7dSYoshinori Sato tcg_gen_movi_i32(cpu_pc, ctx->base.pc_next); 2268*e5918d7dSYoshinori Sato gen_helper_rxbrk(cpu_env); 2269*e5918d7dSYoshinori Sato ctx->base.is_jmp = DISAS_NORETURN; 2270*e5918d7dSYoshinori Sato return true; 2271*e5918d7dSYoshinori Sato } 2272*e5918d7dSYoshinori Sato 2273*e5918d7dSYoshinori Sato /* int #imm */ 2274*e5918d7dSYoshinori Sato static bool trans_INT(DisasContext *ctx, arg_INT *a) 2275*e5918d7dSYoshinori Sato { 2276*e5918d7dSYoshinori Sato TCGv vec; 2277*e5918d7dSYoshinori Sato 2278*e5918d7dSYoshinori Sato tcg_debug_assert(a->imm < 0x100); 2279*e5918d7dSYoshinori Sato vec = tcg_const_i32(a->imm); 2280*e5918d7dSYoshinori Sato tcg_gen_movi_i32(cpu_pc, ctx->base.pc_next); 2281*e5918d7dSYoshinori Sato gen_helper_rxint(cpu_env, vec); 2282*e5918d7dSYoshinori Sato tcg_temp_free(vec); 2283*e5918d7dSYoshinori Sato ctx->base.is_jmp = DISAS_NORETURN; 2284*e5918d7dSYoshinori Sato return true; 2285*e5918d7dSYoshinori Sato } 2286*e5918d7dSYoshinori Sato 2287*e5918d7dSYoshinori Sato /* wait */ 2288*e5918d7dSYoshinori Sato static bool trans_WAIT(DisasContext *ctx, arg_WAIT *a) 2289*e5918d7dSYoshinori Sato { 2290*e5918d7dSYoshinori Sato if (is_privileged(ctx, 1)) { 2291*e5918d7dSYoshinori Sato tcg_gen_addi_i32(cpu_pc, cpu_pc, 2); 2292*e5918d7dSYoshinori Sato gen_helper_wait(cpu_env); 2293*e5918d7dSYoshinori Sato } 2294*e5918d7dSYoshinori Sato return true; 2295*e5918d7dSYoshinori Sato } 2296*e5918d7dSYoshinori Sato 2297*e5918d7dSYoshinori Sato static void rx_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) 2298*e5918d7dSYoshinori Sato { 2299*e5918d7dSYoshinori Sato CPURXState *env = cs->env_ptr; 2300*e5918d7dSYoshinori Sato DisasContext *ctx = container_of(dcbase, DisasContext, base); 2301*e5918d7dSYoshinori Sato ctx->env = env; 2302*e5918d7dSYoshinori Sato } 2303*e5918d7dSYoshinori Sato 2304*e5918d7dSYoshinori Sato static void rx_tr_tb_start(DisasContextBase *dcbase, CPUState *cs) 2305*e5918d7dSYoshinori Sato { 2306*e5918d7dSYoshinori Sato } 2307*e5918d7dSYoshinori Sato 2308*e5918d7dSYoshinori Sato static void rx_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) 2309*e5918d7dSYoshinori Sato { 2310*e5918d7dSYoshinori Sato DisasContext *ctx = container_of(dcbase, DisasContext, base); 2311*e5918d7dSYoshinori Sato 2312*e5918d7dSYoshinori Sato tcg_gen_insn_start(ctx->base.pc_next); 2313*e5918d7dSYoshinori Sato } 2314*e5918d7dSYoshinori Sato 2315*e5918d7dSYoshinori Sato static bool rx_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs, 2316*e5918d7dSYoshinori Sato const CPUBreakpoint *bp) 2317*e5918d7dSYoshinori Sato { 2318*e5918d7dSYoshinori Sato DisasContext *ctx = container_of(dcbase, DisasContext, base); 2319*e5918d7dSYoshinori Sato 2320*e5918d7dSYoshinori Sato /* We have hit a breakpoint - make sure PC is up-to-date */ 2321*e5918d7dSYoshinori Sato tcg_gen_movi_i32(cpu_pc, ctx->base.pc_next); 2322*e5918d7dSYoshinori Sato gen_helper_debug(cpu_env); 2323*e5918d7dSYoshinori Sato ctx->base.is_jmp = DISAS_NORETURN; 2324*e5918d7dSYoshinori Sato ctx->base.pc_next += 1; 2325*e5918d7dSYoshinori Sato return true; 2326*e5918d7dSYoshinori Sato } 2327*e5918d7dSYoshinori Sato 2328*e5918d7dSYoshinori Sato static void rx_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) 2329*e5918d7dSYoshinori Sato { 2330*e5918d7dSYoshinori Sato DisasContext *ctx = container_of(dcbase, DisasContext, base); 2331*e5918d7dSYoshinori Sato uint32_t insn; 2332*e5918d7dSYoshinori Sato 2333*e5918d7dSYoshinori Sato ctx->pc = ctx->base.pc_next; 2334*e5918d7dSYoshinori Sato insn = decode_load(ctx); 2335*e5918d7dSYoshinori Sato if (!decode(ctx, insn)) { 2336*e5918d7dSYoshinori Sato gen_helper_raise_illegal_instruction(cpu_env); 2337*e5918d7dSYoshinori Sato } 2338*e5918d7dSYoshinori Sato } 2339*e5918d7dSYoshinori Sato 2340*e5918d7dSYoshinori Sato static void rx_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) 2341*e5918d7dSYoshinori Sato { 2342*e5918d7dSYoshinori Sato DisasContext *ctx = container_of(dcbase, DisasContext, base); 2343*e5918d7dSYoshinori Sato 2344*e5918d7dSYoshinori Sato switch (ctx->base.is_jmp) { 2345*e5918d7dSYoshinori Sato case DISAS_NEXT: 2346*e5918d7dSYoshinori Sato case DISAS_TOO_MANY: 2347*e5918d7dSYoshinori Sato gen_goto_tb(ctx, 0, dcbase->pc_next); 2348*e5918d7dSYoshinori Sato break; 2349*e5918d7dSYoshinori Sato case DISAS_JUMP: 2350*e5918d7dSYoshinori Sato if (ctx->base.singlestep_enabled) { 2351*e5918d7dSYoshinori Sato gen_helper_debug(cpu_env); 2352*e5918d7dSYoshinori Sato } else { 2353*e5918d7dSYoshinori Sato tcg_gen_lookup_and_goto_ptr(); 2354*e5918d7dSYoshinori Sato } 2355*e5918d7dSYoshinori Sato break; 2356*e5918d7dSYoshinori Sato case DISAS_UPDATE: 2357*e5918d7dSYoshinori Sato tcg_gen_movi_i32(cpu_pc, ctx->base.pc_next); 2358*e5918d7dSYoshinori Sato case DISAS_EXIT: 2359*e5918d7dSYoshinori Sato tcg_gen_exit_tb(NULL, 0); 2360*e5918d7dSYoshinori Sato break; 2361*e5918d7dSYoshinori Sato case DISAS_NORETURN: 2362*e5918d7dSYoshinori Sato break; 2363*e5918d7dSYoshinori Sato default: 2364*e5918d7dSYoshinori Sato g_assert_not_reached(); 2365*e5918d7dSYoshinori Sato } 2366*e5918d7dSYoshinori Sato } 2367*e5918d7dSYoshinori Sato 2368*e5918d7dSYoshinori Sato static void rx_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs) 2369*e5918d7dSYoshinori Sato { 2370*e5918d7dSYoshinori Sato qemu_log("IN:\n"); /* , lookup_symbol(dcbase->pc_first)); */ 2371*e5918d7dSYoshinori Sato log_target_disas(cs, dcbase->pc_first, dcbase->tb->size); 2372*e5918d7dSYoshinori Sato } 2373*e5918d7dSYoshinori Sato 2374*e5918d7dSYoshinori Sato static const TranslatorOps rx_tr_ops = { 2375*e5918d7dSYoshinori Sato .init_disas_context = rx_tr_init_disas_context, 2376*e5918d7dSYoshinori Sato .tb_start = rx_tr_tb_start, 2377*e5918d7dSYoshinori Sato .insn_start = rx_tr_insn_start, 2378*e5918d7dSYoshinori Sato .breakpoint_check = rx_tr_breakpoint_check, 2379*e5918d7dSYoshinori Sato .translate_insn = rx_tr_translate_insn, 2380*e5918d7dSYoshinori Sato .tb_stop = rx_tr_tb_stop, 2381*e5918d7dSYoshinori Sato .disas_log = rx_tr_disas_log, 2382*e5918d7dSYoshinori Sato }; 2383*e5918d7dSYoshinori Sato 2384*e5918d7dSYoshinori Sato void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns) 2385*e5918d7dSYoshinori Sato { 2386*e5918d7dSYoshinori Sato DisasContext dc; 2387*e5918d7dSYoshinori Sato 2388*e5918d7dSYoshinori Sato translator_loop(&rx_tr_ops, &dc.base, cs, tb, max_insns); 2389*e5918d7dSYoshinori Sato } 2390*e5918d7dSYoshinori Sato 2391*e5918d7dSYoshinori Sato void restore_state_to_opc(CPURXState *env, TranslationBlock *tb, 2392*e5918d7dSYoshinori Sato target_ulong *data) 2393*e5918d7dSYoshinori Sato { 2394*e5918d7dSYoshinori Sato env->pc = data[0]; 2395*e5918d7dSYoshinori Sato } 2396*e5918d7dSYoshinori Sato 2397*e5918d7dSYoshinori Sato #define ALLOC_REGISTER(sym, name) \ 2398*e5918d7dSYoshinori Sato cpu_##sym = tcg_global_mem_new_i32(cpu_env, \ 2399*e5918d7dSYoshinori Sato offsetof(CPURXState, sym), name) 2400*e5918d7dSYoshinori Sato 2401*e5918d7dSYoshinori Sato void rx_translate_init(void) 2402*e5918d7dSYoshinori Sato { 2403*e5918d7dSYoshinori Sato static const char * const regnames[NUM_REGS] = { 2404*e5918d7dSYoshinori Sato "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", 2405*e5918d7dSYoshinori Sato "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15" 2406*e5918d7dSYoshinori Sato }; 2407*e5918d7dSYoshinori Sato int i; 2408*e5918d7dSYoshinori Sato 2409*e5918d7dSYoshinori Sato for (i = 0; i < NUM_REGS; i++) { 2410*e5918d7dSYoshinori Sato cpu_regs[i] = tcg_global_mem_new_i32(cpu_env, 2411*e5918d7dSYoshinori Sato offsetof(CPURXState, regs[i]), 2412*e5918d7dSYoshinori Sato regnames[i]); 2413*e5918d7dSYoshinori Sato } 2414*e5918d7dSYoshinori Sato ALLOC_REGISTER(pc, "PC"); 2415*e5918d7dSYoshinori Sato ALLOC_REGISTER(psw_o, "PSW(O)"); 2416*e5918d7dSYoshinori Sato ALLOC_REGISTER(psw_s, "PSW(S)"); 2417*e5918d7dSYoshinori Sato ALLOC_REGISTER(psw_z, "PSW(Z)"); 2418*e5918d7dSYoshinori Sato ALLOC_REGISTER(psw_c, "PSW(C)"); 2419*e5918d7dSYoshinori Sato ALLOC_REGISTER(psw_u, "PSW(U)"); 2420*e5918d7dSYoshinori Sato ALLOC_REGISTER(psw_i, "PSW(I)"); 2421*e5918d7dSYoshinori Sato ALLOC_REGISTER(psw_pm, "PSW(PM)"); 2422*e5918d7dSYoshinori Sato ALLOC_REGISTER(psw_ipl, "PSW(IPL)"); 2423*e5918d7dSYoshinori Sato ALLOC_REGISTER(usp, "USP"); 2424*e5918d7dSYoshinori Sato ALLOC_REGISTER(fpsw, "FPSW"); 2425*e5918d7dSYoshinori Sato ALLOC_REGISTER(bpsw, "BPSW"); 2426*e5918d7dSYoshinori Sato ALLOC_REGISTER(bpc, "BPC"); 2427*e5918d7dSYoshinori Sato ALLOC_REGISTER(isp, "ISP"); 2428*e5918d7dSYoshinori Sato ALLOC_REGISTER(fintv, "FINTV"); 2429*e5918d7dSYoshinori Sato ALLOC_REGISTER(intb, "INTB"); 2430*e5918d7dSYoshinori Sato cpu_acc = tcg_global_mem_new_i64(cpu_env, 2431*e5918d7dSYoshinori Sato offsetof(CPURXState, acc), "ACC"); 2432*e5918d7dSYoshinori Sato } 2433