1 /* 2 * Alpha emulation cpu translation for qemu. 3 * 4 * Copyright (c) 2007 Jocelyn Mayer 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include "qemu/osdep.h" 21 #include "cpu.h" 22 #include "sysemu/cpus.h" 23 #include "sysemu/cpu-timers.h" 24 #include "disas/disas.h" 25 #include "qemu/host-utils.h" 26 #include "exec/exec-all.h" 27 #include "tcg/tcg-op.h" 28 #include "exec/cpu_ldst.h" 29 #include "exec/helper-proto.h" 30 #include "exec/helper-gen.h" 31 #include "exec/translator.h" 32 #include "exec/log.h" 33 34 35 #undef ALPHA_DEBUG_DISAS 36 #define CONFIG_SOFTFLOAT_INLINE 37 38 #ifdef ALPHA_DEBUG_DISAS 39 # define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__) 40 #else 41 # define LOG_DISAS(...) do { } while (0) 42 #endif 43 44 typedef struct DisasContext DisasContext; 45 struct DisasContext { 46 DisasContextBase base; 47 48 #ifdef CONFIG_USER_ONLY 49 MemOp unalign; 50 #else 51 uint64_t palbr; 52 #endif 53 uint32_t tbflags; 54 int mem_idx; 55 56 /* implver and amask values for this CPU. */ 57 int implver; 58 int amask; 59 60 /* Current rounding mode for this TB. */ 61 int tb_rm; 62 /* Current flush-to-zero setting for this TB. */ 63 int tb_ftz; 64 65 /* The set of registers active in the current context. */ 66 TCGv *ir; 67 68 /* Temporaries for $31 and $f31 as source and destination. */ 69 TCGv zero; 70 TCGv sink; 71 }; 72 73 #ifdef CONFIG_USER_ONLY 74 #define UNALIGN(C) (C)->unalign 75 #else 76 #define UNALIGN(C) 0 77 #endif 78 79 /* Target-specific return values from translate_one, indicating the 80 state of the TB. Note that DISAS_NEXT indicates that we are not 81 exiting the TB. */ 82 #define DISAS_PC_UPDATED_NOCHAIN DISAS_TARGET_0 83 #define DISAS_PC_UPDATED DISAS_TARGET_1 84 #define DISAS_PC_STALE DISAS_TARGET_2 85 86 /* global register indexes */ 87 static TCGv cpu_std_ir[31]; 88 static TCGv cpu_fir[31]; 89 static TCGv cpu_pc; 90 static TCGv cpu_lock_addr; 91 static TCGv cpu_lock_value; 92 93 #ifndef CONFIG_USER_ONLY 94 static TCGv cpu_pal_ir[31]; 95 #endif 96 97 #include "exec/gen-icount.h" 98 99 void alpha_translate_init(void) 100 { 101 #define DEF_VAR(V) { &cpu_##V, #V, offsetof(CPUAlphaState, V) } 102 103 typedef struct { TCGv *var; const char *name; int ofs; } GlobalVar; 104 static const GlobalVar vars[] = { 105 DEF_VAR(pc), 106 DEF_VAR(lock_addr), 107 DEF_VAR(lock_value), 108 }; 109 110 #undef DEF_VAR 111 112 /* Use the symbolic register names that match the disassembler. */ 113 static const char greg_names[31][4] = { 114 "v0", "t0", "t1", "t2", "t3", "t4", "t5", "t6", 115 "t7", "s0", "s1", "s2", "s3", "s4", "s5", "fp", 116 "a0", "a1", "a2", "a3", "a4", "a5", "t8", "t9", 117 "t10", "t11", "ra", "t12", "at", "gp", "sp" 118 }; 119 static const char freg_names[31][4] = { 120 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", 121 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", 122 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", 123 "f24", "f25", "f26", "f27", "f28", "f29", "f30" 124 }; 125 #ifndef CONFIG_USER_ONLY 126 static const char shadow_names[8][8] = { 127 "pal_t7", "pal_s0", "pal_s1", "pal_s2", 128 "pal_s3", "pal_s4", "pal_s5", "pal_t11" 129 }; 130 #endif 131 132 int i; 133 134 for (i = 0; i < 31; i++) { 135 cpu_std_ir[i] = tcg_global_mem_new_i64(cpu_env, 136 offsetof(CPUAlphaState, ir[i]), 137 greg_names[i]); 138 } 139 140 for (i = 0; i < 31; i++) { 141 cpu_fir[i] = tcg_global_mem_new_i64(cpu_env, 142 offsetof(CPUAlphaState, fir[i]), 143 freg_names[i]); 144 } 145 146 #ifndef CONFIG_USER_ONLY 147 memcpy(cpu_pal_ir, cpu_std_ir, sizeof(cpu_pal_ir)); 148 for (i = 0; i < 8; i++) { 149 int r = (i == 7 ? 25 : i + 8); 150 cpu_pal_ir[r] = tcg_global_mem_new_i64(cpu_env, 151 offsetof(CPUAlphaState, 152 shadow[i]), 153 shadow_names[i]); 154 } 155 #endif 156 157 for (i = 0; i < ARRAY_SIZE(vars); ++i) { 158 const GlobalVar *v = &vars[i]; 159 *v->var = tcg_global_mem_new_i64(cpu_env, v->ofs, v->name); 160 } 161 } 162 163 static TCGv load_zero(DisasContext *ctx) 164 { 165 if (!ctx->zero) { 166 ctx->zero = tcg_constant_i64(0); 167 } 168 return ctx->zero; 169 } 170 171 static TCGv dest_sink(DisasContext *ctx) 172 { 173 if (!ctx->sink) { 174 ctx->sink = tcg_temp_new(); 175 } 176 return ctx->sink; 177 } 178 179 static void free_context_temps(DisasContext *ctx) 180 { 181 if (ctx->sink) { 182 tcg_gen_discard_i64(ctx->sink); 183 tcg_temp_free(ctx->sink); 184 ctx->sink = NULL; 185 } 186 } 187 188 static TCGv load_gpr(DisasContext *ctx, unsigned reg) 189 { 190 if (likely(reg < 31)) { 191 return ctx->ir[reg]; 192 } else { 193 return load_zero(ctx); 194 } 195 } 196 197 static TCGv load_gpr_lit(DisasContext *ctx, unsigned reg, 198 uint8_t lit, bool islit) 199 { 200 if (islit) { 201 return tcg_constant_i64(lit); 202 } else if (likely(reg < 31)) { 203 return ctx->ir[reg]; 204 } else { 205 return load_zero(ctx); 206 } 207 } 208 209 static TCGv dest_gpr(DisasContext *ctx, unsigned reg) 210 { 211 if (likely(reg < 31)) { 212 return ctx->ir[reg]; 213 } else { 214 return dest_sink(ctx); 215 } 216 } 217 218 static TCGv load_fpr(DisasContext *ctx, unsigned reg) 219 { 220 if (likely(reg < 31)) { 221 return cpu_fir[reg]; 222 } else { 223 return load_zero(ctx); 224 } 225 } 226 227 static TCGv dest_fpr(DisasContext *ctx, unsigned reg) 228 { 229 if (likely(reg < 31)) { 230 return cpu_fir[reg]; 231 } else { 232 return dest_sink(ctx); 233 } 234 } 235 236 static int get_flag_ofs(unsigned shift) 237 { 238 int ofs = offsetof(CPUAlphaState, flags); 239 #ifdef HOST_WORDS_BIGENDIAN 240 ofs += 3 - (shift / 8); 241 #else 242 ofs += shift / 8; 243 #endif 244 return ofs; 245 } 246 247 static void ld_flag_byte(TCGv val, unsigned shift) 248 { 249 tcg_gen_ld8u_i64(val, cpu_env, get_flag_ofs(shift)); 250 } 251 252 static void st_flag_byte(TCGv val, unsigned shift) 253 { 254 tcg_gen_st8_i64(val, cpu_env, get_flag_ofs(shift)); 255 } 256 257 static void gen_excp_1(int exception, int error_code) 258 { 259 TCGv_i32 tmp1, tmp2; 260 261 tmp1 = tcg_constant_i32(exception); 262 tmp2 = tcg_constant_i32(error_code); 263 gen_helper_excp(cpu_env, tmp1, tmp2); 264 } 265 266 static DisasJumpType gen_excp(DisasContext *ctx, int exception, int error_code) 267 { 268 tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next); 269 gen_excp_1(exception, error_code); 270 return DISAS_NORETURN; 271 } 272 273 static inline DisasJumpType gen_invalid(DisasContext *ctx) 274 { 275 return gen_excp(ctx, EXCP_OPCDEC, 0); 276 } 277 278 static void gen_ldf(DisasContext *ctx, TCGv dest, TCGv addr) 279 { 280 TCGv_i32 tmp32 = tcg_temp_new_i32(); 281 tcg_gen_qemu_ld_i32(tmp32, addr, ctx->mem_idx, MO_LEUL | UNALIGN(ctx)); 282 gen_helper_memory_to_f(dest, tmp32); 283 tcg_temp_free_i32(tmp32); 284 } 285 286 static void gen_ldg(DisasContext *ctx, TCGv dest, TCGv addr) 287 { 288 TCGv tmp = tcg_temp_new(); 289 tcg_gen_qemu_ld_i64(tmp, addr, ctx->mem_idx, MO_LEUQ | UNALIGN(ctx)); 290 gen_helper_memory_to_g(dest, tmp); 291 tcg_temp_free(tmp); 292 } 293 294 static void gen_lds(DisasContext *ctx, TCGv dest, TCGv addr) 295 { 296 TCGv_i32 tmp32 = tcg_temp_new_i32(); 297 tcg_gen_qemu_ld_i32(tmp32, addr, ctx->mem_idx, MO_LEUL | UNALIGN(ctx)); 298 gen_helper_memory_to_s(dest, tmp32); 299 tcg_temp_free_i32(tmp32); 300 } 301 302 static void gen_ldt(DisasContext *ctx, TCGv dest, TCGv addr) 303 { 304 tcg_gen_qemu_ld_i64(dest, addr, ctx->mem_idx, MO_LEUQ | UNALIGN(ctx)); 305 } 306 307 static void gen_load_fp(DisasContext *ctx, int ra, int rb, int32_t disp16, 308 void (*func)(DisasContext *, TCGv, TCGv)) 309 { 310 /* Loads to $f31 are prefetches, which we can treat as nops. */ 311 if (likely(ra != 31)) { 312 TCGv addr = tcg_temp_new(); 313 tcg_gen_addi_i64(addr, load_gpr(ctx, rb), disp16); 314 func(ctx, cpu_fir[ra], addr); 315 tcg_temp_free(addr); 316 } 317 } 318 319 static void gen_load_int(DisasContext *ctx, int ra, int rb, int32_t disp16, 320 MemOp op, bool clear, bool locked) 321 { 322 TCGv addr, dest; 323 324 /* LDQ_U with ra $31 is UNOP. Other various loads are forms of 325 prefetches, which we can treat as nops. No worries about 326 missed exceptions here. */ 327 if (unlikely(ra == 31)) { 328 return; 329 } 330 331 addr = tcg_temp_new(); 332 tcg_gen_addi_i64(addr, load_gpr(ctx, rb), disp16); 333 if (clear) { 334 tcg_gen_andi_i64(addr, addr, ~0x7); 335 } else if (!locked) { 336 op |= UNALIGN(ctx); 337 } 338 339 dest = ctx->ir[ra]; 340 tcg_gen_qemu_ld_i64(dest, addr, ctx->mem_idx, op); 341 342 if (locked) { 343 tcg_gen_mov_i64(cpu_lock_addr, addr); 344 tcg_gen_mov_i64(cpu_lock_value, dest); 345 } 346 tcg_temp_free(addr); 347 } 348 349 static void gen_stf(DisasContext *ctx, TCGv src, TCGv addr) 350 { 351 TCGv_i32 tmp32 = tcg_temp_new_i32(); 352 gen_helper_f_to_memory(tmp32, addr); 353 tcg_gen_qemu_st_i32(tmp32, addr, ctx->mem_idx, MO_LEUL | UNALIGN(ctx)); 354 tcg_temp_free_i32(tmp32); 355 } 356 357 static void gen_stg(DisasContext *ctx, TCGv src, TCGv addr) 358 { 359 TCGv tmp = tcg_temp_new(); 360 gen_helper_g_to_memory(tmp, src); 361 tcg_gen_qemu_st_i64(tmp, addr, ctx->mem_idx, MO_LEUQ | UNALIGN(ctx)); 362 tcg_temp_free(tmp); 363 } 364 365 static void gen_sts(DisasContext *ctx, TCGv src, TCGv addr) 366 { 367 TCGv_i32 tmp32 = tcg_temp_new_i32(); 368 gen_helper_s_to_memory(tmp32, src); 369 tcg_gen_qemu_st_i32(tmp32, addr, ctx->mem_idx, MO_LEUL | UNALIGN(ctx)); 370 tcg_temp_free_i32(tmp32); 371 } 372 373 static void gen_stt(DisasContext *ctx, TCGv src, TCGv addr) 374 { 375 tcg_gen_qemu_st_i64(src, addr, ctx->mem_idx, MO_LEUQ | UNALIGN(ctx)); 376 } 377 378 static void gen_store_fp(DisasContext *ctx, int ra, int rb, int32_t disp16, 379 void (*func)(DisasContext *, TCGv, TCGv)) 380 { 381 TCGv addr = tcg_temp_new(); 382 tcg_gen_addi_i64(addr, load_gpr(ctx, rb), disp16); 383 func(ctx, load_fpr(ctx, ra), addr); 384 tcg_temp_free(addr); 385 } 386 387 static void gen_store_int(DisasContext *ctx, int ra, int rb, int32_t disp16, 388 MemOp op, bool clear) 389 { 390 TCGv addr, src; 391 392 addr = tcg_temp_new(); 393 tcg_gen_addi_i64(addr, load_gpr(ctx, rb), disp16); 394 if (clear) { 395 tcg_gen_andi_i64(addr, addr, ~0x7); 396 } else { 397 op |= UNALIGN(ctx); 398 } 399 400 src = load_gpr(ctx, ra); 401 tcg_gen_qemu_st_i64(src, addr, ctx->mem_idx, op); 402 403 tcg_temp_free(addr); 404 } 405 406 static DisasJumpType gen_store_conditional(DisasContext *ctx, int ra, int rb, 407 int32_t disp16, int mem_idx, 408 MemOp op) 409 { 410 TCGLabel *lab_fail, *lab_done; 411 TCGv addr, val; 412 413 addr = tcg_temp_new_i64(); 414 tcg_gen_addi_i64(addr, load_gpr(ctx, rb), disp16); 415 free_context_temps(ctx); 416 417 lab_fail = gen_new_label(); 418 lab_done = gen_new_label(); 419 tcg_gen_brcond_i64(TCG_COND_NE, addr, cpu_lock_addr, lab_fail); 420 tcg_temp_free_i64(addr); 421 422 val = tcg_temp_new_i64(); 423 tcg_gen_atomic_cmpxchg_i64(val, cpu_lock_addr, cpu_lock_value, 424 load_gpr(ctx, ra), mem_idx, op); 425 free_context_temps(ctx); 426 427 if (ra != 31) { 428 tcg_gen_setcond_i64(TCG_COND_EQ, ctx->ir[ra], val, cpu_lock_value); 429 } 430 tcg_temp_free_i64(val); 431 tcg_gen_br(lab_done); 432 433 gen_set_label(lab_fail); 434 if (ra != 31) { 435 tcg_gen_movi_i64(ctx->ir[ra], 0); 436 } 437 438 gen_set_label(lab_done); 439 tcg_gen_movi_i64(cpu_lock_addr, -1); 440 return DISAS_NEXT; 441 } 442 443 static bool use_goto_tb(DisasContext *ctx, uint64_t dest) 444 { 445 return translator_use_goto_tb(&ctx->base, dest); 446 } 447 448 static DisasJumpType gen_bdirect(DisasContext *ctx, int ra, int32_t disp) 449 { 450 uint64_t dest = ctx->base.pc_next + (disp << 2); 451 452 if (ra != 31) { 453 tcg_gen_movi_i64(ctx->ir[ra], ctx->base.pc_next); 454 } 455 456 /* Notice branch-to-next; used to initialize RA with the PC. */ 457 if (disp == 0) { 458 return 0; 459 } else if (use_goto_tb(ctx, dest)) { 460 tcg_gen_goto_tb(0); 461 tcg_gen_movi_i64(cpu_pc, dest); 462 tcg_gen_exit_tb(ctx->base.tb, 0); 463 return DISAS_NORETURN; 464 } else { 465 tcg_gen_movi_i64(cpu_pc, dest); 466 return DISAS_PC_UPDATED; 467 } 468 } 469 470 static DisasJumpType gen_bcond_internal(DisasContext *ctx, TCGCond cond, 471 TCGv cmp, int32_t disp) 472 { 473 uint64_t dest = ctx->base.pc_next + (disp << 2); 474 TCGLabel *lab_true = gen_new_label(); 475 476 if (use_goto_tb(ctx, dest)) { 477 tcg_gen_brcondi_i64(cond, cmp, 0, lab_true); 478 479 tcg_gen_goto_tb(0); 480 tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next); 481 tcg_gen_exit_tb(ctx->base.tb, 0); 482 483 gen_set_label(lab_true); 484 tcg_gen_goto_tb(1); 485 tcg_gen_movi_i64(cpu_pc, dest); 486 tcg_gen_exit_tb(ctx->base.tb, 1); 487 488 return DISAS_NORETURN; 489 } else { 490 TCGv_i64 z = load_zero(ctx); 491 TCGv_i64 d = tcg_constant_i64(dest); 492 TCGv_i64 p = tcg_constant_i64(ctx->base.pc_next); 493 494 tcg_gen_movcond_i64(cond, cpu_pc, cmp, z, d, p); 495 return DISAS_PC_UPDATED; 496 } 497 } 498 499 static DisasJumpType gen_bcond(DisasContext *ctx, TCGCond cond, int ra, 500 int32_t disp, int mask) 501 { 502 if (mask) { 503 TCGv tmp = tcg_temp_new(); 504 DisasJumpType ret; 505 506 tcg_gen_andi_i64(tmp, load_gpr(ctx, ra), 1); 507 ret = gen_bcond_internal(ctx, cond, tmp, disp); 508 tcg_temp_free(tmp); 509 return ret; 510 } 511 return gen_bcond_internal(ctx, cond, load_gpr(ctx, ra), disp); 512 } 513 514 /* Fold -0.0 for comparison with COND. */ 515 516 static void gen_fold_mzero(TCGCond cond, TCGv dest, TCGv src) 517 { 518 uint64_t mzero = 1ull << 63; 519 520 switch (cond) { 521 case TCG_COND_LE: 522 case TCG_COND_GT: 523 /* For <= or >, the -0.0 value directly compares the way we want. */ 524 tcg_gen_mov_i64(dest, src); 525 break; 526 527 case TCG_COND_EQ: 528 case TCG_COND_NE: 529 /* For == or !=, we can simply mask off the sign bit and compare. */ 530 tcg_gen_andi_i64(dest, src, mzero - 1); 531 break; 532 533 case TCG_COND_GE: 534 case TCG_COND_LT: 535 /* For >= or <, map -0.0 to +0.0 via comparison and mask. */ 536 tcg_gen_setcondi_i64(TCG_COND_NE, dest, src, mzero); 537 tcg_gen_neg_i64(dest, dest); 538 tcg_gen_and_i64(dest, dest, src); 539 break; 540 541 default: 542 abort(); 543 } 544 } 545 546 static DisasJumpType gen_fbcond(DisasContext *ctx, TCGCond cond, int ra, 547 int32_t disp) 548 { 549 TCGv cmp_tmp = tcg_temp_new(); 550 DisasJumpType ret; 551 552 gen_fold_mzero(cond, cmp_tmp, load_fpr(ctx, ra)); 553 ret = gen_bcond_internal(ctx, cond, cmp_tmp, disp); 554 tcg_temp_free(cmp_tmp); 555 return ret; 556 } 557 558 static void gen_fcmov(DisasContext *ctx, TCGCond cond, int ra, int rb, int rc) 559 { 560 TCGv_i64 va, vb, z; 561 562 z = load_zero(ctx); 563 vb = load_fpr(ctx, rb); 564 va = tcg_temp_new(); 565 gen_fold_mzero(cond, va, load_fpr(ctx, ra)); 566 567 tcg_gen_movcond_i64(cond, dest_fpr(ctx, rc), va, z, vb, load_fpr(ctx, rc)); 568 569 tcg_temp_free(va); 570 } 571 572 #define QUAL_RM_N 0x080 /* Round mode nearest even */ 573 #define QUAL_RM_C 0x000 /* Round mode chopped */ 574 #define QUAL_RM_M 0x040 /* Round mode minus infinity */ 575 #define QUAL_RM_D 0x0c0 /* Round mode dynamic */ 576 #define QUAL_RM_MASK 0x0c0 577 578 #define QUAL_U 0x100 /* Underflow enable (fp output) */ 579 #define QUAL_V 0x100 /* Overflow enable (int output) */ 580 #define QUAL_S 0x400 /* Software completion enable */ 581 #define QUAL_I 0x200 /* Inexact detection enable */ 582 583 static void gen_qual_roundmode(DisasContext *ctx, int fn11) 584 { 585 TCGv_i32 tmp; 586 587 fn11 &= QUAL_RM_MASK; 588 if (fn11 == ctx->tb_rm) { 589 return; 590 } 591 ctx->tb_rm = fn11; 592 593 tmp = tcg_temp_new_i32(); 594 switch (fn11) { 595 case QUAL_RM_N: 596 tcg_gen_movi_i32(tmp, float_round_nearest_even); 597 break; 598 case QUAL_RM_C: 599 tcg_gen_movi_i32(tmp, float_round_to_zero); 600 break; 601 case QUAL_RM_M: 602 tcg_gen_movi_i32(tmp, float_round_down); 603 break; 604 case QUAL_RM_D: 605 tcg_gen_ld8u_i32(tmp, cpu_env, 606 offsetof(CPUAlphaState, fpcr_dyn_round)); 607 break; 608 } 609 610 #if defined(CONFIG_SOFTFLOAT_INLINE) 611 /* ??? The "fpu/softfloat.h" interface is to call set_float_rounding_mode. 612 With CONFIG_SOFTFLOAT that expands to an out-of-line call that just 613 sets the one field. */ 614 tcg_gen_st8_i32(tmp, cpu_env, 615 offsetof(CPUAlphaState, fp_status.float_rounding_mode)); 616 #else 617 gen_helper_setroundmode(tmp); 618 #endif 619 620 tcg_temp_free_i32(tmp); 621 } 622 623 static void gen_qual_flushzero(DisasContext *ctx, int fn11) 624 { 625 TCGv_i32 tmp; 626 627 fn11 &= QUAL_U; 628 if (fn11 == ctx->tb_ftz) { 629 return; 630 } 631 ctx->tb_ftz = fn11; 632 633 tmp = tcg_temp_new_i32(); 634 if (fn11) { 635 /* Underflow is enabled, use the FPCR setting. */ 636 tcg_gen_ld8u_i32(tmp, cpu_env, 637 offsetof(CPUAlphaState, fpcr_flush_to_zero)); 638 } else { 639 /* Underflow is disabled, force flush-to-zero. */ 640 tcg_gen_movi_i32(tmp, 1); 641 } 642 643 #if defined(CONFIG_SOFTFLOAT_INLINE) 644 tcg_gen_st8_i32(tmp, cpu_env, 645 offsetof(CPUAlphaState, fp_status.flush_to_zero)); 646 #else 647 gen_helper_setflushzero(tmp); 648 #endif 649 650 tcg_temp_free_i32(tmp); 651 } 652 653 static TCGv gen_ieee_input(DisasContext *ctx, int reg, int fn11, int is_cmp) 654 { 655 TCGv val; 656 657 if (unlikely(reg == 31)) { 658 val = load_zero(ctx); 659 } else { 660 val = cpu_fir[reg]; 661 if ((fn11 & QUAL_S) == 0) { 662 if (is_cmp) { 663 gen_helper_ieee_input_cmp(cpu_env, val); 664 } else { 665 gen_helper_ieee_input(cpu_env, val); 666 } 667 } else { 668 #ifndef CONFIG_USER_ONLY 669 /* In system mode, raise exceptions for denormals like real 670 hardware. In user mode, proceed as if the OS completion 671 handler is handling the denormal as per spec. */ 672 gen_helper_ieee_input_s(cpu_env, val); 673 #endif 674 } 675 } 676 return val; 677 } 678 679 static void gen_fp_exc_raise(int rc, int fn11) 680 { 681 /* ??? We ought to be able to do something with imprecise exceptions. 682 E.g. notice we're still in the trap shadow of something within the 683 TB and do not generate the code to signal the exception; end the TB 684 when an exception is forced to arrive, either by consumption of a 685 register value or TRAPB or EXCB. */ 686 TCGv_i32 reg, ign; 687 uint32_t ignore = 0; 688 689 if (!(fn11 & QUAL_U)) { 690 /* Note that QUAL_U == QUAL_V, so ignore either. */ 691 ignore |= FPCR_UNF | FPCR_IOV; 692 } 693 if (!(fn11 & QUAL_I)) { 694 ignore |= FPCR_INE; 695 } 696 ign = tcg_constant_i32(ignore); 697 698 /* ??? Pass in the regno of the destination so that the helper can 699 set EXC_MASK, which contains a bitmask of destination registers 700 that have caused arithmetic traps. A simple userspace emulation 701 does not require this. We do need it for a guest kernel's entArith, 702 or if we were to do something clever with imprecise exceptions. */ 703 reg = tcg_constant_i32(rc + 32); 704 if (fn11 & QUAL_S) { 705 gen_helper_fp_exc_raise_s(cpu_env, ign, reg); 706 } else { 707 gen_helper_fp_exc_raise(cpu_env, ign, reg); 708 } 709 } 710 711 static void gen_cvtlq(TCGv vc, TCGv vb) 712 { 713 TCGv tmp = tcg_temp_new(); 714 715 /* The arithmetic right shift here, plus the sign-extended mask below 716 yields a sign-extended result without an explicit ext32s_i64. */ 717 tcg_gen_shri_i64(tmp, vb, 29); 718 tcg_gen_sari_i64(vc, vb, 32); 719 tcg_gen_deposit_i64(vc, vc, tmp, 0, 30); 720 721 tcg_temp_free(tmp); 722 } 723 724 static void gen_ieee_arith2(DisasContext *ctx, 725 void (*helper)(TCGv, TCGv_ptr, TCGv), 726 int rb, int rc, int fn11) 727 { 728 TCGv vb; 729 730 gen_qual_roundmode(ctx, fn11); 731 gen_qual_flushzero(ctx, fn11); 732 733 vb = gen_ieee_input(ctx, rb, fn11, 0); 734 helper(dest_fpr(ctx, rc), cpu_env, vb); 735 736 gen_fp_exc_raise(rc, fn11); 737 } 738 739 #define IEEE_ARITH2(name) \ 740 static inline void glue(gen_, name)(DisasContext *ctx, \ 741 int rb, int rc, int fn11) \ 742 { \ 743 gen_ieee_arith2(ctx, gen_helper_##name, rb, rc, fn11); \ 744 } 745 IEEE_ARITH2(sqrts) 746 IEEE_ARITH2(sqrtt) 747 IEEE_ARITH2(cvtst) 748 IEEE_ARITH2(cvtts) 749 750 static void gen_cvttq(DisasContext *ctx, int rb, int rc, int fn11) 751 { 752 TCGv vb, vc; 753 754 /* No need to set flushzero, since we have an integer output. */ 755 vb = gen_ieee_input(ctx, rb, fn11, 0); 756 vc = dest_fpr(ctx, rc); 757 758 /* Almost all integer conversions use cropped rounding; 759 special case that. */ 760 if ((fn11 & QUAL_RM_MASK) == QUAL_RM_C) { 761 gen_helper_cvttq_c(vc, cpu_env, vb); 762 } else { 763 gen_qual_roundmode(ctx, fn11); 764 gen_helper_cvttq(vc, cpu_env, vb); 765 } 766 gen_fp_exc_raise(rc, fn11); 767 } 768 769 static void gen_ieee_intcvt(DisasContext *ctx, 770 void (*helper)(TCGv, TCGv_ptr, TCGv), 771 int rb, int rc, int fn11) 772 { 773 TCGv vb, vc; 774 775 gen_qual_roundmode(ctx, fn11); 776 vb = load_fpr(ctx, rb); 777 vc = dest_fpr(ctx, rc); 778 779 /* The only exception that can be raised by integer conversion 780 is inexact. Thus we only need to worry about exceptions when 781 inexact handling is requested. */ 782 if (fn11 & QUAL_I) { 783 helper(vc, cpu_env, vb); 784 gen_fp_exc_raise(rc, fn11); 785 } else { 786 helper(vc, cpu_env, vb); 787 } 788 } 789 790 #define IEEE_INTCVT(name) \ 791 static inline void glue(gen_, name)(DisasContext *ctx, \ 792 int rb, int rc, int fn11) \ 793 { \ 794 gen_ieee_intcvt(ctx, gen_helper_##name, rb, rc, fn11); \ 795 } 796 IEEE_INTCVT(cvtqs) 797 IEEE_INTCVT(cvtqt) 798 799 static void gen_cpy_mask(TCGv vc, TCGv va, TCGv vb, bool inv_a, uint64_t mask) 800 { 801 TCGv vmask = tcg_constant_i64(mask); 802 TCGv tmp = tcg_temp_new_i64(); 803 804 if (inv_a) { 805 tcg_gen_andc_i64(tmp, vmask, va); 806 } else { 807 tcg_gen_and_i64(tmp, va, vmask); 808 } 809 810 tcg_gen_andc_i64(vc, vb, vmask); 811 tcg_gen_or_i64(vc, vc, tmp); 812 813 tcg_temp_free(tmp); 814 } 815 816 static void gen_ieee_arith3(DisasContext *ctx, 817 void (*helper)(TCGv, TCGv_ptr, TCGv, TCGv), 818 int ra, int rb, int rc, int fn11) 819 { 820 TCGv va, vb, vc; 821 822 gen_qual_roundmode(ctx, fn11); 823 gen_qual_flushzero(ctx, fn11); 824 825 va = gen_ieee_input(ctx, ra, fn11, 0); 826 vb = gen_ieee_input(ctx, rb, fn11, 0); 827 vc = dest_fpr(ctx, rc); 828 helper(vc, cpu_env, va, vb); 829 830 gen_fp_exc_raise(rc, fn11); 831 } 832 833 #define IEEE_ARITH3(name) \ 834 static inline void glue(gen_, name)(DisasContext *ctx, \ 835 int ra, int rb, int rc, int fn11) \ 836 { \ 837 gen_ieee_arith3(ctx, gen_helper_##name, ra, rb, rc, fn11); \ 838 } 839 IEEE_ARITH3(adds) 840 IEEE_ARITH3(subs) 841 IEEE_ARITH3(muls) 842 IEEE_ARITH3(divs) 843 IEEE_ARITH3(addt) 844 IEEE_ARITH3(subt) 845 IEEE_ARITH3(mult) 846 IEEE_ARITH3(divt) 847 848 static void gen_ieee_compare(DisasContext *ctx, 849 void (*helper)(TCGv, TCGv_ptr, TCGv, TCGv), 850 int ra, int rb, int rc, int fn11) 851 { 852 TCGv va, vb, vc; 853 854 va = gen_ieee_input(ctx, ra, fn11, 1); 855 vb = gen_ieee_input(ctx, rb, fn11, 1); 856 vc = dest_fpr(ctx, rc); 857 helper(vc, cpu_env, va, vb); 858 859 gen_fp_exc_raise(rc, fn11); 860 } 861 862 #define IEEE_CMP3(name) \ 863 static inline void glue(gen_, name)(DisasContext *ctx, \ 864 int ra, int rb, int rc, int fn11) \ 865 { \ 866 gen_ieee_compare(ctx, gen_helper_##name, ra, rb, rc, fn11); \ 867 } 868 IEEE_CMP3(cmptun) 869 IEEE_CMP3(cmpteq) 870 IEEE_CMP3(cmptlt) 871 IEEE_CMP3(cmptle) 872 873 static inline uint64_t zapnot_mask(uint8_t lit) 874 { 875 uint64_t mask = 0; 876 int i; 877 878 for (i = 0; i < 8; ++i) { 879 if ((lit >> i) & 1) { 880 mask |= 0xffull << (i * 8); 881 } 882 } 883 return mask; 884 } 885 886 /* Implement zapnot with an immediate operand, which expands to some 887 form of immediate AND. This is a basic building block in the 888 definition of many of the other byte manipulation instructions. */ 889 static void gen_zapnoti(TCGv dest, TCGv src, uint8_t lit) 890 { 891 switch (lit) { 892 case 0x00: 893 tcg_gen_movi_i64(dest, 0); 894 break; 895 case 0x01: 896 tcg_gen_ext8u_i64(dest, src); 897 break; 898 case 0x03: 899 tcg_gen_ext16u_i64(dest, src); 900 break; 901 case 0x0f: 902 tcg_gen_ext32u_i64(dest, src); 903 break; 904 case 0xff: 905 tcg_gen_mov_i64(dest, src); 906 break; 907 default: 908 tcg_gen_andi_i64(dest, src, zapnot_mask(lit)); 909 break; 910 } 911 } 912 913 /* EXTWH, EXTLH, EXTQH */ 914 static void gen_ext_h(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit, 915 uint8_t lit, uint8_t byte_mask) 916 { 917 if (islit) { 918 int pos = (64 - lit * 8) & 0x3f; 919 int len = cto32(byte_mask) * 8; 920 if (pos < len) { 921 tcg_gen_deposit_z_i64(vc, va, pos, len - pos); 922 } else { 923 tcg_gen_movi_i64(vc, 0); 924 } 925 } else { 926 TCGv tmp = tcg_temp_new(); 927 tcg_gen_shli_i64(tmp, load_gpr(ctx, rb), 3); 928 tcg_gen_neg_i64(tmp, tmp); 929 tcg_gen_andi_i64(tmp, tmp, 0x3f); 930 tcg_gen_shl_i64(vc, va, tmp); 931 tcg_temp_free(tmp); 932 } 933 gen_zapnoti(vc, vc, byte_mask); 934 } 935 936 /* EXTBL, EXTWL, EXTLL, EXTQL */ 937 static void gen_ext_l(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit, 938 uint8_t lit, uint8_t byte_mask) 939 { 940 if (islit) { 941 int pos = (lit & 7) * 8; 942 int len = cto32(byte_mask) * 8; 943 if (pos + len >= 64) { 944 len = 64 - pos; 945 } 946 tcg_gen_extract_i64(vc, va, pos, len); 947 } else { 948 TCGv tmp = tcg_temp_new(); 949 tcg_gen_andi_i64(tmp, load_gpr(ctx, rb), 7); 950 tcg_gen_shli_i64(tmp, tmp, 3); 951 tcg_gen_shr_i64(vc, va, tmp); 952 tcg_temp_free(tmp); 953 gen_zapnoti(vc, vc, byte_mask); 954 } 955 } 956 957 /* INSWH, INSLH, INSQH */ 958 static void gen_ins_h(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit, 959 uint8_t lit, uint8_t byte_mask) 960 { 961 if (islit) { 962 int pos = 64 - (lit & 7) * 8; 963 int len = cto32(byte_mask) * 8; 964 if (pos < len) { 965 tcg_gen_extract_i64(vc, va, pos, len - pos); 966 } else { 967 tcg_gen_movi_i64(vc, 0); 968 } 969 } else { 970 TCGv tmp = tcg_temp_new(); 971 TCGv shift = tcg_temp_new(); 972 973 /* The instruction description has us left-shift the byte mask 974 and extract bits <15:8> and apply that zap at the end. This 975 is equivalent to simply performing the zap first and shifting 976 afterward. */ 977 gen_zapnoti(tmp, va, byte_mask); 978 979 /* If (B & 7) == 0, we need to shift by 64 and leave a zero. Do this 980 portably by splitting the shift into two parts: shift_count-1 and 1. 981 Arrange for the -1 by using ones-complement instead of 982 twos-complement in the negation: ~(B * 8) & 63. */ 983 984 tcg_gen_shli_i64(shift, load_gpr(ctx, rb), 3); 985 tcg_gen_not_i64(shift, shift); 986 tcg_gen_andi_i64(shift, shift, 0x3f); 987 988 tcg_gen_shr_i64(vc, tmp, shift); 989 tcg_gen_shri_i64(vc, vc, 1); 990 tcg_temp_free(shift); 991 tcg_temp_free(tmp); 992 } 993 } 994 995 /* INSBL, INSWL, INSLL, INSQL */ 996 static void gen_ins_l(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit, 997 uint8_t lit, uint8_t byte_mask) 998 { 999 if (islit) { 1000 int pos = (lit & 7) * 8; 1001 int len = cto32(byte_mask) * 8; 1002 if (pos + len > 64) { 1003 len = 64 - pos; 1004 } 1005 tcg_gen_deposit_z_i64(vc, va, pos, len); 1006 } else { 1007 TCGv tmp = tcg_temp_new(); 1008 TCGv shift = tcg_temp_new(); 1009 1010 /* The instruction description has us left-shift the byte mask 1011 and extract bits <15:8> and apply that zap at the end. This 1012 is equivalent to simply performing the zap first and shifting 1013 afterward. */ 1014 gen_zapnoti(tmp, va, byte_mask); 1015 1016 tcg_gen_andi_i64(shift, load_gpr(ctx, rb), 7); 1017 tcg_gen_shli_i64(shift, shift, 3); 1018 tcg_gen_shl_i64(vc, tmp, shift); 1019 tcg_temp_free(shift); 1020 tcg_temp_free(tmp); 1021 } 1022 } 1023 1024 /* MSKWH, MSKLH, MSKQH */ 1025 static void gen_msk_h(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit, 1026 uint8_t lit, uint8_t byte_mask) 1027 { 1028 if (islit) { 1029 gen_zapnoti(vc, va, ~((byte_mask << (lit & 7)) >> 8)); 1030 } else { 1031 TCGv shift = tcg_temp_new(); 1032 TCGv mask = tcg_temp_new(); 1033 1034 /* The instruction description is as above, where the byte_mask 1035 is shifted left, and then we extract bits <15:8>. This can be 1036 emulated with a right-shift on the expanded byte mask. This 1037 requires extra care because for an input <2:0> == 0 we need a 1038 shift of 64 bits in order to generate a zero. This is done by 1039 splitting the shift into two parts, the variable shift - 1 1040 followed by a constant 1 shift. The code we expand below is 1041 equivalent to ~(B * 8) & 63. */ 1042 1043 tcg_gen_shli_i64(shift, load_gpr(ctx, rb), 3); 1044 tcg_gen_not_i64(shift, shift); 1045 tcg_gen_andi_i64(shift, shift, 0x3f); 1046 tcg_gen_movi_i64(mask, zapnot_mask (byte_mask)); 1047 tcg_gen_shr_i64(mask, mask, shift); 1048 tcg_gen_shri_i64(mask, mask, 1); 1049 1050 tcg_gen_andc_i64(vc, va, mask); 1051 1052 tcg_temp_free(mask); 1053 tcg_temp_free(shift); 1054 } 1055 } 1056 1057 /* MSKBL, MSKWL, MSKLL, MSKQL */ 1058 static void gen_msk_l(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit, 1059 uint8_t lit, uint8_t byte_mask) 1060 { 1061 if (islit) { 1062 gen_zapnoti(vc, va, ~(byte_mask << (lit & 7))); 1063 } else { 1064 TCGv shift = tcg_temp_new(); 1065 TCGv mask = tcg_temp_new(); 1066 1067 tcg_gen_andi_i64(shift, load_gpr(ctx, rb), 7); 1068 tcg_gen_shli_i64(shift, shift, 3); 1069 tcg_gen_movi_i64(mask, zapnot_mask(byte_mask)); 1070 tcg_gen_shl_i64(mask, mask, shift); 1071 1072 tcg_gen_andc_i64(vc, va, mask); 1073 1074 tcg_temp_free(mask); 1075 tcg_temp_free(shift); 1076 } 1077 } 1078 1079 static void gen_rx(DisasContext *ctx, int ra, int set) 1080 { 1081 if (ra != 31) { 1082 ld_flag_byte(ctx->ir[ra], ENV_FLAG_RX_SHIFT); 1083 } 1084 1085 st_flag_byte(tcg_constant_i64(set), ENV_FLAG_RX_SHIFT); 1086 } 1087 1088 static DisasJumpType gen_call_pal(DisasContext *ctx, int palcode) 1089 { 1090 /* We're emulating OSF/1 PALcode. Many of these are trivial access 1091 to internal cpu registers. */ 1092 1093 /* Unprivileged PAL call */ 1094 if (palcode >= 0x80 && palcode < 0xC0) { 1095 switch (palcode) { 1096 case 0x86: 1097 /* IMB */ 1098 /* No-op inside QEMU. */ 1099 break; 1100 case 0x9E: 1101 /* RDUNIQUE */ 1102 tcg_gen_ld_i64(ctx->ir[IR_V0], cpu_env, 1103 offsetof(CPUAlphaState, unique)); 1104 break; 1105 case 0x9F: 1106 /* WRUNIQUE */ 1107 tcg_gen_st_i64(ctx->ir[IR_A0], cpu_env, 1108 offsetof(CPUAlphaState, unique)); 1109 break; 1110 default: 1111 palcode &= 0xbf; 1112 goto do_call_pal; 1113 } 1114 return DISAS_NEXT; 1115 } 1116 1117 #ifndef CONFIG_USER_ONLY 1118 /* Privileged PAL code */ 1119 if (palcode < 0x40 && (ctx->tbflags & ENV_FLAG_PS_USER) == 0) { 1120 switch (palcode) { 1121 case 0x01: 1122 /* CFLUSH */ 1123 /* No-op inside QEMU. */ 1124 break; 1125 case 0x02: 1126 /* DRAINA */ 1127 /* No-op inside QEMU. */ 1128 break; 1129 case 0x2D: 1130 /* WRVPTPTR */ 1131 tcg_gen_st_i64(ctx->ir[IR_A0], cpu_env, 1132 offsetof(CPUAlphaState, vptptr)); 1133 break; 1134 case 0x31: 1135 /* WRVAL */ 1136 tcg_gen_st_i64(ctx->ir[IR_A0], cpu_env, 1137 offsetof(CPUAlphaState, sysval)); 1138 break; 1139 case 0x32: 1140 /* RDVAL */ 1141 tcg_gen_ld_i64(ctx->ir[IR_V0], cpu_env, 1142 offsetof(CPUAlphaState, sysval)); 1143 break; 1144 1145 case 0x35: 1146 /* SWPIPL */ 1147 /* Note that we already know we're in kernel mode, so we know 1148 that PS only contains the 3 IPL bits. */ 1149 ld_flag_byte(ctx->ir[IR_V0], ENV_FLAG_PS_SHIFT); 1150 1151 /* But make sure and store only the 3 IPL bits from the user. */ 1152 { 1153 TCGv tmp = tcg_temp_new(); 1154 tcg_gen_andi_i64(tmp, ctx->ir[IR_A0], PS_INT_MASK); 1155 st_flag_byte(tmp, ENV_FLAG_PS_SHIFT); 1156 tcg_temp_free(tmp); 1157 } 1158 1159 /* Allow interrupts to be recognized right away. */ 1160 tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next); 1161 return DISAS_PC_UPDATED_NOCHAIN; 1162 1163 case 0x36: 1164 /* RDPS */ 1165 ld_flag_byte(ctx->ir[IR_V0], ENV_FLAG_PS_SHIFT); 1166 break; 1167 1168 case 0x38: 1169 /* WRUSP */ 1170 tcg_gen_st_i64(ctx->ir[IR_A0], cpu_env, 1171 offsetof(CPUAlphaState, usp)); 1172 break; 1173 case 0x3A: 1174 /* RDUSP */ 1175 tcg_gen_ld_i64(ctx->ir[IR_V0], cpu_env, 1176 offsetof(CPUAlphaState, usp)); 1177 break; 1178 case 0x3C: 1179 /* WHAMI */ 1180 tcg_gen_ld32s_i64(ctx->ir[IR_V0], cpu_env, 1181 -offsetof(AlphaCPU, env) + offsetof(CPUState, cpu_index)); 1182 break; 1183 1184 case 0x3E: 1185 /* WTINT */ 1186 tcg_gen_st_i32(tcg_constant_i32(1), cpu_env, 1187 -offsetof(AlphaCPU, env) + 1188 offsetof(CPUState, halted)); 1189 tcg_gen_movi_i64(ctx->ir[IR_V0], 0); 1190 return gen_excp(ctx, EXCP_HALTED, 0); 1191 1192 default: 1193 palcode &= 0x3f; 1194 goto do_call_pal; 1195 } 1196 return DISAS_NEXT; 1197 } 1198 #endif 1199 return gen_invalid(ctx); 1200 1201 do_call_pal: 1202 #ifdef CONFIG_USER_ONLY 1203 return gen_excp(ctx, EXCP_CALL_PAL, palcode); 1204 #else 1205 { 1206 TCGv tmp = tcg_temp_new(); 1207 uint64_t exc_addr = ctx->base.pc_next; 1208 uint64_t entry = ctx->palbr; 1209 1210 if (ctx->tbflags & ENV_FLAG_PAL_MODE) { 1211 exc_addr |= 1; 1212 } else { 1213 tcg_gen_movi_i64(tmp, 1); 1214 st_flag_byte(tmp, ENV_FLAG_PAL_SHIFT); 1215 } 1216 1217 tcg_gen_movi_i64(tmp, exc_addr); 1218 tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUAlphaState, exc_addr)); 1219 tcg_temp_free(tmp); 1220 1221 entry += (palcode & 0x80 1222 ? 0x2000 + (palcode - 0x80) * 64 1223 : 0x1000 + palcode * 64); 1224 1225 tcg_gen_movi_i64(cpu_pc, entry); 1226 return DISAS_PC_UPDATED; 1227 } 1228 #endif 1229 } 1230 1231 #ifndef CONFIG_USER_ONLY 1232 1233 #define PR_LONG 0x200000 1234 1235 static int cpu_pr_data(int pr) 1236 { 1237 switch (pr) { 1238 case 2: return offsetof(CPUAlphaState, pcc_ofs) | PR_LONG; 1239 case 3: return offsetof(CPUAlphaState, trap_arg0); 1240 case 4: return offsetof(CPUAlphaState, trap_arg1); 1241 case 5: return offsetof(CPUAlphaState, trap_arg2); 1242 case 6: return offsetof(CPUAlphaState, exc_addr); 1243 case 7: return offsetof(CPUAlphaState, palbr); 1244 case 8: return offsetof(CPUAlphaState, ptbr); 1245 case 9: return offsetof(CPUAlphaState, vptptr); 1246 case 10: return offsetof(CPUAlphaState, unique); 1247 case 11: return offsetof(CPUAlphaState, sysval); 1248 case 12: return offsetof(CPUAlphaState, usp); 1249 1250 case 40 ... 63: 1251 return offsetof(CPUAlphaState, scratch[pr - 40]); 1252 1253 case 251: 1254 return offsetof(CPUAlphaState, alarm_expire); 1255 } 1256 return 0; 1257 } 1258 1259 static DisasJumpType gen_mfpr(DisasContext *ctx, TCGv va, int regno) 1260 { 1261 void (*helper)(TCGv); 1262 int data; 1263 1264 switch (regno) { 1265 case 32 ... 39: 1266 /* Accessing the "non-shadow" general registers. */ 1267 regno = regno == 39 ? 25 : regno - 32 + 8; 1268 tcg_gen_mov_i64(va, cpu_std_ir[regno]); 1269 break; 1270 1271 case 250: /* WALLTIME */ 1272 helper = gen_helper_get_walltime; 1273 goto do_helper; 1274 case 249: /* VMTIME */ 1275 helper = gen_helper_get_vmtime; 1276 do_helper: 1277 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 1278 gen_io_start(); 1279 helper(va); 1280 return DISAS_PC_STALE; 1281 } else { 1282 helper(va); 1283 } 1284 break; 1285 1286 case 0: /* PS */ 1287 ld_flag_byte(va, ENV_FLAG_PS_SHIFT); 1288 break; 1289 case 1: /* FEN */ 1290 ld_flag_byte(va, ENV_FLAG_FEN_SHIFT); 1291 break; 1292 1293 default: 1294 /* The basic registers are data only, and unknown registers 1295 are read-zero, write-ignore. */ 1296 data = cpu_pr_data(regno); 1297 if (data == 0) { 1298 tcg_gen_movi_i64(va, 0); 1299 } else if (data & PR_LONG) { 1300 tcg_gen_ld32s_i64(va, cpu_env, data & ~PR_LONG); 1301 } else { 1302 tcg_gen_ld_i64(va, cpu_env, data); 1303 } 1304 break; 1305 } 1306 1307 return DISAS_NEXT; 1308 } 1309 1310 static DisasJumpType gen_mtpr(DisasContext *ctx, TCGv vb, int regno) 1311 { 1312 int data; 1313 DisasJumpType ret = DISAS_NEXT; 1314 1315 switch (regno) { 1316 case 255: 1317 /* TBIA */ 1318 gen_helper_tbia(cpu_env); 1319 break; 1320 1321 case 254: 1322 /* TBIS */ 1323 gen_helper_tbis(cpu_env, vb); 1324 break; 1325 1326 case 253: 1327 /* WAIT */ 1328 tcg_gen_st_i32(tcg_constant_i32(1), cpu_env, 1329 -offsetof(AlphaCPU, env) + offsetof(CPUState, halted)); 1330 return gen_excp(ctx, EXCP_HALTED, 0); 1331 1332 case 252: 1333 /* HALT */ 1334 gen_helper_halt(vb); 1335 return DISAS_PC_STALE; 1336 1337 case 251: 1338 /* ALARM */ 1339 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 1340 gen_io_start(); 1341 ret = DISAS_PC_STALE; 1342 } 1343 gen_helper_set_alarm(cpu_env, vb); 1344 break; 1345 1346 case 7: 1347 /* PALBR */ 1348 tcg_gen_st_i64(vb, cpu_env, offsetof(CPUAlphaState, palbr)); 1349 /* Changing the PAL base register implies un-chaining all of the TBs 1350 that ended with a CALL_PAL. Since the base register usually only 1351 changes during boot, flushing everything works well. */ 1352 gen_helper_tb_flush(cpu_env); 1353 return DISAS_PC_STALE; 1354 1355 case 32 ... 39: 1356 /* Accessing the "non-shadow" general registers. */ 1357 regno = regno == 39 ? 25 : regno - 32 + 8; 1358 tcg_gen_mov_i64(cpu_std_ir[regno], vb); 1359 break; 1360 1361 case 0: /* PS */ 1362 st_flag_byte(vb, ENV_FLAG_PS_SHIFT); 1363 break; 1364 case 1: /* FEN */ 1365 st_flag_byte(vb, ENV_FLAG_FEN_SHIFT); 1366 break; 1367 1368 default: 1369 /* The basic registers are data only, and unknown registers 1370 are read-zero, write-ignore. */ 1371 data = cpu_pr_data(regno); 1372 if (data != 0) { 1373 if (data & PR_LONG) { 1374 tcg_gen_st32_i64(vb, cpu_env, data & ~PR_LONG); 1375 } else { 1376 tcg_gen_st_i64(vb, cpu_env, data); 1377 } 1378 } 1379 break; 1380 } 1381 1382 return ret; 1383 } 1384 #endif /* !USER_ONLY*/ 1385 1386 #define REQUIRE_NO_LIT \ 1387 do { \ 1388 if (real_islit) { \ 1389 goto invalid_opc; \ 1390 } \ 1391 } while (0) 1392 1393 #define REQUIRE_AMASK(FLAG) \ 1394 do { \ 1395 if ((ctx->amask & AMASK_##FLAG) == 0) { \ 1396 goto invalid_opc; \ 1397 } \ 1398 } while (0) 1399 1400 #define REQUIRE_TB_FLAG(FLAG) \ 1401 do { \ 1402 if ((ctx->tbflags & (FLAG)) == 0) { \ 1403 goto invalid_opc; \ 1404 } \ 1405 } while (0) 1406 1407 #define REQUIRE_REG_31(WHICH) \ 1408 do { \ 1409 if (WHICH != 31) { \ 1410 goto invalid_opc; \ 1411 } \ 1412 } while (0) 1413 1414 #define REQUIRE_FEN \ 1415 do { \ 1416 if (!(ctx->tbflags & ENV_FLAG_FEN)) { \ 1417 goto raise_fen; \ 1418 } \ 1419 } while (0) 1420 1421 static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn) 1422 { 1423 int32_t disp21, disp16, disp12 __attribute__((unused)); 1424 uint16_t fn11; 1425 uint8_t opc, ra, rb, rc, fpfn, fn7, lit; 1426 bool islit, real_islit; 1427 TCGv va, vb, vc, tmp, tmp2; 1428 TCGv_i32 t32; 1429 DisasJumpType ret; 1430 1431 /* Decode all instruction fields */ 1432 opc = extract32(insn, 26, 6); 1433 ra = extract32(insn, 21, 5); 1434 rb = extract32(insn, 16, 5); 1435 rc = extract32(insn, 0, 5); 1436 real_islit = islit = extract32(insn, 12, 1); 1437 lit = extract32(insn, 13, 8); 1438 1439 disp21 = sextract32(insn, 0, 21); 1440 disp16 = sextract32(insn, 0, 16); 1441 disp12 = sextract32(insn, 0, 12); 1442 1443 fn11 = extract32(insn, 5, 11); 1444 fpfn = extract32(insn, 5, 6); 1445 fn7 = extract32(insn, 5, 7); 1446 1447 if (rb == 31 && !islit) { 1448 islit = true; 1449 lit = 0; 1450 } 1451 1452 ret = DISAS_NEXT; 1453 switch (opc) { 1454 case 0x00: 1455 /* CALL_PAL */ 1456 ret = gen_call_pal(ctx, insn & 0x03ffffff); 1457 break; 1458 case 0x01: 1459 /* OPC01 */ 1460 goto invalid_opc; 1461 case 0x02: 1462 /* OPC02 */ 1463 goto invalid_opc; 1464 case 0x03: 1465 /* OPC03 */ 1466 goto invalid_opc; 1467 case 0x04: 1468 /* OPC04 */ 1469 goto invalid_opc; 1470 case 0x05: 1471 /* OPC05 */ 1472 goto invalid_opc; 1473 case 0x06: 1474 /* OPC06 */ 1475 goto invalid_opc; 1476 case 0x07: 1477 /* OPC07 */ 1478 goto invalid_opc; 1479 1480 case 0x09: 1481 /* LDAH */ 1482 disp16 = (uint32_t)disp16 << 16; 1483 /* fall through */ 1484 case 0x08: 1485 /* LDA */ 1486 va = dest_gpr(ctx, ra); 1487 /* It's worth special-casing immediate loads. */ 1488 if (rb == 31) { 1489 tcg_gen_movi_i64(va, disp16); 1490 } else { 1491 tcg_gen_addi_i64(va, load_gpr(ctx, rb), disp16); 1492 } 1493 break; 1494 1495 case 0x0A: 1496 /* LDBU */ 1497 REQUIRE_AMASK(BWX); 1498 gen_load_int(ctx, ra, rb, disp16, MO_UB, 0, 0); 1499 break; 1500 case 0x0B: 1501 /* LDQ_U */ 1502 gen_load_int(ctx, ra, rb, disp16, MO_LEUQ, 1, 0); 1503 break; 1504 case 0x0C: 1505 /* LDWU */ 1506 REQUIRE_AMASK(BWX); 1507 gen_load_int(ctx, ra, rb, disp16, MO_LEUW, 0, 0); 1508 break; 1509 case 0x0D: 1510 /* STW */ 1511 REQUIRE_AMASK(BWX); 1512 gen_store_int(ctx, ra, rb, disp16, MO_LEUW, 0); 1513 break; 1514 case 0x0E: 1515 /* STB */ 1516 REQUIRE_AMASK(BWX); 1517 gen_store_int(ctx, ra, rb, disp16, MO_UB, 0); 1518 break; 1519 case 0x0F: 1520 /* STQ_U */ 1521 gen_store_int(ctx, ra, rb, disp16, MO_LEUQ, 1); 1522 break; 1523 1524 case 0x10: 1525 vc = dest_gpr(ctx, rc); 1526 vb = load_gpr_lit(ctx, rb, lit, islit); 1527 1528 if (ra == 31) { 1529 if (fn7 == 0x00) { 1530 /* Special case ADDL as SEXTL. */ 1531 tcg_gen_ext32s_i64(vc, vb); 1532 break; 1533 } 1534 if (fn7 == 0x29) { 1535 /* Special case SUBQ as NEGQ. */ 1536 tcg_gen_neg_i64(vc, vb); 1537 break; 1538 } 1539 } 1540 1541 va = load_gpr(ctx, ra); 1542 switch (fn7) { 1543 case 0x00: 1544 /* ADDL */ 1545 tcg_gen_add_i64(vc, va, vb); 1546 tcg_gen_ext32s_i64(vc, vc); 1547 break; 1548 case 0x02: 1549 /* S4ADDL */ 1550 tmp = tcg_temp_new(); 1551 tcg_gen_shli_i64(tmp, va, 2); 1552 tcg_gen_add_i64(tmp, tmp, vb); 1553 tcg_gen_ext32s_i64(vc, tmp); 1554 tcg_temp_free(tmp); 1555 break; 1556 case 0x09: 1557 /* SUBL */ 1558 tcg_gen_sub_i64(vc, va, vb); 1559 tcg_gen_ext32s_i64(vc, vc); 1560 break; 1561 case 0x0B: 1562 /* S4SUBL */ 1563 tmp = tcg_temp_new(); 1564 tcg_gen_shli_i64(tmp, va, 2); 1565 tcg_gen_sub_i64(tmp, tmp, vb); 1566 tcg_gen_ext32s_i64(vc, tmp); 1567 tcg_temp_free(tmp); 1568 break; 1569 case 0x0F: 1570 /* CMPBGE */ 1571 if (ra == 31) { 1572 /* Special case 0 >= X as X == 0. */ 1573 gen_helper_cmpbe0(vc, vb); 1574 } else { 1575 gen_helper_cmpbge(vc, va, vb); 1576 } 1577 break; 1578 case 0x12: 1579 /* S8ADDL */ 1580 tmp = tcg_temp_new(); 1581 tcg_gen_shli_i64(tmp, va, 3); 1582 tcg_gen_add_i64(tmp, tmp, vb); 1583 tcg_gen_ext32s_i64(vc, tmp); 1584 tcg_temp_free(tmp); 1585 break; 1586 case 0x1B: 1587 /* S8SUBL */ 1588 tmp = tcg_temp_new(); 1589 tcg_gen_shli_i64(tmp, va, 3); 1590 tcg_gen_sub_i64(tmp, tmp, vb); 1591 tcg_gen_ext32s_i64(vc, tmp); 1592 tcg_temp_free(tmp); 1593 break; 1594 case 0x1D: 1595 /* CMPULT */ 1596 tcg_gen_setcond_i64(TCG_COND_LTU, vc, va, vb); 1597 break; 1598 case 0x20: 1599 /* ADDQ */ 1600 tcg_gen_add_i64(vc, va, vb); 1601 break; 1602 case 0x22: 1603 /* S4ADDQ */ 1604 tmp = tcg_temp_new(); 1605 tcg_gen_shli_i64(tmp, va, 2); 1606 tcg_gen_add_i64(vc, tmp, vb); 1607 tcg_temp_free(tmp); 1608 break; 1609 case 0x29: 1610 /* SUBQ */ 1611 tcg_gen_sub_i64(vc, va, vb); 1612 break; 1613 case 0x2B: 1614 /* S4SUBQ */ 1615 tmp = tcg_temp_new(); 1616 tcg_gen_shli_i64(tmp, va, 2); 1617 tcg_gen_sub_i64(vc, tmp, vb); 1618 tcg_temp_free(tmp); 1619 break; 1620 case 0x2D: 1621 /* CMPEQ */ 1622 tcg_gen_setcond_i64(TCG_COND_EQ, vc, va, vb); 1623 break; 1624 case 0x32: 1625 /* S8ADDQ */ 1626 tmp = tcg_temp_new(); 1627 tcg_gen_shli_i64(tmp, va, 3); 1628 tcg_gen_add_i64(vc, tmp, vb); 1629 tcg_temp_free(tmp); 1630 break; 1631 case 0x3B: 1632 /* S8SUBQ */ 1633 tmp = tcg_temp_new(); 1634 tcg_gen_shli_i64(tmp, va, 3); 1635 tcg_gen_sub_i64(vc, tmp, vb); 1636 tcg_temp_free(tmp); 1637 break; 1638 case 0x3D: 1639 /* CMPULE */ 1640 tcg_gen_setcond_i64(TCG_COND_LEU, vc, va, vb); 1641 break; 1642 case 0x40: 1643 /* ADDL/V */ 1644 tmp = tcg_temp_new(); 1645 tcg_gen_ext32s_i64(tmp, va); 1646 tcg_gen_ext32s_i64(vc, vb); 1647 tcg_gen_add_i64(tmp, tmp, vc); 1648 tcg_gen_ext32s_i64(vc, tmp); 1649 gen_helper_check_overflow(cpu_env, vc, tmp); 1650 tcg_temp_free(tmp); 1651 break; 1652 case 0x49: 1653 /* SUBL/V */ 1654 tmp = tcg_temp_new(); 1655 tcg_gen_ext32s_i64(tmp, va); 1656 tcg_gen_ext32s_i64(vc, vb); 1657 tcg_gen_sub_i64(tmp, tmp, vc); 1658 tcg_gen_ext32s_i64(vc, tmp); 1659 gen_helper_check_overflow(cpu_env, vc, tmp); 1660 tcg_temp_free(tmp); 1661 break; 1662 case 0x4D: 1663 /* CMPLT */ 1664 tcg_gen_setcond_i64(TCG_COND_LT, vc, va, vb); 1665 break; 1666 case 0x60: 1667 /* ADDQ/V */ 1668 tmp = tcg_temp_new(); 1669 tmp2 = tcg_temp_new(); 1670 tcg_gen_eqv_i64(tmp, va, vb); 1671 tcg_gen_mov_i64(tmp2, va); 1672 tcg_gen_add_i64(vc, va, vb); 1673 tcg_gen_xor_i64(tmp2, tmp2, vc); 1674 tcg_gen_and_i64(tmp, tmp, tmp2); 1675 tcg_gen_shri_i64(tmp, tmp, 63); 1676 tcg_gen_movi_i64(tmp2, 0); 1677 gen_helper_check_overflow(cpu_env, tmp, tmp2); 1678 tcg_temp_free(tmp); 1679 tcg_temp_free(tmp2); 1680 break; 1681 case 0x69: 1682 /* SUBQ/V */ 1683 tmp = tcg_temp_new(); 1684 tmp2 = tcg_temp_new(); 1685 tcg_gen_xor_i64(tmp, va, vb); 1686 tcg_gen_mov_i64(tmp2, va); 1687 tcg_gen_sub_i64(vc, va, vb); 1688 tcg_gen_xor_i64(tmp2, tmp2, vc); 1689 tcg_gen_and_i64(tmp, tmp, tmp2); 1690 tcg_gen_shri_i64(tmp, tmp, 63); 1691 tcg_gen_movi_i64(tmp2, 0); 1692 gen_helper_check_overflow(cpu_env, tmp, tmp2); 1693 tcg_temp_free(tmp); 1694 tcg_temp_free(tmp2); 1695 break; 1696 case 0x6D: 1697 /* CMPLE */ 1698 tcg_gen_setcond_i64(TCG_COND_LE, vc, va, vb); 1699 break; 1700 default: 1701 goto invalid_opc; 1702 } 1703 break; 1704 1705 case 0x11: 1706 if (fn7 == 0x20) { 1707 if (rc == 31) { 1708 /* Special case BIS as NOP. */ 1709 break; 1710 } 1711 if (ra == 31) { 1712 /* Special case BIS as MOV. */ 1713 vc = dest_gpr(ctx, rc); 1714 if (islit) { 1715 tcg_gen_movi_i64(vc, lit); 1716 } else { 1717 tcg_gen_mov_i64(vc, load_gpr(ctx, rb)); 1718 } 1719 break; 1720 } 1721 } 1722 1723 vc = dest_gpr(ctx, rc); 1724 vb = load_gpr_lit(ctx, rb, lit, islit); 1725 1726 if (fn7 == 0x28 && ra == 31) { 1727 /* Special case ORNOT as NOT. */ 1728 tcg_gen_not_i64(vc, vb); 1729 break; 1730 } 1731 1732 va = load_gpr(ctx, ra); 1733 switch (fn7) { 1734 case 0x00: 1735 /* AND */ 1736 tcg_gen_and_i64(vc, va, vb); 1737 break; 1738 case 0x08: 1739 /* BIC */ 1740 tcg_gen_andc_i64(vc, va, vb); 1741 break; 1742 case 0x14: 1743 /* CMOVLBS */ 1744 tmp = tcg_temp_new(); 1745 tcg_gen_andi_i64(tmp, va, 1); 1746 tcg_gen_movcond_i64(TCG_COND_NE, vc, tmp, load_zero(ctx), 1747 vb, load_gpr(ctx, rc)); 1748 tcg_temp_free(tmp); 1749 break; 1750 case 0x16: 1751 /* CMOVLBC */ 1752 tmp = tcg_temp_new(); 1753 tcg_gen_andi_i64(tmp, va, 1); 1754 tcg_gen_movcond_i64(TCG_COND_EQ, vc, tmp, load_zero(ctx), 1755 vb, load_gpr(ctx, rc)); 1756 tcg_temp_free(tmp); 1757 break; 1758 case 0x20: 1759 /* BIS */ 1760 tcg_gen_or_i64(vc, va, vb); 1761 break; 1762 case 0x24: 1763 /* CMOVEQ */ 1764 tcg_gen_movcond_i64(TCG_COND_EQ, vc, va, load_zero(ctx), 1765 vb, load_gpr(ctx, rc)); 1766 break; 1767 case 0x26: 1768 /* CMOVNE */ 1769 tcg_gen_movcond_i64(TCG_COND_NE, vc, va, load_zero(ctx), 1770 vb, load_gpr(ctx, rc)); 1771 break; 1772 case 0x28: 1773 /* ORNOT */ 1774 tcg_gen_orc_i64(vc, va, vb); 1775 break; 1776 case 0x40: 1777 /* XOR */ 1778 tcg_gen_xor_i64(vc, va, vb); 1779 break; 1780 case 0x44: 1781 /* CMOVLT */ 1782 tcg_gen_movcond_i64(TCG_COND_LT, vc, va, load_zero(ctx), 1783 vb, load_gpr(ctx, rc)); 1784 break; 1785 case 0x46: 1786 /* CMOVGE */ 1787 tcg_gen_movcond_i64(TCG_COND_GE, vc, va, load_zero(ctx), 1788 vb, load_gpr(ctx, rc)); 1789 break; 1790 case 0x48: 1791 /* EQV */ 1792 tcg_gen_eqv_i64(vc, va, vb); 1793 break; 1794 case 0x61: 1795 /* AMASK */ 1796 REQUIRE_REG_31(ra); 1797 tcg_gen_andi_i64(vc, vb, ~ctx->amask); 1798 break; 1799 case 0x64: 1800 /* CMOVLE */ 1801 tcg_gen_movcond_i64(TCG_COND_LE, vc, va, load_zero(ctx), 1802 vb, load_gpr(ctx, rc)); 1803 break; 1804 case 0x66: 1805 /* CMOVGT */ 1806 tcg_gen_movcond_i64(TCG_COND_GT, vc, va, load_zero(ctx), 1807 vb, load_gpr(ctx, rc)); 1808 break; 1809 case 0x6C: 1810 /* IMPLVER */ 1811 REQUIRE_REG_31(ra); 1812 tcg_gen_movi_i64(vc, ctx->implver); 1813 break; 1814 default: 1815 goto invalid_opc; 1816 } 1817 break; 1818 1819 case 0x12: 1820 vc = dest_gpr(ctx, rc); 1821 va = load_gpr(ctx, ra); 1822 switch (fn7) { 1823 case 0x02: 1824 /* MSKBL */ 1825 gen_msk_l(ctx, vc, va, rb, islit, lit, 0x01); 1826 break; 1827 case 0x06: 1828 /* EXTBL */ 1829 gen_ext_l(ctx, vc, va, rb, islit, lit, 0x01); 1830 break; 1831 case 0x0B: 1832 /* INSBL */ 1833 gen_ins_l(ctx, vc, va, rb, islit, lit, 0x01); 1834 break; 1835 case 0x12: 1836 /* MSKWL */ 1837 gen_msk_l(ctx, vc, va, rb, islit, lit, 0x03); 1838 break; 1839 case 0x16: 1840 /* EXTWL */ 1841 gen_ext_l(ctx, vc, va, rb, islit, lit, 0x03); 1842 break; 1843 case 0x1B: 1844 /* INSWL */ 1845 gen_ins_l(ctx, vc, va, rb, islit, lit, 0x03); 1846 break; 1847 case 0x22: 1848 /* MSKLL */ 1849 gen_msk_l(ctx, vc, va, rb, islit, lit, 0x0f); 1850 break; 1851 case 0x26: 1852 /* EXTLL */ 1853 gen_ext_l(ctx, vc, va, rb, islit, lit, 0x0f); 1854 break; 1855 case 0x2B: 1856 /* INSLL */ 1857 gen_ins_l(ctx, vc, va, rb, islit, lit, 0x0f); 1858 break; 1859 case 0x30: 1860 /* ZAP */ 1861 if (islit) { 1862 gen_zapnoti(vc, va, ~lit); 1863 } else { 1864 gen_helper_zap(vc, va, load_gpr(ctx, rb)); 1865 } 1866 break; 1867 case 0x31: 1868 /* ZAPNOT */ 1869 if (islit) { 1870 gen_zapnoti(vc, va, lit); 1871 } else { 1872 gen_helper_zapnot(vc, va, load_gpr(ctx, rb)); 1873 } 1874 break; 1875 case 0x32: 1876 /* MSKQL */ 1877 gen_msk_l(ctx, vc, va, rb, islit, lit, 0xff); 1878 break; 1879 case 0x34: 1880 /* SRL */ 1881 if (islit) { 1882 tcg_gen_shri_i64(vc, va, lit & 0x3f); 1883 } else { 1884 tmp = tcg_temp_new(); 1885 vb = load_gpr(ctx, rb); 1886 tcg_gen_andi_i64(tmp, vb, 0x3f); 1887 tcg_gen_shr_i64(vc, va, tmp); 1888 tcg_temp_free(tmp); 1889 } 1890 break; 1891 case 0x36: 1892 /* EXTQL */ 1893 gen_ext_l(ctx, vc, va, rb, islit, lit, 0xff); 1894 break; 1895 case 0x39: 1896 /* SLL */ 1897 if (islit) { 1898 tcg_gen_shli_i64(vc, va, lit & 0x3f); 1899 } else { 1900 tmp = tcg_temp_new(); 1901 vb = load_gpr(ctx, rb); 1902 tcg_gen_andi_i64(tmp, vb, 0x3f); 1903 tcg_gen_shl_i64(vc, va, tmp); 1904 tcg_temp_free(tmp); 1905 } 1906 break; 1907 case 0x3B: 1908 /* INSQL */ 1909 gen_ins_l(ctx, vc, va, rb, islit, lit, 0xff); 1910 break; 1911 case 0x3C: 1912 /* SRA */ 1913 if (islit) { 1914 tcg_gen_sari_i64(vc, va, lit & 0x3f); 1915 } else { 1916 tmp = tcg_temp_new(); 1917 vb = load_gpr(ctx, rb); 1918 tcg_gen_andi_i64(tmp, vb, 0x3f); 1919 tcg_gen_sar_i64(vc, va, tmp); 1920 tcg_temp_free(tmp); 1921 } 1922 break; 1923 case 0x52: 1924 /* MSKWH */ 1925 gen_msk_h(ctx, vc, va, rb, islit, lit, 0x03); 1926 break; 1927 case 0x57: 1928 /* INSWH */ 1929 gen_ins_h(ctx, vc, va, rb, islit, lit, 0x03); 1930 break; 1931 case 0x5A: 1932 /* EXTWH */ 1933 gen_ext_h(ctx, vc, va, rb, islit, lit, 0x03); 1934 break; 1935 case 0x62: 1936 /* MSKLH */ 1937 gen_msk_h(ctx, vc, va, rb, islit, lit, 0x0f); 1938 break; 1939 case 0x67: 1940 /* INSLH */ 1941 gen_ins_h(ctx, vc, va, rb, islit, lit, 0x0f); 1942 break; 1943 case 0x6A: 1944 /* EXTLH */ 1945 gen_ext_h(ctx, vc, va, rb, islit, lit, 0x0f); 1946 break; 1947 case 0x72: 1948 /* MSKQH */ 1949 gen_msk_h(ctx, vc, va, rb, islit, lit, 0xff); 1950 break; 1951 case 0x77: 1952 /* INSQH */ 1953 gen_ins_h(ctx, vc, va, rb, islit, lit, 0xff); 1954 break; 1955 case 0x7A: 1956 /* EXTQH */ 1957 gen_ext_h(ctx, vc, va, rb, islit, lit, 0xff); 1958 break; 1959 default: 1960 goto invalid_opc; 1961 } 1962 break; 1963 1964 case 0x13: 1965 vc = dest_gpr(ctx, rc); 1966 vb = load_gpr_lit(ctx, rb, lit, islit); 1967 va = load_gpr(ctx, ra); 1968 switch (fn7) { 1969 case 0x00: 1970 /* MULL */ 1971 tcg_gen_mul_i64(vc, va, vb); 1972 tcg_gen_ext32s_i64(vc, vc); 1973 break; 1974 case 0x20: 1975 /* MULQ */ 1976 tcg_gen_mul_i64(vc, va, vb); 1977 break; 1978 case 0x30: 1979 /* UMULH */ 1980 tmp = tcg_temp_new(); 1981 tcg_gen_mulu2_i64(tmp, vc, va, vb); 1982 tcg_temp_free(tmp); 1983 break; 1984 case 0x40: 1985 /* MULL/V */ 1986 tmp = tcg_temp_new(); 1987 tcg_gen_ext32s_i64(tmp, va); 1988 tcg_gen_ext32s_i64(vc, vb); 1989 tcg_gen_mul_i64(tmp, tmp, vc); 1990 tcg_gen_ext32s_i64(vc, tmp); 1991 gen_helper_check_overflow(cpu_env, vc, tmp); 1992 tcg_temp_free(tmp); 1993 break; 1994 case 0x60: 1995 /* MULQ/V */ 1996 tmp = tcg_temp_new(); 1997 tmp2 = tcg_temp_new(); 1998 tcg_gen_muls2_i64(vc, tmp, va, vb); 1999 tcg_gen_sari_i64(tmp2, vc, 63); 2000 gen_helper_check_overflow(cpu_env, tmp, tmp2); 2001 tcg_temp_free(tmp); 2002 tcg_temp_free(tmp2); 2003 break; 2004 default: 2005 goto invalid_opc; 2006 } 2007 break; 2008 2009 case 0x14: 2010 REQUIRE_AMASK(FIX); 2011 vc = dest_fpr(ctx, rc); 2012 switch (fpfn) { /* fn11 & 0x3F */ 2013 case 0x04: 2014 /* ITOFS */ 2015 REQUIRE_REG_31(rb); 2016 REQUIRE_FEN; 2017 t32 = tcg_temp_new_i32(); 2018 va = load_gpr(ctx, ra); 2019 tcg_gen_extrl_i64_i32(t32, va); 2020 gen_helper_memory_to_s(vc, t32); 2021 tcg_temp_free_i32(t32); 2022 break; 2023 case 0x0A: 2024 /* SQRTF */ 2025 REQUIRE_REG_31(ra); 2026 REQUIRE_FEN; 2027 vb = load_fpr(ctx, rb); 2028 gen_helper_sqrtf(vc, cpu_env, vb); 2029 break; 2030 case 0x0B: 2031 /* SQRTS */ 2032 REQUIRE_REG_31(ra); 2033 REQUIRE_FEN; 2034 gen_sqrts(ctx, rb, rc, fn11); 2035 break; 2036 case 0x14: 2037 /* ITOFF */ 2038 REQUIRE_REG_31(rb); 2039 REQUIRE_FEN; 2040 t32 = tcg_temp_new_i32(); 2041 va = load_gpr(ctx, ra); 2042 tcg_gen_extrl_i64_i32(t32, va); 2043 gen_helper_memory_to_f(vc, t32); 2044 tcg_temp_free_i32(t32); 2045 break; 2046 case 0x24: 2047 /* ITOFT */ 2048 REQUIRE_REG_31(rb); 2049 REQUIRE_FEN; 2050 va = load_gpr(ctx, ra); 2051 tcg_gen_mov_i64(vc, va); 2052 break; 2053 case 0x2A: 2054 /* SQRTG */ 2055 REQUIRE_REG_31(ra); 2056 REQUIRE_FEN; 2057 vb = load_fpr(ctx, rb); 2058 gen_helper_sqrtg(vc, cpu_env, vb); 2059 break; 2060 case 0x02B: 2061 /* SQRTT */ 2062 REQUIRE_REG_31(ra); 2063 REQUIRE_FEN; 2064 gen_sqrtt(ctx, rb, rc, fn11); 2065 break; 2066 default: 2067 goto invalid_opc; 2068 } 2069 break; 2070 2071 case 0x15: 2072 /* VAX floating point */ 2073 /* XXX: rounding mode and trap are ignored (!) */ 2074 vc = dest_fpr(ctx, rc); 2075 vb = load_fpr(ctx, rb); 2076 va = load_fpr(ctx, ra); 2077 switch (fpfn) { /* fn11 & 0x3F */ 2078 case 0x00: 2079 /* ADDF */ 2080 REQUIRE_FEN; 2081 gen_helper_addf(vc, cpu_env, va, vb); 2082 break; 2083 case 0x01: 2084 /* SUBF */ 2085 REQUIRE_FEN; 2086 gen_helper_subf(vc, cpu_env, va, vb); 2087 break; 2088 case 0x02: 2089 /* MULF */ 2090 REQUIRE_FEN; 2091 gen_helper_mulf(vc, cpu_env, va, vb); 2092 break; 2093 case 0x03: 2094 /* DIVF */ 2095 REQUIRE_FEN; 2096 gen_helper_divf(vc, cpu_env, va, vb); 2097 break; 2098 case 0x1E: 2099 /* CVTDG -- TODO */ 2100 REQUIRE_REG_31(ra); 2101 goto invalid_opc; 2102 case 0x20: 2103 /* ADDG */ 2104 REQUIRE_FEN; 2105 gen_helper_addg(vc, cpu_env, va, vb); 2106 break; 2107 case 0x21: 2108 /* SUBG */ 2109 REQUIRE_FEN; 2110 gen_helper_subg(vc, cpu_env, va, vb); 2111 break; 2112 case 0x22: 2113 /* MULG */ 2114 REQUIRE_FEN; 2115 gen_helper_mulg(vc, cpu_env, va, vb); 2116 break; 2117 case 0x23: 2118 /* DIVG */ 2119 REQUIRE_FEN; 2120 gen_helper_divg(vc, cpu_env, va, vb); 2121 break; 2122 case 0x25: 2123 /* CMPGEQ */ 2124 REQUIRE_FEN; 2125 gen_helper_cmpgeq(vc, cpu_env, va, vb); 2126 break; 2127 case 0x26: 2128 /* CMPGLT */ 2129 REQUIRE_FEN; 2130 gen_helper_cmpglt(vc, cpu_env, va, vb); 2131 break; 2132 case 0x27: 2133 /* CMPGLE */ 2134 REQUIRE_FEN; 2135 gen_helper_cmpgle(vc, cpu_env, va, vb); 2136 break; 2137 case 0x2C: 2138 /* CVTGF */ 2139 REQUIRE_REG_31(ra); 2140 REQUIRE_FEN; 2141 gen_helper_cvtgf(vc, cpu_env, vb); 2142 break; 2143 case 0x2D: 2144 /* CVTGD -- TODO */ 2145 REQUIRE_REG_31(ra); 2146 goto invalid_opc; 2147 case 0x2F: 2148 /* CVTGQ */ 2149 REQUIRE_REG_31(ra); 2150 REQUIRE_FEN; 2151 gen_helper_cvtgq(vc, cpu_env, vb); 2152 break; 2153 case 0x3C: 2154 /* CVTQF */ 2155 REQUIRE_REG_31(ra); 2156 REQUIRE_FEN; 2157 gen_helper_cvtqf(vc, cpu_env, vb); 2158 break; 2159 case 0x3E: 2160 /* CVTQG */ 2161 REQUIRE_REG_31(ra); 2162 REQUIRE_FEN; 2163 gen_helper_cvtqg(vc, cpu_env, vb); 2164 break; 2165 default: 2166 goto invalid_opc; 2167 } 2168 break; 2169 2170 case 0x16: 2171 /* IEEE floating-point */ 2172 switch (fpfn) { /* fn11 & 0x3F */ 2173 case 0x00: 2174 /* ADDS */ 2175 REQUIRE_FEN; 2176 gen_adds(ctx, ra, rb, rc, fn11); 2177 break; 2178 case 0x01: 2179 /* SUBS */ 2180 REQUIRE_FEN; 2181 gen_subs(ctx, ra, rb, rc, fn11); 2182 break; 2183 case 0x02: 2184 /* MULS */ 2185 REQUIRE_FEN; 2186 gen_muls(ctx, ra, rb, rc, fn11); 2187 break; 2188 case 0x03: 2189 /* DIVS */ 2190 REQUIRE_FEN; 2191 gen_divs(ctx, ra, rb, rc, fn11); 2192 break; 2193 case 0x20: 2194 /* ADDT */ 2195 REQUIRE_FEN; 2196 gen_addt(ctx, ra, rb, rc, fn11); 2197 break; 2198 case 0x21: 2199 /* SUBT */ 2200 REQUIRE_FEN; 2201 gen_subt(ctx, ra, rb, rc, fn11); 2202 break; 2203 case 0x22: 2204 /* MULT */ 2205 REQUIRE_FEN; 2206 gen_mult(ctx, ra, rb, rc, fn11); 2207 break; 2208 case 0x23: 2209 /* DIVT */ 2210 REQUIRE_FEN; 2211 gen_divt(ctx, ra, rb, rc, fn11); 2212 break; 2213 case 0x24: 2214 /* CMPTUN */ 2215 REQUIRE_FEN; 2216 gen_cmptun(ctx, ra, rb, rc, fn11); 2217 break; 2218 case 0x25: 2219 /* CMPTEQ */ 2220 REQUIRE_FEN; 2221 gen_cmpteq(ctx, ra, rb, rc, fn11); 2222 break; 2223 case 0x26: 2224 /* CMPTLT */ 2225 REQUIRE_FEN; 2226 gen_cmptlt(ctx, ra, rb, rc, fn11); 2227 break; 2228 case 0x27: 2229 /* CMPTLE */ 2230 REQUIRE_FEN; 2231 gen_cmptle(ctx, ra, rb, rc, fn11); 2232 break; 2233 case 0x2C: 2234 REQUIRE_REG_31(ra); 2235 REQUIRE_FEN; 2236 if (fn11 == 0x2AC || fn11 == 0x6AC) { 2237 /* CVTST */ 2238 gen_cvtst(ctx, rb, rc, fn11); 2239 } else { 2240 /* CVTTS */ 2241 gen_cvtts(ctx, rb, rc, fn11); 2242 } 2243 break; 2244 case 0x2F: 2245 /* CVTTQ */ 2246 REQUIRE_REG_31(ra); 2247 REQUIRE_FEN; 2248 gen_cvttq(ctx, rb, rc, fn11); 2249 break; 2250 case 0x3C: 2251 /* CVTQS */ 2252 REQUIRE_REG_31(ra); 2253 REQUIRE_FEN; 2254 gen_cvtqs(ctx, rb, rc, fn11); 2255 break; 2256 case 0x3E: 2257 /* CVTQT */ 2258 REQUIRE_REG_31(ra); 2259 REQUIRE_FEN; 2260 gen_cvtqt(ctx, rb, rc, fn11); 2261 break; 2262 default: 2263 goto invalid_opc; 2264 } 2265 break; 2266 2267 case 0x17: 2268 switch (fn11) { 2269 case 0x010: 2270 /* CVTLQ */ 2271 REQUIRE_REG_31(ra); 2272 REQUIRE_FEN; 2273 vc = dest_fpr(ctx, rc); 2274 vb = load_fpr(ctx, rb); 2275 gen_cvtlq(vc, vb); 2276 break; 2277 case 0x020: 2278 /* CPYS */ 2279 REQUIRE_FEN; 2280 if (rc == 31) { 2281 /* Special case CPYS as FNOP. */ 2282 } else { 2283 vc = dest_fpr(ctx, rc); 2284 va = load_fpr(ctx, ra); 2285 if (ra == rb) { 2286 /* Special case CPYS as FMOV. */ 2287 tcg_gen_mov_i64(vc, va); 2288 } else { 2289 vb = load_fpr(ctx, rb); 2290 gen_cpy_mask(vc, va, vb, 0, 0x8000000000000000ULL); 2291 } 2292 } 2293 break; 2294 case 0x021: 2295 /* CPYSN */ 2296 REQUIRE_FEN; 2297 vc = dest_fpr(ctx, rc); 2298 vb = load_fpr(ctx, rb); 2299 va = load_fpr(ctx, ra); 2300 gen_cpy_mask(vc, va, vb, 1, 0x8000000000000000ULL); 2301 break; 2302 case 0x022: 2303 /* CPYSE */ 2304 REQUIRE_FEN; 2305 vc = dest_fpr(ctx, rc); 2306 vb = load_fpr(ctx, rb); 2307 va = load_fpr(ctx, ra); 2308 gen_cpy_mask(vc, va, vb, 0, 0xFFF0000000000000ULL); 2309 break; 2310 case 0x024: 2311 /* MT_FPCR */ 2312 REQUIRE_FEN; 2313 va = load_fpr(ctx, ra); 2314 gen_helper_store_fpcr(cpu_env, va); 2315 if (ctx->tb_rm == QUAL_RM_D) { 2316 /* Re-do the copy of the rounding mode to fp_status 2317 the next time we use dynamic rounding. */ 2318 ctx->tb_rm = -1; 2319 } 2320 break; 2321 case 0x025: 2322 /* MF_FPCR */ 2323 REQUIRE_FEN; 2324 va = dest_fpr(ctx, ra); 2325 gen_helper_load_fpcr(va, cpu_env); 2326 break; 2327 case 0x02A: 2328 /* FCMOVEQ */ 2329 REQUIRE_FEN; 2330 gen_fcmov(ctx, TCG_COND_EQ, ra, rb, rc); 2331 break; 2332 case 0x02B: 2333 /* FCMOVNE */ 2334 REQUIRE_FEN; 2335 gen_fcmov(ctx, TCG_COND_NE, ra, rb, rc); 2336 break; 2337 case 0x02C: 2338 /* FCMOVLT */ 2339 REQUIRE_FEN; 2340 gen_fcmov(ctx, TCG_COND_LT, ra, rb, rc); 2341 break; 2342 case 0x02D: 2343 /* FCMOVGE */ 2344 REQUIRE_FEN; 2345 gen_fcmov(ctx, TCG_COND_GE, ra, rb, rc); 2346 break; 2347 case 0x02E: 2348 /* FCMOVLE */ 2349 REQUIRE_FEN; 2350 gen_fcmov(ctx, TCG_COND_LE, ra, rb, rc); 2351 break; 2352 case 0x02F: 2353 /* FCMOVGT */ 2354 REQUIRE_FEN; 2355 gen_fcmov(ctx, TCG_COND_GT, ra, rb, rc); 2356 break; 2357 case 0x030: /* CVTQL */ 2358 case 0x130: /* CVTQL/V */ 2359 case 0x530: /* CVTQL/SV */ 2360 REQUIRE_REG_31(ra); 2361 REQUIRE_FEN; 2362 vc = dest_fpr(ctx, rc); 2363 vb = load_fpr(ctx, rb); 2364 gen_helper_cvtql(vc, cpu_env, vb); 2365 gen_fp_exc_raise(rc, fn11); 2366 break; 2367 default: 2368 goto invalid_opc; 2369 } 2370 break; 2371 2372 case 0x18: 2373 switch ((uint16_t)disp16) { 2374 case 0x0000: 2375 /* TRAPB */ 2376 /* No-op. */ 2377 break; 2378 case 0x0400: 2379 /* EXCB */ 2380 /* No-op. */ 2381 break; 2382 case 0x4000: 2383 /* MB */ 2384 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC); 2385 break; 2386 case 0x4400: 2387 /* WMB */ 2388 tcg_gen_mb(TCG_MO_ST_ST | TCG_BAR_SC); 2389 break; 2390 case 0x8000: 2391 /* FETCH */ 2392 /* No-op */ 2393 break; 2394 case 0xA000: 2395 /* FETCH_M */ 2396 /* No-op */ 2397 break; 2398 case 0xC000: 2399 /* RPCC */ 2400 va = dest_gpr(ctx, ra); 2401 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 2402 gen_io_start(); 2403 gen_helper_load_pcc(va, cpu_env); 2404 ret = DISAS_PC_STALE; 2405 } else { 2406 gen_helper_load_pcc(va, cpu_env); 2407 } 2408 break; 2409 case 0xE000: 2410 /* RC */ 2411 gen_rx(ctx, ra, 0); 2412 break; 2413 case 0xE800: 2414 /* ECB */ 2415 break; 2416 case 0xF000: 2417 /* RS */ 2418 gen_rx(ctx, ra, 1); 2419 break; 2420 case 0xF800: 2421 /* WH64 */ 2422 /* No-op */ 2423 break; 2424 case 0xFC00: 2425 /* WH64EN */ 2426 /* No-op */ 2427 break; 2428 default: 2429 goto invalid_opc; 2430 } 2431 break; 2432 2433 case 0x19: 2434 /* HW_MFPR (PALcode) */ 2435 #ifndef CONFIG_USER_ONLY 2436 REQUIRE_TB_FLAG(ENV_FLAG_PAL_MODE); 2437 va = dest_gpr(ctx, ra); 2438 ret = gen_mfpr(ctx, va, insn & 0xffff); 2439 break; 2440 #else 2441 goto invalid_opc; 2442 #endif 2443 2444 case 0x1A: 2445 /* JMP, JSR, RET, JSR_COROUTINE. These only differ by the branch 2446 prediction stack action, which of course we don't implement. */ 2447 vb = load_gpr(ctx, rb); 2448 tcg_gen_andi_i64(cpu_pc, vb, ~3); 2449 if (ra != 31) { 2450 tcg_gen_movi_i64(ctx->ir[ra], ctx->base.pc_next); 2451 } 2452 ret = DISAS_PC_UPDATED; 2453 break; 2454 2455 case 0x1B: 2456 /* HW_LD (PALcode) */ 2457 #ifndef CONFIG_USER_ONLY 2458 REQUIRE_TB_FLAG(ENV_FLAG_PAL_MODE); 2459 { 2460 TCGv addr = tcg_temp_new(); 2461 vb = load_gpr(ctx, rb); 2462 va = dest_gpr(ctx, ra); 2463 2464 tcg_gen_addi_i64(addr, vb, disp12); 2465 switch ((insn >> 12) & 0xF) { 2466 case 0x0: 2467 /* Longword physical access (hw_ldl/p) */ 2468 tcg_gen_qemu_ld_i64(va, addr, MMU_PHYS_IDX, MO_LESL); 2469 break; 2470 case 0x1: 2471 /* Quadword physical access (hw_ldq/p) */ 2472 tcg_gen_qemu_ld_i64(va, addr, MMU_PHYS_IDX, MO_LEUQ); 2473 break; 2474 case 0x2: 2475 /* Longword physical access with lock (hw_ldl_l/p) */ 2476 tcg_gen_qemu_ld_i64(va, addr, MMU_PHYS_IDX, MO_LESL); 2477 tcg_gen_mov_i64(cpu_lock_addr, addr); 2478 tcg_gen_mov_i64(cpu_lock_value, va); 2479 break; 2480 case 0x3: 2481 /* Quadword physical access with lock (hw_ldq_l/p) */ 2482 tcg_gen_qemu_ld_i64(va, addr, MMU_PHYS_IDX, MO_LEUQ); 2483 tcg_gen_mov_i64(cpu_lock_addr, addr); 2484 tcg_gen_mov_i64(cpu_lock_value, va); 2485 break; 2486 case 0x4: 2487 /* Longword virtual PTE fetch (hw_ldl/v) */ 2488 goto invalid_opc; 2489 case 0x5: 2490 /* Quadword virtual PTE fetch (hw_ldq/v) */ 2491 goto invalid_opc; 2492 break; 2493 case 0x6: 2494 /* Invalid */ 2495 goto invalid_opc; 2496 case 0x7: 2497 /* Invaliid */ 2498 goto invalid_opc; 2499 case 0x8: 2500 /* Longword virtual access (hw_ldl) */ 2501 goto invalid_opc; 2502 case 0x9: 2503 /* Quadword virtual access (hw_ldq) */ 2504 goto invalid_opc; 2505 case 0xA: 2506 /* Longword virtual access with protection check (hw_ldl/w) */ 2507 tcg_gen_qemu_ld_i64(va, addr, MMU_KERNEL_IDX, MO_LESL); 2508 break; 2509 case 0xB: 2510 /* Quadword virtual access with protection check (hw_ldq/w) */ 2511 tcg_gen_qemu_ld_i64(va, addr, MMU_KERNEL_IDX, MO_LEUQ); 2512 break; 2513 case 0xC: 2514 /* Longword virtual access with alt access mode (hw_ldl/a)*/ 2515 goto invalid_opc; 2516 case 0xD: 2517 /* Quadword virtual access with alt access mode (hw_ldq/a) */ 2518 goto invalid_opc; 2519 case 0xE: 2520 /* Longword virtual access with alternate access mode and 2521 protection checks (hw_ldl/wa) */ 2522 tcg_gen_qemu_ld_i64(va, addr, MMU_USER_IDX, MO_LESL); 2523 break; 2524 case 0xF: 2525 /* Quadword virtual access with alternate access mode and 2526 protection checks (hw_ldq/wa) */ 2527 tcg_gen_qemu_ld_i64(va, addr, MMU_USER_IDX, MO_LEUQ); 2528 break; 2529 } 2530 tcg_temp_free(addr); 2531 break; 2532 } 2533 #else 2534 goto invalid_opc; 2535 #endif 2536 2537 case 0x1C: 2538 vc = dest_gpr(ctx, rc); 2539 if (fn7 == 0x70) { 2540 /* FTOIT */ 2541 REQUIRE_AMASK(FIX); 2542 REQUIRE_REG_31(rb); 2543 va = load_fpr(ctx, ra); 2544 tcg_gen_mov_i64(vc, va); 2545 break; 2546 } else if (fn7 == 0x78) { 2547 /* FTOIS */ 2548 REQUIRE_AMASK(FIX); 2549 REQUIRE_REG_31(rb); 2550 t32 = tcg_temp_new_i32(); 2551 va = load_fpr(ctx, ra); 2552 gen_helper_s_to_memory(t32, va); 2553 tcg_gen_ext_i32_i64(vc, t32); 2554 tcg_temp_free_i32(t32); 2555 break; 2556 } 2557 2558 vb = load_gpr_lit(ctx, rb, lit, islit); 2559 switch (fn7) { 2560 case 0x00: 2561 /* SEXTB */ 2562 REQUIRE_AMASK(BWX); 2563 REQUIRE_REG_31(ra); 2564 tcg_gen_ext8s_i64(vc, vb); 2565 break; 2566 case 0x01: 2567 /* SEXTW */ 2568 REQUIRE_AMASK(BWX); 2569 REQUIRE_REG_31(ra); 2570 tcg_gen_ext16s_i64(vc, vb); 2571 break; 2572 case 0x30: 2573 /* CTPOP */ 2574 REQUIRE_AMASK(CIX); 2575 REQUIRE_REG_31(ra); 2576 REQUIRE_NO_LIT; 2577 tcg_gen_ctpop_i64(vc, vb); 2578 break; 2579 case 0x31: 2580 /* PERR */ 2581 REQUIRE_AMASK(MVI); 2582 REQUIRE_NO_LIT; 2583 va = load_gpr(ctx, ra); 2584 gen_helper_perr(vc, va, vb); 2585 break; 2586 case 0x32: 2587 /* CTLZ */ 2588 REQUIRE_AMASK(CIX); 2589 REQUIRE_REG_31(ra); 2590 REQUIRE_NO_LIT; 2591 tcg_gen_clzi_i64(vc, vb, 64); 2592 break; 2593 case 0x33: 2594 /* CTTZ */ 2595 REQUIRE_AMASK(CIX); 2596 REQUIRE_REG_31(ra); 2597 REQUIRE_NO_LIT; 2598 tcg_gen_ctzi_i64(vc, vb, 64); 2599 break; 2600 case 0x34: 2601 /* UNPKBW */ 2602 REQUIRE_AMASK(MVI); 2603 REQUIRE_REG_31(ra); 2604 REQUIRE_NO_LIT; 2605 gen_helper_unpkbw(vc, vb); 2606 break; 2607 case 0x35: 2608 /* UNPKBL */ 2609 REQUIRE_AMASK(MVI); 2610 REQUIRE_REG_31(ra); 2611 REQUIRE_NO_LIT; 2612 gen_helper_unpkbl(vc, vb); 2613 break; 2614 case 0x36: 2615 /* PKWB */ 2616 REQUIRE_AMASK(MVI); 2617 REQUIRE_REG_31(ra); 2618 REQUIRE_NO_LIT; 2619 gen_helper_pkwb(vc, vb); 2620 break; 2621 case 0x37: 2622 /* PKLB */ 2623 REQUIRE_AMASK(MVI); 2624 REQUIRE_REG_31(ra); 2625 REQUIRE_NO_LIT; 2626 gen_helper_pklb(vc, vb); 2627 break; 2628 case 0x38: 2629 /* MINSB8 */ 2630 REQUIRE_AMASK(MVI); 2631 va = load_gpr(ctx, ra); 2632 gen_helper_minsb8(vc, va, vb); 2633 break; 2634 case 0x39: 2635 /* MINSW4 */ 2636 REQUIRE_AMASK(MVI); 2637 va = load_gpr(ctx, ra); 2638 gen_helper_minsw4(vc, va, vb); 2639 break; 2640 case 0x3A: 2641 /* MINUB8 */ 2642 REQUIRE_AMASK(MVI); 2643 va = load_gpr(ctx, ra); 2644 gen_helper_minub8(vc, va, vb); 2645 break; 2646 case 0x3B: 2647 /* MINUW4 */ 2648 REQUIRE_AMASK(MVI); 2649 va = load_gpr(ctx, ra); 2650 gen_helper_minuw4(vc, va, vb); 2651 break; 2652 case 0x3C: 2653 /* MAXUB8 */ 2654 REQUIRE_AMASK(MVI); 2655 va = load_gpr(ctx, ra); 2656 gen_helper_maxub8(vc, va, vb); 2657 break; 2658 case 0x3D: 2659 /* MAXUW4 */ 2660 REQUIRE_AMASK(MVI); 2661 va = load_gpr(ctx, ra); 2662 gen_helper_maxuw4(vc, va, vb); 2663 break; 2664 case 0x3E: 2665 /* MAXSB8 */ 2666 REQUIRE_AMASK(MVI); 2667 va = load_gpr(ctx, ra); 2668 gen_helper_maxsb8(vc, va, vb); 2669 break; 2670 case 0x3F: 2671 /* MAXSW4 */ 2672 REQUIRE_AMASK(MVI); 2673 va = load_gpr(ctx, ra); 2674 gen_helper_maxsw4(vc, va, vb); 2675 break; 2676 default: 2677 goto invalid_opc; 2678 } 2679 break; 2680 2681 case 0x1D: 2682 /* HW_MTPR (PALcode) */ 2683 #ifndef CONFIG_USER_ONLY 2684 REQUIRE_TB_FLAG(ENV_FLAG_PAL_MODE); 2685 vb = load_gpr(ctx, rb); 2686 ret = gen_mtpr(ctx, vb, insn & 0xffff); 2687 break; 2688 #else 2689 goto invalid_opc; 2690 #endif 2691 2692 case 0x1E: 2693 /* HW_RET (PALcode) */ 2694 #ifndef CONFIG_USER_ONLY 2695 REQUIRE_TB_FLAG(ENV_FLAG_PAL_MODE); 2696 if (rb == 31) { 2697 /* Pre-EV6 CPUs interpreted this as HW_REI, loading the return 2698 address from EXC_ADDR. This turns out to be useful for our 2699 emulation PALcode, so continue to accept it. */ 2700 vb = dest_sink(ctx); 2701 tcg_gen_ld_i64(vb, cpu_env, offsetof(CPUAlphaState, exc_addr)); 2702 } else { 2703 vb = load_gpr(ctx, rb); 2704 } 2705 tcg_gen_movi_i64(cpu_lock_addr, -1); 2706 st_flag_byte(load_zero(ctx), ENV_FLAG_RX_SHIFT); 2707 tmp = tcg_temp_new(); 2708 tcg_gen_andi_i64(tmp, vb, 1); 2709 st_flag_byte(tmp, ENV_FLAG_PAL_SHIFT); 2710 tcg_temp_free(tmp); 2711 tcg_gen_andi_i64(cpu_pc, vb, ~3); 2712 /* Allow interrupts to be recognized right away. */ 2713 ret = DISAS_PC_UPDATED_NOCHAIN; 2714 break; 2715 #else 2716 goto invalid_opc; 2717 #endif 2718 2719 case 0x1F: 2720 /* HW_ST (PALcode) */ 2721 #ifndef CONFIG_USER_ONLY 2722 REQUIRE_TB_FLAG(ENV_FLAG_PAL_MODE); 2723 { 2724 switch ((insn >> 12) & 0xF) { 2725 case 0x0: 2726 /* Longword physical access */ 2727 va = load_gpr(ctx, ra); 2728 vb = load_gpr(ctx, rb); 2729 tmp = tcg_temp_new(); 2730 tcg_gen_addi_i64(tmp, vb, disp12); 2731 tcg_gen_qemu_st_i64(va, tmp, MMU_PHYS_IDX, MO_LESL); 2732 tcg_temp_free(tmp); 2733 break; 2734 case 0x1: 2735 /* Quadword physical access */ 2736 va = load_gpr(ctx, ra); 2737 vb = load_gpr(ctx, rb); 2738 tmp = tcg_temp_new(); 2739 tcg_gen_addi_i64(tmp, vb, disp12); 2740 tcg_gen_qemu_st_i64(va, tmp, MMU_PHYS_IDX, MO_LEUQ); 2741 tcg_temp_free(tmp); 2742 break; 2743 case 0x2: 2744 /* Longword physical access with lock */ 2745 ret = gen_store_conditional(ctx, ra, rb, disp12, 2746 MMU_PHYS_IDX, MO_LESL); 2747 break; 2748 case 0x3: 2749 /* Quadword physical access with lock */ 2750 ret = gen_store_conditional(ctx, ra, rb, disp12, 2751 MMU_PHYS_IDX, MO_LEUQ); 2752 break; 2753 case 0x4: 2754 /* Longword virtual access */ 2755 goto invalid_opc; 2756 case 0x5: 2757 /* Quadword virtual access */ 2758 goto invalid_opc; 2759 case 0x6: 2760 /* Invalid */ 2761 goto invalid_opc; 2762 case 0x7: 2763 /* Invalid */ 2764 goto invalid_opc; 2765 case 0x8: 2766 /* Invalid */ 2767 goto invalid_opc; 2768 case 0x9: 2769 /* Invalid */ 2770 goto invalid_opc; 2771 case 0xA: 2772 /* Invalid */ 2773 goto invalid_opc; 2774 case 0xB: 2775 /* Invalid */ 2776 goto invalid_opc; 2777 case 0xC: 2778 /* Longword virtual access with alternate access mode */ 2779 goto invalid_opc; 2780 case 0xD: 2781 /* Quadword virtual access with alternate access mode */ 2782 goto invalid_opc; 2783 case 0xE: 2784 /* Invalid */ 2785 goto invalid_opc; 2786 case 0xF: 2787 /* Invalid */ 2788 goto invalid_opc; 2789 } 2790 break; 2791 } 2792 #else 2793 goto invalid_opc; 2794 #endif 2795 case 0x20: 2796 /* LDF */ 2797 REQUIRE_FEN; 2798 gen_load_fp(ctx, ra, rb, disp16, gen_ldf); 2799 break; 2800 case 0x21: 2801 /* LDG */ 2802 REQUIRE_FEN; 2803 gen_load_fp(ctx, ra, rb, disp16, gen_ldg); 2804 break; 2805 case 0x22: 2806 /* LDS */ 2807 REQUIRE_FEN; 2808 gen_load_fp(ctx, ra, rb, disp16, gen_lds); 2809 break; 2810 case 0x23: 2811 /* LDT */ 2812 REQUIRE_FEN; 2813 gen_load_fp(ctx, ra, rb, disp16, gen_ldt); 2814 break; 2815 case 0x24: 2816 /* STF */ 2817 REQUIRE_FEN; 2818 gen_store_fp(ctx, ra, rb, disp16, gen_stf); 2819 break; 2820 case 0x25: 2821 /* STG */ 2822 REQUIRE_FEN; 2823 gen_store_fp(ctx, ra, rb, disp16, gen_stg); 2824 break; 2825 case 0x26: 2826 /* STS */ 2827 REQUIRE_FEN; 2828 gen_store_fp(ctx, ra, rb, disp16, gen_sts); 2829 break; 2830 case 0x27: 2831 /* STT */ 2832 REQUIRE_FEN; 2833 gen_store_fp(ctx, ra, rb, disp16, gen_stt); 2834 break; 2835 case 0x28: 2836 /* LDL */ 2837 gen_load_int(ctx, ra, rb, disp16, MO_LESL, 0, 0); 2838 break; 2839 case 0x29: 2840 /* LDQ */ 2841 gen_load_int(ctx, ra, rb, disp16, MO_LEUQ, 0, 0); 2842 break; 2843 case 0x2A: 2844 /* LDL_L */ 2845 gen_load_int(ctx, ra, rb, disp16, MO_LESL, 0, 1); 2846 break; 2847 case 0x2B: 2848 /* LDQ_L */ 2849 gen_load_int(ctx, ra, rb, disp16, MO_LEUQ, 0, 1); 2850 break; 2851 case 0x2C: 2852 /* STL */ 2853 gen_store_int(ctx, ra, rb, disp16, MO_LEUL, 0); 2854 break; 2855 case 0x2D: 2856 /* STQ */ 2857 gen_store_int(ctx, ra, rb, disp16, MO_LEUQ, 0); 2858 break; 2859 case 0x2E: 2860 /* STL_C */ 2861 ret = gen_store_conditional(ctx, ra, rb, disp16, 2862 ctx->mem_idx, MO_LESL); 2863 break; 2864 case 0x2F: 2865 /* STQ_C */ 2866 ret = gen_store_conditional(ctx, ra, rb, disp16, 2867 ctx->mem_idx, MO_LEUQ); 2868 break; 2869 case 0x30: 2870 /* BR */ 2871 ret = gen_bdirect(ctx, ra, disp21); 2872 break; 2873 case 0x31: /* FBEQ */ 2874 REQUIRE_FEN; 2875 ret = gen_fbcond(ctx, TCG_COND_EQ, ra, disp21); 2876 break; 2877 case 0x32: /* FBLT */ 2878 REQUIRE_FEN; 2879 ret = gen_fbcond(ctx, TCG_COND_LT, ra, disp21); 2880 break; 2881 case 0x33: /* FBLE */ 2882 REQUIRE_FEN; 2883 ret = gen_fbcond(ctx, TCG_COND_LE, ra, disp21); 2884 break; 2885 case 0x34: 2886 /* BSR */ 2887 ret = gen_bdirect(ctx, ra, disp21); 2888 break; 2889 case 0x35: /* FBNE */ 2890 REQUIRE_FEN; 2891 ret = gen_fbcond(ctx, TCG_COND_NE, ra, disp21); 2892 break; 2893 case 0x36: /* FBGE */ 2894 REQUIRE_FEN; 2895 ret = gen_fbcond(ctx, TCG_COND_GE, ra, disp21); 2896 break; 2897 case 0x37: /* FBGT */ 2898 REQUIRE_FEN; 2899 ret = gen_fbcond(ctx, TCG_COND_GT, ra, disp21); 2900 break; 2901 case 0x38: 2902 /* BLBC */ 2903 ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 1); 2904 break; 2905 case 0x39: 2906 /* BEQ */ 2907 ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 0); 2908 break; 2909 case 0x3A: 2910 /* BLT */ 2911 ret = gen_bcond(ctx, TCG_COND_LT, ra, disp21, 0); 2912 break; 2913 case 0x3B: 2914 /* BLE */ 2915 ret = gen_bcond(ctx, TCG_COND_LE, ra, disp21, 0); 2916 break; 2917 case 0x3C: 2918 /* BLBS */ 2919 ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, 1); 2920 break; 2921 case 0x3D: 2922 /* BNE */ 2923 ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, 0); 2924 break; 2925 case 0x3E: 2926 /* BGE */ 2927 ret = gen_bcond(ctx, TCG_COND_GE, ra, disp21, 0); 2928 break; 2929 case 0x3F: 2930 /* BGT */ 2931 ret = gen_bcond(ctx, TCG_COND_GT, ra, disp21, 0); 2932 break; 2933 invalid_opc: 2934 ret = gen_invalid(ctx); 2935 break; 2936 raise_fen: 2937 ret = gen_excp(ctx, EXCP_FEN, 0); 2938 break; 2939 } 2940 2941 return ret; 2942 } 2943 2944 static void alpha_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu) 2945 { 2946 DisasContext *ctx = container_of(dcbase, DisasContext, base); 2947 CPUAlphaState *env = cpu->env_ptr; 2948 int64_t bound; 2949 2950 ctx->tbflags = ctx->base.tb->flags; 2951 ctx->mem_idx = cpu_mmu_index(env, false); 2952 ctx->implver = env->implver; 2953 ctx->amask = env->amask; 2954 2955 #ifdef CONFIG_USER_ONLY 2956 ctx->ir = cpu_std_ir; 2957 ctx->unalign = (ctx->tbflags & TB_FLAG_UNALIGN ? MO_UNALN : MO_ALIGN); 2958 #else 2959 ctx->palbr = env->palbr; 2960 ctx->ir = (ctx->tbflags & ENV_FLAG_PAL_MODE ? cpu_pal_ir : cpu_std_ir); 2961 #endif 2962 2963 /* ??? Every TB begins with unset rounding mode, to be initialized on 2964 the first fp insn of the TB. Alternately we could define a proper 2965 default for every TB (e.g. QUAL_RM_N or QUAL_RM_D) and make sure 2966 to reset the FP_STATUS to that default at the end of any TB that 2967 changes the default. We could even (gasp) dynamiclly figure out 2968 what default would be most efficient given the running program. */ 2969 ctx->tb_rm = -1; 2970 /* Similarly for flush-to-zero. */ 2971 ctx->tb_ftz = -1; 2972 2973 ctx->zero = NULL; 2974 ctx->sink = NULL; 2975 2976 /* Bound the number of insns to execute to those left on the page. */ 2977 bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4; 2978 ctx->base.max_insns = MIN(ctx->base.max_insns, bound); 2979 } 2980 2981 static void alpha_tr_tb_start(DisasContextBase *db, CPUState *cpu) 2982 { 2983 } 2984 2985 static void alpha_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) 2986 { 2987 tcg_gen_insn_start(dcbase->pc_next); 2988 } 2989 2990 static void alpha_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) 2991 { 2992 DisasContext *ctx = container_of(dcbase, DisasContext, base); 2993 CPUAlphaState *env = cpu->env_ptr; 2994 uint32_t insn = translator_ldl(env, &ctx->base, ctx->base.pc_next); 2995 2996 ctx->base.pc_next += 4; 2997 ctx->base.is_jmp = translate_one(ctx, insn); 2998 2999 free_context_temps(ctx); 3000 translator_loop_temp_check(&ctx->base); 3001 } 3002 3003 static void alpha_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) 3004 { 3005 DisasContext *ctx = container_of(dcbase, DisasContext, base); 3006 3007 switch (ctx->base.is_jmp) { 3008 case DISAS_NORETURN: 3009 break; 3010 case DISAS_TOO_MANY: 3011 if (use_goto_tb(ctx, ctx->base.pc_next)) { 3012 tcg_gen_goto_tb(0); 3013 tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next); 3014 tcg_gen_exit_tb(ctx->base.tb, 0); 3015 } 3016 /* FALLTHRU */ 3017 case DISAS_PC_STALE: 3018 tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next); 3019 /* FALLTHRU */ 3020 case DISAS_PC_UPDATED: 3021 tcg_gen_lookup_and_goto_ptr(); 3022 break; 3023 case DISAS_PC_UPDATED_NOCHAIN: 3024 tcg_gen_exit_tb(NULL, 0); 3025 break; 3026 default: 3027 g_assert_not_reached(); 3028 } 3029 } 3030 3031 static void alpha_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu) 3032 { 3033 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first)); 3034 log_target_disas(cpu, dcbase->pc_first, dcbase->tb->size); 3035 } 3036 3037 static const TranslatorOps alpha_tr_ops = { 3038 .init_disas_context = alpha_tr_init_disas_context, 3039 .tb_start = alpha_tr_tb_start, 3040 .insn_start = alpha_tr_insn_start, 3041 .translate_insn = alpha_tr_translate_insn, 3042 .tb_stop = alpha_tr_tb_stop, 3043 .disas_log = alpha_tr_disas_log, 3044 }; 3045 3046 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns) 3047 { 3048 DisasContext dc; 3049 translator_loop(&alpha_tr_ops, &dc.base, cpu, tb, max_insns); 3050 } 3051 3052 void restore_state_to_opc(CPUAlphaState *env, TranslationBlock *tb, 3053 target_ulong *data) 3054 { 3055 env->pc = data[0]; 3056 } 3057