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