1 /* 2 * PowerPC emulation for qemu: main translation routines. 3 * 4 * Copyright (c) 2003-2007 Jocelyn Mayer 5 * Copyright (C) 2011 Freescale Semiconductor, Inc. 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 #include "qemu/osdep.h" 22 #include "cpu.h" 23 #include "internal.h" 24 #include "exec/exec-all.h" 25 #include "tcg/tcg-op.h" 26 #include "tcg/tcg-op-gvec.h" 27 #include "qemu/host-utils.h" 28 29 #include "exec/helper-proto.h" 30 #include "exec/helper-gen.h" 31 32 #include "exec/translator.h" 33 #include "exec/log.h" 34 #include "qemu/atomic128.h" 35 #include "spr_common.h" 36 #include "power8-pmu.h" 37 38 #include "qemu/qemu-print.h" 39 #include "qapi/error.h" 40 41 #define HELPER_H "helper.h" 42 #include "exec/helper-info.c.inc" 43 #undef HELPER_H 44 45 #define CPU_SINGLE_STEP 0x1 46 #define CPU_BRANCH_STEP 0x2 47 48 /* Include definitions for instructions classes and implementations flags */ 49 /* #define PPC_DEBUG_DISAS */ 50 51 #ifdef PPC_DEBUG_DISAS 52 # define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__) 53 #else 54 # define LOG_DISAS(...) do { } while (0) 55 #endif 56 /*****************************************************************************/ 57 /* Code translation helpers */ 58 59 /* global register indexes */ 60 static char cpu_reg_names[10 * 3 + 22 * 4 /* GPR */ 61 + 10 * 4 + 22 * 5 /* SPE GPRh */ 62 + 8 * 5 /* CRF */]; 63 static TCGv cpu_gpr[32]; 64 static TCGv cpu_gprh[32]; 65 static TCGv_i32 cpu_crf[8]; 66 static TCGv cpu_nip; 67 static TCGv cpu_msr; 68 static TCGv cpu_ctr; 69 static TCGv cpu_lr; 70 #if defined(TARGET_PPC64) 71 static TCGv cpu_cfar; 72 #endif 73 static TCGv cpu_xer, cpu_so, cpu_ov, cpu_ca, cpu_ov32, cpu_ca32; 74 static TCGv cpu_reserve; 75 static TCGv cpu_reserve_length; 76 static TCGv cpu_reserve_val; 77 #if defined(TARGET_PPC64) 78 static TCGv cpu_reserve_val2; 79 #endif 80 static TCGv cpu_fpscr; 81 static TCGv_i32 cpu_access_type; 82 83 void ppc_translate_init(void) 84 { 85 int i; 86 char *p; 87 size_t cpu_reg_names_size; 88 89 p = cpu_reg_names; 90 cpu_reg_names_size = sizeof(cpu_reg_names); 91 92 for (i = 0; i < 8; i++) { 93 snprintf(p, cpu_reg_names_size, "crf%d", i); 94 cpu_crf[i] = tcg_global_mem_new_i32(tcg_env, 95 offsetof(CPUPPCState, crf[i]), p); 96 p += 5; 97 cpu_reg_names_size -= 5; 98 } 99 100 for (i = 0; i < 32; i++) { 101 snprintf(p, cpu_reg_names_size, "r%d", i); 102 cpu_gpr[i] = tcg_global_mem_new(tcg_env, 103 offsetof(CPUPPCState, gpr[i]), p); 104 p += (i < 10) ? 3 : 4; 105 cpu_reg_names_size -= (i < 10) ? 3 : 4; 106 snprintf(p, cpu_reg_names_size, "r%dH", i); 107 cpu_gprh[i] = tcg_global_mem_new(tcg_env, 108 offsetof(CPUPPCState, gprh[i]), p); 109 p += (i < 10) ? 4 : 5; 110 cpu_reg_names_size -= (i < 10) ? 4 : 5; 111 } 112 113 cpu_nip = tcg_global_mem_new(tcg_env, 114 offsetof(CPUPPCState, nip), "nip"); 115 116 cpu_msr = tcg_global_mem_new(tcg_env, 117 offsetof(CPUPPCState, msr), "msr"); 118 119 cpu_ctr = tcg_global_mem_new(tcg_env, 120 offsetof(CPUPPCState, ctr), "ctr"); 121 122 cpu_lr = tcg_global_mem_new(tcg_env, 123 offsetof(CPUPPCState, lr), "lr"); 124 125 #if defined(TARGET_PPC64) 126 cpu_cfar = tcg_global_mem_new(tcg_env, 127 offsetof(CPUPPCState, cfar), "cfar"); 128 #endif 129 130 cpu_xer = tcg_global_mem_new(tcg_env, 131 offsetof(CPUPPCState, xer), "xer"); 132 cpu_so = tcg_global_mem_new(tcg_env, 133 offsetof(CPUPPCState, so), "SO"); 134 cpu_ov = tcg_global_mem_new(tcg_env, 135 offsetof(CPUPPCState, ov), "OV"); 136 cpu_ca = tcg_global_mem_new(tcg_env, 137 offsetof(CPUPPCState, ca), "CA"); 138 cpu_ov32 = tcg_global_mem_new(tcg_env, 139 offsetof(CPUPPCState, ov32), "OV32"); 140 cpu_ca32 = tcg_global_mem_new(tcg_env, 141 offsetof(CPUPPCState, ca32), "CA32"); 142 143 cpu_reserve = tcg_global_mem_new(tcg_env, 144 offsetof(CPUPPCState, reserve_addr), 145 "reserve_addr"); 146 cpu_reserve_length = tcg_global_mem_new(tcg_env, 147 offsetof(CPUPPCState, 148 reserve_length), 149 "reserve_length"); 150 cpu_reserve_val = tcg_global_mem_new(tcg_env, 151 offsetof(CPUPPCState, reserve_val), 152 "reserve_val"); 153 #if defined(TARGET_PPC64) 154 cpu_reserve_val2 = tcg_global_mem_new(tcg_env, 155 offsetof(CPUPPCState, reserve_val2), 156 "reserve_val2"); 157 #endif 158 159 cpu_fpscr = tcg_global_mem_new(tcg_env, 160 offsetof(CPUPPCState, fpscr), "fpscr"); 161 162 cpu_access_type = tcg_global_mem_new_i32(tcg_env, 163 offsetof(CPUPPCState, access_type), 164 "access_type"); 165 } 166 167 /* internal defines */ 168 struct DisasContext { 169 DisasContextBase base; 170 target_ulong cia; /* current instruction address */ 171 uint32_t opcode; 172 /* Routine used to access memory */ 173 bool pr, hv, dr, le_mode; 174 bool lazy_tlb_flush; 175 bool need_access_type; 176 int mem_idx; 177 int access_type; 178 /* Translation flags */ 179 MemOp default_tcg_memop_mask; 180 #if defined(TARGET_PPC64) 181 bool sf_mode; 182 bool has_cfar; 183 bool has_bhrb; 184 #endif 185 bool fpu_enabled; 186 bool altivec_enabled; 187 bool vsx_enabled; 188 bool spe_enabled; 189 bool tm_enabled; 190 bool gtse; 191 bool hr; 192 bool mmcr0_pmcc0; 193 bool mmcr0_pmcc1; 194 bool mmcr0_pmcjce; 195 bool pmc_other; 196 bool pmu_insn_cnt; 197 bool bhrb_enable; 198 ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */ 199 int singlestep_enabled; 200 uint32_t flags; 201 uint64_t insns_flags; 202 uint64_t insns_flags2; 203 }; 204 205 #define DISAS_EXIT DISAS_TARGET_0 /* exit to main loop, pc updated */ 206 #define DISAS_EXIT_UPDATE DISAS_TARGET_1 /* exit to main loop, pc stale */ 207 #define DISAS_CHAIN DISAS_TARGET_2 /* lookup next tb, pc updated */ 208 #define DISAS_CHAIN_UPDATE DISAS_TARGET_3 /* lookup next tb, pc stale */ 209 210 /* Return true iff byteswap is needed in a scalar memop */ 211 static inline bool need_byteswap(const DisasContext *ctx) 212 { 213 #if TARGET_BIG_ENDIAN 214 return ctx->le_mode; 215 #else 216 return !ctx->le_mode; 217 #endif 218 } 219 220 /* True when active word size < size of target_long. */ 221 #ifdef TARGET_PPC64 222 # define NARROW_MODE(C) (!(C)->sf_mode) 223 #else 224 # define NARROW_MODE(C) 0 225 #endif 226 227 struct opc_handler_t { 228 /* invalid bits for instruction 1 (Rc(opcode) == 0) */ 229 uint32_t inval1; 230 /* invalid bits for instruction 2 (Rc(opcode) == 1) */ 231 uint32_t inval2; 232 /* instruction type */ 233 uint64_t type; 234 /* extended instruction type */ 235 uint64_t type2; 236 /* handler */ 237 void (*handler)(DisasContext *ctx); 238 }; 239 240 static inline bool gen_serialize(DisasContext *ctx) 241 { 242 if (tb_cflags(ctx->base.tb) & CF_PARALLEL) { 243 /* Restart with exclusive lock. */ 244 gen_helper_exit_atomic(tcg_env); 245 ctx->base.is_jmp = DISAS_NORETURN; 246 return false; 247 } 248 return true; 249 } 250 251 #if !defined(CONFIG_USER_ONLY) 252 #if defined(TARGET_PPC64) 253 static inline bool gen_serialize_core(DisasContext *ctx) 254 { 255 if (ctx->flags & POWERPC_FLAG_SMT) { 256 return gen_serialize(ctx); 257 } 258 return true; 259 } 260 #endif 261 262 static inline bool gen_serialize_core_lpar(DisasContext *ctx) 263 { 264 #if defined(TARGET_PPC64) 265 if (ctx->flags & POWERPC_FLAG_SMT_1LPAR) { 266 return gen_serialize(ctx); 267 } 268 #endif 269 return true; 270 } 271 #endif 272 273 /* SPR load/store helpers */ 274 static inline void gen_load_spr(TCGv t, int reg) 275 { 276 tcg_gen_ld_tl(t, tcg_env, offsetof(CPUPPCState, spr[reg])); 277 } 278 279 static inline void gen_store_spr(int reg, TCGv t) 280 { 281 tcg_gen_st_tl(t, tcg_env, offsetof(CPUPPCState, spr[reg])); 282 } 283 284 static inline void gen_set_access_type(DisasContext *ctx, int access_type) 285 { 286 if (ctx->need_access_type && ctx->access_type != access_type) { 287 tcg_gen_movi_i32(cpu_access_type, access_type); 288 ctx->access_type = access_type; 289 } 290 } 291 292 static inline void gen_update_nip(DisasContext *ctx, target_ulong nip) 293 { 294 if (NARROW_MODE(ctx)) { 295 nip = (uint32_t)nip; 296 } 297 tcg_gen_movi_tl(cpu_nip, nip); 298 } 299 300 static void gen_exception_err_nip(DisasContext *ctx, uint32_t excp, 301 uint32_t error, target_ulong nip) 302 { 303 TCGv_i32 t0, t1; 304 305 gen_update_nip(ctx, nip); 306 t0 = tcg_constant_i32(excp); 307 t1 = tcg_constant_i32(error); 308 gen_helper_raise_exception_err(tcg_env, t0, t1); 309 ctx->base.is_jmp = DISAS_NORETURN; 310 } 311 312 static inline void gen_exception_err(DisasContext *ctx, uint32_t excp, 313 uint32_t error) 314 { 315 /* 316 * These are all synchronous exceptions, we set the PC back to the 317 * faulting instruction 318 */ 319 gen_exception_err_nip(ctx, excp, error, ctx->cia); 320 } 321 322 static void gen_exception_nip(DisasContext *ctx, uint32_t excp, 323 target_ulong nip) 324 { 325 TCGv_i32 t0; 326 327 gen_update_nip(ctx, nip); 328 t0 = tcg_constant_i32(excp); 329 gen_helper_raise_exception(tcg_env, t0); 330 ctx->base.is_jmp = DISAS_NORETURN; 331 } 332 333 static inline void gen_exception(DisasContext *ctx, uint32_t excp) 334 { 335 /* 336 * These are all synchronous exceptions, we set the PC back to the 337 * faulting instruction 338 */ 339 gen_exception_nip(ctx, excp, ctx->cia); 340 } 341 342 #if !defined(CONFIG_USER_ONLY) 343 static void gen_ppc_maybe_interrupt(DisasContext *ctx) 344 { 345 translator_io_start(&ctx->base); 346 gen_helper_ppc_maybe_interrupt(tcg_env); 347 } 348 #endif 349 350 /* 351 * Tells the caller what is the appropriate exception to generate and prepares 352 * SPR registers for this exception. 353 * 354 * The exception can be either POWERPC_EXCP_TRACE (on most PowerPCs) or 355 * POWERPC_EXCP_DEBUG (on BookE). 356 */ 357 static void gen_debug_exception(DisasContext *ctx, bool rfi_type) 358 { 359 #if !defined(CONFIG_USER_ONLY) 360 if (ctx->flags & POWERPC_FLAG_DE) { 361 target_ulong dbsr = 0; 362 if (ctx->singlestep_enabled & CPU_SINGLE_STEP) { 363 dbsr = DBCR0_ICMP; 364 } else { 365 /* Must have been branch */ 366 dbsr = DBCR0_BRT; 367 } 368 TCGv t0 = tcg_temp_new(); 369 gen_load_spr(t0, SPR_BOOKE_DBSR); 370 tcg_gen_ori_tl(t0, t0, dbsr); 371 gen_store_spr(SPR_BOOKE_DBSR, t0); 372 gen_helper_raise_exception(tcg_env, 373 tcg_constant_i32(POWERPC_EXCP_DEBUG)); 374 ctx->base.is_jmp = DISAS_NORETURN; 375 } else { 376 if (!rfi_type) { /* BookS does not single step rfi type instructions */ 377 TCGv t0 = tcg_temp_new(); 378 tcg_gen_movi_tl(t0, ctx->cia); 379 gen_helper_book3s_trace(tcg_env, t0); 380 ctx->base.is_jmp = DISAS_NORETURN; 381 } 382 } 383 #endif 384 } 385 386 static inline void gen_inval_exception(DisasContext *ctx, uint32_t error) 387 { 388 /* Will be converted to program check if needed */ 389 gen_exception_err(ctx, POWERPC_EXCP_HV_EMU, POWERPC_EXCP_INVAL | error); 390 } 391 392 static inline void gen_priv_exception(DisasContext *ctx, uint32_t error) 393 { 394 gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_PRIV | error); 395 } 396 397 static inline void gen_hvpriv_exception(DisasContext *ctx, uint32_t error) 398 { 399 /* Will be converted to program check if needed */ 400 gen_exception_err(ctx, POWERPC_EXCP_HV_EMU, POWERPC_EXCP_PRIV | error); 401 } 402 403 /*****************************************************************************/ 404 /* SPR READ/WRITE CALLBACKS */ 405 406 void spr_noaccess(DisasContext *ctx, int gprn, int sprn) 407 { 408 #if 0 409 sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5); 410 printf("ERROR: try to access SPR %d !\n", sprn); 411 #endif 412 } 413 414 /* #define PPC_DUMP_SPR_ACCESSES */ 415 416 /* 417 * Generic callbacks: 418 * do nothing but store/retrieve spr value 419 */ 420 static void spr_load_dump_spr(int sprn) 421 { 422 #ifdef PPC_DUMP_SPR_ACCESSES 423 TCGv_i32 t0 = tcg_constant_i32(sprn); 424 gen_helper_load_dump_spr(tcg_env, t0); 425 #endif 426 } 427 428 void spr_read_generic(DisasContext *ctx, int gprn, int sprn) 429 { 430 gen_load_spr(cpu_gpr[gprn], sprn); 431 spr_load_dump_spr(sprn); 432 } 433 434 static void spr_store_dump_spr(int sprn) 435 { 436 #ifdef PPC_DUMP_SPR_ACCESSES 437 TCGv_i32 t0 = tcg_constant_i32(sprn); 438 gen_helper_store_dump_spr(tcg_env, t0); 439 #endif 440 } 441 442 void spr_write_generic(DisasContext *ctx, int sprn, int gprn) 443 { 444 gen_store_spr(sprn, cpu_gpr[gprn]); 445 spr_store_dump_spr(sprn); 446 } 447 448 void spr_write_generic32(DisasContext *ctx, int sprn, int gprn) 449 { 450 #ifdef TARGET_PPC64 451 TCGv t0 = tcg_temp_new(); 452 tcg_gen_ext32u_tl(t0, cpu_gpr[gprn]); 453 gen_store_spr(sprn, t0); 454 spr_store_dump_spr(sprn); 455 #else 456 spr_write_generic(ctx, sprn, gprn); 457 #endif 458 } 459 460 void spr_core_write_generic(DisasContext *ctx, int sprn, int gprn) 461 { 462 if (!(ctx->flags & POWERPC_FLAG_SMT)) { 463 spr_write_generic(ctx, sprn, gprn); 464 return; 465 } 466 467 if (!gen_serialize(ctx)) { 468 return; 469 } 470 471 gen_helper_spr_core_write_generic(tcg_env, tcg_constant_i32(sprn), 472 cpu_gpr[gprn]); 473 spr_store_dump_spr(sprn); 474 } 475 476 void spr_core_write_generic32(DisasContext *ctx, int sprn, int gprn) 477 { 478 TCGv t0; 479 480 if (!(ctx->flags & POWERPC_FLAG_SMT)) { 481 spr_write_generic32(ctx, sprn, gprn); 482 return; 483 } 484 485 if (!gen_serialize(ctx)) { 486 return; 487 } 488 489 t0 = tcg_temp_new(); 490 tcg_gen_ext32u_tl(t0, cpu_gpr[gprn]); 491 gen_helper_spr_core_write_generic(tcg_env, tcg_constant_i32(sprn), t0); 492 spr_store_dump_spr(sprn); 493 } 494 495 void spr_core_lpar_write_generic(DisasContext *ctx, int sprn, int gprn) 496 { 497 if (ctx->flags & POWERPC_FLAG_SMT_1LPAR) { 498 spr_core_write_generic(ctx, sprn, gprn); 499 } else { 500 spr_write_generic(ctx, sprn, gprn); 501 } 502 } 503 504 static void spr_write_CTRL_ST(DisasContext *ctx, int sprn, int gprn) 505 { 506 /* This does not implement >1 thread */ 507 TCGv t0 = tcg_temp_new(); 508 TCGv t1 = tcg_temp_new(); 509 tcg_gen_extract_tl(t0, cpu_gpr[gprn], 0, 1); /* Extract RUN field */ 510 tcg_gen_shli_tl(t1, t0, 8); /* Duplicate the bit in TS */ 511 tcg_gen_or_tl(t1, t1, t0); 512 gen_store_spr(sprn, t1); 513 } 514 515 void spr_write_CTRL(DisasContext *ctx, int sprn, int gprn) 516 { 517 if (!(ctx->flags & POWERPC_FLAG_SMT_1LPAR)) { 518 /* CTRL behaves as 1-thread in LPAR-per-thread mode */ 519 spr_write_CTRL_ST(ctx, sprn, gprn); 520 goto out; 521 } 522 523 if (!gen_serialize(ctx)) { 524 return; 525 } 526 527 gen_helper_spr_write_CTRL(tcg_env, tcg_constant_i32(sprn), 528 cpu_gpr[gprn]); 529 out: 530 spr_store_dump_spr(sprn); 531 532 /* 533 * SPR_CTRL writes must force a new translation block, 534 * allowing the PMU to calculate the run latch events with 535 * more accuracy. 536 */ 537 ctx->base.is_jmp = DISAS_EXIT_UPDATE; 538 } 539 540 #if !defined(CONFIG_USER_ONLY) 541 void spr_write_clear(DisasContext *ctx, int sprn, int gprn) 542 { 543 TCGv t0 = tcg_temp_new(); 544 TCGv t1 = tcg_temp_new(); 545 gen_load_spr(t0, sprn); 546 tcg_gen_neg_tl(t1, cpu_gpr[gprn]); 547 tcg_gen_and_tl(t0, t0, t1); 548 gen_store_spr(sprn, t0); 549 } 550 551 void spr_access_nop(DisasContext *ctx, int sprn, int gprn) 552 { 553 } 554 555 #endif 556 557 /* SPR common to all PowerPC */ 558 /* XER */ 559 void spr_read_xer(DisasContext *ctx, int gprn, int sprn) 560 { 561 TCGv dst = cpu_gpr[gprn]; 562 TCGv t0 = tcg_temp_new(); 563 TCGv t1 = tcg_temp_new(); 564 TCGv t2 = tcg_temp_new(); 565 tcg_gen_mov_tl(dst, cpu_xer); 566 tcg_gen_shli_tl(t0, cpu_so, XER_SO); 567 tcg_gen_shli_tl(t1, cpu_ov, XER_OV); 568 tcg_gen_shli_tl(t2, cpu_ca, XER_CA); 569 tcg_gen_or_tl(t0, t0, t1); 570 tcg_gen_or_tl(dst, dst, t2); 571 tcg_gen_or_tl(dst, dst, t0); 572 if (is_isa300(ctx)) { 573 tcg_gen_shli_tl(t0, cpu_ov32, XER_OV32); 574 tcg_gen_or_tl(dst, dst, t0); 575 tcg_gen_shli_tl(t0, cpu_ca32, XER_CA32); 576 tcg_gen_or_tl(dst, dst, t0); 577 } 578 } 579 580 void spr_write_xer(DisasContext *ctx, int sprn, int gprn) 581 { 582 TCGv src = cpu_gpr[gprn]; 583 /* Write all flags, while reading back check for isa300 */ 584 tcg_gen_andi_tl(cpu_xer, src, 585 ~((1u << XER_SO) | 586 (1u << XER_OV) | (1u << XER_OV32) | 587 (1u << XER_CA) | (1u << XER_CA32))); 588 tcg_gen_extract_tl(cpu_ov32, src, XER_OV32, 1); 589 tcg_gen_extract_tl(cpu_ca32, src, XER_CA32, 1); 590 tcg_gen_extract_tl(cpu_so, src, XER_SO, 1); 591 tcg_gen_extract_tl(cpu_ov, src, XER_OV, 1); 592 tcg_gen_extract_tl(cpu_ca, src, XER_CA, 1); 593 } 594 595 /* LR */ 596 void spr_read_lr(DisasContext *ctx, int gprn, int sprn) 597 { 598 tcg_gen_mov_tl(cpu_gpr[gprn], cpu_lr); 599 } 600 601 void spr_write_lr(DisasContext *ctx, int sprn, int gprn) 602 { 603 tcg_gen_mov_tl(cpu_lr, cpu_gpr[gprn]); 604 } 605 606 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) 607 /* Debug facilities */ 608 /* CFAR */ 609 void spr_read_cfar(DisasContext *ctx, int gprn, int sprn) 610 { 611 tcg_gen_mov_tl(cpu_gpr[gprn], cpu_cfar); 612 } 613 614 void spr_write_cfar(DisasContext *ctx, int sprn, int gprn) 615 { 616 tcg_gen_mov_tl(cpu_cfar, cpu_gpr[gprn]); 617 } 618 619 /* Breakpoint */ 620 void spr_write_ciabr(DisasContext *ctx, int sprn, int gprn) 621 { 622 translator_io_start(&ctx->base); 623 gen_helper_store_ciabr(tcg_env, cpu_gpr[gprn]); 624 } 625 626 /* Watchpoint */ 627 void spr_write_dawr0(DisasContext *ctx, int sprn, int gprn) 628 { 629 translator_io_start(&ctx->base); 630 gen_helper_store_dawr0(tcg_env, cpu_gpr[gprn]); 631 } 632 633 void spr_write_dawrx0(DisasContext *ctx, int sprn, int gprn) 634 { 635 translator_io_start(&ctx->base); 636 gen_helper_store_dawrx0(tcg_env, cpu_gpr[gprn]); 637 } 638 #endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */ 639 640 /* CTR */ 641 void spr_read_ctr(DisasContext *ctx, int gprn, int sprn) 642 { 643 tcg_gen_mov_tl(cpu_gpr[gprn], cpu_ctr); 644 } 645 646 void spr_write_ctr(DisasContext *ctx, int sprn, int gprn) 647 { 648 tcg_gen_mov_tl(cpu_ctr, cpu_gpr[gprn]); 649 } 650 651 /* User read access to SPR */ 652 /* USPRx */ 653 /* UMMCRx */ 654 /* UPMCx */ 655 /* USIA */ 656 /* UDECR */ 657 void spr_read_ureg(DisasContext *ctx, int gprn, int sprn) 658 { 659 gen_load_spr(cpu_gpr[gprn], sprn + 0x10); 660 } 661 662 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) 663 void spr_write_ureg(DisasContext *ctx, int sprn, int gprn) 664 { 665 gen_store_spr(sprn + 0x10, cpu_gpr[gprn]); 666 } 667 #endif 668 669 /* SPR common to all non-embedded PowerPC */ 670 /* DECR */ 671 #if !defined(CONFIG_USER_ONLY) 672 void spr_read_decr(DisasContext *ctx, int gprn, int sprn) 673 { 674 translator_io_start(&ctx->base); 675 gen_helper_load_decr(cpu_gpr[gprn], tcg_env); 676 } 677 678 void spr_write_decr(DisasContext *ctx, int sprn, int gprn) 679 { 680 translator_io_start(&ctx->base); 681 gen_helper_store_decr(tcg_env, cpu_gpr[gprn]); 682 } 683 #endif 684 685 /* SPR common to all non-embedded PowerPC, except 601 */ 686 /* Time base */ 687 void spr_read_tbl(DisasContext *ctx, int gprn, int sprn) 688 { 689 translator_io_start(&ctx->base); 690 gen_helper_load_tbl(cpu_gpr[gprn], tcg_env); 691 } 692 693 void spr_read_tbu(DisasContext *ctx, int gprn, int sprn) 694 { 695 translator_io_start(&ctx->base); 696 gen_helper_load_tbu(cpu_gpr[gprn], tcg_env); 697 } 698 699 void spr_read_atbl(DisasContext *ctx, int gprn, int sprn) 700 { 701 gen_helper_load_atbl(cpu_gpr[gprn], tcg_env); 702 } 703 704 void spr_read_atbu(DisasContext *ctx, int gprn, int sprn) 705 { 706 gen_helper_load_atbu(cpu_gpr[gprn], tcg_env); 707 } 708 709 #if !defined(CONFIG_USER_ONLY) 710 void spr_write_tbl(DisasContext *ctx, int sprn, int gprn) 711 { 712 if (!gen_serialize_core_lpar(ctx)) { 713 return; 714 } 715 716 translator_io_start(&ctx->base); 717 gen_helper_store_tbl(tcg_env, cpu_gpr[gprn]); 718 } 719 720 void spr_write_tbu(DisasContext *ctx, int sprn, int gprn) 721 { 722 if (!gen_serialize_core_lpar(ctx)) { 723 return; 724 } 725 726 translator_io_start(&ctx->base); 727 gen_helper_store_tbu(tcg_env, cpu_gpr[gprn]); 728 } 729 730 void spr_write_atbl(DisasContext *ctx, int sprn, int gprn) 731 { 732 gen_helper_store_atbl(tcg_env, cpu_gpr[gprn]); 733 } 734 735 void spr_write_atbu(DisasContext *ctx, int sprn, int gprn) 736 { 737 gen_helper_store_atbu(tcg_env, cpu_gpr[gprn]); 738 } 739 740 #if defined(TARGET_PPC64) 741 void spr_read_purr(DisasContext *ctx, int gprn, int sprn) 742 { 743 translator_io_start(&ctx->base); 744 gen_helper_load_purr(cpu_gpr[gprn], tcg_env); 745 } 746 747 void spr_write_purr(DisasContext *ctx, int sprn, int gprn) 748 { 749 if (!gen_serialize_core_lpar(ctx)) { 750 return; 751 } 752 translator_io_start(&ctx->base); 753 gen_helper_store_purr(tcg_env, cpu_gpr[gprn]); 754 } 755 756 /* HDECR */ 757 void spr_read_hdecr(DisasContext *ctx, int gprn, int sprn) 758 { 759 translator_io_start(&ctx->base); 760 gen_helper_load_hdecr(cpu_gpr[gprn], tcg_env); 761 } 762 763 void spr_write_hdecr(DisasContext *ctx, int sprn, int gprn) 764 { 765 if (!gen_serialize_core_lpar(ctx)) { 766 return; 767 } 768 translator_io_start(&ctx->base); 769 gen_helper_store_hdecr(tcg_env, cpu_gpr[gprn]); 770 } 771 772 void spr_read_vtb(DisasContext *ctx, int gprn, int sprn) 773 { 774 translator_io_start(&ctx->base); 775 gen_helper_load_vtb(cpu_gpr[gprn], tcg_env); 776 } 777 778 void spr_write_vtb(DisasContext *ctx, int sprn, int gprn) 779 { 780 if (!gen_serialize_core_lpar(ctx)) { 781 return; 782 } 783 translator_io_start(&ctx->base); 784 gen_helper_store_vtb(tcg_env, cpu_gpr[gprn]); 785 } 786 787 void spr_write_tbu40(DisasContext *ctx, int sprn, int gprn) 788 { 789 if (!gen_serialize_core_lpar(ctx)) { 790 return; 791 } 792 translator_io_start(&ctx->base); 793 gen_helper_store_tbu40(tcg_env, cpu_gpr[gprn]); 794 } 795 796 #endif 797 #endif 798 799 #if !defined(CONFIG_USER_ONLY) 800 /* IBAT0U...IBAT0U */ 801 /* IBAT0L...IBAT7L */ 802 void spr_read_ibat(DisasContext *ctx, int gprn, int sprn) 803 { 804 tcg_gen_ld_tl(cpu_gpr[gprn], tcg_env, 805 offsetof(CPUPPCState, 806 IBAT[sprn & 1][(sprn - SPR_IBAT0U) / 2])); 807 } 808 809 void spr_read_ibat_h(DisasContext *ctx, int gprn, int sprn) 810 { 811 tcg_gen_ld_tl(cpu_gpr[gprn], tcg_env, 812 offsetof(CPUPPCState, 813 IBAT[sprn & 1][((sprn - SPR_IBAT4U) / 2) + 4])); 814 } 815 816 void spr_write_ibatu(DisasContext *ctx, int sprn, int gprn) 817 { 818 TCGv_i32 t0 = tcg_constant_i32((sprn - SPR_IBAT0U) / 2); 819 gen_helper_store_ibatu(tcg_env, t0, cpu_gpr[gprn]); 820 } 821 822 void spr_write_ibatu_h(DisasContext *ctx, int sprn, int gprn) 823 { 824 TCGv_i32 t0 = tcg_constant_i32(((sprn - SPR_IBAT4U) / 2) + 4); 825 gen_helper_store_ibatu(tcg_env, t0, cpu_gpr[gprn]); 826 } 827 828 void spr_write_ibatl(DisasContext *ctx, int sprn, int gprn) 829 { 830 TCGv_i32 t0 = tcg_constant_i32((sprn - SPR_IBAT0L) / 2); 831 gen_helper_store_ibatl(tcg_env, t0, cpu_gpr[gprn]); 832 } 833 834 void spr_write_ibatl_h(DisasContext *ctx, int sprn, int gprn) 835 { 836 TCGv_i32 t0 = tcg_constant_i32(((sprn - SPR_IBAT4L) / 2) + 4); 837 gen_helper_store_ibatl(tcg_env, t0, cpu_gpr[gprn]); 838 } 839 840 /* DBAT0U...DBAT7U */ 841 /* DBAT0L...DBAT7L */ 842 void spr_read_dbat(DisasContext *ctx, int gprn, int sprn) 843 { 844 tcg_gen_ld_tl(cpu_gpr[gprn], tcg_env, 845 offsetof(CPUPPCState, 846 DBAT[sprn & 1][(sprn - SPR_DBAT0U) / 2])); 847 } 848 849 void spr_read_dbat_h(DisasContext *ctx, int gprn, int sprn) 850 { 851 tcg_gen_ld_tl(cpu_gpr[gprn], tcg_env, 852 offsetof(CPUPPCState, 853 DBAT[sprn & 1][((sprn - SPR_DBAT4U) / 2) + 4])); 854 } 855 856 void spr_write_dbatu(DisasContext *ctx, int sprn, int gprn) 857 { 858 TCGv_i32 t0 = tcg_constant_i32((sprn - SPR_DBAT0U) / 2); 859 gen_helper_store_dbatu(tcg_env, t0, cpu_gpr[gprn]); 860 } 861 862 void spr_write_dbatu_h(DisasContext *ctx, int sprn, int gprn) 863 { 864 TCGv_i32 t0 = tcg_constant_i32(((sprn - SPR_DBAT4U) / 2) + 4); 865 gen_helper_store_dbatu(tcg_env, t0, cpu_gpr[gprn]); 866 } 867 868 void spr_write_dbatl(DisasContext *ctx, int sprn, int gprn) 869 { 870 TCGv_i32 t0 = tcg_constant_i32((sprn - SPR_DBAT0L) / 2); 871 gen_helper_store_dbatl(tcg_env, t0, cpu_gpr[gprn]); 872 } 873 874 void spr_write_dbatl_h(DisasContext *ctx, int sprn, int gprn) 875 { 876 TCGv_i32 t0 = tcg_constant_i32(((sprn - SPR_DBAT4L) / 2) + 4); 877 gen_helper_store_dbatl(tcg_env, t0, cpu_gpr[gprn]); 878 } 879 880 /* SDR1 */ 881 void spr_write_sdr1(DisasContext *ctx, int sprn, int gprn) 882 { 883 gen_helper_store_sdr1(tcg_env, cpu_gpr[gprn]); 884 } 885 886 #if defined(TARGET_PPC64) 887 /* 64 bits PowerPC specific SPRs */ 888 /* PIDR */ 889 void spr_write_pidr(DisasContext *ctx, int sprn, int gprn) 890 { 891 gen_helper_store_pidr(tcg_env, cpu_gpr[gprn]); 892 } 893 894 void spr_write_lpidr(DisasContext *ctx, int sprn, int gprn) 895 { 896 gen_helper_store_lpidr(tcg_env, cpu_gpr[gprn]); 897 } 898 899 void spr_read_hior(DisasContext *ctx, int gprn, int sprn) 900 { 901 tcg_gen_ld_tl(cpu_gpr[gprn], tcg_env, offsetof(CPUPPCState, excp_prefix)); 902 } 903 904 void spr_write_hior(DisasContext *ctx, int sprn, int gprn) 905 { 906 TCGv t0 = tcg_temp_new(); 907 tcg_gen_andi_tl(t0, cpu_gpr[gprn], 0x3FFFFF00000ULL); 908 tcg_gen_st_tl(t0, tcg_env, offsetof(CPUPPCState, excp_prefix)); 909 } 910 void spr_write_ptcr(DisasContext *ctx, int sprn, int gprn) 911 { 912 if (!gen_serialize_core(ctx)) { 913 return; 914 } 915 916 gen_helper_store_ptcr(tcg_env, cpu_gpr[gprn]); 917 } 918 919 void spr_write_pcr(DisasContext *ctx, int sprn, int gprn) 920 { 921 gen_helper_store_pcr(tcg_env, cpu_gpr[gprn]); 922 } 923 924 /* DPDES */ 925 void spr_read_dpdes(DisasContext *ctx, int gprn, int sprn) 926 { 927 if (!gen_serialize_core_lpar(ctx)) { 928 return; 929 } 930 931 gen_helper_load_dpdes(cpu_gpr[gprn], tcg_env); 932 } 933 934 void spr_write_dpdes(DisasContext *ctx, int sprn, int gprn) 935 { 936 if (!gen_serialize_core_lpar(ctx)) { 937 return; 938 } 939 940 gen_helper_store_dpdes(tcg_env, cpu_gpr[gprn]); 941 } 942 #endif 943 #endif 944 945 /* PowerPC 40x specific registers */ 946 #if !defined(CONFIG_USER_ONLY) 947 void spr_read_40x_pit(DisasContext *ctx, int gprn, int sprn) 948 { 949 translator_io_start(&ctx->base); 950 gen_helper_load_40x_pit(cpu_gpr[gprn], tcg_env); 951 } 952 953 void spr_write_40x_pit(DisasContext *ctx, int sprn, int gprn) 954 { 955 translator_io_start(&ctx->base); 956 gen_helper_store_40x_pit(tcg_env, cpu_gpr[gprn]); 957 } 958 959 void spr_write_40x_dbcr0(DisasContext *ctx, int sprn, int gprn) 960 { 961 translator_io_start(&ctx->base); 962 gen_store_spr(sprn, cpu_gpr[gprn]); 963 gen_helper_store_40x_dbcr0(tcg_env, cpu_gpr[gprn]); 964 /* We must stop translation as we may have rebooted */ 965 ctx->base.is_jmp = DISAS_EXIT_UPDATE; 966 } 967 968 void spr_write_40x_sler(DisasContext *ctx, int sprn, int gprn) 969 { 970 translator_io_start(&ctx->base); 971 gen_helper_store_40x_sler(tcg_env, cpu_gpr[gprn]); 972 } 973 974 void spr_write_40x_tcr(DisasContext *ctx, int sprn, int gprn) 975 { 976 translator_io_start(&ctx->base); 977 gen_helper_store_40x_tcr(tcg_env, cpu_gpr[gprn]); 978 } 979 980 void spr_write_40x_tsr(DisasContext *ctx, int sprn, int gprn) 981 { 982 translator_io_start(&ctx->base); 983 gen_helper_store_40x_tsr(tcg_env, cpu_gpr[gprn]); 984 } 985 986 void spr_write_40x_pid(DisasContext *ctx, int sprn, int gprn) 987 { 988 TCGv t0 = tcg_temp_new(); 989 tcg_gen_andi_tl(t0, cpu_gpr[gprn], 0xFF); 990 gen_helper_store_40x_pid(tcg_env, t0); 991 } 992 993 void spr_write_booke_tcr(DisasContext *ctx, int sprn, int gprn) 994 { 995 translator_io_start(&ctx->base); 996 gen_helper_store_booke_tcr(tcg_env, cpu_gpr[gprn]); 997 } 998 999 void spr_write_booke_tsr(DisasContext *ctx, int sprn, int gprn) 1000 { 1001 translator_io_start(&ctx->base); 1002 gen_helper_store_booke_tsr(tcg_env, cpu_gpr[gprn]); 1003 } 1004 #endif 1005 1006 /* PIR */ 1007 #if !defined(CONFIG_USER_ONLY) 1008 void spr_write_pir(DisasContext *ctx, int sprn, int gprn) 1009 { 1010 TCGv t0 = tcg_temp_new(); 1011 tcg_gen_andi_tl(t0, cpu_gpr[gprn], 0xF); 1012 gen_store_spr(SPR_PIR, t0); 1013 } 1014 #endif 1015 1016 /* SPE specific registers */ 1017 void spr_read_spefscr(DisasContext *ctx, int gprn, int sprn) 1018 { 1019 TCGv_i32 t0 = tcg_temp_new_i32(); 1020 tcg_gen_ld_i32(t0, tcg_env, offsetof(CPUPPCState, spe_fscr)); 1021 tcg_gen_extu_i32_tl(cpu_gpr[gprn], t0); 1022 } 1023 1024 void spr_write_spefscr(DisasContext *ctx, int sprn, int gprn) 1025 { 1026 TCGv_i32 t0 = tcg_temp_new_i32(); 1027 tcg_gen_trunc_tl_i32(t0, cpu_gpr[gprn]); 1028 tcg_gen_st_i32(t0, tcg_env, offsetof(CPUPPCState, spe_fscr)); 1029 } 1030 1031 #if !defined(CONFIG_USER_ONLY) 1032 /* Callback used to write the exception vector base */ 1033 void spr_write_excp_prefix(DisasContext *ctx, int sprn, int gprn) 1034 { 1035 TCGv t0 = tcg_temp_new(); 1036 tcg_gen_ld_tl(t0, tcg_env, offsetof(CPUPPCState, ivpr_mask)); 1037 tcg_gen_and_tl(t0, t0, cpu_gpr[gprn]); 1038 tcg_gen_st_tl(t0, tcg_env, offsetof(CPUPPCState, excp_prefix)); 1039 gen_store_spr(sprn, t0); 1040 } 1041 1042 void spr_write_excp_vector(DisasContext *ctx, int sprn, int gprn) 1043 { 1044 int sprn_offs; 1045 1046 if (sprn >= SPR_BOOKE_IVOR0 && sprn <= SPR_BOOKE_IVOR15) { 1047 sprn_offs = sprn - SPR_BOOKE_IVOR0; 1048 } else if (sprn >= SPR_BOOKE_IVOR32 && sprn <= SPR_BOOKE_IVOR37) { 1049 sprn_offs = sprn - SPR_BOOKE_IVOR32 + 32; 1050 } else if (sprn >= SPR_BOOKE_IVOR38 && sprn <= SPR_BOOKE_IVOR42) { 1051 sprn_offs = sprn - SPR_BOOKE_IVOR38 + 38; 1052 } else { 1053 qemu_log_mask(LOG_GUEST_ERROR, "Trying to write an unknown exception" 1054 " vector 0x%03x\n", sprn); 1055 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 1056 return; 1057 } 1058 1059 TCGv t0 = tcg_temp_new(); 1060 tcg_gen_ld_tl(t0, tcg_env, offsetof(CPUPPCState, ivor_mask)); 1061 tcg_gen_and_tl(t0, t0, cpu_gpr[gprn]); 1062 tcg_gen_st_tl(t0, tcg_env, offsetof(CPUPPCState, excp_vectors[sprn_offs])); 1063 gen_store_spr(sprn, t0); 1064 } 1065 #endif 1066 1067 #ifdef TARGET_PPC64 1068 #ifndef CONFIG_USER_ONLY 1069 void spr_write_amr(DisasContext *ctx, int sprn, int gprn) 1070 { 1071 TCGv t0 = tcg_temp_new(); 1072 TCGv t1 = tcg_temp_new(); 1073 TCGv t2 = tcg_temp_new(); 1074 1075 /* 1076 * Note, the HV=1 PR=0 case is handled earlier by simply using 1077 * spr_write_generic for HV mode in the SPR table 1078 */ 1079 1080 /* Build insertion mask into t1 based on context */ 1081 if (ctx->pr) { 1082 gen_load_spr(t1, SPR_UAMOR); 1083 } else { 1084 gen_load_spr(t1, SPR_AMOR); 1085 } 1086 1087 /* Mask new bits into t2 */ 1088 tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]); 1089 1090 /* Load AMR and clear new bits in t0 */ 1091 gen_load_spr(t0, SPR_AMR); 1092 tcg_gen_andc_tl(t0, t0, t1); 1093 1094 /* Or'in new bits and write it out */ 1095 tcg_gen_or_tl(t0, t0, t2); 1096 gen_store_spr(SPR_AMR, t0); 1097 spr_store_dump_spr(SPR_AMR); 1098 } 1099 1100 void spr_write_uamor(DisasContext *ctx, int sprn, int gprn) 1101 { 1102 TCGv t0 = tcg_temp_new(); 1103 TCGv t1 = tcg_temp_new(); 1104 TCGv t2 = tcg_temp_new(); 1105 1106 /* 1107 * Note, the HV=1 case is handled earlier by simply using 1108 * spr_write_generic for HV mode in the SPR table 1109 */ 1110 1111 /* Build insertion mask into t1 based on context */ 1112 gen_load_spr(t1, SPR_AMOR); 1113 1114 /* Mask new bits into t2 */ 1115 tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]); 1116 1117 /* Load AMR and clear new bits in t0 */ 1118 gen_load_spr(t0, SPR_UAMOR); 1119 tcg_gen_andc_tl(t0, t0, t1); 1120 1121 /* Or'in new bits and write it out */ 1122 tcg_gen_or_tl(t0, t0, t2); 1123 gen_store_spr(SPR_UAMOR, t0); 1124 spr_store_dump_spr(SPR_UAMOR); 1125 } 1126 1127 void spr_write_iamr(DisasContext *ctx, int sprn, int gprn) 1128 { 1129 TCGv t0 = tcg_temp_new(); 1130 TCGv t1 = tcg_temp_new(); 1131 TCGv t2 = tcg_temp_new(); 1132 1133 /* 1134 * Note, the HV=1 case is handled earlier by simply using 1135 * spr_write_generic for HV mode in the SPR table 1136 */ 1137 1138 /* Build insertion mask into t1 based on context */ 1139 gen_load_spr(t1, SPR_AMOR); 1140 1141 /* Mask new bits into t2 */ 1142 tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]); 1143 1144 /* Load AMR and clear new bits in t0 */ 1145 gen_load_spr(t0, SPR_IAMR); 1146 tcg_gen_andc_tl(t0, t0, t1); 1147 1148 /* Or'in new bits and write it out */ 1149 tcg_gen_or_tl(t0, t0, t2); 1150 gen_store_spr(SPR_IAMR, t0); 1151 spr_store_dump_spr(SPR_IAMR); 1152 } 1153 #endif 1154 #endif 1155 1156 #ifndef CONFIG_USER_ONLY 1157 void spr_read_thrm(DisasContext *ctx, int gprn, int sprn) 1158 { 1159 gen_helper_fixup_thrm(tcg_env); 1160 gen_load_spr(cpu_gpr[gprn], sprn); 1161 spr_load_dump_spr(sprn); 1162 } 1163 #endif /* !CONFIG_USER_ONLY */ 1164 1165 #if !defined(CONFIG_USER_ONLY) 1166 void spr_write_e500_l1csr0(DisasContext *ctx, int sprn, int gprn) 1167 { 1168 TCGv t0 = tcg_temp_new(); 1169 1170 tcg_gen_andi_tl(t0, cpu_gpr[gprn], L1CSR0_DCE | L1CSR0_CPE); 1171 gen_store_spr(sprn, t0); 1172 } 1173 1174 void spr_write_e500_l1csr1(DisasContext *ctx, int sprn, int gprn) 1175 { 1176 TCGv t0 = tcg_temp_new(); 1177 1178 tcg_gen_andi_tl(t0, cpu_gpr[gprn], L1CSR1_ICE | L1CSR1_CPE); 1179 gen_store_spr(sprn, t0); 1180 } 1181 1182 void spr_write_e500_l2csr0(DisasContext *ctx, int sprn, int gprn) 1183 { 1184 TCGv t0 = tcg_temp_new(); 1185 1186 tcg_gen_andi_tl(t0, cpu_gpr[gprn], 1187 ~(E500_L2CSR0_L2FI | E500_L2CSR0_L2FL | E500_L2CSR0_L2LFC)); 1188 gen_store_spr(sprn, t0); 1189 } 1190 1191 void spr_write_booke206_mmucsr0(DisasContext *ctx, int sprn, int gprn) 1192 { 1193 gen_helper_booke206_tlbflush(tcg_env, cpu_gpr[gprn]); 1194 } 1195 1196 void spr_write_booke_pid(DisasContext *ctx, int sprn, int gprn) 1197 { 1198 TCGv_i32 t0 = tcg_constant_i32(sprn); 1199 gen_helper_booke_setpid(tcg_env, t0, cpu_gpr[gprn]); 1200 } 1201 1202 void spr_write_eplc(DisasContext *ctx, int sprn, int gprn) 1203 { 1204 gen_helper_booke_set_eplc(tcg_env, cpu_gpr[gprn]); 1205 } 1206 1207 void spr_write_epsc(DisasContext *ctx, int sprn, int gprn) 1208 { 1209 gen_helper_booke_set_epsc(tcg_env, cpu_gpr[gprn]); 1210 } 1211 1212 #endif 1213 1214 #if !defined(CONFIG_USER_ONLY) 1215 void spr_write_mas73(DisasContext *ctx, int sprn, int gprn) 1216 { 1217 TCGv val = tcg_temp_new(); 1218 tcg_gen_ext32u_tl(val, cpu_gpr[gprn]); 1219 gen_store_spr(SPR_BOOKE_MAS3, val); 1220 tcg_gen_shri_tl(val, cpu_gpr[gprn], 32); 1221 gen_store_spr(SPR_BOOKE_MAS7, val); 1222 } 1223 1224 void spr_read_mas73(DisasContext *ctx, int gprn, int sprn) 1225 { 1226 TCGv mas7 = tcg_temp_new(); 1227 TCGv mas3 = tcg_temp_new(); 1228 gen_load_spr(mas7, SPR_BOOKE_MAS7); 1229 tcg_gen_shli_tl(mas7, mas7, 32); 1230 gen_load_spr(mas3, SPR_BOOKE_MAS3); 1231 tcg_gen_or_tl(cpu_gpr[gprn], mas3, mas7); 1232 } 1233 1234 #endif 1235 1236 #ifdef TARGET_PPC64 1237 static void gen_fscr_facility_check(DisasContext *ctx, int facility_sprn, 1238 int bit, int sprn, int cause) 1239 { 1240 TCGv_i32 t1 = tcg_constant_i32(bit); 1241 TCGv_i32 t2 = tcg_constant_i32(sprn); 1242 TCGv_i32 t3 = tcg_constant_i32(cause); 1243 1244 gen_helper_fscr_facility_check(tcg_env, t1, t2, t3); 1245 } 1246 1247 static void gen_msr_facility_check(DisasContext *ctx, int facility_sprn, 1248 int bit, int sprn, int cause) 1249 { 1250 TCGv_i32 t1 = tcg_constant_i32(bit); 1251 TCGv_i32 t2 = tcg_constant_i32(sprn); 1252 TCGv_i32 t3 = tcg_constant_i32(cause); 1253 1254 gen_helper_msr_facility_check(tcg_env, t1, t2, t3); 1255 } 1256 1257 void spr_read_prev_upper32(DisasContext *ctx, int gprn, int sprn) 1258 { 1259 TCGv spr_up = tcg_temp_new(); 1260 TCGv spr = tcg_temp_new(); 1261 1262 gen_load_spr(spr, sprn - 1); 1263 tcg_gen_shri_tl(spr_up, spr, 32); 1264 tcg_gen_ext32u_tl(cpu_gpr[gprn], spr_up); 1265 } 1266 1267 void spr_write_prev_upper32(DisasContext *ctx, int sprn, int gprn) 1268 { 1269 TCGv spr = tcg_temp_new(); 1270 1271 gen_load_spr(spr, sprn - 1); 1272 tcg_gen_deposit_tl(spr, spr, cpu_gpr[gprn], 32, 32); 1273 gen_store_spr(sprn - 1, spr); 1274 } 1275 1276 #if !defined(CONFIG_USER_ONLY) 1277 void spr_write_hmer(DisasContext *ctx, int sprn, int gprn) 1278 { 1279 TCGv hmer = tcg_temp_new(); 1280 1281 gen_load_spr(hmer, sprn); 1282 tcg_gen_and_tl(hmer, cpu_gpr[gprn], hmer); 1283 gen_store_spr(sprn, hmer); 1284 spr_store_dump_spr(sprn); 1285 } 1286 1287 void spr_read_tfmr(DisasContext *ctx, int gprn, int sprn) 1288 { 1289 /* Reading TFMR can cause it to be updated, so serialize threads here too */ 1290 if (!gen_serialize_core(ctx)) { 1291 return; 1292 } 1293 gen_helper_load_tfmr(cpu_gpr[gprn], tcg_env); 1294 } 1295 1296 void spr_write_tfmr(DisasContext *ctx, int sprn, int gprn) 1297 { 1298 if (!gen_serialize_core(ctx)) { 1299 return; 1300 } 1301 gen_helper_store_tfmr(tcg_env, cpu_gpr[gprn]); 1302 } 1303 1304 void spr_write_sprc(DisasContext *ctx, int sprn, int gprn) 1305 { 1306 gen_helper_store_sprc(tcg_env, cpu_gpr[gprn]); 1307 } 1308 1309 void spr_read_sprd(DisasContext *ctx, int gprn, int sprn) 1310 { 1311 gen_helper_load_sprd(cpu_gpr[gprn], tcg_env); 1312 } 1313 1314 void spr_write_sprd(DisasContext *ctx, int sprn, int gprn) 1315 { 1316 if (!gen_serialize_core(ctx)) { 1317 return; 1318 } 1319 gen_helper_store_sprd(tcg_env, cpu_gpr[gprn]); 1320 } 1321 1322 void spr_write_lpcr(DisasContext *ctx, int sprn, int gprn) 1323 { 1324 translator_io_start(&ctx->base); 1325 gen_helper_store_lpcr(tcg_env, cpu_gpr[gprn]); 1326 } 1327 #endif /* !defined(CONFIG_USER_ONLY) */ 1328 1329 void spr_read_tar(DisasContext *ctx, int gprn, int sprn) 1330 { 1331 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_TAR, sprn, FSCR_IC_TAR); 1332 spr_read_generic(ctx, gprn, sprn); 1333 } 1334 1335 void spr_write_tar(DisasContext *ctx, int sprn, int gprn) 1336 { 1337 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_TAR, sprn, FSCR_IC_TAR); 1338 spr_write_generic(ctx, sprn, gprn); 1339 } 1340 1341 void spr_read_tm(DisasContext *ctx, int gprn, int sprn) 1342 { 1343 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM); 1344 spr_read_generic(ctx, gprn, sprn); 1345 } 1346 1347 void spr_write_tm(DisasContext *ctx, int sprn, int gprn) 1348 { 1349 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM); 1350 spr_write_generic(ctx, sprn, gprn); 1351 } 1352 1353 void spr_read_tm_upper32(DisasContext *ctx, int gprn, int sprn) 1354 { 1355 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM); 1356 spr_read_prev_upper32(ctx, gprn, sprn); 1357 } 1358 1359 void spr_write_tm_upper32(DisasContext *ctx, int sprn, int gprn) 1360 { 1361 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM); 1362 spr_write_prev_upper32(ctx, sprn, gprn); 1363 } 1364 1365 void spr_read_ebb(DisasContext *ctx, int gprn, int sprn) 1366 { 1367 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB); 1368 spr_read_generic(ctx, gprn, sprn); 1369 } 1370 1371 void spr_write_ebb(DisasContext *ctx, int sprn, int gprn) 1372 { 1373 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB); 1374 spr_write_generic(ctx, sprn, gprn); 1375 } 1376 1377 void spr_read_ebb_upper32(DisasContext *ctx, int gprn, int sprn) 1378 { 1379 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB); 1380 spr_read_prev_upper32(ctx, gprn, sprn); 1381 } 1382 1383 void spr_write_ebb_upper32(DisasContext *ctx, int sprn, int gprn) 1384 { 1385 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB); 1386 spr_write_prev_upper32(ctx, sprn, gprn); 1387 } 1388 1389 void spr_read_dexcr_ureg(DisasContext *ctx, int gprn, int sprn) 1390 { 1391 TCGv t0 = tcg_temp_new(); 1392 1393 /* 1394 * Access to the (H)DEXCR in problem state is done using separated 1395 * SPR indexes which are 16 below the SPR indexes which have full 1396 * access to the (H)DEXCR in privileged state. Problem state can 1397 * only read bits 32:63, bits 0:31 return 0. 1398 * 1399 * See section 9.3.1-9.3.2 of PowerISA v3.1B 1400 */ 1401 1402 gen_load_spr(t0, sprn + 16); 1403 tcg_gen_ext32u_tl(cpu_gpr[gprn], t0); 1404 } 1405 1406 /* The PPR32 SPR accesses the upper 32-bits of PPR */ 1407 void spr_read_ppr32(DisasContext *ctx, int gprn, int sprn) 1408 { 1409 gen_load_spr(cpu_gpr[gprn], SPR_PPR); 1410 tcg_gen_shri_tl(cpu_gpr[gprn], cpu_gpr[gprn], 32); 1411 spr_load_dump_spr(SPR_PPR); 1412 } 1413 1414 void spr_write_ppr32(DisasContext *ctx, int sprn, int gprn) 1415 { 1416 TCGv t0 = tcg_temp_new(); 1417 1418 /* 1419 * Don't clobber the low 32-bits of the PPR. These are all reserved bits 1420 * but TCG does implement them, so it would be surprising to zero them 1421 * here. "Priority nops" are similarly careful not to clobber reserved 1422 * bits. 1423 */ 1424 gen_load_spr(t0, SPR_PPR); 1425 tcg_gen_deposit_tl(t0, t0, cpu_gpr[gprn], 32, 32); 1426 gen_store_spr(SPR_PPR, t0); 1427 spr_store_dump_spr(SPR_PPR); 1428 } 1429 #endif 1430 1431 #define GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \ 1432 GEN_OPCODE(name, opc1, opc2, opc3, inval, type, PPC_NONE) 1433 1434 #define GEN_HANDLER_E(name, opc1, opc2, opc3, inval, type, type2) \ 1435 GEN_OPCODE(name, opc1, opc2, opc3, inval, type, type2) 1436 1437 #define GEN_HANDLER2(name, onam, opc1, opc2, opc3, inval, type) \ 1438 GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, PPC_NONE) 1439 1440 #define GEN_HANDLER2_E(name, onam, opc1, opc2, opc3, inval, type, type2) \ 1441 GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, type2) 1442 1443 #define GEN_HANDLER_E_2(name, opc1, opc2, opc3, opc4, inval, type, type2) \ 1444 GEN_OPCODE3(name, opc1, opc2, opc3, opc4, inval, type, type2) 1445 1446 #define GEN_HANDLER2_E_2(name, onam, opc1, opc2, opc3, opc4, inval, typ, typ2) \ 1447 GEN_OPCODE4(name, onam, opc1, opc2, opc3, opc4, inval, typ, typ2) 1448 1449 typedef struct opcode_t { 1450 unsigned char opc1, opc2, opc3, opc4; 1451 #if HOST_LONG_BITS == 64 /* Explicitly align to 64 bits */ 1452 unsigned char pad[4]; 1453 #endif 1454 opc_handler_t handler; 1455 const char *oname; 1456 } opcode_t; 1457 1458 static void gen_priv_opc(DisasContext *ctx) 1459 { 1460 gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC); 1461 } 1462 1463 /* Helpers for priv. check */ 1464 #define GEN_PRIV(CTX) \ 1465 do { \ 1466 gen_priv_opc(CTX); return; \ 1467 } while (0) 1468 1469 #if defined(CONFIG_USER_ONLY) 1470 #define CHK_HV(CTX) GEN_PRIV(CTX) 1471 #define CHK_SV(CTX) GEN_PRIV(CTX) 1472 #define CHK_HVRM(CTX) GEN_PRIV(CTX) 1473 #else 1474 #define CHK_HV(CTX) \ 1475 do { \ 1476 if (unlikely(ctx->pr || !ctx->hv)) {\ 1477 GEN_PRIV(CTX); \ 1478 } \ 1479 } while (0) 1480 #define CHK_SV(CTX) \ 1481 do { \ 1482 if (unlikely(ctx->pr)) { \ 1483 GEN_PRIV(CTX); \ 1484 } \ 1485 } while (0) 1486 #define CHK_HVRM(CTX) \ 1487 do { \ 1488 if (unlikely(ctx->pr || !ctx->hv || ctx->dr)) { \ 1489 GEN_PRIV(CTX); \ 1490 } \ 1491 } while (0) 1492 #endif 1493 1494 #define CHK_NONE(CTX) 1495 1496 /*****************************************************************************/ 1497 /* PowerPC instructions table */ 1498 1499 #define GEN_OPCODE(name, op1, op2, op3, invl, _typ, _typ2) \ 1500 { \ 1501 .opc1 = op1, \ 1502 .opc2 = op2, \ 1503 .opc3 = op3, \ 1504 .opc4 = 0xff, \ 1505 .handler = { \ 1506 .inval1 = invl, \ 1507 .type = _typ, \ 1508 .type2 = _typ2, \ 1509 .handler = &gen_##name, \ 1510 }, \ 1511 .oname = stringify(name), \ 1512 } 1513 #define GEN_OPCODE_DUAL(name, op1, op2, op3, invl1, invl2, _typ, _typ2) \ 1514 { \ 1515 .opc1 = op1, \ 1516 .opc2 = op2, \ 1517 .opc3 = op3, \ 1518 .opc4 = 0xff, \ 1519 .handler = { \ 1520 .inval1 = invl1, \ 1521 .inval2 = invl2, \ 1522 .type = _typ, \ 1523 .type2 = _typ2, \ 1524 .handler = &gen_##name, \ 1525 }, \ 1526 .oname = stringify(name), \ 1527 } 1528 #define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ, _typ2) \ 1529 { \ 1530 .opc1 = op1, \ 1531 .opc2 = op2, \ 1532 .opc3 = op3, \ 1533 .opc4 = 0xff, \ 1534 .handler = { \ 1535 .inval1 = invl, \ 1536 .type = _typ, \ 1537 .type2 = _typ2, \ 1538 .handler = &gen_##name, \ 1539 }, \ 1540 .oname = onam, \ 1541 } 1542 #define GEN_OPCODE3(name, op1, op2, op3, op4, invl, _typ, _typ2) \ 1543 { \ 1544 .opc1 = op1, \ 1545 .opc2 = op2, \ 1546 .opc3 = op3, \ 1547 .opc4 = op4, \ 1548 .handler = { \ 1549 .inval1 = invl, \ 1550 .type = _typ, \ 1551 .type2 = _typ2, \ 1552 .handler = &gen_##name, \ 1553 }, \ 1554 .oname = stringify(name), \ 1555 } 1556 #define GEN_OPCODE4(name, onam, op1, op2, op3, op4, invl, _typ, _typ2) \ 1557 { \ 1558 .opc1 = op1, \ 1559 .opc2 = op2, \ 1560 .opc3 = op3, \ 1561 .opc4 = op4, \ 1562 .handler = { \ 1563 .inval1 = invl, \ 1564 .type = _typ, \ 1565 .type2 = _typ2, \ 1566 .handler = &gen_##name, \ 1567 }, \ 1568 .oname = onam, \ 1569 } 1570 1571 /* Invalid instruction */ 1572 static void gen_invalid(DisasContext *ctx) 1573 { 1574 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 1575 } 1576 1577 static opc_handler_t invalid_handler = { 1578 .inval1 = 0xFFFFFFFF, 1579 .inval2 = 0xFFFFFFFF, 1580 .type = PPC_NONE, 1581 .type2 = PPC_NONE, 1582 .handler = gen_invalid, 1583 }; 1584 1585 /*** Integer comparison ***/ 1586 1587 static inline void gen_op_cmp(TCGv arg0, TCGv arg1, int s, int crf) 1588 { 1589 TCGv t0 = tcg_temp_new(); 1590 TCGv t1 = tcg_temp_new(); 1591 TCGv_i32 t = tcg_temp_new_i32(); 1592 1593 tcg_gen_movi_tl(t0, CRF_EQ); 1594 tcg_gen_movi_tl(t1, CRF_LT); 1595 tcg_gen_movcond_tl((s ? TCG_COND_LT : TCG_COND_LTU), 1596 t0, arg0, arg1, t1, t0); 1597 tcg_gen_movi_tl(t1, CRF_GT); 1598 tcg_gen_movcond_tl((s ? TCG_COND_GT : TCG_COND_GTU), 1599 t0, arg0, arg1, t1, t0); 1600 1601 tcg_gen_trunc_tl_i32(t, t0); 1602 tcg_gen_trunc_tl_i32(cpu_crf[crf], cpu_so); 1603 tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t); 1604 } 1605 1606 static inline void gen_op_cmpi(TCGv arg0, target_ulong arg1, int s, int crf) 1607 { 1608 TCGv t0 = tcg_constant_tl(arg1); 1609 gen_op_cmp(arg0, t0, s, crf); 1610 } 1611 1612 static inline void gen_op_cmp32(TCGv arg0, TCGv arg1, int s, int crf) 1613 { 1614 TCGv t0, t1; 1615 t0 = tcg_temp_new(); 1616 t1 = tcg_temp_new(); 1617 if (s) { 1618 tcg_gen_ext32s_tl(t0, arg0); 1619 tcg_gen_ext32s_tl(t1, arg1); 1620 } else { 1621 tcg_gen_ext32u_tl(t0, arg0); 1622 tcg_gen_ext32u_tl(t1, arg1); 1623 } 1624 gen_op_cmp(t0, t1, s, crf); 1625 } 1626 1627 static inline void gen_op_cmpi32(TCGv arg0, target_ulong arg1, int s, int crf) 1628 { 1629 TCGv t0 = tcg_constant_tl(arg1); 1630 gen_op_cmp32(arg0, t0, s, crf); 1631 } 1632 1633 static inline void gen_set_Rc0(DisasContext *ctx, TCGv reg) 1634 { 1635 if (NARROW_MODE(ctx)) { 1636 gen_op_cmpi32(reg, 0, 1, 0); 1637 } else { 1638 gen_op_cmpi(reg, 0, 1, 0); 1639 } 1640 } 1641 1642 /*** Integer arithmetic ***/ 1643 1644 static inline void gen_op_arith_compute_ov(DisasContext *ctx, TCGv arg0, 1645 TCGv arg1, TCGv arg2, int sub) 1646 { 1647 TCGv t0 = tcg_temp_new(); 1648 1649 tcg_gen_xor_tl(cpu_ov, arg0, arg2); 1650 tcg_gen_xor_tl(t0, arg1, arg2); 1651 if (sub) { 1652 tcg_gen_and_tl(cpu_ov, cpu_ov, t0); 1653 } else { 1654 tcg_gen_andc_tl(cpu_ov, cpu_ov, t0); 1655 } 1656 if (NARROW_MODE(ctx)) { 1657 tcg_gen_extract_tl(cpu_ov, cpu_ov, 31, 1); 1658 if (is_isa300(ctx)) { 1659 tcg_gen_mov_tl(cpu_ov32, cpu_ov); 1660 } 1661 } else { 1662 if (is_isa300(ctx)) { 1663 tcg_gen_extract_tl(cpu_ov32, cpu_ov, 31, 1); 1664 } 1665 tcg_gen_extract_tl(cpu_ov, cpu_ov, TARGET_LONG_BITS - 1, 1); 1666 } 1667 tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov); 1668 } 1669 1670 static inline void gen_op_arith_compute_ca32(DisasContext *ctx, 1671 TCGv res, TCGv arg0, TCGv arg1, 1672 TCGv ca32, int sub) 1673 { 1674 TCGv t0; 1675 1676 if (!is_isa300(ctx)) { 1677 return; 1678 } 1679 1680 t0 = tcg_temp_new(); 1681 if (sub) { 1682 tcg_gen_eqv_tl(t0, arg0, arg1); 1683 } else { 1684 tcg_gen_xor_tl(t0, arg0, arg1); 1685 } 1686 tcg_gen_xor_tl(t0, t0, res); 1687 tcg_gen_extract_tl(ca32, t0, 32, 1); 1688 } 1689 1690 /* Common add function */ 1691 static inline void gen_op_arith_add(DisasContext *ctx, TCGv ret, TCGv arg1, 1692 TCGv arg2, TCGv ca, TCGv ca32, 1693 bool add_ca, bool compute_ca, 1694 bool compute_ov, bool compute_rc0) 1695 { 1696 TCGv t0 = ret; 1697 1698 if (compute_ca || compute_ov) { 1699 t0 = tcg_temp_new(); 1700 } 1701 1702 if (compute_ca) { 1703 if (NARROW_MODE(ctx)) { 1704 /* 1705 * Caution: a non-obvious corner case of the spec is that 1706 * we must produce the *entire* 64-bit addition, but 1707 * produce the carry into bit 32. 1708 */ 1709 TCGv t1 = tcg_temp_new(); 1710 tcg_gen_xor_tl(t1, arg1, arg2); /* add without carry */ 1711 tcg_gen_add_tl(t0, arg1, arg2); 1712 if (add_ca) { 1713 tcg_gen_add_tl(t0, t0, ca); 1714 } 1715 tcg_gen_xor_tl(ca, t0, t1); /* bits changed w/ carry */ 1716 tcg_gen_extract_tl(ca, ca, 32, 1); 1717 if (is_isa300(ctx)) { 1718 tcg_gen_mov_tl(ca32, ca); 1719 } 1720 } else { 1721 TCGv zero = tcg_constant_tl(0); 1722 if (add_ca) { 1723 tcg_gen_add2_tl(t0, ca, arg1, zero, ca, zero); 1724 tcg_gen_add2_tl(t0, ca, t0, ca, arg2, zero); 1725 } else { 1726 tcg_gen_add2_tl(t0, ca, arg1, zero, arg2, zero); 1727 } 1728 gen_op_arith_compute_ca32(ctx, t0, arg1, arg2, ca32, 0); 1729 } 1730 } else { 1731 tcg_gen_add_tl(t0, arg1, arg2); 1732 if (add_ca) { 1733 tcg_gen_add_tl(t0, t0, ca); 1734 } 1735 } 1736 1737 if (compute_ov) { 1738 gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 0); 1739 } 1740 if (unlikely(compute_rc0)) { 1741 gen_set_Rc0(ctx, t0); 1742 } 1743 1744 if (t0 != ret) { 1745 tcg_gen_mov_tl(ret, t0); 1746 } 1747 } 1748 1749 static inline void gen_op_arith_divw(DisasContext *ctx, TCGv ret, 1750 TCGv arg1, TCGv arg2, bool sign, 1751 bool compute_ov, bool compute_rc0) 1752 { 1753 TCGv_i32 t0 = tcg_temp_new_i32(); 1754 TCGv_i32 t1 = tcg_temp_new_i32(); 1755 TCGv_i32 t2 = tcg_temp_new_i32(); 1756 TCGv_i32 t3 = tcg_temp_new_i32(); 1757 1758 tcg_gen_trunc_tl_i32(t0, arg1); 1759 tcg_gen_trunc_tl_i32(t1, arg2); 1760 if (sign) { 1761 tcg_gen_setcondi_i32(TCG_COND_EQ, t2, t0, INT_MIN); 1762 tcg_gen_setcondi_i32(TCG_COND_EQ, t3, t1, -1); 1763 tcg_gen_and_i32(t2, t2, t3); 1764 tcg_gen_setcondi_i32(TCG_COND_EQ, t3, t1, 0); 1765 tcg_gen_or_i32(t2, t2, t3); 1766 tcg_gen_movi_i32(t3, 0); 1767 tcg_gen_movcond_i32(TCG_COND_NE, t1, t2, t3, t2, t1); 1768 tcg_gen_div_i32(t3, t0, t1); 1769 tcg_gen_extu_i32_tl(ret, t3); 1770 } else { 1771 tcg_gen_setcondi_i32(TCG_COND_EQ, t2, t1, 0); 1772 tcg_gen_movi_i32(t3, 0); 1773 tcg_gen_movcond_i32(TCG_COND_NE, t1, t2, t3, t2, t1); 1774 tcg_gen_divu_i32(t3, t0, t1); 1775 tcg_gen_extu_i32_tl(ret, t3); 1776 } 1777 if (compute_ov) { 1778 tcg_gen_extu_i32_tl(cpu_ov, t2); 1779 if (is_isa300(ctx)) { 1780 tcg_gen_extu_i32_tl(cpu_ov32, t2); 1781 } 1782 tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov); 1783 } 1784 1785 if (unlikely(compute_rc0)) { 1786 gen_set_Rc0(ctx, ret); 1787 } 1788 } 1789 1790 #if defined(TARGET_PPC64) 1791 static inline void gen_op_arith_divd(DisasContext *ctx, TCGv ret, 1792 TCGv arg1, TCGv arg2, bool sign, 1793 bool compute_ov, bool compute_rc0) 1794 { 1795 TCGv_i64 t0 = tcg_temp_new_i64(); 1796 TCGv_i64 t1 = tcg_temp_new_i64(); 1797 TCGv_i64 t2 = tcg_temp_new_i64(); 1798 TCGv_i64 t3 = tcg_temp_new_i64(); 1799 1800 tcg_gen_mov_i64(t0, arg1); 1801 tcg_gen_mov_i64(t1, arg2); 1802 if (sign) { 1803 tcg_gen_setcondi_i64(TCG_COND_EQ, t2, t0, INT64_MIN); 1804 tcg_gen_setcondi_i64(TCG_COND_EQ, t3, t1, -1); 1805 tcg_gen_and_i64(t2, t2, t3); 1806 tcg_gen_setcondi_i64(TCG_COND_EQ, t3, t1, 0); 1807 tcg_gen_or_i64(t2, t2, t3); 1808 tcg_gen_movi_i64(t3, 0); 1809 tcg_gen_movcond_i64(TCG_COND_NE, t1, t2, t3, t2, t1); 1810 tcg_gen_div_i64(ret, t0, t1); 1811 } else { 1812 tcg_gen_setcondi_i64(TCG_COND_EQ, t2, t1, 0); 1813 tcg_gen_movi_i64(t3, 0); 1814 tcg_gen_movcond_i64(TCG_COND_NE, t1, t2, t3, t2, t1); 1815 tcg_gen_divu_i64(ret, t0, t1); 1816 } 1817 if (compute_ov) { 1818 tcg_gen_mov_tl(cpu_ov, t2); 1819 if (is_isa300(ctx)) { 1820 tcg_gen_mov_tl(cpu_ov32, t2); 1821 } 1822 tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov); 1823 } 1824 1825 if (unlikely(Rc(ctx->opcode) != 0)) { 1826 gen_set_Rc0(ctx, ret); 1827 } 1828 } 1829 #endif 1830 1831 static inline void gen_op_arith_modw(DisasContext *ctx, TCGv ret, TCGv arg1, 1832 TCGv arg2, int sign) 1833 { 1834 TCGv_i32 t0 = tcg_temp_new_i32(); 1835 TCGv_i32 t1 = tcg_temp_new_i32(); 1836 1837 tcg_gen_trunc_tl_i32(t0, arg1); 1838 tcg_gen_trunc_tl_i32(t1, arg2); 1839 if (sign) { 1840 TCGv_i32 t2 = tcg_temp_new_i32(); 1841 TCGv_i32 t3 = tcg_temp_new_i32(); 1842 tcg_gen_setcondi_i32(TCG_COND_EQ, t2, t0, INT_MIN); 1843 tcg_gen_setcondi_i32(TCG_COND_EQ, t3, t1, -1); 1844 tcg_gen_and_i32(t2, t2, t3); 1845 tcg_gen_setcondi_i32(TCG_COND_EQ, t3, t1, 0); 1846 tcg_gen_or_i32(t2, t2, t3); 1847 tcg_gen_movi_i32(t3, 0); 1848 tcg_gen_movcond_i32(TCG_COND_NE, t1, t2, t3, t2, t1); 1849 tcg_gen_rem_i32(t3, t0, t1); 1850 tcg_gen_ext_i32_tl(ret, t3); 1851 } else { 1852 TCGv_i32 t2 = tcg_constant_i32(1); 1853 TCGv_i32 t3 = tcg_constant_i32(0); 1854 tcg_gen_movcond_i32(TCG_COND_EQ, t1, t1, t3, t2, t1); 1855 tcg_gen_remu_i32(t0, t0, t1); 1856 tcg_gen_extu_i32_tl(ret, t0); 1857 } 1858 } 1859 1860 #if defined(TARGET_PPC64) 1861 static inline void gen_op_arith_modd(DisasContext *ctx, TCGv ret, TCGv arg1, 1862 TCGv arg2, int sign) 1863 { 1864 TCGv_i64 t0 = tcg_temp_new_i64(); 1865 TCGv_i64 t1 = tcg_temp_new_i64(); 1866 1867 tcg_gen_mov_i64(t0, arg1); 1868 tcg_gen_mov_i64(t1, arg2); 1869 if (sign) { 1870 TCGv_i64 t2 = tcg_temp_new_i64(); 1871 TCGv_i64 t3 = tcg_temp_new_i64(); 1872 tcg_gen_setcondi_i64(TCG_COND_EQ, t2, t0, INT64_MIN); 1873 tcg_gen_setcondi_i64(TCG_COND_EQ, t3, t1, -1); 1874 tcg_gen_and_i64(t2, t2, t3); 1875 tcg_gen_setcondi_i64(TCG_COND_EQ, t3, t1, 0); 1876 tcg_gen_or_i64(t2, t2, t3); 1877 tcg_gen_movi_i64(t3, 0); 1878 tcg_gen_movcond_i64(TCG_COND_NE, t1, t2, t3, t2, t1); 1879 tcg_gen_rem_i64(ret, t0, t1); 1880 } else { 1881 TCGv_i64 t2 = tcg_constant_i64(1); 1882 TCGv_i64 t3 = tcg_constant_i64(0); 1883 tcg_gen_movcond_i64(TCG_COND_EQ, t1, t1, t3, t2, t1); 1884 tcg_gen_remu_i64(ret, t0, t1); 1885 } 1886 } 1887 #endif 1888 1889 /* Common subf function */ 1890 static inline void gen_op_arith_subf(DisasContext *ctx, TCGv ret, TCGv arg1, 1891 TCGv arg2, bool add_ca, bool compute_ca, 1892 bool compute_ov, bool compute_rc0) 1893 { 1894 TCGv t0 = ret; 1895 1896 if (compute_ca || compute_ov) { 1897 t0 = tcg_temp_new(); 1898 } 1899 1900 if (compute_ca) { 1901 /* dest = ~arg1 + arg2 [+ ca]. */ 1902 if (NARROW_MODE(ctx)) { 1903 /* 1904 * Caution: a non-obvious corner case of the spec is that 1905 * we must produce the *entire* 64-bit addition, but 1906 * produce the carry into bit 32. 1907 */ 1908 TCGv inv1 = tcg_temp_new(); 1909 TCGv t1 = tcg_temp_new(); 1910 tcg_gen_not_tl(inv1, arg1); 1911 if (add_ca) { 1912 tcg_gen_add_tl(t0, arg2, cpu_ca); 1913 } else { 1914 tcg_gen_addi_tl(t0, arg2, 1); 1915 } 1916 tcg_gen_xor_tl(t1, arg2, inv1); /* add without carry */ 1917 tcg_gen_add_tl(t0, t0, inv1); 1918 tcg_gen_xor_tl(cpu_ca, t0, t1); /* bits changes w/ carry */ 1919 tcg_gen_extract_tl(cpu_ca, cpu_ca, 32, 1); 1920 if (is_isa300(ctx)) { 1921 tcg_gen_mov_tl(cpu_ca32, cpu_ca); 1922 } 1923 } else if (add_ca) { 1924 TCGv zero, inv1 = tcg_temp_new(); 1925 tcg_gen_not_tl(inv1, arg1); 1926 zero = tcg_constant_tl(0); 1927 tcg_gen_add2_tl(t0, cpu_ca, arg2, zero, cpu_ca, zero); 1928 tcg_gen_add2_tl(t0, cpu_ca, t0, cpu_ca, inv1, zero); 1929 gen_op_arith_compute_ca32(ctx, t0, inv1, arg2, cpu_ca32, 0); 1930 } else { 1931 tcg_gen_setcond_tl(TCG_COND_GEU, cpu_ca, arg2, arg1); 1932 tcg_gen_sub_tl(t0, arg2, arg1); 1933 gen_op_arith_compute_ca32(ctx, t0, arg1, arg2, cpu_ca32, 1); 1934 } 1935 } else if (add_ca) { 1936 /* 1937 * Since we're ignoring carry-out, we can simplify the 1938 * standard ~arg1 + arg2 + ca to arg2 - arg1 + ca - 1. 1939 */ 1940 tcg_gen_sub_tl(t0, arg2, arg1); 1941 tcg_gen_add_tl(t0, t0, cpu_ca); 1942 tcg_gen_subi_tl(t0, t0, 1); 1943 } else { 1944 tcg_gen_sub_tl(t0, arg2, arg1); 1945 } 1946 1947 if (compute_ov) { 1948 gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 1); 1949 } 1950 if (unlikely(compute_rc0)) { 1951 gen_set_Rc0(ctx, t0); 1952 } 1953 1954 if (t0 != ret) { 1955 tcg_gen_mov_tl(ret, t0); 1956 } 1957 } 1958 1959 /*** Integer logical ***/ 1960 1961 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) 1962 static void gen_pause(DisasContext *ctx) 1963 { 1964 TCGv_i32 t0 = tcg_constant_i32(0); 1965 tcg_gen_st_i32(t0, tcg_env, 1966 -offsetof(PowerPCCPU, env) + offsetof(CPUState, halted)); 1967 1968 /* Stop translation, this gives other CPUs a chance to run */ 1969 gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next); 1970 } 1971 #endif /* defined(TARGET_PPC64) */ 1972 1973 /*** Integer rotate ***/ 1974 1975 /* rlwimi & rlwimi. */ 1976 static void gen_rlwimi(DisasContext *ctx) 1977 { 1978 TCGv t_ra = cpu_gpr[rA(ctx->opcode)]; 1979 TCGv t_rs = cpu_gpr[rS(ctx->opcode)]; 1980 uint32_t sh = SH(ctx->opcode); 1981 uint32_t mb = MB(ctx->opcode); 1982 uint32_t me = ME(ctx->opcode); 1983 1984 if (sh == (31 - me) && mb <= me) { 1985 tcg_gen_deposit_tl(t_ra, t_ra, t_rs, sh, me - mb + 1); 1986 } else { 1987 target_ulong mask; 1988 bool mask_in_32b = true; 1989 TCGv t1; 1990 1991 #if defined(TARGET_PPC64) 1992 mb += 32; 1993 me += 32; 1994 #endif 1995 mask = MASK(mb, me); 1996 1997 #if defined(TARGET_PPC64) 1998 if (mask > 0xffffffffu) { 1999 mask_in_32b = false; 2000 } 2001 #endif 2002 t1 = tcg_temp_new(); 2003 if (mask_in_32b) { 2004 TCGv_i32 t0 = tcg_temp_new_i32(); 2005 tcg_gen_trunc_tl_i32(t0, t_rs); 2006 tcg_gen_rotli_i32(t0, t0, sh); 2007 tcg_gen_extu_i32_tl(t1, t0); 2008 } else { 2009 #if defined(TARGET_PPC64) 2010 tcg_gen_deposit_i64(t1, t_rs, t_rs, 32, 32); 2011 tcg_gen_rotli_i64(t1, t1, sh); 2012 #else 2013 g_assert_not_reached(); 2014 #endif 2015 } 2016 2017 tcg_gen_andi_tl(t1, t1, mask); 2018 tcg_gen_andi_tl(t_ra, t_ra, ~mask); 2019 tcg_gen_or_tl(t_ra, t_ra, t1); 2020 } 2021 if (unlikely(Rc(ctx->opcode) != 0)) { 2022 gen_set_Rc0(ctx, t_ra); 2023 } 2024 } 2025 2026 /* rlwinm & rlwinm. */ 2027 static void gen_rlwinm(DisasContext *ctx) 2028 { 2029 TCGv t_ra = cpu_gpr[rA(ctx->opcode)]; 2030 TCGv t_rs = cpu_gpr[rS(ctx->opcode)]; 2031 int sh = SH(ctx->opcode); 2032 int mb = MB(ctx->opcode); 2033 int me = ME(ctx->opcode); 2034 int len = me - mb + 1; 2035 int rsh = (32 - sh) & 31; 2036 2037 if (sh != 0 && len > 0 && me == (31 - sh)) { 2038 tcg_gen_deposit_z_tl(t_ra, t_rs, sh, len); 2039 } else if (me == 31 && rsh + len <= 32) { 2040 tcg_gen_extract_tl(t_ra, t_rs, rsh, len); 2041 } else { 2042 target_ulong mask; 2043 bool mask_in_32b = true; 2044 #if defined(TARGET_PPC64) 2045 mb += 32; 2046 me += 32; 2047 #endif 2048 mask = MASK(mb, me); 2049 #if defined(TARGET_PPC64) 2050 if (mask > 0xffffffffu) { 2051 mask_in_32b = false; 2052 } 2053 #endif 2054 if (mask_in_32b) { 2055 if (sh == 0) { 2056 tcg_gen_andi_tl(t_ra, t_rs, mask); 2057 } else { 2058 TCGv_i32 t0 = tcg_temp_new_i32(); 2059 tcg_gen_trunc_tl_i32(t0, t_rs); 2060 tcg_gen_rotli_i32(t0, t0, sh); 2061 tcg_gen_andi_i32(t0, t0, mask); 2062 tcg_gen_extu_i32_tl(t_ra, t0); 2063 } 2064 } else { 2065 #if defined(TARGET_PPC64) 2066 tcg_gen_deposit_i64(t_ra, t_rs, t_rs, 32, 32); 2067 tcg_gen_rotli_i64(t_ra, t_ra, sh); 2068 tcg_gen_andi_i64(t_ra, t_ra, mask); 2069 #else 2070 g_assert_not_reached(); 2071 #endif 2072 } 2073 } 2074 if (unlikely(Rc(ctx->opcode) != 0)) { 2075 gen_set_Rc0(ctx, t_ra); 2076 } 2077 } 2078 2079 /* rlwnm & rlwnm. */ 2080 static void gen_rlwnm(DisasContext *ctx) 2081 { 2082 TCGv t_ra = cpu_gpr[rA(ctx->opcode)]; 2083 TCGv t_rs = cpu_gpr[rS(ctx->opcode)]; 2084 TCGv t_rb = cpu_gpr[rB(ctx->opcode)]; 2085 uint32_t mb = MB(ctx->opcode); 2086 uint32_t me = ME(ctx->opcode); 2087 target_ulong mask; 2088 bool mask_in_32b = true; 2089 2090 #if defined(TARGET_PPC64) 2091 mb += 32; 2092 me += 32; 2093 #endif 2094 mask = MASK(mb, me); 2095 2096 #if defined(TARGET_PPC64) 2097 if (mask > 0xffffffffu) { 2098 mask_in_32b = false; 2099 } 2100 #endif 2101 if (mask_in_32b) { 2102 TCGv_i32 t0 = tcg_temp_new_i32(); 2103 TCGv_i32 t1 = tcg_temp_new_i32(); 2104 tcg_gen_trunc_tl_i32(t0, t_rb); 2105 tcg_gen_trunc_tl_i32(t1, t_rs); 2106 tcg_gen_andi_i32(t0, t0, 0x1f); 2107 tcg_gen_rotl_i32(t1, t1, t0); 2108 tcg_gen_extu_i32_tl(t_ra, t1); 2109 } else { 2110 #if defined(TARGET_PPC64) 2111 TCGv_i64 t0 = tcg_temp_new_i64(); 2112 tcg_gen_andi_i64(t0, t_rb, 0x1f); 2113 tcg_gen_deposit_i64(t_ra, t_rs, t_rs, 32, 32); 2114 tcg_gen_rotl_i64(t_ra, t_ra, t0); 2115 #else 2116 g_assert_not_reached(); 2117 #endif 2118 } 2119 2120 tcg_gen_andi_tl(t_ra, t_ra, mask); 2121 2122 if (unlikely(Rc(ctx->opcode) != 0)) { 2123 gen_set_Rc0(ctx, t_ra); 2124 } 2125 } 2126 2127 #if defined(TARGET_PPC64) 2128 #define GEN_PPC64_R2(name, opc1, opc2) \ 2129 static void glue(gen_, name##0)(DisasContext *ctx) \ 2130 { \ 2131 gen_##name(ctx, 0); \ 2132 } \ 2133 \ 2134 static void glue(gen_, name##1)(DisasContext *ctx) \ 2135 { \ 2136 gen_##name(ctx, 1); \ 2137 } 2138 #define GEN_PPC64_R4(name, opc1, opc2) \ 2139 static void glue(gen_, name##0)(DisasContext *ctx) \ 2140 { \ 2141 gen_##name(ctx, 0, 0); \ 2142 } \ 2143 \ 2144 static void glue(gen_, name##1)(DisasContext *ctx) \ 2145 { \ 2146 gen_##name(ctx, 0, 1); \ 2147 } \ 2148 \ 2149 static void glue(gen_, name##2)(DisasContext *ctx) \ 2150 { \ 2151 gen_##name(ctx, 1, 0); \ 2152 } \ 2153 \ 2154 static void glue(gen_, name##3)(DisasContext *ctx) \ 2155 { \ 2156 gen_##name(ctx, 1, 1); \ 2157 } 2158 2159 static void gen_rldinm(DisasContext *ctx, int mb, int me, int sh) 2160 { 2161 TCGv t_ra = cpu_gpr[rA(ctx->opcode)]; 2162 TCGv t_rs = cpu_gpr[rS(ctx->opcode)]; 2163 int len = me - mb + 1; 2164 int rsh = (64 - sh) & 63; 2165 2166 if (sh != 0 && len > 0 && me == (63 - sh)) { 2167 tcg_gen_deposit_z_tl(t_ra, t_rs, sh, len); 2168 } else if (me == 63 && rsh + len <= 64) { 2169 tcg_gen_extract_tl(t_ra, t_rs, rsh, len); 2170 } else { 2171 tcg_gen_rotli_tl(t_ra, t_rs, sh); 2172 tcg_gen_andi_tl(t_ra, t_ra, MASK(mb, me)); 2173 } 2174 if (unlikely(Rc(ctx->opcode) != 0)) { 2175 gen_set_Rc0(ctx, t_ra); 2176 } 2177 } 2178 2179 /* rldicl - rldicl. */ 2180 static inline void gen_rldicl(DisasContext *ctx, int mbn, int shn) 2181 { 2182 uint32_t sh, mb; 2183 2184 sh = SH(ctx->opcode) | (shn << 5); 2185 mb = MB(ctx->opcode) | (mbn << 5); 2186 gen_rldinm(ctx, mb, 63, sh); 2187 } 2188 GEN_PPC64_R4(rldicl, 0x1E, 0x00); 2189 2190 /* rldicr - rldicr. */ 2191 static inline void gen_rldicr(DisasContext *ctx, int men, int shn) 2192 { 2193 uint32_t sh, me; 2194 2195 sh = SH(ctx->opcode) | (shn << 5); 2196 me = MB(ctx->opcode) | (men << 5); 2197 gen_rldinm(ctx, 0, me, sh); 2198 } 2199 GEN_PPC64_R4(rldicr, 0x1E, 0x02); 2200 2201 /* rldic - rldic. */ 2202 static inline void gen_rldic(DisasContext *ctx, int mbn, int shn) 2203 { 2204 uint32_t sh, mb; 2205 2206 sh = SH(ctx->opcode) | (shn << 5); 2207 mb = MB(ctx->opcode) | (mbn << 5); 2208 gen_rldinm(ctx, mb, 63 - sh, sh); 2209 } 2210 GEN_PPC64_R4(rldic, 0x1E, 0x04); 2211 2212 static void gen_rldnm(DisasContext *ctx, int mb, int me) 2213 { 2214 TCGv t_ra = cpu_gpr[rA(ctx->opcode)]; 2215 TCGv t_rs = cpu_gpr[rS(ctx->opcode)]; 2216 TCGv t_rb = cpu_gpr[rB(ctx->opcode)]; 2217 TCGv t0; 2218 2219 t0 = tcg_temp_new(); 2220 tcg_gen_andi_tl(t0, t_rb, 0x3f); 2221 tcg_gen_rotl_tl(t_ra, t_rs, t0); 2222 2223 tcg_gen_andi_tl(t_ra, t_ra, MASK(mb, me)); 2224 if (unlikely(Rc(ctx->opcode) != 0)) { 2225 gen_set_Rc0(ctx, t_ra); 2226 } 2227 } 2228 2229 /* rldcl - rldcl. */ 2230 static inline void gen_rldcl(DisasContext *ctx, int mbn) 2231 { 2232 uint32_t mb; 2233 2234 mb = MB(ctx->opcode) | (mbn << 5); 2235 gen_rldnm(ctx, mb, 63); 2236 } 2237 GEN_PPC64_R2(rldcl, 0x1E, 0x08); 2238 2239 /* rldcr - rldcr. */ 2240 static inline void gen_rldcr(DisasContext *ctx, int men) 2241 { 2242 uint32_t me; 2243 2244 me = MB(ctx->opcode) | (men << 5); 2245 gen_rldnm(ctx, 0, me); 2246 } 2247 GEN_PPC64_R2(rldcr, 0x1E, 0x09); 2248 2249 /* rldimi - rldimi. */ 2250 static void gen_rldimi(DisasContext *ctx, int mbn, int shn) 2251 { 2252 TCGv t_ra = cpu_gpr[rA(ctx->opcode)]; 2253 TCGv t_rs = cpu_gpr[rS(ctx->opcode)]; 2254 uint32_t sh = SH(ctx->opcode) | (shn << 5); 2255 uint32_t mb = MB(ctx->opcode) | (mbn << 5); 2256 uint32_t me = 63 - sh; 2257 2258 if (mb <= me) { 2259 tcg_gen_deposit_tl(t_ra, t_ra, t_rs, sh, me - mb + 1); 2260 } else { 2261 target_ulong mask = MASK(mb, me); 2262 TCGv t1 = tcg_temp_new(); 2263 2264 tcg_gen_rotli_tl(t1, t_rs, sh); 2265 tcg_gen_andi_tl(t1, t1, mask); 2266 tcg_gen_andi_tl(t_ra, t_ra, ~mask); 2267 tcg_gen_or_tl(t_ra, t_ra, t1); 2268 } 2269 if (unlikely(Rc(ctx->opcode) != 0)) { 2270 gen_set_Rc0(ctx, t_ra); 2271 } 2272 } 2273 GEN_PPC64_R4(rldimi, 0x1E, 0x06); 2274 #endif 2275 2276 /*** Integer shift ***/ 2277 2278 /* slw & slw. */ 2279 static void gen_slw(DisasContext *ctx) 2280 { 2281 TCGv t0, t1; 2282 2283 t0 = tcg_temp_new(); 2284 /* AND rS with a mask that is 0 when rB >= 0x20 */ 2285 #if defined(TARGET_PPC64) 2286 tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3a); 2287 tcg_gen_sari_tl(t0, t0, 0x3f); 2288 #else 2289 tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1a); 2290 tcg_gen_sari_tl(t0, t0, 0x1f); 2291 #endif 2292 tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0); 2293 t1 = tcg_temp_new(); 2294 tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1f); 2295 tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], t0, t1); 2296 tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); 2297 if (unlikely(Rc(ctx->opcode) != 0)) { 2298 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 2299 } 2300 } 2301 2302 /* sraw & sraw. */ 2303 static void gen_sraw(DisasContext *ctx) 2304 { 2305 gen_helper_sraw(cpu_gpr[rA(ctx->opcode)], tcg_env, 2306 cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); 2307 if (unlikely(Rc(ctx->opcode) != 0)) { 2308 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 2309 } 2310 } 2311 2312 /* srawi & srawi. */ 2313 static void gen_srawi(DisasContext *ctx) 2314 { 2315 int sh = SH(ctx->opcode); 2316 TCGv dst = cpu_gpr[rA(ctx->opcode)]; 2317 TCGv src = cpu_gpr[rS(ctx->opcode)]; 2318 if (sh == 0) { 2319 tcg_gen_ext32s_tl(dst, src); 2320 tcg_gen_movi_tl(cpu_ca, 0); 2321 if (is_isa300(ctx)) { 2322 tcg_gen_movi_tl(cpu_ca32, 0); 2323 } 2324 } else { 2325 TCGv t0; 2326 tcg_gen_ext32s_tl(dst, src); 2327 tcg_gen_andi_tl(cpu_ca, dst, (1ULL << sh) - 1); 2328 t0 = tcg_temp_new(); 2329 tcg_gen_sari_tl(t0, dst, TARGET_LONG_BITS - 1); 2330 tcg_gen_and_tl(cpu_ca, cpu_ca, t0); 2331 tcg_gen_setcondi_tl(TCG_COND_NE, cpu_ca, cpu_ca, 0); 2332 if (is_isa300(ctx)) { 2333 tcg_gen_mov_tl(cpu_ca32, cpu_ca); 2334 } 2335 tcg_gen_sari_tl(dst, dst, sh); 2336 } 2337 if (unlikely(Rc(ctx->opcode) != 0)) { 2338 gen_set_Rc0(ctx, dst); 2339 } 2340 } 2341 2342 /* srw & srw. */ 2343 static void gen_srw(DisasContext *ctx) 2344 { 2345 TCGv t0, t1; 2346 2347 t0 = tcg_temp_new(); 2348 /* AND rS with a mask that is 0 when rB >= 0x20 */ 2349 #if defined(TARGET_PPC64) 2350 tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3a); 2351 tcg_gen_sari_tl(t0, t0, 0x3f); 2352 #else 2353 tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1a); 2354 tcg_gen_sari_tl(t0, t0, 0x1f); 2355 #endif 2356 tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0); 2357 tcg_gen_ext32u_tl(t0, t0); 2358 t1 = tcg_temp_new(); 2359 tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1f); 2360 tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], t0, t1); 2361 if (unlikely(Rc(ctx->opcode) != 0)) { 2362 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 2363 } 2364 } 2365 2366 #if defined(TARGET_PPC64) 2367 /* sld & sld. */ 2368 static void gen_sld(DisasContext *ctx) 2369 { 2370 TCGv t0, t1; 2371 2372 t0 = tcg_temp_new(); 2373 /* AND rS with a mask that is 0 when rB >= 0x40 */ 2374 tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x39); 2375 tcg_gen_sari_tl(t0, t0, 0x3f); 2376 tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0); 2377 t1 = tcg_temp_new(); 2378 tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x3f); 2379 tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], t0, t1); 2380 if (unlikely(Rc(ctx->opcode) != 0)) { 2381 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 2382 } 2383 } 2384 2385 /* srad & srad. */ 2386 static void gen_srad(DisasContext *ctx) 2387 { 2388 gen_helper_srad(cpu_gpr[rA(ctx->opcode)], tcg_env, 2389 cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); 2390 if (unlikely(Rc(ctx->opcode) != 0)) { 2391 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 2392 } 2393 } 2394 /* sradi & sradi. */ 2395 static inline void gen_sradi(DisasContext *ctx, int n) 2396 { 2397 int sh = SH(ctx->opcode) + (n << 5); 2398 TCGv dst = cpu_gpr[rA(ctx->opcode)]; 2399 TCGv src = cpu_gpr[rS(ctx->opcode)]; 2400 if (sh == 0) { 2401 tcg_gen_mov_tl(dst, src); 2402 tcg_gen_movi_tl(cpu_ca, 0); 2403 if (is_isa300(ctx)) { 2404 tcg_gen_movi_tl(cpu_ca32, 0); 2405 } 2406 } else { 2407 TCGv t0; 2408 tcg_gen_andi_tl(cpu_ca, src, (1ULL << sh) - 1); 2409 t0 = tcg_temp_new(); 2410 tcg_gen_sari_tl(t0, src, TARGET_LONG_BITS - 1); 2411 tcg_gen_and_tl(cpu_ca, cpu_ca, t0); 2412 tcg_gen_setcondi_tl(TCG_COND_NE, cpu_ca, cpu_ca, 0); 2413 if (is_isa300(ctx)) { 2414 tcg_gen_mov_tl(cpu_ca32, cpu_ca); 2415 } 2416 tcg_gen_sari_tl(dst, src, sh); 2417 } 2418 if (unlikely(Rc(ctx->opcode) != 0)) { 2419 gen_set_Rc0(ctx, dst); 2420 } 2421 } 2422 2423 static void gen_sradi0(DisasContext *ctx) 2424 { 2425 gen_sradi(ctx, 0); 2426 } 2427 2428 static void gen_sradi1(DisasContext *ctx) 2429 { 2430 gen_sradi(ctx, 1); 2431 } 2432 2433 /* extswsli & extswsli. */ 2434 static inline void gen_extswsli(DisasContext *ctx, int n) 2435 { 2436 int sh = SH(ctx->opcode) + (n << 5); 2437 TCGv dst = cpu_gpr[rA(ctx->opcode)]; 2438 TCGv src = cpu_gpr[rS(ctx->opcode)]; 2439 2440 tcg_gen_ext32s_tl(dst, src); 2441 tcg_gen_shli_tl(dst, dst, sh); 2442 if (unlikely(Rc(ctx->opcode) != 0)) { 2443 gen_set_Rc0(ctx, dst); 2444 } 2445 } 2446 2447 static void gen_extswsli0(DisasContext *ctx) 2448 { 2449 gen_extswsli(ctx, 0); 2450 } 2451 2452 static void gen_extswsli1(DisasContext *ctx) 2453 { 2454 gen_extswsli(ctx, 1); 2455 } 2456 2457 /* srd & srd. */ 2458 static void gen_srd(DisasContext *ctx) 2459 { 2460 TCGv t0, t1; 2461 2462 t0 = tcg_temp_new(); 2463 /* AND rS with a mask that is 0 when rB >= 0x40 */ 2464 tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x39); 2465 tcg_gen_sari_tl(t0, t0, 0x3f); 2466 tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0); 2467 t1 = tcg_temp_new(); 2468 tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x3f); 2469 tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], t0, t1); 2470 if (unlikely(Rc(ctx->opcode) != 0)) { 2471 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 2472 } 2473 } 2474 #endif 2475 2476 /*** Addressing modes ***/ 2477 /* Register indirect with immediate index : EA = (rA|0) + SIMM */ 2478 static inline void gen_addr_imm_index(DisasContext *ctx, TCGv EA, 2479 target_long maskl) 2480 { 2481 target_long simm = SIMM(ctx->opcode); 2482 2483 simm &= ~maskl; 2484 if (rA(ctx->opcode) == 0) { 2485 if (NARROW_MODE(ctx)) { 2486 simm = (uint32_t)simm; 2487 } 2488 tcg_gen_movi_tl(EA, simm); 2489 } else if (likely(simm != 0)) { 2490 tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], simm); 2491 if (NARROW_MODE(ctx)) { 2492 tcg_gen_ext32u_tl(EA, EA); 2493 } 2494 } else { 2495 if (NARROW_MODE(ctx)) { 2496 tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]); 2497 } else { 2498 tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]); 2499 } 2500 } 2501 } 2502 2503 static inline void gen_addr_reg_index(DisasContext *ctx, TCGv EA) 2504 { 2505 if (rA(ctx->opcode) == 0) { 2506 if (NARROW_MODE(ctx)) { 2507 tcg_gen_ext32u_tl(EA, cpu_gpr[rB(ctx->opcode)]); 2508 } else { 2509 tcg_gen_mov_tl(EA, cpu_gpr[rB(ctx->opcode)]); 2510 } 2511 } else { 2512 tcg_gen_add_tl(EA, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); 2513 if (NARROW_MODE(ctx)) { 2514 tcg_gen_ext32u_tl(EA, EA); 2515 } 2516 } 2517 } 2518 2519 static inline void gen_addr_register(DisasContext *ctx, TCGv EA) 2520 { 2521 if (rA(ctx->opcode) == 0) { 2522 tcg_gen_movi_tl(EA, 0); 2523 } else if (NARROW_MODE(ctx)) { 2524 tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]); 2525 } else { 2526 tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]); 2527 } 2528 } 2529 2530 static inline void gen_addr_add(DisasContext *ctx, TCGv ret, TCGv arg1, 2531 target_long val) 2532 { 2533 tcg_gen_addi_tl(ret, arg1, val); 2534 if (NARROW_MODE(ctx)) { 2535 tcg_gen_ext32u_tl(ret, ret); 2536 } 2537 } 2538 2539 static inline void gen_align_no_le(DisasContext *ctx) 2540 { 2541 gen_exception_err(ctx, POWERPC_EXCP_ALIGN, 2542 (ctx->opcode & 0x03FF0000) | POWERPC_EXCP_ALIGN_LE); 2543 } 2544 2545 static TCGv do_ea_calc(DisasContext *ctx, int ra, TCGv displ) 2546 { 2547 TCGv ea = tcg_temp_new(); 2548 if (ra) { 2549 tcg_gen_add_tl(ea, cpu_gpr[ra], displ); 2550 } else { 2551 tcg_gen_mov_tl(ea, displ); 2552 } 2553 if (NARROW_MODE(ctx)) { 2554 tcg_gen_ext32u_tl(ea, ea); 2555 } 2556 return ea; 2557 } 2558 2559 /*** Integer load ***/ 2560 #define DEF_MEMOP(op) ((op) | ctx->default_tcg_memop_mask) 2561 #define BSWAP_MEMOP(op) ((op) | (ctx->default_tcg_memop_mask ^ MO_BSWAP)) 2562 2563 #define GEN_QEMU_LOAD_TL(ldop, op) \ 2564 static void glue(gen_qemu_, ldop)(DisasContext *ctx, \ 2565 TCGv val, \ 2566 TCGv addr) \ 2567 { \ 2568 tcg_gen_qemu_ld_tl(val, addr, ctx->mem_idx, op); \ 2569 } 2570 2571 GEN_QEMU_LOAD_TL(ld8u, DEF_MEMOP(MO_UB)) 2572 GEN_QEMU_LOAD_TL(ld16u, DEF_MEMOP(MO_UW)) 2573 GEN_QEMU_LOAD_TL(ld16s, DEF_MEMOP(MO_SW)) 2574 GEN_QEMU_LOAD_TL(ld32u, DEF_MEMOP(MO_UL)) 2575 GEN_QEMU_LOAD_TL(ld32s, DEF_MEMOP(MO_SL)) 2576 2577 GEN_QEMU_LOAD_TL(ld16ur, BSWAP_MEMOP(MO_UW)) 2578 GEN_QEMU_LOAD_TL(ld32ur, BSWAP_MEMOP(MO_UL)) 2579 2580 #define GEN_QEMU_LOAD_64(ldop, op) \ 2581 static void glue(gen_qemu_, glue(ldop, _i64))(DisasContext *ctx, \ 2582 TCGv_i64 val, \ 2583 TCGv addr) \ 2584 { \ 2585 tcg_gen_qemu_ld_i64(val, addr, ctx->mem_idx, op); \ 2586 } 2587 2588 GEN_QEMU_LOAD_64(ld8u, DEF_MEMOP(MO_UB)) 2589 GEN_QEMU_LOAD_64(ld16u, DEF_MEMOP(MO_UW)) 2590 GEN_QEMU_LOAD_64(ld32u, DEF_MEMOP(MO_UL)) 2591 GEN_QEMU_LOAD_64(ld32s, DEF_MEMOP(MO_SL)) 2592 GEN_QEMU_LOAD_64(ld64, DEF_MEMOP(MO_UQ)) 2593 2594 #if defined(TARGET_PPC64) 2595 GEN_QEMU_LOAD_64(ld64ur, BSWAP_MEMOP(MO_UQ)) 2596 #endif 2597 2598 #define GEN_QEMU_STORE_TL(stop, op) \ 2599 static void glue(gen_qemu_, stop)(DisasContext *ctx, \ 2600 TCGv val, \ 2601 TCGv addr) \ 2602 { \ 2603 tcg_gen_qemu_st_tl(val, addr, ctx->mem_idx, op); \ 2604 } 2605 2606 #if defined(TARGET_PPC64) || !defined(CONFIG_USER_ONLY) 2607 GEN_QEMU_STORE_TL(st8, DEF_MEMOP(MO_UB)) 2608 #endif 2609 GEN_QEMU_STORE_TL(st16, DEF_MEMOP(MO_UW)) 2610 GEN_QEMU_STORE_TL(st32, DEF_MEMOP(MO_UL)) 2611 2612 GEN_QEMU_STORE_TL(st16r, BSWAP_MEMOP(MO_UW)) 2613 GEN_QEMU_STORE_TL(st32r, BSWAP_MEMOP(MO_UL)) 2614 2615 #define GEN_QEMU_STORE_64(stop, op) \ 2616 static void glue(gen_qemu_, glue(stop, _i64))(DisasContext *ctx, \ 2617 TCGv_i64 val, \ 2618 TCGv addr) \ 2619 { \ 2620 tcg_gen_qemu_st_i64(val, addr, ctx->mem_idx, op); \ 2621 } 2622 2623 GEN_QEMU_STORE_64(st8, DEF_MEMOP(MO_UB)) 2624 GEN_QEMU_STORE_64(st16, DEF_MEMOP(MO_UW)) 2625 GEN_QEMU_STORE_64(st32, DEF_MEMOP(MO_UL)) 2626 GEN_QEMU_STORE_64(st64, DEF_MEMOP(MO_UQ)) 2627 2628 #if defined(TARGET_PPC64) 2629 GEN_QEMU_STORE_64(st64r, BSWAP_MEMOP(MO_UQ)) 2630 #endif 2631 2632 #define GEN_LDX_E(name, ldop, opc2, opc3, type, type2, chk) \ 2633 static void glue(gen_, name##x)(DisasContext *ctx) \ 2634 { \ 2635 TCGv EA; \ 2636 chk(ctx); \ 2637 gen_set_access_type(ctx, ACCESS_INT); \ 2638 EA = tcg_temp_new(); \ 2639 gen_addr_reg_index(ctx, EA); \ 2640 gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA); \ 2641 } 2642 2643 #define GEN_LDX(name, ldop, opc2, opc3, type) \ 2644 GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE, CHK_NONE) 2645 2646 #define GEN_LDX_HVRM(name, ldop, opc2, opc3, type) \ 2647 GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE, CHK_HVRM) 2648 2649 #define GEN_LDEPX(name, ldop, opc2, opc3) \ 2650 static void glue(gen_, name##epx)(DisasContext *ctx) \ 2651 { \ 2652 TCGv EA; \ 2653 CHK_SV(ctx); \ 2654 gen_set_access_type(ctx, ACCESS_INT); \ 2655 EA = tcg_temp_new(); \ 2656 gen_addr_reg_index(ctx, EA); \ 2657 tcg_gen_qemu_ld_tl(cpu_gpr[rD(ctx->opcode)], EA, PPC_TLB_EPID_LOAD, ldop);\ 2658 } 2659 2660 GEN_LDEPX(lb, DEF_MEMOP(MO_UB), 0x1F, 0x02) 2661 GEN_LDEPX(lh, DEF_MEMOP(MO_UW), 0x1F, 0x08) 2662 GEN_LDEPX(lw, DEF_MEMOP(MO_UL), 0x1F, 0x00) 2663 #if defined(TARGET_PPC64) 2664 GEN_LDEPX(ld, DEF_MEMOP(MO_UQ), 0x1D, 0x00) 2665 #endif 2666 2667 #if defined(TARGET_PPC64) 2668 /* CI load/store variants */ 2669 GEN_LDX_HVRM(ldcix, ld64_i64, 0x15, 0x1b, PPC_CILDST) 2670 GEN_LDX_HVRM(lwzcix, ld32u, 0x15, 0x15, PPC_CILDST) 2671 GEN_LDX_HVRM(lhzcix, ld16u, 0x15, 0x19, PPC_CILDST) 2672 GEN_LDX_HVRM(lbzcix, ld8u, 0x15, 0x1a, PPC_CILDST) 2673 #endif 2674 2675 /*** Integer store ***/ 2676 #define GEN_STX_E(name, stop, opc2, opc3, type, type2, chk) \ 2677 static void glue(gen_, name##x)(DisasContext *ctx) \ 2678 { \ 2679 TCGv EA; \ 2680 chk(ctx); \ 2681 gen_set_access_type(ctx, ACCESS_INT); \ 2682 EA = tcg_temp_new(); \ 2683 gen_addr_reg_index(ctx, EA); \ 2684 gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA); \ 2685 } 2686 #define GEN_STX(name, stop, opc2, opc3, type) \ 2687 GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE, CHK_NONE) 2688 2689 #define GEN_STX_HVRM(name, stop, opc2, opc3, type) \ 2690 GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE, CHK_HVRM) 2691 2692 #define GEN_STEPX(name, stop, opc2, opc3) \ 2693 static void glue(gen_, name##epx)(DisasContext *ctx) \ 2694 { \ 2695 TCGv EA; \ 2696 CHK_SV(ctx); \ 2697 gen_set_access_type(ctx, ACCESS_INT); \ 2698 EA = tcg_temp_new(); \ 2699 gen_addr_reg_index(ctx, EA); \ 2700 tcg_gen_qemu_st_tl( \ 2701 cpu_gpr[rD(ctx->opcode)], EA, PPC_TLB_EPID_STORE, stop); \ 2702 } 2703 2704 GEN_STEPX(stb, DEF_MEMOP(MO_UB), 0x1F, 0x06) 2705 GEN_STEPX(sth, DEF_MEMOP(MO_UW), 0x1F, 0x0C) 2706 GEN_STEPX(stw, DEF_MEMOP(MO_UL), 0x1F, 0x04) 2707 #if defined(TARGET_PPC64) 2708 GEN_STEPX(std, DEF_MEMOP(MO_UQ), 0x1d, 0x04) 2709 #endif 2710 2711 #if defined(TARGET_PPC64) 2712 GEN_STX_HVRM(stdcix, st64_i64, 0x15, 0x1f, PPC_CILDST) 2713 GEN_STX_HVRM(stwcix, st32, 0x15, 0x1c, PPC_CILDST) 2714 GEN_STX_HVRM(sthcix, st16, 0x15, 0x1d, PPC_CILDST) 2715 GEN_STX_HVRM(stbcix, st8, 0x15, 0x1e, PPC_CILDST) 2716 #endif 2717 /*** Integer load and store with byte reverse ***/ 2718 2719 /* lhbrx */ 2720 GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER); 2721 2722 /* lwbrx */ 2723 GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER); 2724 2725 #if defined(TARGET_PPC64) 2726 /* ldbrx */ 2727 GEN_LDX_E(ldbr, ld64ur_i64, 0x14, 0x10, PPC_NONE, PPC2_DBRX, CHK_NONE); 2728 /* stdbrx */ 2729 GEN_STX_E(stdbr, st64r_i64, 0x14, 0x14, PPC_NONE, PPC2_DBRX, CHK_NONE); 2730 #endif /* TARGET_PPC64 */ 2731 2732 /* sthbrx */ 2733 GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER); 2734 /* stwbrx */ 2735 GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER); 2736 2737 /*** Integer load and store multiple ***/ 2738 2739 /* lmw */ 2740 static void gen_lmw(DisasContext *ctx) 2741 { 2742 TCGv t0; 2743 TCGv_i32 t1; 2744 2745 if (ctx->le_mode) { 2746 gen_align_no_le(ctx); 2747 return; 2748 } 2749 gen_set_access_type(ctx, ACCESS_INT); 2750 t0 = tcg_temp_new(); 2751 t1 = tcg_constant_i32(rD(ctx->opcode)); 2752 gen_addr_imm_index(ctx, t0, 0); 2753 gen_helper_lmw(tcg_env, t0, t1); 2754 } 2755 2756 /* stmw */ 2757 static void gen_stmw(DisasContext *ctx) 2758 { 2759 TCGv t0; 2760 TCGv_i32 t1; 2761 2762 if (ctx->le_mode) { 2763 gen_align_no_le(ctx); 2764 return; 2765 } 2766 gen_set_access_type(ctx, ACCESS_INT); 2767 t0 = tcg_temp_new(); 2768 t1 = tcg_constant_i32(rS(ctx->opcode)); 2769 gen_addr_imm_index(ctx, t0, 0); 2770 gen_helper_stmw(tcg_env, t0, t1); 2771 } 2772 2773 /*** Integer load and store strings ***/ 2774 2775 /* lswi */ 2776 /* 2777 * PowerPC32 specification says we must generate an exception if rA is 2778 * in the range of registers to be loaded. In an other hand, IBM says 2779 * this is valid, but rA won't be loaded. For now, I'll follow the 2780 * spec... 2781 */ 2782 static void gen_lswi(DisasContext *ctx) 2783 { 2784 TCGv t0; 2785 TCGv_i32 t1, t2; 2786 int nb = NB(ctx->opcode); 2787 int start = rD(ctx->opcode); 2788 int ra = rA(ctx->opcode); 2789 int nr; 2790 2791 if (ctx->le_mode) { 2792 gen_align_no_le(ctx); 2793 return; 2794 } 2795 if (nb == 0) { 2796 nb = 32; 2797 } 2798 nr = DIV_ROUND_UP(nb, 4); 2799 if (unlikely(lsw_reg_in_range(start, nr, ra))) { 2800 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX); 2801 return; 2802 } 2803 gen_set_access_type(ctx, ACCESS_INT); 2804 t0 = tcg_temp_new(); 2805 gen_addr_register(ctx, t0); 2806 t1 = tcg_constant_i32(nb); 2807 t2 = tcg_constant_i32(start); 2808 gen_helper_lsw(tcg_env, t0, t1, t2); 2809 } 2810 2811 /* lswx */ 2812 static void gen_lswx(DisasContext *ctx) 2813 { 2814 TCGv t0; 2815 TCGv_i32 t1, t2, t3; 2816 2817 if (ctx->le_mode) { 2818 gen_align_no_le(ctx); 2819 return; 2820 } 2821 gen_set_access_type(ctx, ACCESS_INT); 2822 t0 = tcg_temp_new(); 2823 gen_addr_reg_index(ctx, t0); 2824 t1 = tcg_constant_i32(rD(ctx->opcode)); 2825 t2 = tcg_constant_i32(rA(ctx->opcode)); 2826 t3 = tcg_constant_i32(rB(ctx->opcode)); 2827 gen_helper_lswx(tcg_env, t0, t1, t2, t3); 2828 } 2829 2830 /* stswi */ 2831 static void gen_stswi(DisasContext *ctx) 2832 { 2833 TCGv t0; 2834 TCGv_i32 t1, t2; 2835 int nb = NB(ctx->opcode); 2836 2837 if (ctx->le_mode) { 2838 gen_align_no_le(ctx); 2839 return; 2840 } 2841 gen_set_access_type(ctx, ACCESS_INT); 2842 t0 = tcg_temp_new(); 2843 gen_addr_register(ctx, t0); 2844 if (nb == 0) { 2845 nb = 32; 2846 } 2847 t1 = tcg_constant_i32(nb); 2848 t2 = tcg_constant_i32(rS(ctx->opcode)); 2849 gen_helper_stsw(tcg_env, t0, t1, t2); 2850 } 2851 2852 /* stswx */ 2853 static void gen_stswx(DisasContext *ctx) 2854 { 2855 TCGv t0; 2856 TCGv_i32 t1, t2; 2857 2858 if (ctx->le_mode) { 2859 gen_align_no_le(ctx); 2860 return; 2861 } 2862 gen_set_access_type(ctx, ACCESS_INT); 2863 t0 = tcg_temp_new(); 2864 gen_addr_reg_index(ctx, t0); 2865 t1 = tcg_temp_new_i32(); 2866 tcg_gen_trunc_tl_i32(t1, cpu_xer); 2867 tcg_gen_andi_i32(t1, t1, 0x7F); 2868 t2 = tcg_constant_i32(rS(ctx->opcode)); 2869 gen_helper_stsw(tcg_env, t0, t1, t2); 2870 } 2871 2872 #if !defined(CONFIG_USER_ONLY) 2873 static inline void gen_check_tlb_flush(DisasContext *ctx, bool global) 2874 { 2875 TCGv_i32 t; 2876 TCGLabel *l; 2877 2878 if (!ctx->lazy_tlb_flush) { 2879 return; 2880 } 2881 l = gen_new_label(); 2882 t = tcg_temp_new_i32(); 2883 tcg_gen_ld_i32(t, tcg_env, offsetof(CPUPPCState, tlb_need_flush)); 2884 tcg_gen_brcondi_i32(TCG_COND_EQ, t, 0, l); 2885 if (global) { 2886 gen_helper_check_tlb_flush_global(tcg_env); 2887 } else { 2888 gen_helper_check_tlb_flush_local(tcg_env); 2889 } 2890 gen_set_label(l); 2891 if (global) { 2892 /* 2893 * Global TLB flush uses async-work which must run before the 2894 * next instruction, so this must be the last in the TB. 2895 */ 2896 ctx->base.is_jmp = DISAS_EXIT_UPDATE; 2897 } 2898 } 2899 #else 2900 static inline void gen_check_tlb_flush(DisasContext *ctx, bool global) { } 2901 #endif 2902 2903 /* isync */ 2904 static void gen_isync(DisasContext *ctx) 2905 { 2906 /* 2907 * We need to check for a pending TLB flush. This can only happen in 2908 * kernel mode however so check MSR_PR 2909 */ 2910 if (!ctx->pr) { 2911 gen_check_tlb_flush(ctx, false); 2912 } 2913 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC); 2914 ctx->base.is_jmp = DISAS_EXIT_UPDATE; 2915 } 2916 2917 static void gen_load_locked(DisasContext *ctx, MemOp memop) 2918 { 2919 TCGv gpr = cpu_gpr[rD(ctx->opcode)]; 2920 TCGv t0 = tcg_temp_new(); 2921 2922 gen_set_access_type(ctx, ACCESS_RES); 2923 gen_addr_reg_index(ctx, t0); 2924 tcg_gen_qemu_ld_tl(gpr, t0, ctx->mem_idx, DEF_MEMOP(memop) | MO_ALIGN); 2925 tcg_gen_mov_tl(cpu_reserve, t0); 2926 tcg_gen_movi_tl(cpu_reserve_length, memop_size(memop)); 2927 tcg_gen_mov_tl(cpu_reserve_val, gpr); 2928 } 2929 2930 #define LARX(name, memop) \ 2931 static void gen_##name(DisasContext *ctx) \ 2932 { \ 2933 gen_load_locked(ctx, memop); \ 2934 } 2935 2936 /* lwarx */ 2937 LARX(lbarx, MO_UB) 2938 LARX(lharx, MO_UW) 2939 LARX(lwarx, MO_UL) 2940 2941 static void gen_fetch_inc_conditional(DisasContext *ctx, MemOp memop, 2942 TCGv EA, TCGCond cond, int addend) 2943 { 2944 TCGv t = tcg_temp_new(); 2945 TCGv t2 = tcg_temp_new(); 2946 TCGv u = tcg_temp_new(); 2947 2948 tcg_gen_qemu_ld_tl(t, EA, ctx->mem_idx, memop); 2949 tcg_gen_addi_tl(t2, EA, memop_size(memop)); 2950 tcg_gen_qemu_ld_tl(t2, t2, ctx->mem_idx, memop); 2951 tcg_gen_addi_tl(u, t, addend); 2952 2953 /* E.g. for fetch and increment bounded... */ 2954 /* mem(EA,s) = (t != t2 ? u = t + 1 : t) */ 2955 tcg_gen_movcond_tl(cond, u, t, t2, u, t); 2956 tcg_gen_qemu_st_tl(u, EA, ctx->mem_idx, memop); 2957 2958 /* RT = (t != t2 ? t : u = 1<<(s*8-1)) */ 2959 tcg_gen_movi_tl(u, 1 << (memop_size(memop) * 8 - 1)); 2960 tcg_gen_movcond_tl(cond, cpu_gpr[rD(ctx->opcode)], t, t2, t, u); 2961 } 2962 2963 static void gen_ld_atomic(DisasContext *ctx, MemOp memop) 2964 { 2965 uint32_t gpr_FC = FC(ctx->opcode); 2966 TCGv EA = tcg_temp_new(); 2967 int rt = rD(ctx->opcode); 2968 bool need_serial; 2969 TCGv src, dst; 2970 2971 gen_addr_register(ctx, EA); 2972 dst = cpu_gpr[rt]; 2973 src = cpu_gpr[(rt + 1) & 31]; 2974 2975 need_serial = false; 2976 memop |= MO_ALIGN; 2977 switch (gpr_FC) { 2978 case 0: /* Fetch and add */ 2979 tcg_gen_atomic_fetch_add_tl(dst, EA, src, ctx->mem_idx, memop); 2980 break; 2981 case 1: /* Fetch and xor */ 2982 tcg_gen_atomic_fetch_xor_tl(dst, EA, src, ctx->mem_idx, memop); 2983 break; 2984 case 2: /* Fetch and or */ 2985 tcg_gen_atomic_fetch_or_tl(dst, EA, src, ctx->mem_idx, memop); 2986 break; 2987 case 3: /* Fetch and 'and' */ 2988 tcg_gen_atomic_fetch_and_tl(dst, EA, src, ctx->mem_idx, memop); 2989 break; 2990 case 4: /* Fetch and max unsigned */ 2991 tcg_gen_atomic_fetch_umax_tl(dst, EA, src, ctx->mem_idx, memop); 2992 break; 2993 case 5: /* Fetch and max signed */ 2994 tcg_gen_atomic_fetch_smax_tl(dst, EA, src, ctx->mem_idx, memop); 2995 break; 2996 case 6: /* Fetch and min unsigned */ 2997 tcg_gen_atomic_fetch_umin_tl(dst, EA, src, ctx->mem_idx, memop); 2998 break; 2999 case 7: /* Fetch and min signed */ 3000 tcg_gen_atomic_fetch_smin_tl(dst, EA, src, ctx->mem_idx, memop); 3001 break; 3002 case 8: /* Swap */ 3003 tcg_gen_atomic_xchg_tl(dst, EA, src, ctx->mem_idx, memop); 3004 break; 3005 3006 case 16: /* Compare and swap not equal */ 3007 if (tb_cflags(ctx->base.tb) & CF_PARALLEL) { 3008 need_serial = true; 3009 } else { 3010 TCGv t0 = tcg_temp_new(); 3011 TCGv t1 = tcg_temp_new(); 3012 3013 tcg_gen_qemu_ld_tl(t0, EA, ctx->mem_idx, memop); 3014 if ((memop & MO_SIZE) == MO_64 || TARGET_LONG_BITS == 32) { 3015 tcg_gen_mov_tl(t1, src); 3016 } else { 3017 tcg_gen_ext32u_tl(t1, src); 3018 } 3019 tcg_gen_movcond_tl(TCG_COND_NE, t1, t0, t1, 3020 cpu_gpr[(rt + 2) & 31], t0); 3021 tcg_gen_qemu_st_tl(t1, EA, ctx->mem_idx, memop); 3022 tcg_gen_mov_tl(dst, t0); 3023 } 3024 break; 3025 3026 case 24: /* Fetch and increment bounded */ 3027 if (tb_cflags(ctx->base.tb) & CF_PARALLEL) { 3028 need_serial = true; 3029 } else { 3030 gen_fetch_inc_conditional(ctx, memop, EA, TCG_COND_NE, 1); 3031 } 3032 break; 3033 case 25: /* Fetch and increment equal */ 3034 if (tb_cflags(ctx->base.tb) & CF_PARALLEL) { 3035 need_serial = true; 3036 } else { 3037 gen_fetch_inc_conditional(ctx, memop, EA, TCG_COND_EQ, 1); 3038 } 3039 break; 3040 case 28: /* Fetch and decrement bounded */ 3041 if (tb_cflags(ctx->base.tb) & CF_PARALLEL) { 3042 need_serial = true; 3043 } else { 3044 gen_fetch_inc_conditional(ctx, memop, EA, TCG_COND_NE, -1); 3045 } 3046 break; 3047 3048 default: 3049 /* invoke data storage error handler */ 3050 gen_exception_err(ctx, POWERPC_EXCP_DSI, POWERPC_EXCP_INVAL); 3051 } 3052 3053 if (need_serial) { 3054 /* Restart with exclusive lock. */ 3055 gen_helper_exit_atomic(tcg_env); 3056 ctx->base.is_jmp = DISAS_NORETURN; 3057 } 3058 } 3059 3060 static void gen_lwat(DisasContext *ctx) 3061 { 3062 gen_ld_atomic(ctx, DEF_MEMOP(MO_UL)); 3063 } 3064 3065 #ifdef TARGET_PPC64 3066 static void gen_ldat(DisasContext *ctx) 3067 { 3068 gen_ld_atomic(ctx, DEF_MEMOP(MO_UQ)); 3069 } 3070 #endif 3071 3072 static void gen_st_atomic(DisasContext *ctx, MemOp memop) 3073 { 3074 uint32_t gpr_FC = FC(ctx->opcode); 3075 TCGv EA = tcg_temp_new(); 3076 TCGv src, discard; 3077 3078 gen_addr_register(ctx, EA); 3079 src = cpu_gpr[rD(ctx->opcode)]; 3080 discard = tcg_temp_new(); 3081 3082 memop |= MO_ALIGN; 3083 switch (gpr_FC) { 3084 case 0: /* add and Store */ 3085 tcg_gen_atomic_add_fetch_tl(discard, EA, src, ctx->mem_idx, memop); 3086 break; 3087 case 1: /* xor and Store */ 3088 tcg_gen_atomic_xor_fetch_tl(discard, EA, src, ctx->mem_idx, memop); 3089 break; 3090 case 2: /* Or and Store */ 3091 tcg_gen_atomic_or_fetch_tl(discard, EA, src, ctx->mem_idx, memop); 3092 break; 3093 case 3: /* 'and' and Store */ 3094 tcg_gen_atomic_and_fetch_tl(discard, EA, src, ctx->mem_idx, memop); 3095 break; 3096 case 4: /* Store max unsigned */ 3097 tcg_gen_atomic_umax_fetch_tl(discard, EA, src, ctx->mem_idx, memop); 3098 break; 3099 case 5: /* Store max signed */ 3100 tcg_gen_atomic_smax_fetch_tl(discard, EA, src, ctx->mem_idx, memop); 3101 break; 3102 case 6: /* Store min unsigned */ 3103 tcg_gen_atomic_umin_fetch_tl(discard, EA, src, ctx->mem_idx, memop); 3104 break; 3105 case 7: /* Store min signed */ 3106 tcg_gen_atomic_smin_fetch_tl(discard, EA, src, ctx->mem_idx, memop); 3107 break; 3108 case 24: /* Store twin */ 3109 if (tb_cflags(ctx->base.tb) & CF_PARALLEL) { 3110 /* Restart with exclusive lock. */ 3111 gen_helper_exit_atomic(tcg_env); 3112 ctx->base.is_jmp = DISAS_NORETURN; 3113 } else { 3114 TCGv t = tcg_temp_new(); 3115 TCGv t2 = tcg_temp_new(); 3116 TCGv s = tcg_temp_new(); 3117 TCGv s2 = tcg_temp_new(); 3118 TCGv ea_plus_s = tcg_temp_new(); 3119 3120 tcg_gen_qemu_ld_tl(t, EA, ctx->mem_idx, memop); 3121 tcg_gen_addi_tl(ea_plus_s, EA, memop_size(memop)); 3122 tcg_gen_qemu_ld_tl(t2, ea_plus_s, ctx->mem_idx, memop); 3123 tcg_gen_movcond_tl(TCG_COND_EQ, s, t, t2, src, t); 3124 tcg_gen_movcond_tl(TCG_COND_EQ, s2, t, t2, src, t2); 3125 tcg_gen_qemu_st_tl(s, EA, ctx->mem_idx, memop); 3126 tcg_gen_qemu_st_tl(s2, ea_plus_s, ctx->mem_idx, memop); 3127 } 3128 break; 3129 default: 3130 /* invoke data storage error handler */ 3131 gen_exception_err(ctx, POWERPC_EXCP_DSI, POWERPC_EXCP_INVAL); 3132 } 3133 } 3134 3135 static void gen_stwat(DisasContext *ctx) 3136 { 3137 gen_st_atomic(ctx, DEF_MEMOP(MO_UL)); 3138 } 3139 3140 #ifdef TARGET_PPC64 3141 static void gen_stdat(DisasContext *ctx) 3142 { 3143 gen_st_atomic(ctx, DEF_MEMOP(MO_UQ)); 3144 } 3145 #endif 3146 3147 static void gen_conditional_store(DisasContext *ctx, MemOp memop) 3148 { 3149 TCGLabel *lfail; 3150 TCGv EA; 3151 TCGv cr0; 3152 TCGv t0; 3153 int rs = rS(ctx->opcode); 3154 3155 lfail = gen_new_label(); 3156 EA = tcg_temp_new(); 3157 cr0 = tcg_temp_new(); 3158 t0 = tcg_temp_new(); 3159 3160 tcg_gen_mov_tl(cr0, cpu_so); 3161 gen_set_access_type(ctx, ACCESS_RES); 3162 gen_addr_reg_index(ctx, EA); 3163 tcg_gen_brcond_tl(TCG_COND_NE, EA, cpu_reserve, lfail); 3164 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_reserve_length, memop_size(memop), lfail); 3165 3166 tcg_gen_atomic_cmpxchg_tl(t0, cpu_reserve, cpu_reserve_val, 3167 cpu_gpr[rs], ctx->mem_idx, 3168 DEF_MEMOP(memop) | MO_ALIGN); 3169 tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_reserve_val); 3170 tcg_gen_shli_tl(t0, t0, CRF_EQ_BIT); 3171 tcg_gen_or_tl(cr0, cr0, t0); 3172 3173 gen_set_label(lfail); 3174 tcg_gen_trunc_tl_i32(cpu_crf[0], cr0); 3175 tcg_gen_movi_tl(cpu_reserve, -1); 3176 } 3177 3178 #define STCX(name, memop) \ 3179 static void gen_##name(DisasContext *ctx) \ 3180 { \ 3181 gen_conditional_store(ctx, memop); \ 3182 } 3183 3184 STCX(stbcx_, MO_UB) 3185 STCX(sthcx_, MO_UW) 3186 STCX(stwcx_, MO_UL) 3187 3188 #if defined(TARGET_PPC64) 3189 /* ldarx */ 3190 LARX(ldarx, MO_UQ) 3191 /* stdcx. */ 3192 STCX(stdcx_, MO_UQ) 3193 3194 /* lqarx */ 3195 static void gen_lqarx(DisasContext *ctx) 3196 { 3197 int rd = rD(ctx->opcode); 3198 TCGv EA, hi, lo; 3199 TCGv_i128 t16; 3200 3201 if (unlikely((rd & 1) || (rd == rA(ctx->opcode)) || 3202 (rd == rB(ctx->opcode)))) { 3203 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 3204 return; 3205 } 3206 3207 gen_set_access_type(ctx, ACCESS_RES); 3208 EA = tcg_temp_new(); 3209 gen_addr_reg_index(ctx, EA); 3210 3211 /* Note that the low part is always in RD+1, even in LE mode. */ 3212 lo = cpu_gpr[rd + 1]; 3213 hi = cpu_gpr[rd]; 3214 3215 t16 = tcg_temp_new_i128(); 3216 tcg_gen_qemu_ld_i128(t16, EA, ctx->mem_idx, DEF_MEMOP(MO_128 | MO_ALIGN)); 3217 tcg_gen_extr_i128_i64(lo, hi, t16); 3218 3219 tcg_gen_mov_tl(cpu_reserve, EA); 3220 tcg_gen_movi_tl(cpu_reserve_length, 16); 3221 tcg_gen_st_tl(hi, tcg_env, offsetof(CPUPPCState, reserve_val)); 3222 tcg_gen_st_tl(lo, tcg_env, offsetof(CPUPPCState, reserve_val2)); 3223 } 3224 3225 /* stqcx. */ 3226 static void gen_stqcx_(DisasContext *ctx) 3227 { 3228 TCGLabel *lfail; 3229 TCGv EA, t0, t1; 3230 TCGv cr0; 3231 TCGv_i128 cmp, val; 3232 int rs = rS(ctx->opcode); 3233 3234 if (unlikely(rs & 1)) { 3235 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 3236 return; 3237 } 3238 3239 lfail = gen_new_label(); 3240 EA = tcg_temp_new(); 3241 cr0 = tcg_temp_new(); 3242 3243 tcg_gen_mov_tl(cr0, cpu_so); 3244 gen_set_access_type(ctx, ACCESS_RES); 3245 gen_addr_reg_index(ctx, EA); 3246 tcg_gen_brcond_tl(TCG_COND_NE, EA, cpu_reserve, lfail); 3247 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_reserve_length, 16, lfail); 3248 3249 cmp = tcg_temp_new_i128(); 3250 val = tcg_temp_new_i128(); 3251 3252 tcg_gen_concat_i64_i128(cmp, cpu_reserve_val2, cpu_reserve_val); 3253 3254 /* Note that the low part is always in RS+1, even in LE mode. */ 3255 tcg_gen_concat_i64_i128(val, cpu_gpr[rs + 1], cpu_gpr[rs]); 3256 3257 tcg_gen_atomic_cmpxchg_i128(val, cpu_reserve, cmp, val, ctx->mem_idx, 3258 DEF_MEMOP(MO_128 | MO_ALIGN)); 3259 3260 t0 = tcg_temp_new(); 3261 t1 = tcg_temp_new(); 3262 tcg_gen_extr_i128_i64(t1, t0, val); 3263 3264 tcg_gen_xor_tl(t1, t1, cpu_reserve_val2); 3265 tcg_gen_xor_tl(t0, t0, cpu_reserve_val); 3266 tcg_gen_or_tl(t0, t0, t1); 3267 3268 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, 0); 3269 tcg_gen_shli_tl(t0, t0, CRF_EQ_BIT); 3270 tcg_gen_or_tl(cr0, cr0, t0); 3271 3272 gen_set_label(lfail); 3273 tcg_gen_trunc_tl_i32(cpu_crf[0], cr0); 3274 tcg_gen_movi_tl(cpu_reserve, -1); 3275 } 3276 #endif /* defined(TARGET_PPC64) */ 3277 3278 /* wait */ 3279 static void gen_wait(DisasContext *ctx) 3280 { 3281 uint32_t wc; 3282 3283 if (ctx->insns_flags & PPC_WAIT) { 3284 /* v2.03-v2.07 define an older incompatible 'wait' encoding. */ 3285 3286 if (ctx->insns_flags2 & PPC2_PM_ISA206) { 3287 /* v2.06 introduced the WC field. WC > 0 may be treated as no-op. */ 3288 wc = WC(ctx->opcode); 3289 } else { 3290 wc = 0; 3291 } 3292 3293 } else if (ctx->insns_flags2 & PPC2_ISA300) { 3294 /* v3.0 defines a new 'wait' encoding. */ 3295 wc = WC(ctx->opcode); 3296 if (ctx->insns_flags2 & PPC2_ISA310) { 3297 uint32_t pl = PL(ctx->opcode); 3298 3299 /* WC 1,2 may be treated as no-op. WC 3 is reserved. */ 3300 if (wc == 3) { 3301 gen_invalid(ctx); 3302 return; 3303 } 3304 3305 /* PL 1-3 are reserved. If WC=2 then the insn is treated as noop. */ 3306 if (pl > 0 && wc != 2) { 3307 gen_invalid(ctx); 3308 return; 3309 } 3310 3311 } else { /* ISA300 */ 3312 /* WC 1-3 are reserved */ 3313 if (wc > 0) { 3314 gen_invalid(ctx); 3315 return; 3316 } 3317 } 3318 3319 } else { 3320 warn_report("wait instruction decoded with wrong ISA flags."); 3321 gen_invalid(ctx); 3322 return; 3323 } 3324 3325 /* 3326 * wait without WC field or with WC=0 waits for an exception / interrupt 3327 * to occur. 3328 */ 3329 if (wc == 0) { 3330 TCGv_i32 t0 = tcg_constant_i32(1); 3331 tcg_gen_st_i32(t0, tcg_env, 3332 -offsetof(PowerPCCPU, env) + offsetof(CPUState, halted)); 3333 /* Stop translation, as the CPU is supposed to sleep from now */ 3334 gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next); 3335 } 3336 3337 /* 3338 * Other wait types must not just wait until an exception occurs because 3339 * ignoring their other wake-up conditions could cause a hang. 3340 * 3341 * For v2.06 and 2.07, wc=1,2,3 are architected but may be implemented as 3342 * no-ops. 3343 * 3344 * wc=1 and wc=3 explicitly allow the instruction to be treated as a no-op. 3345 * 3346 * wc=2 waits for an implementation-specific condition, such could be 3347 * always true, so it can be implemented as a no-op. 3348 * 3349 * For v3.1, wc=1,2 are architected but may be implemented as no-ops. 3350 * 3351 * wc=1 (waitrsv) waits for an exception or a reservation to be lost. 3352 * Reservation-loss may have implementation-specific conditions, so it 3353 * can be implemented as a no-op. 3354 * 3355 * wc=2 waits for an exception or an amount of time to pass. This 3356 * amount is implementation-specific so it can be implemented as a 3357 * no-op. 3358 * 3359 * ISA v3.1 allows for execution to resume "in the rare case of 3360 * an implementation-dependent event", so in any case software must 3361 * not depend on the architected resumption condition to become 3362 * true, so no-op implementations should be architecturally correct 3363 * (if suboptimal). 3364 */ 3365 } 3366 3367 #if defined(TARGET_PPC64) 3368 static void gen_doze(DisasContext *ctx) 3369 { 3370 #if defined(CONFIG_USER_ONLY) 3371 GEN_PRIV(ctx); 3372 #else 3373 TCGv_i32 t; 3374 3375 CHK_HV(ctx); 3376 translator_io_start(&ctx->base); 3377 t = tcg_constant_i32(PPC_PM_DOZE); 3378 gen_helper_pminsn(tcg_env, t); 3379 /* Stop translation, as the CPU is supposed to sleep from now */ 3380 gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next); 3381 #endif /* defined(CONFIG_USER_ONLY) */ 3382 } 3383 3384 static void gen_nap(DisasContext *ctx) 3385 { 3386 #if defined(CONFIG_USER_ONLY) 3387 GEN_PRIV(ctx); 3388 #else 3389 TCGv_i32 t; 3390 3391 CHK_HV(ctx); 3392 translator_io_start(&ctx->base); 3393 t = tcg_constant_i32(PPC_PM_NAP); 3394 gen_helper_pminsn(tcg_env, t); 3395 /* Stop translation, as the CPU is supposed to sleep from now */ 3396 gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next); 3397 #endif /* defined(CONFIG_USER_ONLY) */ 3398 } 3399 3400 static void gen_stop(DisasContext *ctx) 3401 { 3402 #if defined(CONFIG_USER_ONLY) 3403 GEN_PRIV(ctx); 3404 #else 3405 TCGv_i32 t; 3406 3407 CHK_HV(ctx); 3408 translator_io_start(&ctx->base); 3409 t = tcg_constant_i32(PPC_PM_STOP); 3410 gen_helper_pminsn(tcg_env, t); 3411 /* Stop translation, as the CPU is supposed to sleep from now */ 3412 gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next); 3413 #endif /* defined(CONFIG_USER_ONLY) */ 3414 } 3415 3416 static void gen_sleep(DisasContext *ctx) 3417 { 3418 #if defined(CONFIG_USER_ONLY) 3419 GEN_PRIV(ctx); 3420 #else 3421 TCGv_i32 t; 3422 3423 CHK_HV(ctx); 3424 translator_io_start(&ctx->base); 3425 t = tcg_constant_i32(PPC_PM_SLEEP); 3426 gen_helper_pminsn(tcg_env, t); 3427 /* Stop translation, as the CPU is supposed to sleep from now */ 3428 gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next); 3429 #endif /* defined(CONFIG_USER_ONLY) */ 3430 } 3431 3432 static void gen_rvwinkle(DisasContext *ctx) 3433 { 3434 #if defined(CONFIG_USER_ONLY) 3435 GEN_PRIV(ctx); 3436 #else 3437 TCGv_i32 t; 3438 3439 CHK_HV(ctx); 3440 translator_io_start(&ctx->base); 3441 t = tcg_constant_i32(PPC_PM_RVWINKLE); 3442 gen_helper_pminsn(tcg_env, t); 3443 /* Stop translation, as the CPU is supposed to sleep from now */ 3444 gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next); 3445 #endif /* defined(CONFIG_USER_ONLY) */ 3446 } 3447 3448 static inline TCGv gen_write_bhrb(TCGv_ptr base, TCGv offset, TCGv mask, TCGv value) 3449 { 3450 TCGv_ptr tmp = tcg_temp_new_ptr(); 3451 3452 /* add base and offset to get address of bhrb entry */ 3453 tcg_gen_add_ptr(tmp, base, (TCGv_ptr)offset); 3454 3455 /* store value into bhrb at bhrb_offset */ 3456 tcg_gen_st_i64(value, tmp, 0); 3457 3458 /* add 8 to current bhrb_offset */ 3459 tcg_gen_addi_tl(offset, offset, 8); 3460 3461 /* apply offset mask */ 3462 tcg_gen_and_tl(offset, offset, mask); 3463 3464 return offset; 3465 } 3466 #endif /* #if defined(TARGET_PPC64) */ 3467 3468 static inline void gen_update_branch_history(DisasContext *ctx, 3469 target_ulong nip, 3470 TCGv target, 3471 target_long inst_type) 3472 { 3473 #if defined(TARGET_PPC64) 3474 TCGv_ptr base; 3475 TCGv tmp; 3476 TCGv offset; 3477 TCGv mask; 3478 TCGLabel *no_update; 3479 3480 if (ctx->has_cfar) { 3481 tcg_gen_movi_tl(cpu_cfar, nip); 3482 } 3483 3484 if (!ctx->has_bhrb || 3485 !ctx->bhrb_enable || 3486 inst_type == BHRB_TYPE_NORECORD) { 3487 return; 3488 } 3489 3490 tmp = tcg_temp_new(); 3491 no_update = gen_new_label(); 3492 3493 /* check for bhrb filtering */ 3494 tcg_gen_ld_tl(tmp, tcg_env, offsetof(CPUPPCState, bhrb_filter)); 3495 tcg_gen_andi_tl(tmp, tmp, inst_type); 3496 tcg_gen_brcondi_tl(TCG_COND_EQ, tmp, 0, no_update); 3497 3498 base = tcg_temp_new_ptr(); 3499 offset = tcg_temp_new(); 3500 mask = tcg_temp_new(); 3501 3502 /* load bhrb base address */ 3503 tcg_gen_ld_ptr(base, tcg_env, offsetof(CPUPPCState, bhrb_base)); 3504 3505 /* load current bhrb_offset */ 3506 tcg_gen_ld_tl(offset, tcg_env, offsetof(CPUPPCState, bhrb_offset)); 3507 3508 /* load a BHRB offset mask */ 3509 tcg_gen_ld_tl(mask, tcg_env, offsetof(CPUPPCState, bhrb_offset_mask)); 3510 3511 offset = gen_write_bhrb(base, offset, mask, tcg_constant_i64(nip)); 3512 3513 /* Also record the target address for XL-Form branches */ 3514 if (inst_type & BHRB_TYPE_XL_FORM) { 3515 3516 /* Set the 'T' bit for target entries */ 3517 tcg_gen_ori_tl(tmp, target, 0x2); 3518 3519 offset = gen_write_bhrb(base, offset, mask, tmp); 3520 } 3521 3522 /* save updated bhrb_offset for next time */ 3523 tcg_gen_st_tl(offset, tcg_env, offsetof(CPUPPCState, bhrb_offset)); 3524 3525 gen_set_label(no_update); 3526 #endif 3527 } 3528 3529 #if defined(TARGET_PPC64) 3530 static void pmu_count_insns(DisasContext *ctx) 3531 { 3532 /* 3533 * Do not bother calling the helper if the PMU isn't counting 3534 * instructions. 3535 */ 3536 if (!ctx->pmu_insn_cnt) { 3537 return; 3538 } 3539 3540 #if !defined(CONFIG_USER_ONLY) 3541 TCGLabel *l; 3542 TCGv t0; 3543 3544 /* 3545 * The PMU insns_inc() helper stops the internal PMU timer if a 3546 * counter overflows happens. In that case, if the guest is 3547 * running with icount and we do not handle it beforehand, 3548 * the helper can trigger a 'bad icount read'. 3549 */ 3550 translator_io_start(&ctx->base); 3551 3552 /* Avoid helper calls when only PMC5-6 are enabled. */ 3553 if (!ctx->pmc_other) { 3554 l = gen_new_label(); 3555 t0 = tcg_temp_new(); 3556 3557 gen_load_spr(t0, SPR_POWER_PMC5); 3558 tcg_gen_addi_tl(t0, t0, ctx->base.num_insns); 3559 gen_store_spr(SPR_POWER_PMC5, t0); 3560 /* Check for overflow, if it's enabled */ 3561 if (ctx->mmcr0_pmcjce) { 3562 tcg_gen_brcondi_tl(TCG_COND_LT, t0, PMC_COUNTER_NEGATIVE_VAL, l); 3563 gen_helper_handle_pmc5_overflow(tcg_env); 3564 } 3565 3566 gen_set_label(l); 3567 } else { 3568 gen_helper_insns_inc(tcg_env, tcg_constant_i32(ctx->base.num_insns)); 3569 } 3570 #else 3571 /* 3572 * User mode can read (but not write) PMC5 and start/stop 3573 * the PMU via MMCR0_FC. In this case just increment 3574 * PMC5 with base.num_insns. 3575 */ 3576 TCGv t0 = tcg_temp_new(); 3577 3578 gen_load_spr(t0, SPR_POWER_PMC5); 3579 tcg_gen_addi_tl(t0, t0, ctx->base.num_insns); 3580 gen_store_spr(SPR_POWER_PMC5, t0); 3581 #endif /* #if !defined(CONFIG_USER_ONLY) */ 3582 } 3583 #else 3584 static void pmu_count_insns(DisasContext *ctx) 3585 { 3586 return; 3587 } 3588 #endif /* #if defined(TARGET_PPC64) */ 3589 3590 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest) 3591 { 3592 if (unlikely(ctx->singlestep_enabled)) { 3593 return false; 3594 } 3595 return translator_use_goto_tb(&ctx->base, dest); 3596 } 3597 3598 static void gen_lookup_and_goto_ptr(DisasContext *ctx) 3599 { 3600 if (unlikely(ctx->singlestep_enabled)) { 3601 gen_debug_exception(ctx, false); 3602 } else { 3603 /* 3604 * tcg_gen_lookup_and_goto_ptr will exit the TB if 3605 * CF_NO_GOTO_PTR is set. Count insns now. 3606 */ 3607 if (ctx->base.tb->flags & CF_NO_GOTO_PTR) { 3608 pmu_count_insns(ctx); 3609 } 3610 3611 tcg_gen_lookup_and_goto_ptr(); 3612 } 3613 } 3614 3615 /*** Branch ***/ 3616 static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) 3617 { 3618 if (NARROW_MODE(ctx)) { 3619 dest = (uint32_t) dest; 3620 } 3621 if (use_goto_tb(ctx, dest)) { 3622 pmu_count_insns(ctx); 3623 tcg_gen_goto_tb(n); 3624 tcg_gen_movi_tl(cpu_nip, dest & ~3); 3625 tcg_gen_exit_tb(ctx->base.tb, n); 3626 } else { 3627 tcg_gen_movi_tl(cpu_nip, dest & ~3); 3628 gen_lookup_and_goto_ptr(ctx); 3629 } 3630 } 3631 3632 static inline void gen_setlr(DisasContext *ctx, target_ulong nip) 3633 { 3634 if (NARROW_MODE(ctx)) { 3635 nip = (uint32_t)nip; 3636 } 3637 tcg_gen_movi_tl(cpu_lr, nip); 3638 } 3639 3640 /* b ba bl bla */ 3641 static void gen_b(DisasContext *ctx) 3642 { 3643 target_ulong li, target; 3644 3645 /* sign extend LI */ 3646 li = LI(ctx->opcode); 3647 li = (li ^ 0x02000000) - 0x02000000; 3648 if (likely(AA(ctx->opcode) == 0)) { 3649 target = ctx->cia + li; 3650 } else { 3651 target = li; 3652 } 3653 if (LK(ctx->opcode)) { 3654 gen_setlr(ctx, ctx->base.pc_next); 3655 gen_update_branch_history(ctx, ctx->cia, NULL, BHRB_TYPE_CALL); 3656 } else { 3657 gen_update_branch_history(ctx, ctx->cia, NULL, BHRB_TYPE_OTHER); 3658 } 3659 gen_goto_tb(ctx, 0, target); 3660 ctx->base.is_jmp = DISAS_NORETURN; 3661 } 3662 3663 #define BCOND_IM 0 3664 #define BCOND_LR 1 3665 #define BCOND_CTR 2 3666 #define BCOND_TAR 3 3667 3668 static void gen_bcond(DisasContext *ctx, int type) 3669 { 3670 uint32_t bo = BO(ctx->opcode); 3671 TCGLabel *l1; 3672 TCGv target; 3673 target_long bhrb_type = BHRB_TYPE_OTHER; 3674 3675 if (type == BCOND_LR || type == BCOND_CTR || type == BCOND_TAR) { 3676 target = tcg_temp_new(); 3677 if (type == BCOND_CTR) { 3678 tcg_gen_mov_tl(target, cpu_ctr); 3679 } else if (type == BCOND_TAR) { 3680 gen_load_spr(target, SPR_TAR); 3681 } else { 3682 tcg_gen_mov_tl(target, cpu_lr); 3683 } 3684 if (!LK(ctx->opcode)) { 3685 bhrb_type |= BHRB_TYPE_INDIRECT; 3686 } 3687 bhrb_type |= BHRB_TYPE_XL_FORM; 3688 } else { 3689 target = NULL; 3690 } 3691 if (LK(ctx->opcode)) { 3692 gen_setlr(ctx, ctx->base.pc_next); 3693 bhrb_type |= BHRB_TYPE_CALL; 3694 } 3695 l1 = gen_new_label(); 3696 if ((bo & 0x4) == 0) { 3697 /* Decrement and test CTR */ 3698 TCGv temp = tcg_temp_new(); 3699 3700 if (type == BCOND_CTR) { 3701 /* 3702 * All ISAs up to v3 describe this form of bcctr as invalid but 3703 * some processors, ie. 64-bit server processors compliant with 3704 * arch 2.x, do implement a "test and decrement" logic instead, 3705 * as described in their respective UMs. This logic involves CTR 3706 * to act as both the branch target and a counter, which makes 3707 * it basically useless and thus never used in real code. 3708 * 3709 * This form was hence chosen to trigger extra micro-architectural 3710 * side-effect on real HW needed for the Spectre v2 workaround. 3711 * It is up to guests that implement such workaround, ie. linux, to 3712 * use this form in a way it just triggers the side-effect without 3713 * doing anything else harmful. 3714 */ 3715 if (unlikely(!is_book3s_arch2x(ctx))) { 3716 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 3717 return; 3718 } 3719 3720 if (NARROW_MODE(ctx)) { 3721 tcg_gen_ext32u_tl(temp, cpu_ctr); 3722 } else { 3723 tcg_gen_mov_tl(temp, cpu_ctr); 3724 } 3725 if (bo & 0x2) { 3726 tcg_gen_brcondi_tl(TCG_COND_NE, temp, 0, l1); 3727 } else { 3728 tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1); 3729 } 3730 tcg_gen_subi_tl(cpu_ctr, cpu_ctr, 1); 3731 } else { 3732 tcg_gen_subi_tl(cpu_ctr, cpu_ctr, 1); 3733 if (NARROW_MODE(ctx)) { 3734 tcg_gen_ext32u_tl(temp, cpu_ctr); 3735 } else { 3736 tcg_gen_mov_tl(temp, cpu_ctr); 3737 } 3738 if (bo & 0x2) { 3739 tcg_gen_brcondi_tl(TCG_COND_NE, temp, 0, l1); 3740 } else { 3741 tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1); 3742 } 3743 } 3744 bhrb_type |= BHRB_TYPE_COND; 3745 } 3746 if ((bo & 0x10) == 0) { 3747 /* Test CR */ 3748 uint32_t bi = BI(ctx->opcode); 3749 uint32_t mask = 0x08 >> (bi & 0x03); 3750 TCGv_i32 temp = tcg_temp_new_i32(); 3751 3752 if (bo & 0x8) { 3753 tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask); 3754 tcg_gen_brcondi_i32(TCG_COND_EQ, temp, 0, l1); 3755 } else { 3756 tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask); 3757 tcg_gen_brcondi_i32(TCG_COND_NE, temp, 0, l1); 3758 } 3759 bhrb_type |= BHRB_TYPE_COND; 3760 } 3761 3762 gen_update_branch_history(ctx, ctx->cia, target, bhrb_type); 3763 3764 if (type == BCOND_IM) { 3765 target_ulong li = (target_long)((int16_t)(BD(ctx->opcode))); 3766 if (likely(AA(ctx->opcode) == 0)) { 3767 gen_goto_tb(ctx, 0, ctx->cia + li); 3768 } else { 3769 gen_goto_tb(ctx, 0, li); 3770 } 3771 } else { 3772 if (NARROW_MODE(ctx)) { 3773 tcg_gen_andi_tl(cpu_nip, target, (uint32_t)~3); 3774 } else { 3775 tcg_gen_andi_tl(cpu_nip, target, ~3); 3776 } 3777 gen_lookup_and_goto_ptr(ctx); 3778 } 3779 if ((bo & 0x14) != 0x14) { 3780 /* fallthrough case */ 3781 gen_set_label(l1); 3782 gen_goto_tb(ctx, 1, ctx->base.pc_next); 3783 } 3784 ctx->base.is_jmp = DISAS_NORETURN; 3785 } 3786 3787 static void gen_bc(DisasContext *ctx) 3788 { 3789 gen_bcond(ctx, BCOND_IM); 3790 } 3791 3792 static void gen_bcctr(DisasContext *ctx) 3793 { 3794 gen_bcond(ctx, BCOND_CTR); 3795 } 3796 3797 static void gen_bclr(DisasContext *ctx) 3798 { 3799 gen_bcond(ctx, BCOND_LR); 3800 } 3801 3802 static void gen_bctar(DisasContext *ctx) 3803 { 3804 gen_bcond(ctx, BCOND_TAR); 3805 } 3806 3807 /*** Condition register logical ***/ 3808 #define GEN_CRLOGIC(name, tcg_op, opc) \ 3809 static void glue(gen_, name)(DisasContext *ctx) \ 3810 { \ 3811 uint8_t bitmask; \ 3812 int sh; \ 3813 TCGv_i32 t0, t1; \ 3814 sh = (crbD(ctx->opcode) & 0x03) - (crbA(ctx->opcode) & 0x03); \ 3815 t0 = tcg_temp_new_i32(); \ 3816 if (sh > 0) \ 3817 tcg_gen_shri_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], sh); \ 3818 else if (sh < 0) \ 3819 tcg_gen_shli_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], -sh); \ 3820 else \ 3821 tcg_gen_mov_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2]); \ 3822 t1 = tcg_temp_new_i32(); \ 3823 sh = (crbD(ctx->opcode) & 0x03) - (crbB(ctx->opcode) & 0x03); \ 3824 if (sh > 0) \ 3825 tcg_gen_shri_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], sh); \ 3826 else if (sh < 0) \ 3827 tcg_gen_shli_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], -sh); \ 3828 else \ 3829 tcg_gen_mov_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2]); \ 3830 tcg_op(t0, t0, t1); \ 3831 bitmask = 0x08 >> (crbD(ctx->opcode) & 0x03); \ 3832 tcg_gen_andi_i32(t0, t0, bitmask); \ 3833 tcg_gen_andi_i32(t1, cpu_crf[crbD(ctx->opcode) >> 2], ~bitmask); \ 3834 tcg_gen_or_i32(cpu_crf[crbD(ctx->opcode) >> 2], t0, t1); \ 3835 } 3836 3837 /* crand */ 3838 GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08); 3839 /* crandc */ 3840 GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04); 3841 /* creqv */ 3842 GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09); 3843 /* crnand */ 3844 GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07); 3845 /* crnor */ 3846 GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01); 3847 /* cror */ 3848 GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E); 3849 /* crorc */ 3850 GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D); 3851 /* crxor */ 3852 GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06); 3853 3854 /* mcrf */ 3855 static void gen_mcrf(DisasContext *ctx) 3856 { 3857 tcg_gen_mov_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfS(ctx->opcode)]); 3858 } 3859 3860 /*** System linkage ***/ 3861 3862 /* rfi (supervisor only) */ 3863 static void gen_rfi(DisasContext *ctx) 3864 { 3865 #if defined(CONFIG_USER_ONLY) 3866 GEN_PRIV(ctx); 3867 #else 3868 /* 3869 * This instruction doesn't exist anymore on 64-bit server 3870 * processors compliant with arch 2.x 3871 */ 3872 if (is_book3s_arch2x(ctx)) { 3873 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 3874 return; 3875 } 3876 /* Restore CPU state */ 3877 CHK_SV(ctx); 3878 translator_io_start(&ctx->base); 3879 gen_update_branch_history(ctx, ctx->cia, NULL, BHRB_TYPE_NORECORD); 3880 gen_helper_rfi(tcg_env); 3881 ctx->base.is_jmp = DISAS_EXIT; 3882 #endif 3883 } 3884 3885 #if defined(TARGET_PPC64) 3886 static void gen_rfid(DisasContext *ctx) 3887 { 3888 #if defined(CONFIG_USER_ONLY) 3889 GEN_PRIV(ctx); 3890 #else 3891 /* Restore CPU state */ 3892 CHK_SV(ctx); 3893 translator_io_start(&ctx->base); 3894 gen_update_branch_history(ctx, ctx->cia, NULL, BHRB_TYPE_NORECORD); 3895 gen_helper_rfid(tcg_env); 3896 ctx->base.is_jmp = DISAS_EXIT; 3897 #endif 3898 } 3899 3900 #if !defined(CONFIG_USER_ONLY) 3901 static void gen_rfscv(DisasContext *ctx) 3902 { 3903 #if defined(CONFIG_USER_ONLY) 3904 GEN_PRIV(ctx); 3905 #else 3906 /* Restore CPU state */ 3907 CHK_SV(ctx); 3908 translator_io_start(&ctx->base); 3909 gen_update_branch_history(ctx, ctx->cia, NULL, BHRB_TYPE_NORECORD); 3910 gen_helper_rfscv(tcg_env); 3911 ctx->base.is_jmp = DISAS_EXIT; 3912 #endif 3913 } 3914 #endif 3915 3916 static void gen_hrfid(DisasContext *ctx) 3917 { 3918 #if defined(CONFIG_USER_ONLY) 3919 GEN_PRIV(ctx); 3920 #else 3921 /* Restore CPU state */ 3922 CHK_HV(ctx); 3923 translator_io_start(&ctx->base); 3924 gen_helper_hrfid(tcg_env); 3925 ctx->base.is_jmp = DISAS_EXIT; 3926 #endif 3927 } 3928 #endif 3929 3930 /* sc */ 3931 #if defined(CONFIG_USER_ONLY) 3932 #define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER 3933 #else 3934 #define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL 3935 #endif 3936 static void gen_sc(DisasContext *ctx) 3937 { 3938 uint32_t lev; 3939 3940 /* 3941 * LEV is a 7-bit field, but the top 6 bits are treated as a reserved 3942 * field (i.e., ignored). ISA v3.1 changes that to 5 bits, but that is 3943 * for Ultravisor which TCG does not support, so just ignore the top 6. 3944 */ 3945 lev = (ctx->opcode >> 5) & 0x1; 3946 gen_exception_err(ctx, POWERPC_SYSCALL, lev); 3947 } 3948 3949 #if defined(TARGET_PPC64) 3950 #if !defined(CONFIG_USER_ONLY) 3951 static void gen_scv(DisasContext *ctx) 3952 { 3953 uint32_t lev = (ctx->opcode >> 5) & 0x7F; 3954 3955 /* Set the PC back to the faulting instruction. */ 3956 gen_update_nip(ctx, ctx->cia); 3957 gen_helper_scv(tcg_env, tcg_constant_i32(lev)); 3958 3959 ctx->base.is_jmp = DISAS_NORETURN; 3960 } 3961 #endif 3962 #endif 3963 3964 /*** Trap ***/ 3965 3966 /* Check for unconditional traps (always or never) */ 3967 static bool check_unconditional_trap(DisasContext *ctx, int to) 3968 { 3969 /* Trap never */ 3970 if (to == 0) { 3971 return true; 3972 } 3973 /* Trap always */ 3974 if (to == 31) { 3975 gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_TRAP); 3976 return true; 3977 } 3978 return false; 3979 } 3980 3981 /*** Processor control ***/ 3982 3983 /* mcrxr */ 3984 static void gen_mcrxr(DisasContext *ctx) 3985 { 3986 TCGv_i32 t0 = tcg_temp_new_i32(); 3987 TCGv_i32 t1 = tcg_temp_new_i32(); 3988 TCGv_i32 dst = cpu_crf[crfD(ctx->opcode)]; 3989 3990 tcg_gen_trunc_tl_i32(t0, cpu_so); 3991 tcg_gen_trunc_tl_i32(t1, cpu_ov); 3992 tcg_gen_trunc_tl_i32(dst, cpu_ca); 3993 tcg_gen_shli_i32(t0, t0, 3); 3994 tcg_gen_shli_i32(t1, t1, 2); 3995 tcg_gen_shli_i32(dst, dst, 1); 3996 tcg_gen_or_i32(dst, dst, t0); 3997 tcg_gen_or_i32(dst, dst, t1); 3998 3999 tcg_gen_movi_tl(cpu_so, 0); 4000 tcg_gen_movi_tl(cpu_ov, 0); 4001 tcg_gen_movi_tl(cpu_ca, 0); 4002 } 4003 4004 #ifdef TARGET_PPC64 4005 /* mcrxrx */ 4006 static void gen_mcrxrx(DisasContext *ctx) 4007 { 4008 TCGv t0 = tcg_temp_new(); 4009 TCGv t1 = tcg_temp_new(); 4010 TCGv_i32 dst = cpu_crf[crfD(ctx->opcode)]; 4011 4012 /* copy OV and OV32 */ 4013 tcg_gen_shli_tl(t0, cpu_ov, 1); 4014 tcg_gen_or_tl(t0, t0, cpu_ov32); 4015 tcg_gen_shli_tl(t0, t0, 2); 4016 /* copy CA and CA32 */ 4017 tcg_gen_shli_tl(t1, cpu_ca, 1); 4018 tcg_gen_or_tl(t1, t1, cpu_ca32); 4019 tcg_gen_or_tl(t0, t0, t1); 4020 tcg_gen_trunc_tl_i32(dst, t0); 4021 } 4022 #endif 4023 4024 /* mfcr mfocrf */ 4025 static void gen_mfcr(DisasContext *ctx) 4026 { 4027 uint32_t crm, crn; 4028 4029 if (likely(ctx->opcode & 0x00100000)) { 4030 crm = CRM(ctx->opcode); 4031 if (likely(crm && ((crm & (crm - 1)) == 0))) { 4032 crn = ctz32(crm); 4033 tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], cpu_crf[7 - crn]); 4034 tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], 4035 cpu_gpr[rD(ctx->opcode)], crn * 4); 4036 } 4037 } else { 4038 TCGv_i32 t0 = tcg_temp_new_i32(); 4039 tcg_gen_mov_i32(t0, cpu_crf[0]); 4040 tcg_gen_shli_i32(t0, t0, 4); 4041 tcg_gen_or_i32(t0, t0, cpu_crf[1]); 4042 tcg_gen_shli_i32(t0, t0, 4); 4043 tcg_gen_or_i32(t0, t0, cpu_crf[2]); 4044 tcg_gen_shli_i32(t0, t0, 4); 4045 tcg_gen_or_i32(t0, t0, cpu_crf[3]); 4046 tcg_gen_shli_i32(t0, t0, 4); 4047 tcg_gen_or_i32(t0, t0, cpu_crf[4]); 4048 tcg_gen_shli_i32(t0, t0, 4); 4049 tcg_gen_or_i32(t0, t0, cpu_crf[5]); 4050 tcg_gen_shli_i32(t0, t0, 4); 4051 tcg_gen_or_i32(t0, t0, cpu_crf[6]); 4052 tcg_gen_shli_i32(t0, t0, 4); 4053 tcg_gen_or_i32(t0, t0, cpu_crf[7]); 4054 tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); 4055 } 4056 } 4057 4058 /* mfmsr */ 4059 static void gen_mfmsr(DisasContext *ctx) 4060 { 4061 CHK_SV(ctx); 4062 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_msr); 4063 } 4064 4065 /* mfspr */ 4066 static inline void gen_op_mfspr(DisasContext *ctx) 4067 { 4068 void (*read_cb)(DisasContext *ctx, int gprn, int sprn); 4069 uint32_t sprn = SPR(ctx->opcode); 4070 4071 #if defined(CONFIG_USER_ONLY) 4072 read_cb = ctx->spr_cb[sprn].uea_read; 4073 #else 4074 if (ctx->pr) { 4075 read_cb = ctx->spr_cb[sprn].uea_read; 4076 } else if (ctx->hv) { 4077 read_cb = ctx->spr_cb[sprn].hea_read; 4078 } else { 4079 read_cb = ctx->spr_cb[sprn].oea_read; 4080 } 4081 #endif 4082 if (likely(read_cb != NULL)) { 4083 if (likely(read_cb != SPR_NOACCESS)) { 4084 (*read_cb)(ctx, rD(ctx->opcode), sprn); 4085 } else { 4086 /* Privilege exception */ 4087 /* 4088 * This is a hack to avoid warnings when running Linux: 4089 * this OS breaks the PowerPC virtualisation model, 4090 * allowing userland application to read the PVR 4091 */ 4092 if (sprn != SPR_PVR) { 4093 qemu_log_mask(LOG_GUEST_ERROR, "Trying to read privileged spr " 4094 "%d (0x%03x) at " TARGET_FMT_lx "\n", sprn, sprn, 4095 ctx->cia); 4096 } 4097 gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG); 4098 } 4099 } else { 4100 /* ISA 2.07 defines these as no-ops */ 4101 if ((ctx->insns_flags2 & PPC2_ISA207S) && 4102 (sprn >= 808 && sprn <= 811)) { 4103 /* This is a nop */ 4104 return; 4105 } 4106 /* Not defined */ 4107 qemu_log_mask(LOG_GUEST_ERROR, 4108 "Trying to read invalid spr %d (0x%03x) at " 4109 TARGET_FMT_lx "\n", sprn, sprn, ctx->cia); 4110 4111 /* 4112 * The behaviour depends on MSR:PR and SPR# bit 0x10, it can 4113 * generate a priv, a hv emu or a no-op 4114 */ 4115 if (sprn & 0x10) { 4116 if (ctx->pr) { 4117 gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG); 4118 } 4119 } else { 4120 if (ctx->pr || sprn == 0 || sprn == 4 || sprn == 5 || sprn == 6) { 4121 gen_hvpriv_exception(ctx, POWERPC_EXCP_PRIV_REG); 4122 } 4123 } 4124 } 4125 } 4126 4127 static void gen_mfspr(DisasContext *ctx) 4128 { 4129 gen_op_mfspr(ctx); 4130 } 4131 4132 /* mftb */ 4133 static void gen_mftb(DisasContext *ctx) 4134 { 4135 gen_op_mfspr(ctx); 4136 } 4137 4138 /* mtcrf mtocrf*/ 4139 static void gen_mtcrf(DisasContext *ctx) 4140 { 4141 uint32_t crm, crn; 4142 4143 crm = CRM(ctx->opcode); 4144 if (likely((ctx->opcode & 0x00100000))) { 4145 if (crm && ((crm & (crm - 1)) == 0)) { 4146 TCGv_i32 temp = tcg_temp_new_i32(); 4147 crn = ctz32(crm); 4148 tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]); 4149 tcg_gen_shri_i32(temp, temp, crn * 4); 4150 tcg_gen_andi_i32(cpu_crf[7 - crn], temp, 0xf); 4151 } 4152 } else { 4153 TCGv_i32 temp = tcg_temp_new_i32(); 4154 tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]); 4155 for (crn = 0 ; crn < 8 ; crn++) { 4156 if (crm & (1 << crn)) { 4157 tcg_gen_shri_i32(cpu_crf[7 - crn], temp, crn * 4); 4158 tcg_gen_andi_i32(cpu_crf[7 - crn], cpu_crf[7 - crn], 0xf); 4159 } 4160 } 4161 } 4162 } 4163 4164 /* mtmsr */ 4165 #if defined(TARGET_PPC64) 4166 static void gen_mtmsrd(DisasContext *ctx) 4167 { 4168 if (unlikely(!is_book3s_arch2x(ctx))) { 4169 gen_invalid(ctx); 4170 return; 4171 } 4172 4173 CHK_SV(ctx); 4174 4175 #if !defined(CONFIG_USER_ONLY) 4176 TCGv t0, t1; 4177 target_ulong mask; 4178 4179 t0 = tcg_temp_new(); 4180 t1 = tcg_temp_new(); 4181 4182 translator_io_start(&ctx->base); 4183 4184 if (ctx->opcode & 0x00010000) { 4185 /* L=1 form only updates EE and RI */ 4186 mask = (1ULL << MSR_RI) | (1ULL << MSR_EE); 4187 } else { 4188 /* mtmsrd does not alter HV, S, ME, or LE */ 4189 mask = ~((1ULL << MSR_LE) | (1ULL << MSR_ME) | (1ULL << MSR_S) | 4190 (1ULL << MSR_HV)); 4191 /* 4192 * XXX: we need to update nip before the store if we enter 4193 * power saving mode, we will exit the loop directly from 4194 * ppc_store_msr 4195 */ 4196 gen_update_nip(ctx, ctx->base.pc_next); 4197 } 4198 4199 tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], mask); 4200 tcg_gen_andi_tl(t1, cpu_msr, ~mask); 4201 tcg_gen_or_tl(t0, t0, t1); 4202 4203 gen_helper_store_msr(tcg_env, t0); 4204 4205 /* Must stop the translation as machine state (may have) changed */ 4206 ctx->base.is_jmp = DISAS_EXIT_UPDATE; 4207 #endif /* !defined(CONFIG_USER_ONLY) */ 4208 } 4209 #endif /* defined(TARGET_PPC64) */ 4210 4211 static void gen_mtmsr(DisasContext *ctx) 4212 { 4213 CHK_SV(ctx); 4214 4215 #if !defined(CONFIG_USER_ONLY) 4216 TCGv t0, t1; 4217 target_ulong mask = 0xFFFFFFFF; 4218 4219 t0 = tcg_temp_new(); 4220 t1 = tcg_temp_new(); 4221 4222 translator_io_start(&ctx->base); 4223 if (ctx->opcode & 0x00010000) { 4224 /* L=1 form only updates EE and RI */ 4225 mask &= (1ULL << MSR_RI) | (1ULL << MSR_EE); 4226 } else { 4227 /* mtmsr does not alter S, ME, or LE */ 4228 mask &= ~((1ULL << MSR_LE) | (1ULL << MSR_ME) | (1ULL << MSR_S)); 4229 4230 /* 4231 * XXX: we need to update nip before the store if we enter 4232 * power saving mode, we will exit the loop directly from 4233 * ppc_store_msr 4234 */ 4235 gen_update_nip(ctx, ctx->base.pc_next); 4236 } 4237 4238 tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], mask); 4239 tcg_gen_andi_tl(t1, cpu_msr, ~mask); 4240 tcg_gen_or_tl(t0, t0, t1); 4241 4242 gen_helper_store_msr(tcg_env, t0); 4243 4244 /* Must stop the translation as machine state (may have) changed */ 4245 ctx->base.is_jmp = DISAS_EXIT_UPDATE; 4246 #endif 4247 } 4248 4249 /* mtspr */ 4250 static void gen_mtspr(DisasContext *ctx) 4251 { 4252 void (*write_cb)(DisasContext *ctx, int sprn, int gprn); 4253 uint32_t sprn = SPR(ctx->opcode); 4254 4255 #if defined(CONFIG_USER_ONLY) 4256 write_cb = ctx->spr_cb[sprn].uea_write; 4257 #else 4258 if (ctx->pr) { 4259 write_cb = ctx->spr_cb[sprn].uea_write; 4260 } else if (ctx->hv) { 4261 write_cb = ctx->spr_cb[sprn].hea_write; 4262 } else { 4263 write_cb = ctx->spr_cb[sprn].oea_write; 4264 } 4265 #endif 4266 if (likely(write_cb != NULL)) { 4267 if (likely(write_cb != SPR_NOACCESS)) { 4268 (*write_cb)(ctx, sprn, rS(ctx->opcode)); 4269 } else { 4270 /* Privilege exception */ 4271 qemu_log_mask(LOG_GUEST_ERROR, "Trying to write privileged spr " 4272 "%d (0x%03x) at " TARGET_FMT_lx "\n", sprn, sprn, 4273 ctx->cia); 4274 gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG); 4275 } 4276 } else { 4277 /* ISA 2.07 defines these as no-ops */ 4278 if ((ctx->insns_flags2 & PPC2_ISA207S) && 4279 (sprn >= 808 && sprn <= 811)) { 4280 /* This is a nop */ 4281 return; 4282 } 4283 4284 /* Not defined */ 4285 qemu_log_mask(LOG_GUEST_ERROR, 4286 "Trying to write invalid spr %d (0x%03x) at " 4287 TARGET_FMT_lx "\n", sprn, sprn, ctx->cia); 4288 4289 4290 /* 4291 * The behaviour depends on MSR:PR and SPR# bit 0x10, it can 4292 * generate a priv, a hv emu or a no-op 4293 */ 4294 if (sprn & 0x10) { 4295 if (ctx->pr) { 4296 gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG); 4297 } 4298 } else { 4299 if (ctx->pr || sprn == 0) { 4300 gen_hvpriv_exception(ctx, POWERPC_EXCP_PRIV_REG); 4301 } 4302 } 4303 } 4304 } 4305 4306 #if defined(TARGET_PPC64) 4307 /* setb */ 4308 static void gen_setb(DisasContext *ctx) 4309 { 4310 TCGv_i32 t0 = tcg_temp_new_i32(); 4311 TCGv_i32 t8 = tcg_constant_i32(8); 4312 TCGv_i32 tm1 = tcg_constant_i32(-1); 4313 int crf = crfS(ctx->opcode); 4314 4315 tcg_gen_setcondi_i32(TCG_COND_GEU, t0, cpu_crf[crf], 4); 4316 tcg_gen_movcond_i32(TCG_COND_GEU, t0, cpu_crf[crf], t8, tm1, t0); 4317 tcg_gen_ext_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); 4318 } 4319 #endif 4320 4321 /*** Cache management ***/ 4322 4323 /* dcbf */ 4324 static void gen_dcbf(DisasContext *ctx) 4325 { 4326 /* XXX: specification says this is treated as a load by the MMU */ 4327 TCGv t0; 4328 gen_set_access_type(ctx, ACCESS_CACHE); 4329 t0 = tcg_temp_new(); 4330 gen_addr_reg_index(ctx, t0); 4331 gen_qemu_ld8u(ctx, t0, t0); 4332 } 4333 4334 /* dcbfep (external PID dcbf) */ 4335 static void gen_dcbfep(DisasContext *ctx) 4336 { 4337 /* XXX: specification says this is treated as a load by the MMU */ 4338 TCGv t0; 4339 CHK_SV(ctx); 4340 gen_set_access_type(ctx, ACCESS_CACHE); 4341 t0 = tcg_temp_new(); 4342 gen_addr_reg_index(ctx, t0); 4343 tcg_gen_qemu_ld_tl(t0, t0, PPC_TLB_EPID_LOAD, DEF_MEMOP(MO_UB)); 4344 } 4345 4346 /* dcbi (Supervisor only) */ 4347 static void gen_dcbi(DisasContext *ctx) 4348 { 4349 #if defined(CONFIG_USER_ONLY) 4350 GEN_PRIV(ctx); 4351 #else 4352 TCGv EA, val; 4353 4354 CHK_SV(ctx); 4355 EA = tcg_temp_new(); 4356 gen_set_access_type(ctx, ACCESS_CACHE); 4357 gen_addr_reg_index(ctx, EA); 4358 val = tcg_temp_new(); 4359 /* XXX: specification says this should be treated as a store by the MMU */ 4360 gen_qemu_ld8u(ctx, val, EA); 4361 gen_qemu_st8(ctx, val, EA); 4362 #endif /* defined(CONFIG_USER_ONLY) */ 4363 } 4364 4365 /* dcdst */ 4366 static void gen_dcbst(DisasContext *ctx) 4367 { 4368 /* XXX: specification say this is treated as a load by the MMU */ 4369 TCGv t0; 4370 gen_set_access_type(ctx, ACCESS_CACHE); 4371 t0 = tcg_temp_new(); 4372 gen_addr_reg_index(ctx, t0); 4373 gen_qemu_ld8u(ctx, t0, t0); 4374 } 4375 4376 /* dcbstep (dcbstep External PID version) */ 4377 static void gen_dcbstep(DisasContext *ctx) 4378 { 4379 /* XXX: specification say this is treated as a load by the MMU */ 4380 TCGv t0; 4381 gen_set_access_type(ctx, ACCESS_CACHE); 4382 t0 = tcg_temp_new(); 4383 gen_addr_reg_index(ctx, t0); 4384 tcg_gen_qemu_ld_tl(t0, t0, PPC_TLB_EPID_LOAD, DEF_MEMOP(MO_UB)); 4385 } 4386 4387 /* dcbt */ 4388 static void gen_dcbt(DisasContext *ctx) 4389 { 4390 /* 4391 * interpreted as no-op 4392 * XXX: specification say this is treated as a load by the MMU but 4393 * does not generate any exception 4394 */ 4395 } 4396 4397 /* dcbtep */ 4398 static void gen_dcbtep(DisasContext *ctx) 4399 { 4400 /* 4401 * interpreted as no-op 4402 * XXX: specification say this is treated as a load by the MMU but 4403 * does not generate any exception 4404 */ 4405 } 4406 4407 /* dcbtst */ 4408 static void gen_dcbtst(DisasContext *ctx) 4409 { 4410 /* 4411 * interpreted as no-op 4412 * XXX: specification say this is treated as a load by the MMU but 4413 * does not generate any exception 4414 */ 4415 } 4416 4417 /* dcbtstep */ 4418 static void gen_dcbtstep(DisasContext *ctx) 4419 { 4420 /* 4421 * interpreted as no-op 4422 * XXX: specification say this is treated as a load by the MMU but 4423 * does not generate any exception 4424 */ 4425 } 4426 4427 /* dcbtls */ 4428 static void gen_dcbtls(DisasContext *ctx) 4429 { 4430 /* Always fails locking the cache */ 4431 TCGv t0 = tcg_temp_new(); 4432 gen_load_spr(t0, SPR_Exxx_L1CSR0); 4433 tcg_gen_ori_tl(t0, t0, L1CSR0_CUL); 4434 gen_store_spr(SPR_Exxx_L1CSR0, t0); 4435 } 4436 4437 /* dcblc */ 4438 static void gen_dcblc(DisasContext *ctx) 4439 { 4440 /* 4441 * interpreted as no-op 4442 */ 4443 } 4444 4445 /* dcbz */ 4446 static void gen_dcbz(DisasContext *ctx) 4447 { 4448 TCGv tcgv_addr; 4449 TCGv_i32 tcgv_op; 4450 4451 gen_set_access_type(ctx, ACCESS_CACHE); 4452 tcgv_addr = tcg_temp_new(); 4453 tcgv_op = tcg_constant_i32(ctx->opcode & 0x03FF000); 4454 gen_addr_reg_index(ctx, tcgv_addr); 4455 gen_helper_dcbz(tcg_env, tcgv_addr, tcgv_op); 4456 } 4457 4458 /* dcbzep */ 4459 static void gen_dcbzep(DisasContext *ctx) 4460 { 4461 TCGv tcgv_addr; 4462 TCGv_i32 tcgv_op; 4463 4464 gen_set_access_type(ctx, ACCESS_CACHE); 4465 tcgv_addr = tcg_temp_new(); 4466 tcgv_op = tcg_constant_i32(ctx->opcode & 0x03FF000); 4467 gen_addr_reg_index(ctx, tcgv_addr); 4468 gen_helper_dcbzep(tcg_env, tcgv_addr, tcgv_op); 4469 } 4470 4471 /* dst / dstt */ 4472 static void gen_dst(DisasContext *ctx) 4473 { 4474 if (rA(ctx->opcode) == 0) { 4475 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 4476 } else { 4477 /* interpreted as no-op */ 4478 } 4479 } 4480 4481 /* dstst /dststt */ 4482 static void gen_dstst(DisasContext *ctx) 4483 { 4484 if (rA(ctx->opcode) == 0) { 4485 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 4486 } else { 4487 /* interpreted as no-op */ 4488 } 4489 4490 } 4491 4492 /* dss / dssall */ 4493 static void gen_dss(DisasContext *ctx) 4494 { 4495 /* interpreted as no-op */ 4496 } 4497 4498 /* icbi */ 4499 static void gen_icbi(DisasContext *ctx) 4500 { 4501 TCGv t0; 4502 gen_set_access_type(ctx, ACCESS_CACHE); 4503 t0 = tcg_temp_new(); 4504 gen_addr_reg_index(ctx, t0); 4505 gen_helper_icbi(tcg_env, t0); 4506 } 4507 4508 /* icbiep */ 4509 static void gen_icbiep(DisasContext *ctx) 4510 { 4511 TCGv t0; 4512 gen_set_access_type(ctx, ACCESS_CACHE); 4513 t0 = tcg_temp_new(); 4514 gen_addr_reg_index(ctx, t0); 4515 gen_helper_icbiep(tcg_env, t0); 4516 } 4517 4518 /* Optional: */ 4519 /* dcba */ 4520 static void gen_dcba(DisasContext *ctx) 4521 { 4522 /* 4523 * interpreted as no-op 4524 * XXX: specification say this is treated as a store by the MMU 4525 * but does not generate any exception 4526 */ 4527 } 4528 4529 /*** Segment register manipulation ***/ 4530 /* Supervisor only: */ 4531 4532 /* mfsr */ 4533 static void gen_mfsr(DisasContext *ctx) 4534 { 4535 #if defined(CONFIG_USER_ONLY) 4536 GEN_PRIV(ctx); 4537 #else 4538 TCGv t0; 4539 4540 CHK_SV(ctx); 4541 t0 = tcg_constant_tl(SR(ctx->opcode)); 4542 gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], tcg_env, t0); 4543 #endif /* defined(CONFIG_USER_ONLY) */ 4544 } 4545 4546 /* mfsrin */ 4547 static void gen_mfsrin(DisasContext *ctx) 4548 { 4549 #if defined(CONFIG_USER_ONLY) 4550 GEN_PRIV(ctx); 4551 #else 4552 TCGv t0; 4553 4554 CHK_SV(ctx); 4555 t0 = tcg_temp_new(); 4556 tcg_gen_extract_tl(t0, cpu_gpr[rB(ctx->opcode)], 28, 4); 4557 gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], tcg_env, t0); 4558 #endif /* defined(CONFIG_USER_ONLY) */ 4559 } 4560 4561 /* mtsr */ 4562 static void gen_mtsr(DisasContext *ctx) 4563 { 4564 #if defined(CONFIG_USER_ONLY) 4565 GEN_PRIV(ctx); 4566 #else 4567 TCGv t0; 4568 4569 CHK_SV(ctx); 4570 t0 = tcg_constant_tl(SR(ctx->opcode)); 4571 gen_helper_store_sr(tcg_env, t0, cpu_gpr[rS(ctx->opcode)]); 4572 #endif /* defined(CONFIG_USER_ONLY) */ 4573 } 4574 4575 /* mtsrin */ 4576 static void gen_mtsrin(DisasContext *ctx) 4577 { 4578 #if defined(CONFIG_USER_ONLY) 4579 GEN_PRIV(ctx); 4580 #else 4581 TCGv t0; 4582 CHK_SV(ctx); 4583 4584 t0 = tcg_temp_new(); 4585 tcg_gen_extract_tl(t0, cpu_gpr[rB(ctx->opcode)], 28, 4); 4586 gen_helper_store_sr(tcg_env, t0, cpu_gpr[rD(ctx->opcode)]); 4587 #endif /* defined(CONFIG_USER_ONLY) */ 4588 } 4589 4590 #if defined(TARGET_PPC64) 4591 /* Specific implementation for PowerPC 64 "bridge" emulation using SLB */ 4592 4593 /* mfsr */ 4594 static void gen_mfsr_64b(DisasContext *ctx) 4595 { 4596 #if defined(CONFIG_USER_ONLY) 4597 GEN_PRIV(ctx); 4598 #else 4599 TCGv t0; 4600 4601 CHK_SV(ctx); 4602 t0 = tcg_constant_tl(SR(ctx->opcode)); 4603 gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], tcg_env, t0); 4604 #endif /* defined(CONFIG_USER_ONLY) */ 4605 } 4606 4607 /* mfsrin */ 4608 static void gen_mfsrin_64b(DisasContext *ctx) 4609 { 4610 #if defined(CONFIG_USER_ONLY) 4611 GEN_PRIV(ctx); 4612 #else 4613 TCGv t0; 4614 4615 CHK_SV(ctx); 4616 t0 = tcg_temp_new(); 4617 tcg_gen_extract_tl(t0, cpu_gpr[rB(ctx->opcode)], 28, 4); 4618 gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], tcg_env, t0); 4619 #endif /* defined(CONFIG_USER_ONLY) */ 4620 } 4621 4622 /* mtsr */ 4623 static void gen_mtsr_64b(DisasContext *ctx) 4624 { 4625 #if defined(CONFIG_USER_ONLY) 4626 GEN_PRIV(ctx); 4627 #else 4628 TCGv t0; 4629 4630 CHK_SV(ctx); 4631 t0 = tcg_constant_tl(SR(ctx->opcode)); 4632 gen_helper_store_sr(tcg_env, t0, cpu_gpr[rS(ctx->opcode)]); 4633 #endif /* defined(CONFIG_USER_ONLY) */ 4634 } 4635 4636 /* mtsrin */ 4637 static void gen_mtsrin_64b(DisasContext *ctx) 4638 { 4639 #if defined(CONFIG_USER_ONLY) 4640 GEN_PRIV(ctx); 4641 #else 4642 TCGv t0; 4643 4644 CHK_SV(ctx); 4645 t0 = tcg_temp_new(); 4646 tcg_gen_extract_tl(t0, cpu_gpr[rB(ctx->opcode)], 28, 4); 4647 gen_helper_store_sr(tcg_env, t0, cpu_gpr[rS(ctx->opcode)]); 4648 #endif /* defined(CONFIG_USER_ONLY) */ 4649 } 4650 4651 #endif /* defined(TARGET_PPC64) */ 4652 4653 /*** Lookaside buffer management ***/ 4654 /* Optional & supervisor only: */ 4655 4656 /* tlbia */ 4657 static void gen_tlbia(DisasContext *ctx) 4658 { 4659 #if defined(CONFIG_USER_ONLY) 4660 GEN_PRIV(ctx); 4661 #else 4662 CHK_HV(ctx); 4663 4664 gen_helper_tlbia(tcg_env); 4665 #endif /* defined(CONFIG_USER_ONLY) */ 4666 } 4667 4668 /* tlbsync */ 4669 static void gen_tlbsync(DisasContext *ctx) 4670 { 4671 #if defined(CONFIG_USER_ONLY) 4672 GEN_PRIV(ctx); 4673 #else 4674 4675 if (ctx->gtse) { 4676 CHK_SV(ctx); /* If gtse is set then tlbsync is supervisor privileged */ 4677 } else { 4678 CHK_HV(ctx); /* Else hypervisor privileged */ 4679 } 4680 4681 /* BookS does both ptesync and tlbsync make tlbsync a nop for server */ 4682 if (ctx->insns_flags & PPC_BOOKE) { 4683 gen_check_tlb_flush(ctx, true); 4684 } 4685 #endif /* defined(CONFIG_USER_ONLY) */ 4686 } 4687 4688 /*** External control ***/ 4689 /* Optional: */ 4690 4691 /* eciwx */ 4692 static void gen_eciwx(DisasContext *ctx) 4693 { 4694 TCGv t0; 4695 /* Should check EAR[E] ! */ 4696 gen_set_access_type(ctx, ACCESS_EXT); 4697 t0 = tcg_temp_new(); 4698 gen_addr_reg_index(ctx, t0); 4699 tcg_gen_qemu_ld_tl(cpu_gpr[rD(ctx->opcode)], t0, ctx->mem_idx, 4700 DEF_MEMOP(MO_UL | MO_ALIGN)); 4701 } 4702 4703 /* ecowx */ 4704 static void gen_ecowx(DisasContext *ctx) 4705 { 4706 TCGv t0; 4707 /* Should check EAR[E] ! */ 4708 gen_set_access_type(ctx, ACCESS_EXT); 4709 t0 = tcg_temp_new(); 4710 gen_addr_reg_index(ctx, t0); 4711 tcg_gen_qemu_st_tl(cpu_gpr[rD(ctx->opcode)], t0, ctx->mem_idx, 4712 DEF_MEMOP(MO_UL | MO_ALIGN)); 4713 } 4714 4715 /* 602 - 603 - G2 TLB management */ 4716 4717 /* tlbld */ 4718 static void gen_tlbld_6xx(DisasContext *ctx) 4719 { 4720 #if defined(CONFIG_USER_ONLY) 4721 GEN_PRIV(ctx); 4722 #else 4723 CHK_SV(ctx); 4724 gen_helper_6xx_tlbd(tcg_env, cpu_gpr[rB(ctx->opcode)]); 4725 #endif /* defined(CONFIG_USER_ONLY) */ 4726 } 4727 4728 /* tlbli */ 4729 static void gen_tlbli_6xx(DisasContext *ctx) 4730 { 4731 #if defined(CONFIG_USER_ONLY) 4732 GEN_PRIV(ctx); 4733 #else 4734 CHK_SV(ctx); 4735 gen_helper_6xx_tlbi(tcg_env, cpu_gpr[rB(ctx->opcode)]); 4736 #endif /* defined(CONFIG_USER_ONLY) */ 4737 } 4738 4739 /* BookE specific instructions */ 4740 4741 /* XXX: not implemented on 440 ? */ 4742 static void gen_mfapidi(DisasContext *ctx) 4743 { 4744 /* XXX: TODO */ 4745 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 4746 } 4747 4748 /* XXX: not implemented on 440 ? */ 4749 static void gen_tlbiva(DisasContext *ctx) 4750 { 4751 #if defined(CONFIG_USER_ONLY) 4752 GEN_PRIV(ctx); 4753 #else 4754 TCGv t0; 4755 4756 CHK_SV(ctx); 4757 t0 = tcg_temp_new(); 4758 gen_addr_reg_index(ctx, t0); 4759 gen_helper_tlbiva(tcg_env, cpu_gpr[rB(ctx->opcode)]); 4760 #endif /* defined(CONFIG_USER_ONLY) */ 4761 } 4762 4763 /* All 405 MAC instructions are translated here */ 4764 static inline void gen_405_mulladd_insn(DisasContext *ctx, int opc2, int opc3, 4765 int ra, int rb, int rt, int Rc) 4766 { 4767 TCGv t0, t1; 4768 4769 t0 = tcg_temp_new(); 4770 t1 = tcg_temp_new(); 4771 4772 switch (opc3 & 0x0D) { 4773 case 0x05: 4774 /* macchw - macchw. - macchwo - macchwo. */ 4775 /* macchws - macchws. - macchwso - macchwso. */ 4776 /* nmacchw - nmacchw. - nmacchwo - nmacchwo. */ 4777 /* nmacchws - nmacchws. - nmacchwso - nmacchwso. */ 4778 /* mulchw - mulchw. */ 4779 tcg_gen_ext16s_tl(t0, cpu_gpr[ra]); 4780 tcg_gen_sari_tl(t1, cpu_gpr[rb], 16); 4781 tcg_gen_ext16s_tl(t1, t1); 4782 break; 4783 case 0x04: 4784 /* macchwu - macchwu. - macchwuo - macchwuo. */ 4785 /* macchwsu - macchwsu. - macchwsuo - macchwsuo. */ 4786 /* mulchwu - mulchwu. */ 4787 tcg_gen_ext16u_tl(t0, cpu_gpr[ra]); 4788 tcg_gen_shri_tl(t1, cpu_gpr[rb], 16); 4789 tcg_gen_ext16u_tl(t1, t1); 4790 break; 4791 case 0x01: 4792 /* machhw - machhw. - machhwo - machhwo. */ 4793 /* machhws - machhws. - machhwso - machhwso. */ 4794 /* nmachhw - nmachhw. - nmachhwo - nmachhwo. */ 4795 /* nmachhws - nmachhws. - nmachhwso - nmachhwso. */ 4796 /* mulhhw - mulhhw. */ 4797 tcg_gen_sari_tl(t0, cpu_gpr[ra], 16); 4798 tcg_gen_ext16s_tl(t0, t0); 4799 tcg_gen_sari_tl(t1, cpu_gpr[rb], 16); 4800 tcg_gen_ext16s_tl(t1, t1); 4801 break; 4802 case 0x00: 4803 /* machhwu - machhwu. - machhwuo - machhwuo. */ 4804 /* machhwsu - machhwsu. - machhwsuo - machhwsuo. */ 4805 /* mulhhwu - mulhhwu. */ 4806 tcg_gen_shri_tl(t0, cpu_gpr[ra], 16); 4807 tcg_gen_ext16u_tl(t0, t0); 4808 tcg_gen_shri_tl(t1, cpu_gpr[rb], 16); 4809 tcg_gen_ext16u_tl(t1, t1); 4810 break; 4811 case 0x0D: 4812 /* maclhw - maclhw. - maclhwo - maclhwo. */ 4813 /* maclhws - maclhws. - maclhwso - maclhwso. */ 4814 /* nmaclhw - nmaclhw. - nmaclhwo - nmaclhwo. */ 4815 /* nmaclhws - nmaclhws. - nmaclhwso - nmaclhwso. */ 4816 /* mullhw - mullhw. */ 4817 tcg_gen_ext16s_tl(t0, cpu_gpr[ra]); 4818 tcg_gen_ext16s_tl(t1, cpu_gpr[rb]); 4819 break; 4820 case 0x0C: 4821 /* maclhwu - maclhwu. - maclhwuo - maclhwuo. */ 4822 /* maclhwsu - maclhwsu. - maclhwsuo - maclhwsuo. */ 4823 /* mullhwu - mullhwu. */ 4824 tcg_gen_ext16u_tl(t0, cpu_gpr[ra]); 4825 tcg_gen_ext16u_tl(t1, cpu_gpr[rb]); 4826 break; 4827 } 4828 if (opc2 & 0x04) { 4829 /* (n)multiply-and-accumulate (0x0C / 0x0E) */ 4830 tcg_gen_mul_tl(t1, t0, t1); 4831 if (opc2 & 0x02) { 4832 /* nmultiply-and-accumulate (0x0E) */ 4833 tcg_gen_sub_tl(t0, cpu_gpr[rt], t1); 4834 } else { 4835 /* multiply-and-accumulate (0x0C) */ 4836 tcg_gen_add_tl(t0, cpu_gpr[rt], t1); 4837 } 4838 4839 if (opc3 & 0x12) { 4840 /* Check overflow and/or saturate */ 4841 TCGLabel *l1 = gen_new_label(); 4842 4843 if (opc3 & 0x10) { 4844 /* Start with XER OV disabled, the most likely case */ 4845 tcg_gen_movi_tl(cpu_ov, 0); 4846 } 4847 if (opc3 & 0x01) { 4848 /* Signed */ 4849 tcg_gen_xor_tl(t1, cpu_gpr[rt], t1); 4850 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 4851 tcg_gen_xor_tl(t1, cpu_gpr[rt], t0); 4852 tcg_gen_brcondi_tl(TCG_COND_LT, t1, 0, l1); 4853 if (opc3 & 0x02) { 4854 /* Saturate */ 4855 tcg_gen_sari_tl(t0, cpu_gpr[rt], 31); 4856 tcg_gen_xori_tl(t0, t0, 0x7fffffff); 4857 } 4858 } else { 4859 /* Unsigned */ 4860 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1); 4861 if (opc3 & 0x02) { 4862 /* Saturate */ 4863 tcg_gen_movi_tl(t0, UINT32_MAX); 4864 } 4865 } 4866 if (opc3 & 0x10) { 4867 /* Check overflow */ 4868 tcg_gen_movi_tl(cpu_ov, 1); 4869 tcg_gen_movi_tl(cpu_so, 1); 4870 } 4871 gen_set_label(l1); 4872 tcg_gen_mov_tl(cpu_gpr[rt], t0); 4873 } 4874 } else { 4875 tcg_gen_mul_tl(cpu_gpr[rt], t0, t1); 4876 } 4877 if (unlikely(Rc) != 0) { 4878 /* Update Rc0 */ 4879 gen_set_Rc0(ctx, cpu_gpr[rt]); 4880 } 4881 } 4882 4883 #define GEN_MAC_HANDLER(name, opc2, opc3) \ 4884 static void glue(gen_, name)(DisasContext *ctx) \ 4885 { \ 4886 gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode), \ 4887 rD(ctx->opcode), Rc(ctx->opcode)); \ 4888 } 4889 4890 /* macchw - macchw. */ 4891 GEN_MAC_HANDLER(macchw, 0x0C, 0x05); 4892 /* macchwo - macchwo. */ 4893 GEN_MAC_HANDLER(macchwo, 0x0C, 0x15); 4894 /* macchws - macchws. */ 4895 GEN_MAC_HANDLER(macchws, 0x0C, 0x07); 4896 /* macchwso - macchwso. */ 4897 GEN_MAC_HANDLER(macchwso, 0x0C, 0x17); 4898 /* macchwsu - macchwsu. */ 4899 GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06); 4900 /* macchwsuo - macchwsuo. */ 4901 GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16); 4902 /* macchwu - macchwu. */ 4903 GEN_MAC_HANDLER(macchwu, 0x0C, 0x04); 4904 /* macchwuo - macchwuo. */ 4905 GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14); 4906 /* machhw - machhw. */ 4907 GEN_MAC_HANDLER(machhw, 0x0C, 0x01); 4908 /* machhwo - machhwo. */ 4909 GEN_MAC_HANDLER(machhwo, 0x0C, 0x11); 4910 /* machhws - machhws. */ 4911 GEN_MAC_HANDLER(machhws, 0x0C, 0x03); 4912 /* machhwso - machhwso. */ 4913 GEN_MAC_HANDLER(machhwso, 0x0C, 0x13); 4914 /* machhwsu - machhwsu. */ 4915 GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02); 4916 /* machhwsuo - machhwsuo. */ 4917 GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12); 4918 /* machhwu - machhwu. */ 4919 GEN_MAC_HANDLER(machhwu, 0x0C, 0x00); 4920 /* machhwuo - machhwuo. */ 4921 GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10); 4922 /* maclhw - maclhw. */ 4923 GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D); 4924 /* maclhwo - maclhwo. */ 4925 GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D); 4926 /* maclhws - maclhws. */ 4927 GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F); 4928 /* maclhwso - maclhwso. */ 4929 GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F); 4930 /* maclhwu - maclhwu. */ 4931 GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C); 4932 /* maclhwuo - maclhwuo. */ 4933 GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C); 4934 /* maclhwsu - maclhwsu. */ 4935 GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E); 4936 /* maclhwsuo - maclhwsuo. */ 4937 GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E); 4938 /* nmacchw - nmacchw. */ 4939 GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05); 4940 /* nmacchwo - nmacchwo. */ 4941 GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15); 4942 /* nmacchws - nmacchws. */ 4943 GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07); 4944 /* nmacchwso - nmacchwso. */ 4945 GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17); 4946 /* nmachhw - nmachhw. */ 4947 GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01); 4948 /* nmachhwo - nmachhwo. */ 4949 GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11); 4950 /* nmachhws - nmachhws. */ 4951 GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03); 4952 /* nmachhwso - nmachhwso. */ 4953 GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13); 4954 /* nmaclhw - nmaclhw. */ 4955 GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D); 4956 /* nmaclhwo - nmaclhwo. */ 4957 GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D); 4958 /* nmaclhws - nmaclhws. */ 4959 GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F); 4960 /* nmaclhwso - nmaclhwso. */ 4961 GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F); 4962 4963 /* mulchw - mulchw. */ 4964 GEN_MAC_HANDLER(mulchw, 0x08, 0x05); 4965 /* mulchwu - mulchwu. */ 4966 GEN_MAC_HANDLER(mulchwu, 0x08, 0x04); 4967 /* mulhhw - mulhhw. */ 4968 GEN_MAC_HANDLER(mulhhw, 0x08, 0x01); 4969 /* mulhhwu - mulhhwu. */ 4970 GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00); 4971 /* mullhw - mullhw. */ 4972 GEN_MAC_HANDLER(mullhw, 0x08, 0x0D); 4973 /* mullhwu - mullhwu. */ 4974 GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C); 4975 4976 /* mfdcr */ 4977 static void gen_mfdcr(DisasContext *ctx) 4978 { 4979 #if defined(CONFIG_USER_ONLY) 4980 GEN_PRIV(ctx); 4981 #else 4982 TCGv dcrn; 4983 4984 CHK_SV(ctx); 4985 dcrn = tcg_constant_tl(SPR(ctx->opcode)); 4986 gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], tcg_env, dcrn); 4987 #endif /* defined(CONFIG_USER_ONLY) */ 4988 } 4989 4990 /* mtdcr */ 4991 static void gen_mtdcr(DisasContext *ctx) 4992 { 4993 #if defined(CONFIG_USER_ONLY) 4994 GEN_PRIV(ctx); 4995 #else 4996 TCGv dcrn; 4997 4998 CHK_SV(ctx); 4999 dcrn = tcg_constant_tl(SPR(ctx->opcode)); 5000 gen_helper_store_dcr(tcg_env, dcrn, cpu_gpr[rS(ctx->opcode)]); 5001 #endif /* defined(CONFIG_USER_ONLY) */ 5002 } 5003 5004 /* mfdcrx */ 5005 /* XXX: not implemented on 440 ? */ 5006 static void gen_mfdcrx(DisasContext *ctx) 5007 { 5008 #if defined(CONFIG_USER_ONLY) 5009 GEN_PRIV(ctx); 5010 #else 5011 CHK_SV(ctx); 5012 gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], tcg_env, 5013 cpu_gpr[rA(ctx->opcode)]); 5014 /* Note: Rc update flag set leads to undefined state of Rc0 */ 5015 #endif /* defined(CONFIG_USER_ONLY) */ 5016 } 5017 5018 /* mtdcrx */ 5019 /* XXX: not implemented on 440 ? */ 5020 static void gen_mtdcrx(DisasContext *ctx) 5021 { 5022 #if defined(CONFIG_USER_ONLY) 5023 GEN_PRIV(ctx); 5024 #else 5025 CHK_SV(ctx); 5026 gen_helper_store_dcr(tcg_env, cpu_gpr[rA(ctx->opcode)], 5027 cpu_gpr[rS(ctx->opcode)]); 5028 /* Note: Rc update flag set leads to undefined state of Rc0 */ 5029 #endif /* defined(CONFIG_USER_ONLY) */ 5030 } 5031 5032 /* dccci */ 5033 static void gen_dccci(DisasContext *ctx) 5034 { 5035 CHK_SV(ctx); 5036 /* interpreted as no-op */ 5037 } 5038 5039 /* dcread */ 5040 static void gen_dcread(DisasContext *ctx) 5041 { 5042 #if defined(CONFIG_USER_ONLY) 5043 GEN_PRIV(ctx); 5044 #else 5045 TCGv EA, val; 5046 5047 CHK_SV(ctx); 5048 gen_set_access_type(ctx, ACCESS_CACHE); 5049 EA = tcg_temp_new(); 5050 gen_addr_reg_index(ctx, EA); 5051 val = tcg_temp_new(); 5052 gen_qemu_ld32u(ctx, val, EA); 5053 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], EA); 5054 #endif /* defined(CONFIG_USER_ONLY) */ 5055 } 5056 5057 /* icbt */ 5058 static void gen_icbt_40x(DisasContext *ctx) 5059 { 5060 /* 5061 * interpreted as no-op 5062 * XXX: specification say this is treated as a load by the MMU but 5063 * does not generate any exception 5064 */ 5065 } 5066 5067 /* iccci */ 5068 static void gen_iccci(DisasContext *ctx) 5069 { 5070 CHK_SV(ctx); 5071 /* interpreted as no-op */ 5072 } 5073 5074 /* icread */ 5075 static void gen_icread(DisasContext *ctx) 5076 { 5077 CHK_SV(ctx); 5078 /* interpreted as no-op */ 5079 } 5080 5081 /* rfci (supervisor only) */ 5082 static void gen_rfci_40x(DisasContext *ctx) 5083 { 5084 #if defined(CONFIG_USER_ONLY) 5085 GEN_PRIV(ctx); 5086 #else 5087 CHK_SV(ctx); 5088 /* Restore CPU state */ 5089 gen_helper_40x_rfci(tcg_env); 5090 ctx->base.is_jmp = DISAS_EXIT; 5091 #endif /* defined(CONFIG_USER_ONLY) */ 5092 } 5093 5094 static void gen_rfci(DisasContext *ctx) 5095 { 5096 #if defined(CONFIG_USER_ONLY) 5097 GEN_PRIV(ctx); 5098 #else 5099 CHK_SV(ctx); 5100 /* Restore CPU state */ 5101 gen_helper_rfci(tcg_env); 5102 ctx->base.is_jmp = DISAS_EXIT; 5103 #endif /* defined(CONFIG_USER_ONLY) */ 5104 } 5105 5106 /* BookE specific */ 5107 5108 /* XXX: not implemented on 440 ? */ 5109 static void gen_rfdi(DisasContext *ctx) 5110 { 5111 #if defined(CONFIG_USER_ONLY) 5112 GEN_PRIV(ctx); 5113 #else 5114 CHK_SV(ctx); 5115 /* Restore CPU state */ 5116 gen_helper_rfdi(tcg_env); 5117 ctx->base.is_jmp = DISAS_EXIT; 5118 #endif /* defined(CONFIG_USER_ONLY) */ 5119 } 5120 5121 /* XXX: not implemented on 440 ? */ 5122 static void gen_rfmci(DisasContext *ctx) 5123 { 5124 #if defined(CONFIG_USER_ONLY) 5125 GEN_PRIV(ctx); 5126 #else 5127 CHK_SV(ctx); 5128 /* Restore CPU state */ 5129 gen_helper_rfmci(tcg_env); 5130 ctx->base.is_jmp = DISAS_EXIT; 5131 #endif /* defined(CONFIG_USER_ONLY) */ 5132 } 5133 5134 /* TLB management - PowerPC 405 implementation */ 5135 5136 /* tlbre */ 5137 static void gen_tlbre_40x(DisasContext *ctx) 5138 { 5139 #if defined(CONFIG_USER_ONLY) 5140 GEN_PRIV(ctx); 5141 #else 5142 CHK_SV(ctx); 5143 switch (rB(ctx->opcode)) { 5144 case 0: 5145 gen_helper_4xx_tlbre_hi(cpu_gpr[rD(ctx->opcode)], tcg_env, 5146 cpu_gpr[rA(ctx->opcode)]); 5147 break; 5148 case 1: 5149 gen_helper_4xx_tlbre_lo(cpu_gpr[rD(ctx->opcode)], tcg_env, 5150 cpu_gpr[rA(ctx->opcode)]); 5151 break; 5152 default: 5153 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 5154 break; 5155 } 5156 #endif /* defined(CONFIG_USER_ONLY) */ 5157 } 5158 5159 /* tlbsx - tlbsx. */ 5160 static void gen_tlbsx_40x(DisasContext *ctx) 5161 { 5162 #if defined(CONFIG_USER_ONLY) 5163 GEN_PRIV(ctx); 5164 #else 5165 TCGv t0; 5166 5167 CHK_SV(ctx); 5168 t0 = tcg_temp_new(); 5169 gen_addr_reg_index(ctx, t0); 5170 gen_helper_4xx_tlbsx(cpu_gpr[rD(ctx->opcode)], tcg_env, t0); 5171 if (Rc(ctx->opcode)) { 5172 TCGLabel *l1 = gen_new_label(); 5173 tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so); 5174 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1); 5175 tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02); 5176 gen_set_label(l1); 5177 } 5178 #endif /* defined(CONFIG_USER_ONLY) */ 5179 } 5180 5181 /* tlbwe */ 5182 static void gen_tlbwe_40x(DisasContext *ctx) 5183 { 5184 #if defined(CONFIG_USER_ONLY) 5185 GEN_PRIV(ctx); 5186 #else 5187 CHK_SV(ctx); 5188 5189 switch (rB(ctx->opcode)) { 5190 case 0: 5191 gen_helper_4xx_tlbwe_hi(tcg_env, cpu_gpr[rA(ctx->opcode)], 5192 cpu_gpr[rS(ctx->opcode)]); 5193 break; 5194 case 1: 5195 gen_helper_4xx_tlbwe_lo(tcg_env, cpu_gpr[rA(ctx->opcode)], 5196 cpu_gpr[rS(ctx->opcode)]); 5197 break; 5198 default: 5199 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 5200 break; 5201 } 5202 #endif /* defined(CONFIG_USER_ONLY) */ 5203 } 5204 5205 /* TLB management - PowerPC 440 implementation */ 5206 5207 /* tlbre */ 5208 static void gen_tlbre_440(DisasContext *ctx) 5209 { 5210 #if defined(CONFIG_USER_ONLY) 5211 GEN_PRIV(ctx); 5212 #else 5213 CHK_SV(ctx); 5214 5215 switch (rB(ctx->opcode)) { 5216 case 0: 5217 case 1: 5218 case 2: 5219 { 5220 TCGv_i32 t0 = tcg_constant_i32(rB(ctx->opcode)); 5221 gen_helper_440_tlbre(cpu_gpr[rD(ctx->opcode)], tcg_env, 5222 t0, cpu_gpr[rA(ctx->opcode)]); 5223 } 5224 break; 5225 default: 5226 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 5227 break; 5228 } 5229 #endif /* defined(CONFIG_USER_ONLY) */ 5230 } 5231 5232 /* tlbsx - tlbsx. */ 5233 static void gen_tlbsx_440(DisasContext *ctx) 5234 { 5235 #if defined(CONFIG_USER_ONLY) 5236 GEN_PRIV(ctx); 5237 #else 5238 TCGv t0; 5239 5240 CHK_SV(ctx); 5241 t0 = tcg_temp_new(); 5242 gen_addr_reg_index(ctx, t0); 5243 gen_helper_440_tlbsx(cpu_gpr[rD(ctx->opcode)], tcg_env, t0); 5244 if (Rc(ctx->opcode)) { 5245 TCGLabel *l1 = gen_new_label(); 5246 tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so); 5247 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1); 5248 tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02); 5249 gen_set_label(l1); 5250 } 5251 #endif /* defined(CONFIG_USER_ONLY) */ 5252 } 5253 5254 /* tlbwe */ 5255 static void gen_tlbwe_440(DisasContext *ctx) 5256 { 5257 #if defined(CONFIG_USER_ONLY) 5258 GEN_PRIV(ctx); 5259 #else 5260 CHK_SV(ctx); 5261 switch (rB(ctx->opcode)) { 5262 case 0: 5263 case 1: 5264 case 2: 5265 { 5266 TCGv_i32 t0 = tcg_constant_i32(rB(ctx->opcode)); 5267 gen_helper_440_tlbwe(tcg_env, t0, cpu_gpr[rA(ctx->opcode)], 5268 cpu_gpr[rS(ctx->opcode)]); 5269 } 5270 break; 5271 default: 5272 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 5273 break; 5274 } 5275 #endif /* defined(CONFIG_USER_ONLY) */ 5276 } 5277 5278 /* TLB management - PowerPC BookE 2.06 implementation */ 5279 5280 /* tlbre */ 5281 static void gen_tlbre_booke206(DisasContext *ctx) 5282 { 5283 #if defined(CONFIG_USER_ONLY) 5284 GEN_PRIV(ctx); 5285 #else 5286 CHK_SV(ctx); 5287 gen_helper_booke206_tlbre(tcg_env); 5288 #endif /* defined(CONFIG_USER_ONLY) */ 5289 } 5290 5291 /* tlbsx - tlbsx. */ 5292 static void gen_tlbsx_booke206(DisasContext *ctx) 5293 { 5294 #if defined(CONFIG_USER_ONLY) 5295 GEN_PRIV(ctx); 5296 #else 5297 TCGv t0; 5298 5299 CHK_SV(ctx); 5300 if (rA(ctx->opcode)) { 5301 t0 = tcg_temp_new(); 5302 tcg_gen_add_tl(t0, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); 5303 } else { 5304 t0 = cpu_gpr[rB(ctx->opcode)]; 5305 } 5306 gen_helper_booke206_tlbsx(tcg_env, t0); 5307 #endif /* defined(CONFIG_USER_ONLY) */ 5308 } 5309 5310 /* tlbwe */ 5311 static void gen_tlbwe_booke206(DisasContext *ctx) 5312 { 5313 #if defined(CONFIG_USER_ONLY) 5314 GEN_PRIV(ctx); 5315 #else 5316 CHK_SV(ctx); 5317 gen_helper_booke206_tlbwe(tcg_env); 5318 #endif /* defined(CONFIG_USER_ONLY) */ 5319 } 5320 5321 static void gen_tlbivax_booke206(DisasContext *ctx) 5322 { 5323 #if defined(CONFIG_USER_ONLY) 5324 GEN_PRIV(ctx); 5325 #else 5326 TCGv t0; 5327 5328 CHK_SV(ctx); 5329 t0 = tcg_temp_new(); 5330 gen_addr_reg_index(ctx, t0); 5331 gen_helper_booke206_tlbivax(tcg_env, t0); 5332 #endif /* defined(CONFIG_USER_ONLY) */ 5333 } 5334 5335 static void gen_tlbilx_booke206(DisasContext *ctx) 5336 { 5337 #if defined(CONFIG_USER_ONLY) 5338 GEN_PRIV(ctx); 5339 #else 5340 TCGv t0; 5341 5342 CHK_SV(ctx); 5343 t0 = tcg_temp_new(); 5344 gen_addr_reg_index(ctx, t0); 5345 5346 switch ((ctx->opcode >> 21) & 0x3) { 5347 case 0: 5348 gen_helper_booke206_tlbilx0(tcg_env, t0); 5349 break; 5350 case 1: 5351 gen_helper_booke206_tlbilx1(tcg_env, t0); 5352 break; 5353 case 3: 5354 gen_helper_booke206_tlbilx3(tcg_env, t0); 5355 break; 5356 default: 5357 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 5358 break; 5359 } 5360 #endif /* defined(CONFIG_USER_ONLY) */ 5361 } 5362 5363 /* wrtee */ 5364 static void gen_wrtee(DisasContext *ctx) 5365 { 5366 #if defined(CONFIG_USER_ONLY) 5367 GEN_PRIV(ctx); 5368 #else 5369 TCGv t0; 5370 5371 CHK_SV(ctx); 5372 t0 = tcg_temp_new(); 5373 tcg_gen_andi_tl(t0, cpu_gpr[rD(ctx->opcode)], (1 << MSR_EE)); 5374 tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE)); 5375 tcg_gen_or_tl(cpu_msr, cpu_msr, t0); 5376 gen_ppc_maybe_interrupt(ctx); 5377 /* 5378 * Stop translation to have a chance to raise an exception if we 5379 * just set msr_ee to 1 5380 */ 5381 ctx->base.is_jmp = DISAS_EXIT_UPDATE; 5382 #endif /* defined(CONFIG_USER_ONLY) */ 5383 } 5384 5385 /* wrteei */ 5386 static void gen_wrteei(DisasContext *ctx) 5387 { 5388 #if defined(CONFIG_USER_ONLY) 5389 GEN_PRIV(ctx); 5390 #else 5391 CHK_SV(ctx); 5392 if (ctx->opcode & 0x00008000) { 5393 tcg_gen_ori_tl(cpu_msr, cpu_msr, (1 << MSR_EE)); 5394 gen_ppc_maybe_interrupt(ctx); 5395 /* Stop translation to have a chance to raise an exception */ 5396 ctx->base.is_jmp = DISAS_EXIT_UPDATE; 5397 } else { 5398 tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE)); 5399 } 5400 #endif /* defined(CONFIG_USER_ONLY) */ 5401 } 5402 5403 /* PowerPC 440 specific instructions */ 5404 5405 /* dlmzb */ 5406 static void gen_dlmzb(DisasContext *ctx) 5407 { 5408 TCGv_i32 t0 = tcg_constant_i32(Rc(ctx->opcode)); 5409 gen_helper_dlmzb(cpu_gpr[rA(ctx->opcode)], tcg_env, 5410 cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], t0); 5411 } 5412 5413 /* icbt */ 5414 static void gen_icbt_440(DisasContext *ctx) 5415 { 5416 /* 5417 * interpreted as no-op 5418 * XXX: specification say this is treated as a load by the MMU but 5419 * does not generate any exception 5420 */ 5421 } 5422 5423 static void gen_tbegin(DisasContext *ctx) 5424 { 5425 if (unlikely(!ctx->tm_enabled)) { 5426 gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM); 5427 return; 5428 } 5429 gen_helper_tbegin(tcg_env); 5430 } 5431 5432 #define GEN_TM_NOOP(name) \ 5433 static inline void gen_##name(DisasContext *ctx) \ 5434 { \ 5435 if (unlikely(!ctx->tm_enabled)) { \ 5436 gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM); \ 5437 return; \ 5438 } \ 5439 /* \ 5440 * Because tbegin always fails in QEMU, these user \ 5441 * space instructions all have a simple implementation: \ 5442 * \ 5443 * CR[0] = 0b0 || MSR[TS] || 0b0 \ 5444 * = 0b0 || 0b00 || 0b0 \ 5445 */ \ 5446 tcg_gen_movi_i32(cpu_crf[0], 0); \ 5447 } 5448 5449 GEN_TM_NOOP(tend); 5450 GEN_TM_NOOP(tabort); 5451 GEN_TM_NOOP(tabortwc); 5452 GEN_TM_NOOP(tabortwci); 5453 GEN_TM_NOOP(tabortdc); 5454 GEN_TM_NOOP(tabortdci); 5455 GEN_TM_NOOP(tsr); 5456 5457 static inline void gen_cp_abort(DisasContext *ctx) 5458 { 5459 /* Do Nothing */ 5460 } 5461 5462 #define GEN_CP_PASTE_NOOP(name) \ 5463 static inline void gen_##name(DisasContext *ctx) \ 5464 { \ 5465 /* \ 5466 * Generate invalid exception until we have an \ 5467 * implementation of the copy paste facility \ 5468 */ \ 5469 gen_invalid(ctx); \ 5470 } 5471 5472 GEN_CP_PASTE_NOOP(copy) 5473 GEN_CP_PASTE_NOOP(paste) 5474 5475 static void gen_tcheck(DisasContext *ctx) 5476 { 5477 if (unlikely(!ctx->tm_enabled)) { 5478 gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM); 5479 return; 5480 } 5481 /* 5482 * Because tbegin always fails, the tcheck implementation is 5483 * simple: 5484 * 5485 * CR[CRF] = TDOOMED || MSR[TS] || 0b0 5486 * = 0b1 || 0b00 || 0b0 5487 */ 5488 tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], 0x8); 5489 } 5490 5491 #if defined(CONFIG_USER_ONLY) 5492 #define GEN_TM_PRIV_NOOP(name) \ 5493 static inline void gen_##name(DisasContext *ctx) \ 5494 { \ 5495 gen_priv_opc(ctx); \ 5496 } 5497 5498 #else 5499 5500 #define GEN_TM_PRIV_NOOP(name) \ 5501 static inline void gen_##name(DisasContext *ctx) \ 5502 { \ 5503 CHK_SV(ctx); \ 5504 if (unlikely(!ctx->tm_enabled)) { \ 5505 gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM); \ 5506 return; \ 5507 } \ 5508 /* \ 5509 * Because tbegin always fails, the implementation is \ 5510 * simple: \ 5511 * \ 5512 * CR[0] = 0b0 || MSR[TS] || 0b0 \ 5513 * = 0b0 || 0b00 | 0b0 \ 5514 */ \ 5515 tcg_gen_movi_i32(cpu_crf[0], 0); \ 5516 } 5517 5518 #endif 5519 5520 GEN_TM_PRIV_NOOP(treclaim); 5521 GEN_TM_PRIV_NOOP(trechkpt); 5522 5523 static inline void get_fpr(TCGv_i64 dst, int regno) 5524 { 5525 tcg_gen_ld_i64(dst, tcg_env, fpr_offset(regno)); 5526 } 5527 5528 static inline void set_fpr(int regno, TCGv_i64 src) 5529 { 5530 tcg_gen_st_i64(src, tcg_env, fpr_offset(regno)); 5531 /* 5532 * Before PowerISA v3.1 the result of doubleword 1 of the VSR 5533 * corresponding to the target FPR was undefined. However, 5534 * most (if not all) real hardware were setting the result to 0. 5535 * Starting at ISA v3.1, the result for doubleword 1 is now defined 5536 * to be 0. 5537 */ 5538 tcg_gen_st_i64(tcg_constant_i64(0), tcg_env, vsr64_offset(regno, false)); 5539 } 5540 5541 static inline void get_avr64(TCGv_i64 dst, int regno, bool high) 5542 { 5543 tcg_gen_ld_i64(dst, tcg_env, avr64_offset(regno, high)); 5544 } 5545 5546 static inline void set_avr64(int regno, TCGv_i64 src, bool high) 5547 { 5548 tcg_gen_st_i64(src, tcg_env, avr64_offset(regno, high)); 5549 } 5550 5551 /* 5552 * Helpers for decodetree used by !function for decoding arguments. 5553 */ 5554 static int times_2(DisasContext *ctx, int x) 5555 { 5556 return x * 2; 5557 } 5558 5559 static int times_4(DisasContext *ctx, int x) 5560 { 5561 return x * 4; 5562 } 5563 5564 static int times_16(DisasContext *ctx, int x) 5565 { 5566 return x * 16; 5567 } 5568 5569 static int64_t dw_compose_ea(DisasContext *ctx, int x) 5570 { 5571 return deposit64(0xfffffffffffffe00, 3, 6, x); 5572 } 5573 5574 /* 5575 * Helpers for trans_* functions to check for specific insns flags. 5576 * Use token pasting to ensure that we use the proper flag with the 5577 * proper variable. 5578 */ 5579 #define REQUIRE_INSNS_FLAGS(CTX, NAME) \ 5580 do { \ 5581 if (((CTX)->insns_flags & PPC_##NAME) == 0) { \ 5582 return false; \ 5583 } \ 5584 } while (0) 5585 5586 #define REQUIRE_INSNS_FLAGS2(CTX, NAME) \ 5587 do { \ 5588 if (((CTX)->insns_flags2 & PPC2_##NAME) == 0) { \ 5589 return false; \ 5590 } \ 5591 } while (0) 5592 5593 /* Then special-case the check for 64-bit so that we elide code for ppc32. */ 5594 #if TARGET_LONG_BITS == 32 5595 # define REQUIRE_64BIT(CTX) return false 5596 #else 5597 # define REQUIRE_64BIT(CTX) REQUIRE_INSNS_FLAGS(CTX, 64B) 5598 #endif 5599 5600 #define REQUIRE_VECTOR(CTX) \ 5601 do { \ 5602 if (unlikely(!(CTX)->altivec_enabled)) { \ 5603 gen_exception((CTX), POWERPC_EXCP_VPU); \ 5604 return true; \ 5605 } \ 5606 } while (0) 5607 5608 #define REQUIRE_VSX(CTX) \ 5609 do { \ 5610 if (unlikely(!(CTX)->vsx_enabled)) { \ 5611 gen_exception((CTX), POWERPC_EXCP_VSXU); \ 5612 return true; \ 5613 } \ 5614 } while (0) 5615 5616 #define REQUIRE_FPU(ctx) \ 5617 do { \ 5618 if (unlikely(!(ctx)->fpu_enabled)) { \ 5619 gen_exception((ctx), POWERPC_EXCP_FPU); \ 5620 return true; \ 5621 } \ 5622 } while (0) 5623 5624 #if !defined(CONFIG_USER_ONLY) 5625 #define REQUIRE_SV(CTX) \ 5626 do { \ 5627 if (unlikely((CTX)->pr)) { \ 5628 gen_priv_opc(CTX); \ 5629 return true; \ 5630 } \ 5631 } while (0) 5632 5633 #define REQUIRE_HV(CTX) \ 5634 do { \ 5635 if (unlikely((CTX)->pr || !(CTX)->hv)) { \ 5636 gen_priv_opc(CTX); \ 5637 return true; \ 5638 } \ 5639 } while (0) 5640 #else 5641 #define REQUIRE_SV(CTX) do { gen_priv_opc(CTX); return true; } while (0) 5642 #define REQUIRE_HV(CTX) do { gen_priv_opc(CTX); return true; } while (0) 5643 #endif 5644 5645 /* 5646 * Helpers for implementing sets of trans_* functions. 5647 * Defer the implementation of NAME to FUNC, with optional extra arguments. 5648 */ 5649 #define TRANS(NAME, FUNC, ...) \ 5650 static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a) \ 5651 { return FUNC(ctx, a, __VA_ARGS__); } 5652 #define TRANS_FLAGS(FLAGS, NAME, FUNC, ...) \ 5653 static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a) \ 5654 { \ 5655 REQUIRE_INSNS_FLAGS(ctx, FLAGS); \ 5656 return FUNC(ctx, a, __VA_ARGS__); \ 5657 } 5658 #define TRANS_FLAGS2(FLAGS2, NAME, FUNC, ...) \ 5659 static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a) \ 5660 { \ 5661 REQUIRE_INSNS_FLAGS2(ctx, FLAGS2); \ 5662 return FUNC(ctx, a, __VA_ARGS__); \ 5663 } 5664 5665 #define TRANS64(NAME, FUNC, ...) \ 5666 static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a) \ 5667 { REQUIRE_64BIT(ctx); return FUNC(ctx, a, __VA_ARGS__); } 5668 #define TRANS64_FLAGS2(FLAGS2, NAME, FUNC, ...) \ 5669 static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a) \ 5670 { \ 5671 REQUIRE_64BIT(ctx); \ 5672 REQUIRE_INSNS_FLAGS2(ctx, FLAGS2); \ 5673 return FUNC(ctx, a, __VA_ARGS__); \ 5674 } 5675 5676 /* TODO: More TRANS* helpers for extra insn_flags checks. */ 5677 5678 5679 #include "decode-insn32.c.inc" 5680 #include "decode-insn64.c.inc" 5681 #include "power8-pmu-regs.c.inc" 5682 5683 /* 5684 * Incorporate CIA into the constant when R=1. 5685 * Validate that when R=1, RA=0. 5686 */ 5687 static bool resolve_PLS_D(DisasContext *ctx, arg_D *d, arg_PLS_D *a) 5688 { 5689 d->rt = a->rt; 5690 d->ra = a->ra; 5691 d->si = a->si; 5692 if (a->r) { 5693 if (unlikely(a->ra != 0)) { 5694 gen_invalid(ctx); 5695 return false; 5696 } 5697 d->si += ctx->cia; 5698 } 5699 return true; 5700 } 5701 5702 #include "translate/fixedpoint-impl.c.inc" 5703 5704 #include "translate/fp-impl.c.inc" 5705 5706 #include "translate/vmx-impl.c.inc" 5707 5708 #include "translate/vsx-impl.c.inc" 5709 5710 #include "translate/dfp-impl.c.inc" 5711 5712 #include "translate/spe-impl.c.inc" 5713 5714 #include "translate/branch-impl.c.inc" 5715 5716 #include "translate/processor-ctrl-impl.c.inc" 5717 5718 #include "translate/storage-ctrl-impl.c.inc" 5719 5720 #include "translate/misc-impl.c.inc" 5721 5722 #include "translate/bhrb-impl.c.inc" 5723 5724 /* Handles lfdp */ 5725 static void gen_dform39(DisasContext *ctx) 5726 { 5727 if ((ctx->opcode & 0x3) == 0) { 5728 if (ctx->insns_flags2 & PPC2_ISA205) { 5729 return gen_lfdp(ctx); 5730 } 5731 } 5732 return gen_invalid(ctx); 5733 } 5734 5735 /* Handles stfdp */ 5736 static void gen_dform3D(DisasContext *ctx) 5737 { 5738 if ((ctx->opcode & 3) == 0) { /* DS-FORM */ 5739 /* stfdp */ 5740 if (ctx->insns_flags2 & PPC2_ISA205) { 5741 return gen_stfdp(ctx); 5742 } 5743 } 5744 return gen_invalid(ctx); 5745 } 5746 5747 #if defined(TARGET_PPC64) 5748 /* brd */ 5749 static void gen_brd(DisasContext *ctx) 5750 { 5751 tcg_gen_bswap64_i64(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]); 5752 } 5753 5754 /* brw */ 5755 static void gen_brw(DisasContext *ctx) 5756 { 5757 tcg_gen_bswap64_i64(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]); 5758 tcg_gen_rotli_i64(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 32); 5759 5760 } 5761 5762 /* brh */ 5763 static void gen_brh(DisasContext *ctx) 5764 { 5765 TCGv_i64 mask = tcg_constant_i64(0x00ff00ff00ff00ffull); 5766 TCGv_i64 t1 = tcg_temp_new_i64(); 5767 TCGv_i64 t2 = tcg_temp_new_i64(); 5768 5769 tcg_gen_shri_i64(t1, cpu_gpr[rS(ctx->opcode)], 8); 5770 tcg_gen_and_i64(t2, t1, mask); 5771 tcg_gen_and_i64(t1, cpu_gpr[rS(ctx->opcode)], mask); 5772 tcg_gen_shli_i64(t1, t1, 8); 5773 tcg_gen_or_i64(cpu_gpr[rA(ctx->opcode)], t1, t2); 5774 } 5775 #endif 5776 5777 static opcode_t opcodes[] = { 5778 #if defined(TARGET_PPC64) 5779 GEN_HANDLER_E(brd, 0x1F, 0x1B, 0x05, 0x0000F801, PPC_NONE, PPC2_ISA310), 5780 GEN_HANDLER_E(brw, 0x1F, 0x1B, 0x04, 0x0000F801, PPC_NONE, PPC2_ISA310), 5781 GEN_HANDLER_E(brh, 0x1F, 0x1B, 0x06, 0x0000F801, PPC_NONE, PPC2_ISA310), 5782 #endif 5783 GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE), 5784 GEN_HANDLER_E(copy, 0x1F, 0x06, 0x18, 0x03C00001, PPC_NONE, PPC2_ISA300), 5785 GEN_HANDLER_E(cp_abort, 0x1F, 0x06, 0x1A, 0x03FFF801, PPC_NONE, PPC2_ISA300), 5786 GEN_HANDLER_E(paste, 0x1F, 0x06, 0x1C, 0x03C00000, PPC_NONE, PPC2_ISA300), 5787 GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), 5788 GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), 5789 GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), 5790 GEN_HANDLER(slw, 0x1F, 0x18, 0x00, 0x00000000, PPC_INTEGER), 5791 GEN_HANDLER(sraw, 0x1F, 0x18, 0x18, 0x00000000, PPC_INTEGER), 5792 GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER), 5793 GEN_HANDLER(srw, 0x1F, 0x18, 0x10, 0x00000000, PPC_INTEGER), 5794 #if defined(TARGET_PPC64) 5795 GEN_HANDLER(sld, 0x1F, 0x1B, 0x00, 0x00000000, PPC_64B), 5796 GEN_HANDLER(srad, 0x1F, 0x1A, 0x18, 0x00000000, PPC_64B), 5797 GEN_HANDLER2(sradi0, "sradi", 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B), 5798 GEN_HANDLER2(sradi1, "sradi", 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B), 5799 GEN_HANDLER(srd, 0x1F, 0x1B, 0x10, 0x00000000, PPC_64B), 5800 GEN_HANDLER2_E(extswsli0, "extswsli", 0x1F, 0x1A, 0x1B, 0x00000000, 5801 PPC_NONE, PPC2_ISA300), 5802 GEN_HANDLER2_E(extswsli1, "extswsli", 0x1F, 0x1B, 0x1B, 0x00000000, 5803 PPC_NONE, PPC2_ISA300), 5804 #endif 5805 /* handles lfdp, lxsd, lxssp */ 5806 GEN_HANDLER_E(dform39, 0x39, 0xFF, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA205), 5807 /* handles stfdp, stxsd, stxssp */ 5808 GEN_HANDLER_E(dform3D, 0x3D, 0xFF, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA205), 5809 GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), 5810 GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), 5811 GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING), 5812 GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING), 5813 GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING), 5814 GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING), 5815 GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM), 5816 GEN_HANDLER_E(lbarx, 0x1F, 0x14, 0x01, 0, PPC_NONE, PPC2_ATOMIC_ISA206), 5817 GEN_HANDLER_E(lharx, 0x1F, 0x14, 0x03, 0, PPC_NONE, PPC2_ATOMIC_ISA206), 5818 GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000000, PPC_RES), 5819 GEN_HANDLER_E(lwat, 0x1F, 0x06, 0x12, 0x00000001, PPC_NONE, PPC2_ISA300), 5820 GEN_HANDLER_E(stwat, 0x1F, 0x06, 0x16, 0x00000001, PPC_NONE, PPC2_ISA300), 5821 GEN_HANDLER_E(stbcx_, 0x1F, 0x16, 0x15, 0, PPC_NONE, PPC2_ATOMIC_ISA206), 5822 GEN_HANDLER_E(sthcx_, 0x1F, 0x16, 0x16, 0, PPC_NONE, PPC2_ATOMIC_ISA206), 5823 GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES), 5824 #if defined(TARGET_PPC64) 5825 GEN_HANDLER_E(ldat, 0x1F, 0x06, 0x13, 0x00000001, PPC_NONE, PPC2_ISA300), 5826 GEN_HANDLER_E(stdat, 0x1F, 0x06, 0x17, 0x00000001, PPC_NONE, PPC2_ISA300), 5827 GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000000, PPC_64B), 5828 GEN_HANDLER_E(lqarx, 0x1F, 0x14, 0x08, 0, PPC_NONE, PPC2_LSQ_ISA207), 5829 GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B), 5830 GEN_HANDLER_E(stqcx_, 0x1F, 0x16, 0x05, 0, PPC_NONE, PPC2_LSQ_ISA207), 5831 #endif 5832 /* ISA v3.0 changed the extended opcode from 62 to 30 */ 5833 GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x039FF801, PPC_WAIT), 5834 GEN_HANDLER_E(wait, 0x1F, 0x1E, 0x00, 0x039CF801, PPC_NONE, PPC2_ISA300), 5835 GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW), 5836 GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW), 5837 GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW), 5838 GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW), 5839 GEN_HANDLER_E(bctar, 0x13, 0x10, 0x11, 0x0000E000, PPC_NONE, PPC2_BCTAR_ISA207), 5840 GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER), 5841 GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW), 5842 #if defined(TARGET_PPC64) 5843 GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B), 5844 #if !defined(CONFIG_USER_ONLY) 5845 /* Top bit of opc2 corresponds with low bit of LEV, so use two handlers */ 5846 GEN_HANDLER_E(scv, 0x11, 0x10, 0xFF, 0x03FFF01E, PPC_NONE, PPC2_ISA300), 5847 GEN_HANDLER_E(scv, 0x11, 0x00, 0xFF, 0x03FFF01E, PPC_NONE, PPC2_ISA300), 5848 GEN_HANDLER_E(rfscv, 0x13, 0x12, 0x02, 0x03FF8001, PPC_NONE, PPC2_ISA300), 5849 #endif 5850 GEN_HANDLER_E(stop, 0x13, 0x12, 0x0b, 0x03FFF801, PPC_NONE, PPC2_ISA300), 5851 GEN_HANDLER_E(doze, 0x13, 0x12, 0x0c, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206), 5852 GEN_HANDLER_E(nap, 0x13, 0x12, 0x0d, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206), 5853 GEN_HANDLER_E(sleep, 0x13, 0x12, 0x0e, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206), 5854 GEN_HANDLER_E(rvwinkle, 0x13, 0x12, 0x0f, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206), 5855 GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H), 5856 #endif 5857 /* Top bit of opc2 corresponds with low bit of LEV, so use two handlers */ 5858 GEN_HANDLER(sc, 0x11, 0x11, 0xFF, 0x03FFF01D, PPC_FLOW), 5859 GEN_HANDLER(sc, 0x11, 0x01, 0xFF, 0x03FFF01D, PPC_FLOW), 5860 GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC), 5861 GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC), 5862 GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC), 5863 GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC), 5864 GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB), 5865 GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC), 5866 #if defined(TARGET_PPC64) 5867 GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B), 5868 GEN_HANDLER_E(setb, 0x1F, 0x00, 0x04, 0x0003F801, PPC_NONE, PPC2_ISA300), 5869 GEN_HANDLER_E(mcrxrx, 0x1F, 0x00, 0x12, 0x007FF801, PPC_NONE, PPC2_ISA300), 5870 #endif 5871 GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001EF801, PPC_MISC), 5872 GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000000, PPC_MISC), 5873 GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE), 5874 GEN_HANDLER_E(dcbfep, 0x1F, 0x1F, 0x03, 0x03C00001, PPC_NONE, PPC2_BOOKE206), 5875 GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE), 5876 GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE), 5877 GEN_HANDLER_E(dcbstep, 0x1F, 0x1F, 0x01, 0x03E00001, PPC_NONE, PPC2_BOOKE206), 5878 GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x00000001, PPC_CACHE), 5879 GEN_HANDLER_E(dcbtep, 0x1F, 0x1F, 0x09, 0x00000001, PPC_NONE, PPC2_BOOKE206), 5880 GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x00000001, PPC_CACHE), 5881 GEN_HANDLER_E(dcbtstep, 0x1F, 0x1F, 0x07, 0x00000001, PPC_NONE, PPC2_BOOKE206), 5882 GEN_HANDLER_E(dcbtls, 0x1F, 0x06, 0x05, 0x02000001, PPC_BOOKE, PPC2_BOOKE206), 5883 GEN_HANDLER_E(dcblc, 0x1F, 0x06, 0x0c, 0x02000001, PPC_BOOKE, PPC2_BOOKE206), 5884 GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZ), 5885 GEN_HANDLER_E(dcbzep, 0x1F, 0x1F, 0x1F, 0x03C00001, PPC_NONE, PPC2_BOOKE206), 5886 GEN_HANDLER(dst, 0x1F, 0x16, 0x0A, 0x01800001, PPC_ALTIVEC), 5887 GEN_HANDLER(dstst, 0x1F, 0x16, 0x0B, 0x01800001, PPC_ALTIVEC), 5888 GEN_HANDLER(dss, 0x1F, 0x16, 0x19, 0x019FF801, PPC_ALTIVEC), 5889 GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI), 5890 GEN_HANDLER_E(icbiep, 0x1F, 0x1F, 0x1E, 0x03E00001, PPC_NONE, PPC2_BOOKE206), 5891 GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA), 5892 GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT), 5893 GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT), 5894 GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT), 5895 GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT), 5896 #if defined(TARGET_PPC64) 5897 GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B), 5898 GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001, 5899 PPC_SEGMENT_64B), 5900 GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B), 5901 GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001, 5902 PPC_SEGMENT_64B), 5903 #endif 5904 GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA), 5905 /* 5906 * XXX Those instructions will need to be handled differently for 5907 * different ISA versions 5908 */ 5909 GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC), 5910 GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN), 5911 GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN), 5912 GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB), 5913 GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB), 5914 GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_MFAPIDI), 5915 GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_TLBIVA), 5916 GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_DCR), 5917 GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_DCR), 5918 GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_DCRX), 5919 GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_DCRX), 5920 GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON), 5921 GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON), 5922 GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT), 5923 GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON), 5924 GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON), 5925 GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP), 5926 GEN_HANDLER_E(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE, PPC2_BOOKE206), 5927 GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI), 5928 GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI), 5929 GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB), 5930 GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB), 5931 GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB), 5932 GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE), 5933 GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE), 5934 GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE), 5935 GEN_HANDLER2_E(tlbre_booke206, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, 5936 PPC_NONE, PPC2_BOOKE206), 5937 GEN_HANDLER2_E(tlbsx_booke206, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, 5938 PPC_NONE, PPC2_BOOKE206), 5939 GEN_HANDLER2_E(tlbwe_booke206, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, 5940 PPC_NONE, PPC2_BOOKE206), 5941 GEN_HANDLER2_E(tlbivax_booke206, "tlbivax", 0x1F, 0x12, 0x18, 0x00000001, 5942 PPC_NONE, PPC2_BOOKE206), 5943 GEN_HANDLER2_E(tlbilx_booke206, "tlbilx", 0x1F, 0x12, 0x00, 0x03800001, 5944 PPC_NONE, PPC2_BOOKE206), 5945 GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE), 5946 GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000E7C01, PPC_WRTEE), 5947 GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC), 5948 GEN_HANDLER2_E(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001, 5949 PPC_BOOKE, PPC2_BOOKE206), 5950 GEN_HANDLER2(icbt_440, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, 5951 PPC_440_SPEC), 5952 GEN_HANDLER(mfvscr, 0x04, 0x2, 0x18, 0x001ff800, PPC_ALTIVEC), 5953 GEN_HANDLER(mtvscr, 0x04, 0x2, 0x19, 0x03ff0000, PPC_ALTIVEC), 5954 5955 #if defined(TARGET_PPC64) 5956 #undef GEN_PPC64_R2 5957 #undef GEN_PPC64_R4 5958 #define GEN_PPC64_R2(name, opc1, opc2) \ 5959 GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\ 5960 GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000, \ 5961 PPC_64B) 5962 #define GEN_PPC64_R4(name, opc1, opc2) \ 5963 GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\ 5964 GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x01, 0xFF, 0x00000000, \ 5965 PPC_64B), \ 5966 GEN_HANDLER2(name##2, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000, \ 5967 PPC_64B), \ 5968 GEN_HANDLER2(name##3, stringify(name), opc1, opc2 | 0x11, 0xFF, 0x00000000, \ 5969 PPC_64B) 5970 GEN_PPC64_R4(rldicl, 0x1E, 0x00), 5971 GEN_PPC64_R4(rldicr, 0x1E, 0x02), 5972 GEN_PPC64_R4(rldic, 0x1E, 0x04), 5973 GEN_PPC64_R2(rldcl, 0x1E, 0x08), 5974 GEN_PPC64_R2(rldcr, 0x1E, 0x09), 5975 GEN_PPC64_R4(rldimi, 0x1E, 0x06), 5976 #endif 5977 5978 #undef GEN_LDX_E 5979 #define GEN_LDX_E(name, ldop, opc2, opc3, type, type2, chk) \ 5980 GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2), 5981 5982 #if defined(TARGET_PPC64) 5983 GEN_LDX_E(ldbr, ld64ur_i64, 0x14, 0x10, PPC_NONE, PPC2_DBRX, CHK_NONE) 5984 5985 /* HV/P7 and later only */ 5986 GEN_LDX_HVRM(ldcix, ld64_i64, 0x15, 0x1b, PPC_CILDST) 5987 GEN_LDX_HVRM(lwzcix, ld32u, 0x15, 0x18, PPC_CILDST) 5988 GEN_LDX_HVRM(lhzcix, ld16u, 0x15, 0x19, PPC_CILDST) 5989 GEN_LDX_HVRM(lbzcix, ld8u, 0x15, 0x1a, PPC_CILDST) 5990 #endif 5991 GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER) 5992 GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER) 5993 5994 /* External PID based load */ 5995 #undef GEN_LDEPX 5996 #define GEN_LDEPX(name, ldop, opc2, opc3) \ 5997 GEN_HANDLER_E(name##epx, 0x1F, opc2, opc3, \ 5998 0x00000001, PPC_NONE, PPC2_BOOKE206), 5999 6000 GEN_LDEPX(lb, DEF_MEMOP(MO_UB), 0x1F, 0x02) 6001 GEN_LDEPX(lh, DEF_MEMOP(MO_UW), 0x1F, 0x08) 6002 GEN_LDEPX(lw, DEF_MEMOP(MO_UL), 0x1F, 0x00) 6003 #if defined(TARGET_PPC64) 6004 GEN_LDEPX(ld, DEF_MEMOP(MO_UQ), 0x1D, 0x00) 6005 #endif 6006 6007 #undef GEN_STX_E 6008 #define GEN_STX_E(name, stop, opc2, opc3, type, type2, chk) \ 6009 GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000000, type, type2), 6010 6011 #if defined(TARGET_PPC64) 6012 GEN_STX_E(stdbr, st64r_i64, 0x14, 0x14, PPC_NONE, PPC2_DBRX, CHK_NONE) 6013 GEN_STX_HVRM(stdcix, st64_i64, 0x15, 0x1f, PPC_CILDST) 6014 GEN_STX_HVRM(stwcix, st32, 0x15, 0x1c, PPC_CILDST) 6015 GEN_STX_HVRM(sthcix, st16, 0x15, 0x1d, PPC_CILDST) 6016 GEN_STX_HVRM(stbcix, st8, 0x15, 0x1e, PPC_CILDST) 6017 #endif 6018 GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER) 6019 GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER) 6020 6021 #undef GEN_STEPX 6022 #define GEN_STEPX(name, ldop, opc2, opc3) \ 6023 GEN_HANDLER_E(name##epx, 0x1F, opc2, opc3, \ 6024 0x00000001, PPC_NONE, PPC2_BOOKE206), 6025 6026 GEN_STEPX(stb, DEF_MEMOP(MO_UB), 0x1F, 0x06) 6027 GEN_STEPX(sth, DEF_MEMOP(MO_UW), 0x1F, 0x0C) 6028 GEN_STEPX(stw, DEF_MEMOP(MO_UL), 0x1F, 0x04) 6029 #if defined(TARGET_PPC64) 6030 GEN_STEPX(std, DEF_MEMOP(MO_UQ), 0x1D, 0x04) 6031 #endif 6032 6033 #undef GEN_CRLOGIC 6034 #define GEN_CRLOGIC(name, tcg_op, opc) \ 6035 GEN_HANDLER(name, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER) 6036 GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08), 6037 GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04), 6038 GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09), 6039 GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07), 6040 GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01), 6041 GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E), 6042 GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D), 6043 GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06), 6044 6045 #undef GEN_MAC_HANDLER 6046 #define GEN_MAC_HANDLER(name, opc2, opc3) \ 6047 GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC) 6048 GEN_MAC_HANDLER(macchw, 0x0C, 0x05), 6049 GEN_MAC_HANDLER(macchwo, 0x0C, 0x15), 6050 GEN_MAC_HANDLER(macchws, 0x0C, 0x07), 6051 GEN_MAC_HANDLER(macchwso, 0x0C, 0x17), 6052 GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06), 6053 GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16), 6054 GEN_MAC_HANDLER(macchwu, 0x0C, 0x04), 6055 GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14), 6056 GEN_MAC_HANDLER(machhw, 0x0C, 0x01), 6057 GEN_MAC_HANDLER(machhwo, 0x0C, 0x11), 6058 GEN_MAC_HANDLER(machhws, 0x0C, 0x03), 6059 GEN_MAC_HANDLER(machhwso, 0x0C, 0x13), 6060 GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02), 6061 GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12), 6062 GEN_MAC_HANDLER(machhwu, 0x0C, 0x00), 6063 GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10), 6064 GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D), 6065 GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D), 6066 GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F), 6067 GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F), 6068 GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C), 6069 GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C), 6070 GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E), 6071 GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E), 6072 GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05), 6073 GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15), 6074 GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07), 6075 GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17), 6076 GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01), 6077 GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11), 6078 GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03), 6079 GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13), 6080 GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D), 6081 GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D), 6082 GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F), 6083 GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F), 6084 GEN_MAC_HANDLER(mulchw, 0x08, 0x05), 6085 GEN_MAC_HANDLER(mulchwu, 0x08, 0x04), 6086 GEN_MAC_HANDLER(mulhhw, 0x08, 0x01), 6087 GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00), 6088 GEN_MAC_HANDLER(mullhw, 0x08, 0x0D), 6089 GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C), 6090 6091 GEN_HANDLER2_E(tbegin, "tbegin", 0x1F, 0x0E, 0x14, 0x01DFF800, \ 6092 PPC_NONE, PPC2_TM), 6093 GEN_HANDLER2_E(tend, "tend", 0x1F, 0x0E, 0x15, 0x01FFF800, \ 6094 PPC_NONE, PPC2_TM), 6095 GEN_HANDLER2_E(tabort, "tabort", 0x1F, 0x0E, 0x1C, 0x03E0F800, \ 6096 PPC_NONE, PPC2_TM), 6097 GEN_HANDLER2_E(tabortwc, "tabortwc", 0x1F, 0x0E, 0x18, 0x00000000, \ 6098 PPC_NONE, PPC2_TM), 6099 GEN_HANDLER2_E(tabortwci, "tabortwci", 0x1F, 0x0E, 0x1A, 0x00000000, \ 6100 PPC_NONE, PPC2_TM), 6101 GEN_HANDLER2_E(tabortdc, "tabortdc", 0x1F, 0x0E, 0x19, 0x00000000, \ 6102 PPC_NONE, PPC2_TM), 6103 GEN_HANDLER2_E(tabortdci, "tabortdci", 0x1F, 0x0E, 0x1B, 0x00000000, \ 6104 PPC_NONE, PPC2_TM), 6105 GEN_HANDLER2_E(tsr, "tsr", 0x1F, 0x0E, 0x17, 0x03DFF800, \ 6106 PPC_NONE, PPC2_TM), 6107 GEN_HANDLER2_E(tcheck, "tcheck", 0x1F, 0x0E, 0x16, 0x007FF800, \ 6108 PPC_NONE, PPC2_TM), 6109 GEN_HANDLER2_E(treclaim, "treclaim", 0x1F, 0x0E, 0x1D, 0x03E0F800, \ 6110 PPC_NONE, PPC2_TM), 6111 GEN_HANDLER2_E(trechkpt, "trechkpt", 0x1F, 0x0E, 0x1F, 0x03FFF800, \ 6112 PPC_NONE, PPC2_TM), 6113 6114 #include "translate/fp-ops.c.inc" 6115 6116 #include "translate/vmx-ops.c.inc" 6117 6118 #include "translate/vsx-ops.c.inc" 6119 6120 #include "translate/spe-ops.c.inc" 6121 }; 6122 6123 /*****************************************************************************/ 6124 /* Opcode types */ 6125 enum { 6126 PPC_DIRECT = 0, /* Opcode routine */ 6127 PPC_INDIRECT = 1, /* Indirect opcode table */ 6128 }; 6129 6130 #define PPC_OPCODE_MASK 0x3 6131 6132 static inline int is_indirect_opcode(void *handler) 6133 { 6134 return ((uintptr_t)handler & PPC_OPCODE_MASK) == PPC_INDIRECT; 6135 } 6136 6137 static inline opc_handler_t **ind_table(void *handler) 6138 { 6139 return (opc_handler_t **)((uintptr_t)handler & ~PPC_OPCODE_MASK); 6140 } 6141 6142 /* Instruction table creation */ 6143 /* Opcodes tables creation */ 6144 static void fill_new_table(opc_handler_t **table, int len) 6145 { 6146 int i; 6147 6148 for (i = 0; i < len; i++) { 6149 table[i] = &invalid_handler; 6150 } 6151 } 6152 6153 static int create_new_table(opc_handler_t **table, unsigned char idx) 6154 { 6155 opc_handler_t **tmp; 6156 6157 tmp = g_new(opc_handler_t *, PPC_CPU_INDIRECT_OPCODES_LEN); 6158 fill_new_table(tmp, PPC_CPU_INDIRECT_OPCODES_LEN); 6159 table[idx] = (opc_handler_t *)((uintptr_t)tmp | PPC_INDIRECT); 6160 6161 return 0; 6162 } 6163 6164 static int insert_in_table(opc_handler_t **table, unsigned char idx, 6165 opc_handler_t *handler) 6166 { 6167 if (table[idx] != &invalid_handler) { 6168 return -1; 6169 } 6170 table[idx] = handler; 6171 6172 return 0; 6173 } 6174 6175 static int register_direct_insn(opc_handler_t **ppc_opcodes, 6176 unsigned char idx, opc_handler_t *handler) 6177 { 6178 if (insert_in_table(ppc_opcodes, idx, handler) < 0) { 6179 printf("*** ERROR: opcode %02x already assigned in main " 6180 "opcode table\n", idx); 6181 return -1; 6182 } 6183 6184 return 0; 6185 } 6186 6187 static int register_ind_in_table(opc_handler_t **table, 6188 unsigned char idx1, unsigned char idx2, 6189 opc_handler_t *handler) 6190 { 6191 if (table[idx1] == &invalid_handler) { 6192 if (create_new_table(table, idx1) < 0) { 6193 printf("*** ERROR: unable to create indirect table " 6194 "idx=%02x\n", idx1); 6195 return -1; 6196 } 6197 } else { 6198 if (!is_indirect_opcode(table[idx1])) { 6199 printf("*** ERROR: idx %02x already assigned to a direct " 6200 "opcode\n", idx1); 6201 return -1; 6202 } 6203 } 6204 if (handler != NULL && 6205 insert_in_table(ind_table(table[idx1]), idx2, handler) < 0) { 6206 printf("*** ERROR: opcode %02x already assigned in " 6207 "opcode table %02x\n", idx2, idx1); 6208 return -1; 6209 } 6210 6211 return 0; 6212 } 6213 6214 static int register_ind_insn(opc_handler_t **ppc_opcodes, 6215 unsigned char idx1, unsigned char idx2, 6216 opc_handler_t *handler) 6217 { 6218 return register_ind_in_table(ppc_opcodes, idx1, idx2, handler); 6219 } 6220 6221 static int register_dblind_insn(opc_handler_t **ppc_opcodes, 6222 unsigned char idx1, unsigned char idx2, 6223 unsigned char idx3, opc_handler_t *handler) 6224 { 6225 if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) { 6226 printf("*** ERROR: unable to join indirect table idx " 6227 "[%02x-%02x]\n", idx1, idx2); 6228 return -1; 6229 } 6230 if (register_ind_in_table(ind_table(ppc_opcodes[idx1]), idx2, idx3, 6231 handler) < 0) { 6232 printf("*** ERROR: unable to insert opcode " 6233 "[%02x-%02x-%02x]\n", idx1, idx2, idx3); 6234 return -1; 6235 } 6236 6237 return 0; 6238 } 6239 6240 static int register_trplind_insn(opc_handler_t **ppc_opcodes, 6241 unsigned char idx1, unsigned char idx2, 6242 unsigned char idx3, unsigned char idx4, 6243 opc_handler_t *handler) 6244 { 6245 opc_handler_t **table; 6246 6247 if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) { 6248 printf("*** ERROR: unable to join indirect table idx " 6249 "[%02x-%02x]\n", idx1, idx2); 6250 return -1; 6251 } 6252 table = ind_table(ppc_opcodes[idx1]); 6253 if (register_ind_in_table(table, idx2, idx3, NULL) < 0) { 6254 printf("*** ERROR: unable to join 2nd-level indirect table idx " 6255 "[%02x-%02x-%02x]\n", idx1, idx2, idx3); 6256 return -1; 6257 } 6258 table = ind_table(table[idx2]); 6259 if (register_ind_in_table(table, idx3, idx4, handler) < 0) { 6260 printf("*** ERROR: unable to insert opcode " 6261 "[%02x-%02x-%02x-%02x]\n", idx1, idx2, idx3, idx4); 6262 return -1; 6263 } 6264 return 0; 6265 } 6266 static int register_insn(opc_handler_t **ppc_opcodes, opcode_t *insn) 6267 { 6268 if (insn->opc2 != 0xFF) { 6269 if (insn->opc3 != 0xFF) { 6270 if (insn->opc4 != 0xFF) { 6271 if (register_trplind_insn(ppc_opcodes, insn->opc1, insn->opc2, 6272 insn->opc3, insn->opc4, 6273 &insn->handler) < 0) { 6274 return -1; 6275 } 6276 } else { 6277 if (register_dblind_insn(ppc_opcodes, insn->opc1, insn->opc2, 6278 insn->opc3, &insn->handler) < 0) { 6279 return -1; 6280 } 6281 } 6282 } else { 6283 if (register_ind_insn(ppc_opcodes, insn->opc1, 6284 insn->opc2, &insn->handler) < 0) { 6285 return -1; 6286 } 6287 } 6288 } else { 6289 if (register_direct_insn(ppc_opcodes, insn->opc1, &insn->handler) < 0) { 6290 return -1; 6291 } 6292 } 6293 6294 return 0; 6295 } 6296 6297 static int test_opcode_table(opc_handler_t **table, int len) 6298 { 6299 int i, count, tmp; 6300 6301 for (i = 0, count = 0; i < len; i++) { 6302 /* Consistency fixup */ 6303 if (table[i] == NULL) { 6304 table[i] = &invalid_handler; 6305 } 6306 if (table[i] != &invalid_handler) { 6307 if (is_indirect_opcode(table[i])) { 6308 tmp = test_opcode_table(ind_table(table[i]), 6309 PPC_CPU_INDIRECT_OPCODES_LEN); 6310 if (tmp == 0) { 6311 g_free(table[i]); 6312 table[i] = &invalid_handler; 6313 } else { 6314 count++; 6315 } 6316 } else { 6317 count++; 6318 } 6319 } 6320 } 6321 6322 return count; 6323 } 6324 6325 static void fix_opcode_tables(opc_handler_t **ppc_opcodes) 6326 { 6327 if (test_opcode_table(ppc_opcodes, PPC_CPU_OPCODES_LEN) == 0) { 6328 printf("*** WARNING: no opcode defined !\n"); 6329 } 6330 } 6331 6332 /*****************************************************************************/ 6333 void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp) 6334 { 6335 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); 6336 opcode_t *opc; 6337 6338 fill_new_table(cpu->opcodes, PPC_CPU_OPCODES_LEN); 6339 for (opc = opcodes; opc < &opcodes[ARRAY_SIZE(opcodes)]; opc++) { 6340 if (((opc->handler.type & pcc->insns_flags) != 0) || 6341 ((opc->handler.type2 & pcc->insns_flags2) != 0)) { 6342 if (register_insn(cpu->opcodes, opc) < 0) { 6343 error_setg(errp, "ERROR initializing PowerPC instruction " 6344 "0x%02x 0x%02x 0x%02x", opc->opc1, opc->opc2, 6345 opc->opc3); 6346 return; 6347 } 6348 } 6349 } 6350 fix_opcode_tables(cpu->opcodes); 6351 fflush(stdout); 6352 fflush(stderr); 6353 } 6354 6355 void destroy_ppc_opcodes(PowerPCCPU *cpu) 6356 { 6357 opc_handler_t **table, **table_2; 6358 int i, j, k; 6359 6360 for (i = 0; i < PPC_CPU_OPCODES_LEN; i++) { 6361 if (cpu->opcodes[i] == &invalid_handler) { 6362 continue; 6363 } 6364 if (is_indirect_opcode(cpu->opcodes[i])) { 6365 table = ind_table(cpu->opcodes[i]); 6366 for (j = 0; j < PPC_CPU_INDIRECT_OPCODES_LEN; j++) { 6367 if (table[j] == &invalid_handler) { 6368 continue; 6369 } 6370 if (is_indirect_opcode(table[j])) { 6371 table_2 = ind_table(table[j]); 6372 for (k = 0; k < PPC_CPU_INDIRECT_OPCODES_LEN; k++) { 6373 if (table_2[k] != &invalid_handler && 6374 is_indirect_opcode(table_2[k])) { 6375 g_free((opc_handler_t *)((uintptr_t)table_2[k] & 6376 ~PPC_INDIRECT)); 6377 } 6378 } 6379 g_free((opc_handler_t *)((uintptr_t)table[j] & 6380 ~PPC_INDIRECT)); 6381 } 6382 } 6383 g_free((opc_handler_t *)((uintptr_t)cpu->opcodes[i] & 6384 ~PPC_INDIRECT)); 6385 } 6386 } 6387 } 6388 6389 int ppc_fixup_cpu(PowerPCCPU *cpu) 6390 { 6391 CPUPPCState *env = &cpu->env; 6392 6393 /* 6394 * TCG doesn't (yet) emulate some groups of instructions that are 6395 * implemented on some otherwise supported CPUs (e.g. VSX and 6396 * decimal floating point instructions on POWER7). We remove 6397 * unsupported instruction groups from the cpu state's instruction 6398 * masks and hope the guest can cope. For at least the pseries 6399 * machine, the unavailability of these instructions can be 6400 * advertised to the guest via the device tree. 6401 */ 6402 if ((env->insns_flags & ~PPC_TCG_INSNS) 6403 || (env->insns_flags2 & ~PPC_TCG_INSNS2)) { 6404 warn_report("Disabling some instructions which are not " 6405 "emulated by TCG (0x%" PRIx64 ", 0x%" PRIx64 ")", 6406 env->insns_flags & ~PPC_TCG_INSNS, 6407 env->insns_flags2 & ~PPC_TCG_INSNS2); 6408 } 6409 env->insns_flags &= PPC_TCG_INSNS; 6410 env->insns_flags2 &= PPC_TCG_INSNS2; 6411 return 0; 6412 } 6413 6414 static bool decode_legacy(PowerPCCPU *cpu, DisasContext *ctx, uint32_t insn) 6415 { 6416 opc_handler_t **table, *handler; 6417 uint32_t inval; 6418 6419 ctx->opcode = insn; 6420 6421 LOG_DISAS("translate opcode %08x (%02x %02x %02x %02x) (%s)\n", 6422 insn, opc1(insn), opc2(insn), opc3(insn), opc4(insn), 6423 ctx->le_mode ? "little" : "big"); 6424 6425 table = cpu->opcodes; 6426 handler = table[opc1(insn)]; 6427 if (is_indirect_opcode(handler)) { 6428 table = ind_table(handler); 6429 handler = table[opc2(insn)]; 6430 if (is_indirect_opcode(handler)) { 6431 table = ind_table(handler); 6432 handler = table[opc3(insn)]; 6433 if (is_indirect_opcode(handler)) { 6434 table = ind_table(handler); 6435 handler = table[opc4(insn)]; 6436 } 6437 } 6438 } 6439 6440 /* Is opcode *REALLY* valid ? */ 6441 if (unlikely(handler->handler == &gen_invalid)) { 6442 qemu_log_mask(LOG_GUEST_ERROR, "invalid/unsupported opcode: " 6443 "%02x - %02x - %02x - %02x (%08x) " 6444 TARGET_FMT_lx "\n", 6445 opc1(insn), opc2(insn), opc3(insn), opc4(insn), 6446 insn, ctx->cia); 6447 return false; 6448 } 6449 6450 if (unlikely(handler->type & (PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE) 6451 && Rc(insn))) { 6452 inval = handler->inval2; 6453 } else { 6454 inval = handler->inval1; 6455 } 6456 6457 if (unlikely((insn & inval) != 0)) { 6458 qemu_log_mask(LOG_GUEST_ERROR, "invalid bits: %08x for opcode: " 6459 "%02x - %02x - %02x - %02x (%08x) " 6460 TARGET_FMT_lx "\n", insn & inval, 6461 opc1(insn), opc2(insn), opc3(insn), opc4(insn), 6462 insn, ctx->cia); 6463 return false; 6464 } 6465 6466 handler->handler(ctx); 6467 return true; 6468 } 6469 6470 static void ppc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) 6471 { 6472 DisasContext *ctx = container_of(dcbase, DisasContext, base); 6473 CPUPPCState *env = cpu_env(cs); 6474 uint32_t hflags = ctx->base.tb->flags; 6475 6476 ctx->spr_cb = env->spr_cb; 6477 ctx->pr = (hflags >> HFLAGS_PR) & 1; 6478 ctx->mem_idx = (hflags >> HFLAGS_DMMU_IDX) & 7; 6479 ctx->dr = (hflags >> HFLAGS_DR) & 1; 6480 ctx->hv = (hflags >> HFLAGS_HV) & 1; 6481 ctx->insns_flags = env->insns_flags; 6482 ctx->insns_flags2 = env->insns_flags2; 6483 ctx->access_type = -1; 6484 ctx->need_access_type = !mmu_is_64bit(env->mmu_model); 6485 ctx->le_mode = (hflags >> HFLAGS_LE) & 1; 6486 ctx->default_tcg_memop_mask = ctx->le_mode ? MO_LE : MO_BE; 6487 ctx->flags = env->flags; 6488 #if defined(TARGET_PPC64) 6489 ctx->sf_mode = (hflags >> HFLAGS_64) & 1; 6490 ctx->has_cfar = !!(env->flags & POWERPC_FLAG_CFAR); 6491 ctx->has_bhrb = !!(env->flags & POWERPC_FLAG_BHRB); 6492 #endif 6493 ctx->lazy_tlb_flush = env->mmu_model == POWERPC_MMU_32B 6494 || env->mmu_model & POWERPC_MMU_64; 6495 6496 ctx->fpu_enabled = (hflags >> HFLAGS_FP) & 1; 6497 ctx->spe_enabled = (hflags >> HFLAGS_SPE) & 1; 6498 ctx->altivec_enabled = (hflags >> HFLAGS_VR) & 1; 6499 ctx->vsx_enabled = (hflags >> HFLAGS_VSX) & 1; 6500 ctx->tm_enabled = (hflags >> HFLAGS_TM) & 1; 6501 ctx->gtse = (hflags >> HFLAGS_GTSE) & 1; 6502 ctx->hr = (hflags >> HFLAGS_HR) & 1; 6503 ctx->mmcr0_pmcc0 = (hflags >> HFLAGS_PMCC0) & 1; 6504 ctx->mmcr0_pmcc1 = (hflags >> HFLAGS_PMCC1) & 1; 6505 ctx->mmcr0_pmcjce = (hflags >> HFLAGS_PMCJCE) & 1; 6506 ctx->pmc_other = (hflags >> HFLAGS_PMC_OTHER) & 1; 6507 ctx->pmu_insn_cnt = (hflags >> HFLAGS_INSN_CNT) & 1; 6508 ctx->bhrb_enable = (hflags >> HFLAGS_BHRB_ENABLE) & 1; 6509 6510 ctx->singlestep_enabled = 0; 6511 if ((hflags >> HFLAGS_SE) & 1) { 6512 ctx->singlestep_enabled |= CPU_SINGLE_STEP; 6513 ctx->base.max_insns = 1; 6514 } 6515 if ((hflags >> HFLAGS_BE) & 1) { 6516 ctx->singlestep_enabled |= CPU_BRANCH_STEP; 6517 } 6518 } 6519 6520 static void ppc_tr_tb_start(DisasContextBase *db, CPUState *cs) 6521 { 6522 } 6523 6524 static void ppc_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) 6525 { 6526 tcg_gen_insn_start(dcbase->pc_next); 6527 } 6528 6529 static bool is_prefix_insn(DisasContext *ctx, uint32_t insn) 6530 { 6531 REQUIRE_INSNS_FLAGS2(ctx, ISA310); 6532 return opc1(insn) == 1; 6533 } 6534 6535 static void ppc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) 6536 { 6537 DisasContext *ctx = container_of(dcbase, DisasContext, base); 6538 PowerPCCPU *cpu = POWERPC_CPU(cs); 6539 CPUPPCState *env = cpu_env(cs); 6540 target_ulong pc; 6541 uint32_t insn; 6542 bool ok; 6543 6544 LOG_DISAS("----------------\n"); 6545 LOG_DISAS("nip=" TARGET_FMT_lx " super=%d ir=%d\n", 6546 ctx->base.pc_next, ctx->mem_idx, (int)msr_ir); 6547 6548 ctx->cia = pc = ctx->base.pc_next; 6549 insn = translator_ldl_swap(env, dcbase, pc, need_byteswap(ctx)); 6550 ctx->base.pc_next = pc += 4; 6551 6552 if (!is_prefix_insn(ctx, insn)) { 6553 ok = (decode_insn32(ctx, insn) || 6554 decode_legacy(cpu, ctx, insn)); 6555 } else if ((pc & 63) == 0) { 6556 /* 6557 * Power v3.1, section 1.9 Exceptions: 6558 * attempt to execute a prefixed instruction that crosses a 6559 * 64-byte address boundary (system alignment error). 6560 */ 6561 gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_INSN); 6562 ok = true; 6563 } else { 6564 uint32_t insn2 = translator_ldl_swap(env, dcbase, pc, 6565 need_byteswap(ctx)); 6566 ctx->base.pc_next = pc += 4; 6567 ok = decode_insn64(ctx, deposit64(insn2, 32, 32, insn)); 6568 } 6569 if (!ok) { 6570 gen_invalid(ctx); 6571 } 6572 6573 /* End the TB when crossing a page boundary. */ 6574 if (ctx->base.is_jmp == DISAS_NEXT && !(pc & ~TARGET_PAGE_MASK)) { 6575 ctx->base.is_jmp = DISAS_TOO_MANY; 6576 } 6577 } 6578 6579 static void ppc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) 6580 { 6581 DisasContext *ctx = container_of(dcbase, DisasContext, base); 6582 DisasJumpType is_jmp = ctx->base.is_jmp; 6583 target_ulong nip = ctx->base.pc_next; 6584 6585 if (is_jmp == DISAS_NORETURN) { 6586 /* We have already exited the TB. */ 6587 return; 6588 } 6589 6590 /* Honor single stepping. */ 6591 if (unlikely(ctx->singlestep_enabled & CPU_SINGLE_STEP)) { 6592 bool rfi_type = false; 6593 6594 switch (is_jmp) { 6595 case DISAS_TOO_MANY: 6596 case DISAS_EXIT_UPDATE: 6597 case DISAS_CHAIN_UPDATE: 6598 gen_update_nip(ctx, nip); 6599 break; 6600 case DISAS_EXIT: 6601 case DISAS_CHAIN: 6602 /* 6603 * This is a heuristic, to put it kindly. The rfi class of 6604 * instructions are among the few outside branches that change 6605 * NIP without taking an interrupt. Single step trace interrupts 6606 * do not fire on completion of these instructions. 6607 */ 6608 rfi_type = true; 6609 break; 6610 default: 6611 g_assert_not_reached(); 6612 } 6613 6614 gen_debug_exception(ctx, rfi_type); 6615 return; 6616 } 6617 6618 switch (is_jmp) { 6619 case DISAS_TOO_MANY: 6620 if (use_goto_tb(ctx, nip)) { 6621 pmu_count_insns(ctx); 6622 tcg_gen_goto_tb(0); 6623 gen_update_nip(ctx, nip); 6624 tcg_gen_exit_tb(ctx->base.tb, 0); 6625 break; 6626 } 6627 /* fall through */ 6628 case DISAS_CHAIN_UPDATE: 6629 gen_update_nip(ctx, nip); 6630 /* fall through */ 6631 case DISAS_CHAIN: 6632 /* 6633 * tcg_gen_lookup_and_goto_ptr will exit the TB if 6634 * CF_NO_GOTO_PTR is set. Count insns now. 6635 */ 6636 if (ctx->base.tb->flags & CF_NO_GOTO_PTR) { 6637 pmu_count_insns(ctx); 6638 } 6639 6640 tcg_gen_lookup_and_goto_ptr(); 6641 break; 6642 6643 case DISAS_EXIT_UPDATE: 6644 gen_update_nip(ctx, nip); 6645 /* fall through */ 6646 case DISAS_EXIT: 6647 pmu_count_insns(ctx); 6648 tcg_gen_exit_tb(NULL, 0); 6649 break; 6650 6651 default: 6652 g_assert_not_reached(); 6653 } 6654 } 6655 6656 static const TranslatorOps ppc_tr_ops = { 6657 .init_disas_context = ppc_tr_init_disas_context, 6658 .tb_start = ppc_tr_tb_start, 6659 .insn_start = ppc_tr_insn_start, 6660 .translate_insn = ppc_tr_translate_insn, 6661 .tb_stop = ppc_tr_tb_stop, 6662 }; 6663 6664 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns, 6665 vaddr pc, void *host_pc) 6666 { 6667 DisasContext ctx; 6668 6669 translator_loop(cs, tb, max_insns, pc, host_pc, &ppc_tr_ops, &ctx.base); 6670 } 6671