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