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 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 "disas/disas.h" 25 #include "exec/exec-all.h" 26 #include "tcg-op.h" 27 #include "tcg-op-gvec.h" 28 #include "qemu/host-utils.h" 29 #include "exec/cpu_ldst.h" 30 31 #include "exec/helper-proto.h" 32 #include "exec/helper-gen.h" 33 34 #include "trace-tcg.h" 35 #include "exec/translator.h" 36 #include "exec/log.h" 37 #include "qemu/atomic128.h" 38 39 40 #define CPU_SINGLE_STEP 0x1 41 #define CPU_BRANCH_STEP 0x2 42 #define GDBSTUB_SINGLE_STEP 0x4 43 44 /* Include definitions for instructions classes and implementations flags */ 45 /* #define PPC_DEBUG_DISAS */ 46 /* #define DO_PPC_STATISTICS */ 47 48 #ifdef PPC_DEBUG_DISAS 49 # define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__) 50 #else 51 # define LOG_DISAS(...) do { } while (0) 52 #endif 53 /*****************************************************************************/ 54 /* Code translation helpers */ 55 56 /* global register indexes */ 57 static char cpu_reg_names[10 * 3 + 22 * 4 /* GPR */ 58 + 10 * 4 + 22 * 5 /* SPE GPRh */ 59 + 8 * 5 /* CRF */]; 60 static TCGv cpu_gpr[32]; 61 static TCGv cpu_gprh[32]; 62 static TCGv_i32 cpu_crf[8]; 63 static TCGv cpu_nip; 64 static TCGv cpu_msr; 65 static TCGv cpu_ctr; 66 static TCGv cpu_lr; 67 #if defined(TARGET_PPC64) 68 static TCGv cpu_cfar; 69 #endif 70 static TCGv cpu_xer, cpu_so, cpu_ov, cpu_ca, cpu_ov32, cpu_ca32; 71 static TCGv cpu_reserve; 72 static TCGv cpu_reserve_val; 73 static TCGv cpu_fpscr; 74 static TCGv_i32 cpu_access_type; 75 76 #include "exec/gen-icount.h" 77 78 void ppc_translate_init(void) 79 { 80 int i; 81 char *p; 82 size_t cpu_reg_names_size; 83 84 p = cpu_reg_names; 85 cpu_reg_names_size = sizeof(cpu_reg_names); 86 87 for (i = 0; i < 8; i++) { 88 snprintf(p, cpu_reg_names_size, "crf%d", i); 89 cpu_crf[i] = tcg_global_mem_new_i32(cpu_env, 90 offsetof(CPUPPCState, crf[i]), p); 91 p += 5; 92 cpu_reg_names_size -= 5; 93 } 94 95 for (i = 0; i < 32; i++) { 96 snprintf(p, cpu_reg_names_size, "r%d", i); 97 cpu_gpr[i] = tcg_global_mem_new(cpu_env, 98 offsetof(CPUPPCState, gpr[i]), p); 99 p += (i < 10) ? 3 : 4; 100 cpu_reg_names_size -= (i < 10) ? 3 : 4; 101 snprintf(p, cpu_reg_names_size, "r%dH", i); 102 cpu_gprh[i] = tcg_global_mem_new(cpu_env, 103 offsetof(CPUPPCState, gprh[i]), p); 104 p += (i < 10) ? 4 : 5; 105 cpu_reg_names_size -= (i < 10) ? 4 : 5; 106 } 107 108 cpu_nip = tcg_global_mem_new(cpu_env, 109 offsetof(CPUPPCState, nip), "nip"); 110 111 cpu_msr = tcg_global_mem_new(cpu_env, 112 offsetof(CPUPPCState, msr), "msr"); 113 114 cpu_ctr = tcg_global_mem_new(cpu_env, 115 offsetof(CPUPPCState, ctr), "ctr"); 116 117 cpu_lr = tcg_global_mem_new(cpu_env, 118 offsetof(CPUPPCState, lr), "lr"); 119 120 #if defined(TARGET_PPC64) 121 cpu_cfar = tcg_global_mem_new(cpu_env, 122 offsetof(CPUPPCState, cfar), "cfar"); 123 #endif 124 125 cpu_xer = tcg_global_mem_new(cpu_env, 126 offsetof(CPUPPCState, xer), "xer"); 127 cpu_so = tcg_global_mem_new(cpu_env, 128 offsetof(CPUPPCState, so), "SO"); 129 cpu_ov = tcg_global_mem_new(cpu_env, 130 offsetof(CPUPPCState, ov), "OV"); 131 cpu_ca = tcg_global_mem_new(cpu_env, 132 offsetof(CPUPPCState, ca), "CA"); 133 cpu_ov32 = tcg_global_mem_new(cpu_env, 134 offsetof(CPUPPCState, ov32), "OV32"); 135 cpu_ca32 = tcg_global_mem_new(cpu_env, 136 offsetof(CPUPPCState, ca32), "CA32"); 137 138 cpu_reserve = tcg_global_mem_new(cpu_env, 139 offsetof(CPUPPCState, reserve_addr), 140 "reserve_addr"); 141 cpu_reserve_val = tcg_global_mem_new(cpu_env, 142 offsetof(CPUPPCState, reserve_val), 143 "reserve_val"); 144 145 cpu_fpscr = tcg_global_mem_new(cpu_env, 146 offsetof(CPUPPCState, fpscr), "fpscr"); 147 148 cpu_access_type = tcg_global_mem_new_i32(cpu_env, 149 offsetof(CPUPPCState, access_type), 150 "access_type"); 151 } 152 153 /* internal defines */ 154 struct DisasContext { 155 DisasContextBase base; 156 uint32_t opcode; 157 uint32_t exception; 158 /* Routine used to access memory */ 159 bool pr, hv, dr, le_mode; 160 bool lazy_tlb_flush; 161 bool need_access_type; 162 int mem_idx; 163 int access_type; 164 /* Translation flags */ 165 TCGMemOp default_tcg_memop_mask; 166 #if defined(TARGET_PPC64) 167 bool sf_mode; 168 bool has_cfar; 169 #endif 170 bool fpu_enabled; 171 bool altivec_enabled; 172 bool vsx_enabled; 173 bool spe_enabled; 174 bool tm_enabled; 175 bool gtse; 176 ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */ 177 int singlestep_enabled; 178 uint32_t flags; 179 uint64_t insns_flags; 180 uint64_t insns_flags2; 181 }; 182 183 /* Return true iff byteswap is needed in a scalar memop */ 184 static inline bool need_byteswap(const DisasContext *ctx) 185 { 186 #if defined(TARGET_WORDS_BIGENDIAN) 187 return ctx->le_mode; 188 #else 189 return !ctx->le_mode; 190 #endif 191 } 192 193 /* True when active word size < size of target_long. */ 194 #ifdef TARGET_PPC64 195 # define NARROW_MODE(C) (!(C)->sf_mode) 196 #else 197 # define NARROW_MODE(C) 0 198 #endif 199 200 struct opc_handler_t { 201 /* invalid bits for instruction 1 (Rc(opcode) == 0) */ 202 uint32_t inval1; 203 /* invalid bits for instruction 2 (Rc(opcode) == 1) */ 204 uint32_t inval2; 205 /* instruction type */ 206 uint64_t type; 207 /* extended instruction type */ 208 uint64_t type2; 209 /* handler */ 210 void (*handler)(DisasContext *ctx); 211 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU) 212 const char *oname; 213 #endif 214 #if defined(DO_PPC_STATISTICS) 215 uint64_t count; 216 #endif 217 }; 218 219 /* SPR load/store helpers */ 220 static inline void gen_load_spr(TCGv t, int reg) 221 { 222 tcg_gen_ld_tl(t, cpu_env, offsetof(CPUPPCState, spr[reg])); 223 } 224 225 static inline void gen_store_spr(int reg, TCGv t) 226 { 227 tcg_gen_st_tl(t, cpu_env, offsetof(CPUPPCState, spr[reg])); 228 } 229 230 static inline void gen_set_access_type(DisasContext *ctx, int access_type) 231 { 232 if (ctx->need_access_type && ctx->access_type != access_type) { 233 tcg_gen_movi_i32(cpu_access_type, access_type); 234 ctx->access_type = access_type; 235 } 236 } 237 238 static inline void gen_update_nip(DisasContext *ctx, target_ulong nip) 239 { 240 if (NARROW_MODE(ctx)) { 241 nip = (uint32_t)nip; 242 } 243 tcg_gen_movi_tl(cpu_nip, nip); 244 } 245 246 static void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error) 247 { 248 TCGv_i32 t0, t1; 249 250 /* 251 * These are all synchronous exceptions, we set the PC back to the 252 * faulting instruction 253 */ 254 if (ctx->exception == POWERPC_EXCP_NONE) { 255 gen_update_nip(ctx, ctx->base.pc_next - 4); 256 } 257 t0 = tcg_const_i32(excp); 258 t1 = tcg_const_i32(error); 259 gen_helper_raise_exception_err(cpu_env, t0, t1); 260 tcg_temp_free_i32(t0); 261 tcg_temp_free_i32(t1); 262 ctx->exception = (excp); 263 } 264 265 static void gen_exception(DisasContext *ctx, uint32_t excp) 266 { 267 TCGv_i32 t0; 268 269 /* 270 * These are all synchronous exceptions, we set the PC back to the 271 * faulting instruction 272 */ 273 if (ctx->exception == POWERPC_EXCP_NONE) { 274 gen_update_nip(ctx, ctx->base.pc_next - 4); 275 } 276 t0 = tcg_const_i32(excp); 277 gen_helper_raise_exception(cpu_env, t0); 278 tcg_temp_free_i32(t0); 279 ctx->exception = (excp); 280 } 281 282 static void gen_exception_nip(DisasContext *ctx, uint32_t excp, 283 target_ulong nip) 284 { 285 TCGv_i32 t0; 286 287 gen_update_nip(ctx, nip); 288 t0 = tcg_const_i32(excp); 289 gen_helper_raise_exception(cpu_env, t0); 290 tcg_temp_free_i32(t0); 291 ctx->exception = (excp); 292 } 293 294 /* 295 * Tells the caller what is the appropriate exception to generate and prepares 296 * SPR registers for this exception. 297 * 298 * The exception can be either POWERPC_EXCP_TRACE (on most PowerPCs) or 299 * POWERPC_EXCP_DEBUG (on BookE). 300 */ 301 static uint32_t gen_prep_dbgex(DisasContext *ctx) 302 { 303 if (ctx->flags & POWERPC_FLAG_DE) { 304 target_ulong dbsr = 0; 305 if (ctx->singlestep_enabled & CPU_SINGLE_STEP) { 306 dbsr = DBCR0_ICMP; 307 } else { 308 /* Must have been branch */ 309 dbsr = DBCR0_BRT; 310 } 311 TCGv t0 = tcg_temp_new(); 312 gen_load_spr(t0, SPR_BOOKE_DBSR); 313 tcg_gen_ori_tl(t0, t0, dbsr); 314 gen_store_spr(SPR_BOOKE_DBSR, t0); 315 tcg_temp_free(t0); 316 return POWERPC_EXCP_DEBUG; 317 } else { 318 return POWERPC_EXCP_TRACE; 319 } 320 } 321 322 static void gen_debug_exception(DisasContext *ctx) 323 { 324 TCGv_i32 t0; 325 326 /* 327 * These are all synchronous exceptions, we set the PC back to the 328 * faulting instruction 329 */ 330 if ((ctx->exception != POWERPC_EXCP_BRANCH) && 331 (ctx->exception != POWERPC_EXCP_SYNC)) { 332 gen_update_nip(ctx, ctx->base.pc_next); 333 } 334 t0 = tcg_const_i32(EXCP_DEBUG); 335 gen_helper_raise_exception(cpu_env, t0); 336 tcg_temp_free_i32(t0); 337 } 338 339 static inline void gen_inval_exception(DisasContext *ctx, uint32_t error) 340 { 341 /* Will be converted to program check if needed */ 342 gen_exception_err(ctx, POWERPC_EXCP_HV_EMU, POWERPC_EXCP_INVAL | error); 343 } 344 345 static inline void gen_priv_exception(DisasContext *ctx, uint32_t error) 346 { 347 gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_PRIV | error); 348 } 349 350 static inline void gen_hvpriv_exception(DisasContext *ctx, uint32_t error) 351 { 352 /* Will be converted to program check if needed */ 353 gen_exception_err(ctx, POWERPC_EXCP_HV_EMU, POWERPC_EXCP_PRIV | error); 354 } 355 356 /* Stop translation */ 357 static inline void gen_stop_exception(DisasContext *ctx) 358 { 359 gen_update_nip(ctx, ctx->base.pc_next); 360 ctx->exception = POWERPC_EXCP_STOP; 361 } 362 363 #ifndef CONFIG_USER_ONLY 364 /* No need to update nip here, as execution flow will change */ 365 static inline void gen_sync_exception(DisasContext *ctx) 366 { 367 ctx->exception = POWERPC_EXCP_SYNC; 368 } 369 #endif 370 371 #define GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \ 372 GEN_OPCODE(name, opc1, opc2, opc3, inval, type, PPC_NONE) 373 374 #define GEN_HANDLER_E(name, opc1, opc2, opc3, inval, type, type2) \ 375 GEN_OPCODE(name, opc1, opc2, opc3, inval, type, type2) 376 377 #define GEN_HANDLER2(name, onam, opc1, opc2, opc3, inval, type) \ 378 GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, PPC_NONE) 379 380 #define GEN_HANDLER2_E(name, onam, opc1, opc2, opc3, inval, type, type2) \ 381 GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, type2) 382 383 #define GEN_HANDLER_E_2(name, opc1, opc2, opc3, opc4, inval, type, type2) \ 384 GEN_OPCODE3(name, opc1, opc2, opc3, opc4, inval, type, type2) 385 386 #define GEN_HANDLER2_E_2(name, onam, opc1, opc2, opc3, opc4, inval, typ, typ2) \ 387 GEN_OPCODE4(name, onam, opc1, opc2, opc3, opc4, inval, typ, typ2) 388 389 typedef struct opcode_t { 390 unsigned char opc1, opc2, opc3, opc4; 391 #if HOST_LONG_BITS == 64 /* Explicitly align to 64 bits */ 392 unsigned char pad[4]; 393 #endif 394 opc_handler_t handler; 395 const char *oname; 396 } opcode_t; 397 398 /* Helpers for priv. check */ 399 #define GEN_PRIV \ 400 do { \ 401 gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC); return; \ 402 } while (0) 403 404 #if defined(CONFIG_USER_ONLY) 405 #define CHK_HV GEN_PRIV 406 #define CHK_SV GEN_PRIV 407 #define CHK_HVRM GEN_PRIV 408 #else 409 #define CHK_HV \ 410 do { \ 411 if (unlikely(ctx->pr || !ctx->hv)) { \ 412 GEN_PRIV; \ 413 } \ 414 } while (0) 415 #define CHK_SV \ 416 do { \ 417 if (unlikely(ctx->pr)) { \ 418 GEN_PRIV; \ 419 } \ 420 } while (0) 421 #define CHK_HVRM \ 422 do { \ 423 if (unlikely(ctx->pr || !ctx->hv || ctx->dr)) { \ 424 GEN_PRIV; \ 425 } \ 426 } while (0) 427 #endif 428 429 #define CHK_NONE 430 431 /*****************************************************************************/ 432 /* PowerPC instructions table */ 433 434 #if defined(DO_PPC_STATISTICS) 435 #define GEN_OPCODE(name, op1, op2, op3, invl, _typ, _typ2) \ 436 { \ 437 .opc1 = op1, \ 438 .opc2 = op2, \ 439 .opc3 = op3, \ 440 .opc4 = 0xff, \ 441 .handler = { \ 442 .inval1 = invl, \ 443 .type = _typ, \ 444 .type2 = _typ2, \ 445 .handler = &gen_##name, \ 446 .oname = stringify(name), \ 447 }, \ 448 .oname = stringify(name), \ 449 } 450 #define GEN_OPCODE_DUAL(name, op1, op2, op3, invl1, invl2, _typ, _typ2) \ 451 { \ 452 .opc1 = op1, \ 453 .opc2 = op2, \ 454 .opc3 = op3, \ 455 .opc4 = 0xff, \ 456 .handler = { \ 457 .inval1 = invl1, \ 458 .inval2 = invl2, \ 459 .type = _typ, \ 460 .type2 = _typ2, \ 461 .handler = &gen_##name, \ 462 .oname = stringify(name), \ 463 }, \ 464 .oname = stringify(name), \ 465 } 466 #define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ, _typ2) \ 467 { \ 468 .opc1 = op1, \ 469 .opc2 = op2, \ 470 .opc3 = op3, \ 471 .opc4 = 0xff, \ 472 .handler = { \ 473 .inval1 = invl, \ 474 .type = _typ, \ 475 .type2 = _typ2, \ 476 .handler = &gen_##name, \ 477 .oname = onam, \ 478 }, \ 479 .oname = onam, \ 480 } 481 #define GEN_OPCODE3(name, op1, op2, op3, op4, invl, _typ, _typ2) \ 482 { \ 483 .opc1 = op1, \ 484 .opc2 = op2, \ 485 .opc3 = op3, \ 486 .opc4 = op4, \ 487 .handler = { \ 488 .inval1 = invl, \ 489 .type = _typ, \ 490 .type2 = _typ2, \ 491 .handler = &gen_##name, \ 492 .oname = stringify(name), \ 493 }, \ 494 .oname = stringify(name), \ 495 } 496 #define GEN_OPCODE4(name, onam, op1, op2, op3, op4, invl, _typ, _typ2) \ 497 { \ 498 .opc1 = op1, \ 499 .opc2 = op2, \ 500 .opc3 = op3, \ 501 .opc4 = op4, \ 502 .handler = { \ 503 .inval1 = invl, \ 504 .type = _typ, \ 505 .type2 = _typ2, \ 506 .handler = &gen_##name, \ 507 .oname = onam, \ 508 }, \ 509 .oname = onam, \ 510 } 511 #else 512 #define GEN_OPCODE(name, op1, op2, op3, invl, _typ, _typ2) \ 513 { \ 514 .opc1 = op1, \ 515 .opc2 = op2, \ 516 .opc3 = op3, \ 517 .opc4 = 0xff, \ 518 .handler = { \ 519 .inval1 = invl, \ 520 .type = _typ, \ 521 .type2 = _typ2, \ 522 .handler = &gen_##name, \ 523 }, \ 524 .oname = stringify(name), \ 525 } 526 #define GEN_OPCODE_DUAL(name, op1, op2, op3, invl1, invl2, _typ, _typ2) \ 527 { \ 528 .opc1 = op1, \ 529 .opc2 = op2, \ 530 .opc3 = op3, \ 531 .opc4 = 0xff, \ 532 .handler = { \ 533 .inval1 = invl1, \ 534 .inval2 = invl2, \ 535 .type = _typ, \ 536 .type2 = _typ2, \ 537 .handler = &gen_##name, \ 538 }, \ 539 .oname = stringify(name), \ 540 } 541 #define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ, _typ2) \ 542 { \ 543 .opc1 = op1, \ 544 .opc2 = op2, \ 545 .opc3 = op3, \ 546 .opc4 = 0xff, \ 547 .handler = { \ 548 .inval1 = invl, \ 549 .type = _typ, \ 550 .type2 = _typ2, \ 551 .handler = &gen_##name, \ 552 }, \ 553 .oname = onam, \ 554 } 555 #define GEN_OPCODE3(name, op1, op2, op3, op4, invl, _typ, _typ2) \ 556 { \ 557 .opc1 = op1, \ 558 .opc2 = op2, \ 559 .opc3 = op3, \ 560 .opc4 = op4, \ 561 .handler = { \ 562 .inval1 = invl, \ 563 .type = _typ, \ 564 .type2 = _typ2, \ 565 .handler = &gen_##name, \ 566 }, \ 567 .oname = stringify(name), \ 568 } 569 #define GEN_OPCODE4(name, onam, op1, op2, op3, op4, invl, _typ, _typ2) \ 570 { \ 571 .opc1 = op1, \ 572 .opc2 = op2, \ 573 .opc3 = op3, \ 574 .opc4 = op4, \ 575 .handler = { \ 576 .inval1 = invl, \ 577 .type = _typ, \ 578 .type2 = _typ2, \ 579 .handler = &gen_##name, \ 580 }, \ 581 .oname = onam, \ 582 } 583 #endif 584 585 /* Invalid instruction */ 586 static void gen_invalid(DisasContext *ctx) 587 { 588 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 589 } 590 591 static opc_handler_t invalid_handler = { 592 .inval1 = 0xFFFFFFFF, 593 .inval2 = 0xFFFFFFFF, 594 .type = PPC_NONE, 595 .type2 = PPC_NONE, 596 .handler = gen_invalid, 597 }; 598 599 /*** Integer comparison ***/ 600 601 static inline void gen_op_cmp(TCGv arg0, TCGv arg1, int s, int crf) 602 { 603 TCGv t0 = tcg_temp_new(); 604 TCGv t1 = tcg_temp_new(); 605 TCGv_i32 t = tcg_temp_new_i32(); 606 607 tcg_gen_movi_tl(t0, CRF_EQ); 608 tcg_gen_movi_tl(t1, CRF_LT); 609 tcg_gen_movcond_tl((s ? TCG_COND_LT : TCG_COND_LTU), 610 t0, arg0, arg1, t1, t0); 611 tcg_gen_movi_tl(t1, CRF_GT); 612 tcg_gen_movcond_tl((s ? TCG_COND_GT : TCG_COND_GTU), 613 t0, arg0, arg1, t1, t0); 614 615 tcg_gen_trunc_tl_i32(t, t0); 616 tcg_gen_trunc_tl_i32(cpu_crf[crf], cpu_so); 617 tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t); 618 619 tcg_temp_free(t0); 620 tcg_temp_free(t1); 621 tcg_temp_free_i32(t); 622 } 623 624 static inline void gen_op_cmpi(TCGv arg0, target_ulong arg1, int s, int crf) 625 { 626 TCGv t0 = tcg_const_tl(arg1); 627 gen_op_cmp(arg0, t0, s, crf); 628 tcg_temp_free(t0); 629 } 630 631 static inline void gen_op_cmp32(TCGv arg0, TCGv arg1, int s, int crf) 632 { 633 TCGv t0, t1; 634 t0 = tcg_temp_new(); 635 t1 = tcg_temp_new(); 636 if (s) { 637 tcg_gen_ext32s_tl(t0, arg0); 638 tcg_gen_ext32s_tl(t1, arg1); 639 } else { 640 tcg_gen_ext32u_tl(t0, arg0); 641 tcg_gen_ext32u_tl(t1, arg1); 642 } 643 gen_op_cmp(t0, t1, s, crf); 644 tcg_temp_free(t1); 645 tcg_temp_free(t0); 646 } 647 648 static inline void gen_op_cmpi32(TCGv arg0, target_ulong arg1, int s, int crf) 649 { 650 TCGv t0 = tcg_const_tl(arg1); 651 gen_op_cmp32(arg0, t0, s, crf); 652 tcg_temp_free(t0); 653 } 654 655 static inline void gen_set_Rc0(DisasContext *ctx, TCGv reg) 656 { 657 if (NARROW_MODE(ctx)) { 658 gen_op_cmpi32(reg, 0, 1, 0); 659 } else { 660 gen_op_cmpi(reg, 0, 1, 0); 661 } 662 } 663 664 /* cmp */ 665 static void gen_cmp(DisasContext *ctx) 666 { 667 if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) { 668 gen_op_cmp(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], 669 1, crfD(ctx->opcode)); 670 } else { 671 gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], 672 1, crfD(ctx->opcode)); 673 } 674 } 675 676 /* cmpi */ 677 static void gen_cmpi(DisasContext *ctx) 678 { 679 if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) { 680 gen_op_cmpi(cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode), 681 1, crfD(ctx->opcode)); 682 } else { 683 gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode), 684 1, crfD(ctx->opcode)); 685 } 686 } 687 688 /* cmpl */ 689 static void gen_cmpl(DisasContext *ctx) 690 { 691 if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) { 692 gen_op_cmp(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], 693 0, crfD(ctx->opcode)); 694 } else { 695 gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], 696 0, crfD(ctx->opcode)); 697 } 698 } 699 700 /* cmpli */ 701 static void gen_cmpli(DisasContext *ctx) 702 { 703 if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) { 704 gen_op_cmpi(cpu_gpr[rA(ctx->opcode)], UIMM(ctx->opcode), 705 0, crfD(ctx->opcode)); 706 } else { 707 gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], UIMM(ctx->opcode), 708 0, crfD(ctx->opcode)); 709 } 710 } 711 712 /* cmprb - range comparison: isupper, isaplha, islower*/ 713 static void gen_cmprb(DisasContext *ctx) 714 { 715 TCGv_i32 src1 = tcg_temp_new_i32(); 716 TCGv_i32 src2 = tcg_temp_new_i32(); 717 TCGv_i32 src2lo = tcg_temp_new_i32(); 718 TCGv_i32 src2hi = tcg_temp_new_i32(); 719 TCGv_i32 crf = cpu_crf[crfD(ctx->opcode)]; 720 721 tcg_gen_trunc_tl_i32(src1, cpu_gpr[rA(ctx->opcode)]); 722 tcg_gen_trunc_tl_i32(src2, cpu_gpr[rB(ctx->opcode)]); 723 724 tcg_gen_andi_i32(src1, src1, 0xFF); 725 tcg_gen_ext8u_i32(src2lo, src2); 726 tcg_gen_shri_i32(src2, src2, 8); 727 tcg_gen_ext8u_i32(src2hi, src2); 728 729 tcg_gen_setcond_i32(TCG_COND_LEU, src2lo, src2lo, src1); 730 tcg_gen_setcond_i32(TCG_COND_LEU, src2hi, src1, src2hi); 731 tcg_gen_and_i32(crf, src2lo, src2hi); 732 733 if (ctx->opcode & 0x00200000) { 734 tcg_gen_shri_i32(src2, src2, 8); 735 tcg_gen_ext8u_i32(src2lo, src2); 736 tcg_gen_shri_i32(src2, src2, 8); 737 tcg_gen_ext8u_i32(src2hi, src2); 738 tcg_gen_setcond_i32(TCG_COND_LEU, src2lo, src2lo, src1); 739 tcg_gen_setcond_i32(TCG_COND_LEU, src2hi, src1, src2hi); 740 tcg_gen_and_i32(src2lo, src2lo, src2hi); 741 tcg_gen_or_i32(crf, crf, src2lo); 742 } 743 tcg_gen_shli_i32(crf, crf, CRF_GT_BIT); 744 tcg_temp_free_i32(src1); 745 tcg_temp_free_i32(src2); 746 tcg_temp_free_i32(src2lo); 747 tcg_temp_free_i32(src2hi); 748 } 749 750 #if defined(TARGET_PPC64) 751 /* cmpeqb */ 752 static void gen_cmpeqb(DisasContext *ctx) 753 { 754 gen_helper_cmpeqb(cpu_crf[crfD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 755 cpu_gpr[rB(ctx->opcode)]); 756 } 757 #endif 758 759 /* isel (PowerPC 2.03 specification) */ 760 static void gen_isel(DisasContext *ctx) 761 { 762 uint32_t bi = rC(ctx->opcode); 763 uint32_t mask = 0x08 >> (bi & 0x03); 764 TCGv t0 = tcg_temp_new(); 765 TCGv zr; 766 767 tcg_gen_extu_i32_tl(t0, cpu_crf[bi >> 2]); 768 tcg_gen_andi_tl(t0, t0, mask); 769 770 zr = tcg_const_tl(0); 771 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rD(ctx->opcode)], t0, zr, 772 rA(ctx->opcode) ? cpu_gpr[rA(ctx->opcode)] : zr, 773 cpu_gpr[rB(ctx->opcode)]); 774 tcg_temp_free(zr); 775 tcg_temp_free(t0); 776 } 777 778 /* cmpb: PowerPC 2.05 specification */ 779 static void gen_cmpb(DisasContext *ctx) 780 { 781 gen_helper_cmpb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], 782 cpu_gpr[rB(ctx->opcode)]); 783 } 784 785 /*** Integer arithmetic ***/ 786 787 static inline void gen_op_arith_compute_ov(DisasContext *ctx, TCGv arg0, 788 TCGv arg1, TCGv arg2, int sub) 789 { 790 TCGv t0 = tcg_temp_new(); 791 792 tcg_gen_xor_tl(cpu_ov, arg0, arg2); 793 tcg_gen_xor_tl(t0, arg1, arg2); 794 if (sub) { 795 tcg_gen_and_tl(cpu_ov, cpu_ov, t0); 796 } else { 797 tcg_gen_andc_tl(cpu_ov, cpu_ov, t0); 798 } 799 tcg_temp_free(t0); 800 if (NARROW_MODE(ctx)) { 801 tcg_gen_extract_tl(cpu_ov, cpu_ov, 31, 1); 802 if (is_isa300(ctx)) { 803 tcg_gen_mov_tl(cpu_ov32, cpu_ov); 804 } 805 } else { 806 if (is_isa300(ctx)) { 807 tcg_gen_extract_tl(cpu_ov32, cpu_ov, 31, 1); 808 } 809 tcg_gen_extract_tl(cpu_ov, cpu_ov, TARGET_LONG_BITS - 1, 1); 810 } 811 tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov); 812 } 813 814 static inline void gen_op_arith_compute_ca32(DisasContext *ctx, 815 TCGv res, TCGv arg0, TCGv arg1, 816 TCGv ca32, int sub) 817 { 818 TCGv t0; 819 820 if (!is_isa300(ctx)) { 821 return; 822 } 823 824 t0 = tcg_temp_new(); 825 if (sub) { 826 tcg_gen_eqv_tl(t0, arg0, arg1); 827 } else { 828 tcg_gen_xor_tl(t0, arg0, arg1); 829 } 830 tcg_gen_xor_tl(t0, t0, res); 831 tcg_gen_extract_tl(ca32, t0, 32, 1); 832 tcg_temp_free(t0); 833 } 834 835 /* Common add function */ 836 static inline void gen_op_arith_add(DisasContext *ctx, TCGv ret, TCGv arg1, 837 TCGv arg2, TCGv ca, TCGv ca32, 838 bool add_ca, bool compute_ca, 839 bool compute_ov, bool compute_rc0) 840 { 841 TCGv t0 = ret; 842 843 if (compute_ca || compute_ov) { 844 t0 = tcg_temp_new(); 845 } 846 847 if (compute_ca) { 848 if (NARROW_MODE(ctx)) { 849 /* 850 * Caution: a non-obvious corner case of the spec is that 851 * we must produce the *entire* 64-bit addition, but 852 * produce the carry into bit 32. 853 */ 854 TCGv t1 = tcg_temp_new(); 855 tcg_gen_xor_tl(t1, arg1, arg2); /* add without carry */ 856 tcg_gen_add_tl(t0, arg1, arg2); 857 if (add_ca) { 858 tcg_gen_add_tl(t0, t0, ca); 859 } 860 tcg_gen_xor_tl(ca, t0, t1); /* bits changed w/ carry */ 861 tcg_temp_free(t1); 862 tcg_gen_extract_tl(ca, ca, 32, 1); 863 if (is_isa300(ctx)) { 864 tcg_gen_mov_tl(ca32, ca); 865 } 866 } else { 867 TCGv zero = tcg_const_tl(0); 868 if (add_ca) { 869 tcg_gen_add2_tl(t0, ca, arg1, zero, ca, zero); 870 tcg_gen_add2_tl(t0, ca, t0, ca, arg2, zero); 871 } else { 872 tcg_gen_add2_tl(t0, ca, arg1, zero, arg2, zero); 873 } 874 gen_op_arith_compute_ca32(ctx, t0, arg1, arg2, ca32, 0); 875 tcg_temp_free(zero); 876 } 877 } else { 878 tcg_gen_add_tl(t0, arg1, arg2); 879 if (add_ca) { 880 tcg_gen_add_tl(t0, t0, ca); 881 } 882 } 883 884 if (compute_ov) { 885 gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 0); 886 } 887 if (unlikely(compute_rc0)) { 888 gen_set_Rc0(ctx, t0); 889 } 890 891 if (t0 != ret) { 892 tcg_gen_mov_tl(ret, t0); 893 tcg_temp_free(t0); 894 } 895 } 896 /* Add functions with two operands */ 897 #define GEN_INT_ARITH_ADD(name, opc3, ca, add_ca, compute_ca, compute_ov) \ 898 static void glue(gen_, name)(DisasContext *ctx) \ 899 { \ 900 gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)], \ 901 cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \ 902 ca, glue(ca, 32), \ 903 add_ca, compute_ca, compute_ov, Rc(ctx->opcode)); \ 904 } 905 /* Add functions with one operand and one immediate */ 906 #define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val, ca, \ 907 add_ca, compute_ca, compute_ov) \ 908 static void glue(gen_, name)(DisasContext *ctx) \ 909 { \ 910 TCGv t0 = tcg_const_tl(const_val); \ 911 gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)], \ 912 cpu_gpr[rA(ctx->opcode)], t0, \ 913 ca, glue(ca, 32), \ 914 add_ca, compute_ca, compute_ov, Rc(ctx->opcode)); \ 915 tcg_temp_free(t0); \ 916 } 917 918 /* add add. addo addo. */ 919 GEN_INT_ARITH_ADD(add, 0x08, cpu_ca, 0, 0, 0) 920 GEN_INT_ARITH_ADD(addo, 0x18, cpu_ca, 0, 0, 1) 921 /* addc addc. addco addco. */ 922 GEN_INT_ARITH_ADD(addc, 0x00, cpu_ca, 0, 1, 0) 923 GEN_INT_ARITH_ADD(addco, 0x10, cpu_ca, 0, 1, 1) 924 /* adde adde. addeo addeo. */ 925 GEN_INT_ARITH_ADD(adde, 0x04, cpu_ca, 1, 1, 0) 926 GEN_INT_ARITH_ADD(addeo, 0x14, cpu_ca, 1, 1, 1) 927 /* addme addme. addmeo addmeo. */ 928 GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, cpu_ca, 1, 1, 0) 929 GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, cpu_ca, 1, 1, 1) 930 /* addex */ 931 GEN_INT_ARITH_ADD(addex, 0x05, cpu_ov, 1, 1, 0); 932 /* addze addze. addzeo addzeo.*/ 933 GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, cpu_ca, 1, 1, 0) 934 GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, cpu_ca, 1, 1, 1) 935 /* addi */ 936 static void gen_addi(DisasContext *ctx) 937 { 938 target_long simm = SIMM(ctx->opcode); 939 940 if (rA(ctx->opcode) == 0) { 941 /* li case */ 942 tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], simm); 943 } else { 944 tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)], 945 cpu_gpr[rA(ctx->opcode)], simm); 946 } 947 } 948 /* addic addic.*/ 949 static inline void gen_op_addic(DisasContext *ctx, bool compute_rc0) 950 { 951 TCGv c = tcg_const_tl(SIMM(ctx->opcode)); 952 gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 953 c, cpu_ca, cpu_ca32, 0, 1, 0, compute_rc0); 954 tcg_temp_free(c); 955 } 956 957 static void gen_addic(DisasContext *ctx) 958 { 959 gen_op_addic(ctx, 0); 960 } 961 962 static void gen_addic_(DisasContext *ctx) 963 { 964 gen_op_addic(ctx, 1); 965 } 966 967 /* addis */ 968 static void gen_addis(DisasContext *ctx) 969 { 970 target_long simm = SIMM(ctx->opcode); 971 972 if (rA(ctx->opcode) == 0) { 973 /* lis case */ 974 tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], simm << 16); 975 } else { 976 tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)], 977 cpu_gpr[rA(ctx->opcode)], simm << 16); 978 } 979 } 980 981 /* addpcis */ 982 static void gen_addpcis(DisasContext *ctx) 983 { 984 target_long d = DX(ctx->opcode); 985 986 tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], ctx->base.pc_next + (d << 16)); 987 } 988 989 static inline void gen_op_arith_divw(DisasContext *ctx, TCGv ret, TCGv arg1, 990 TCGv arg2, int sign, int compute_ov) 991 { 992 TCGv_i32 t0 = tcg_temp_new_i32(); 993 TCGv_i32 t1 = tcg_temp_new_i32(); 994 TCGv_i32 t2 = tcg_temp_new_i32(); 995 TCGv_i32 t3 = tcg_temp_new_i32(); 996 997 tcg_gen_trunc_tl_i32(t0, arg1); 998 tcg_gen_trunc_tl_i32(t1, arg2); 999 if (sign) { 1000 tcg_gen_setcondi_i32(TCG_COND_EQ, t2, t0, INT_MIN); 1001 tcg_gen_setcondi_i32(TCG_COND_EQ, t3, t1, -1); 1002 tcg_gen_and_i32(t2, t2, t3); 1003 tcg_gen_setcondi_i32(TCG_COND_EQ, t3, t1, 0); 1004 tcg_gen_or_i32(t2, t2, t3); 1005 tcg_gen_movi_i32(t3, 0); 1006 tcg_gen_movcond_i32(TCG_COND_NE, t1, t2, t3, t2, t1); 1007 tcg_gen_div_i32(t3, t0, t1); 1008 tcg_gen_extu_i32_tl(ret, t3); 1009 } else { 1010 tcg_gen_setcondi_i32(TCG_COND_EQ, t2, t1, 0); 1011 tcg_gen_movi_i32(t3, 0); 1012 tcg_gen_movcond_i32(TCG_COND_NE, t1, t2, t3, t2, t1); 1013 tcg_gen_divu_i32(t3, t0, t1); 1014 tcg_gen_extu_i32_tl(ret, t3); 1015 } 1016 if (compute_ov) { 1017 tcg_gen_extu_i32_tl(cpu_ov, t2); 1018 if (is_isa300(ctx)) { 1019 tcg_gen_extu_i32_tl(cpu_ov32, t2); 1020 } 1021 tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov); 1022 } 1023 tcg_temp_free_i32(t0); 1024 tcg_temp_free_i32(t1); 1025 tcg_temp_free_i32(t2); 1026 tcg_temp_free_i32(t3); 1027 1028 if (unlikely(Rc(ctx->opcode) != 0)) { 1029 gen_set_Rc0(ctx, ret); 1030 } 1031 } 1032 /* Div functions */ 1033 #define GEN_INT_ARITH_DIVW(name, opc3, sign, compute_ov) \ 1034 static void glue(gen_, name)(DisasContext *ctx) \ 1035 { \ 1036 gen_op_arith_divw(ctx, cpu_gpr[rD(ctx->opcode)], \ 1037 cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \ 1038 sign, compute_ov); \ 1039 } 1040 /* divwu divwu. divwuo divwuo. */ 1041 GEN_INT_ARITH_DIVW(divwu, 0x0E, 0, 0); 1042 GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1); 1043 /* divw divw. divwo divwo. */ 1044 GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0); 1045 GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1); 1046 1047 /* div[wd]eu[o][.] */ 1048 #define GEN_DIVE(name, hlpr, compute_ov) \ 1049 static void gen_##name(DisasContext *ctx) \ 1050 { \ 1051 TCGv_i32 t0 = tcg_const_i32(compute_ov); \ 1052 gen_helper_##hlpr(cpu_gpr[rD(ctx->opcode)], cpu_env, \ 1053 cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], t0); \ 1054 tcg_temp_free_i32(t0); \ 1055 if (unlikely(Rc(ctx->opcode) != 0)) { \ 1056 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); \ 1057 } \ 1058 } 1059 1060 GEN_DIVE(divweu, divweu, 0); 1061 GEN_DIVE(divweuo, divweu, 1); 1062 GEN_DIVE(divwe, divwe, 0); 1063 GEN_DIVE(divweo, divwe, 1); 1064 1065 #if defined(TARGET_PPC64) 1066 static inline void gen_op_arith_divd(DisasContext *ctx, TCGv ret, TCGv arg1, 1067 TCGv arg2, int sign, int compute_ov) 1068 { 1069 TCGv_i64 t0 = tcg_temp_new_i64(); 1070 TCGv_i64 t1 = tcg_temp_new_i64(); 1071 TCGv_i64 t2 = tcg_temp_new_i64(); 1072 TCGv_i64 t3 = tcg_temp_new_i64(); 1073 1074 tcg_gen_mov_i64(t0, arg1); 1075 tcg_gen_mov_i64(t1, arg2); 1076 if (sign) { 1077 tcg_gen_setcondi_i64(TCG_COND_EQ, t2, t0, INT64_MIN); 1078 tcg_gen_setcondi_i64(TCG_COND_EQ, t3, t1, -1); 1079 tcg_gen_and_i64(t2, t2, t3); 1080 tcg_gen_setcondi_i64(TCG_COND_EQ, t3, t1, 0); 1081 tcg_gen_or_i64(t2, t2, t3); 1082 tcg_gen_movi_i64(t3, 0); 1083 tcg_gen_movcond_i64(TCG_COND_NE, t1, t2, t3, t2, t1); 1084 tcg_gen_div_i64(ret, t0, t1); 1085 } else { 1086 tcg_gen_setcondi_i64(TCG_COND_EQ, t2, t1, 0); 1087 tcg_gen_movi_i64(t3, 0); 1088 tcg_gen_movcond_i64(TCG_COND_NE, t1, t2, t3, t2, t1); 1089 tcg_gen_divu_i64(ret, t0, t1); 1090 } 1091 if (compute_ov) { 1092 tcg_gen_mov_tl(cpu_ov, t2); 1093 if (is_isa300(ctx)) { 1094 tcg_gen_mov_tl(cpu_ov32, t2); 1095 } 1096 tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov); 1097 } 1098 tcg_temp_free_i64(t0); 1099 tcg_temp_free_i64(t1); 1100 tcg_temp_free_i64(t2); 1101 tcg_temp_free_i64(t3); 1102 1103 if (unlikely(Rc(ctx->opcode) != 0)) { 1104 gen_set_Rc0(ctx, ret); 1105 } 1106 } 1107 1108 #define GEN_INT_ARITH_DIVD(name, opc3, sign, compute_ov) \ 1109 static void glue(gen_, name)(DisasContext *ctx) \ 1110 { \ 1111 gen_op_arith_divd(ctx, cpu_gpr[rD(ctx->opcode)], \ 1112 cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \ 1113 sign, compute_ov); \ 1114 } 1115 /* divdu divdu. divduo divduo. */ 1116 GEN_INT_ARITH_DIVD(divdu, 0x0E, 0, 0); 1117 GEN_INT_ARITH_DIVD(divduo, 0x1E, 0, 1); 1118 /* divd divd. divdo divdo. */ 1119 GEN_INT_ARITH_DIVD(divd, 0x0F, 1, 0); 1120 GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1); 1121 1122 GEN_DIVE(divdeu, divdeu, 0); 1123 GEN_DIVE(divdeuo, divdeu, 1); 1124 GEN_DIVE(divde, divde, 0); 1125 GEN_DIVE(divdeo, divde, 1); 1126 #endif 1127 1128 static inline void gen_op_arith_modw(DisasContext *ctx, TCGv ret, TCGv arg1, 1129 TCGv arg2, int sign) 1130 { 1131 TCGv_i32 t0 = tcg_temp_new_i32(); 1132 TCGv_i32 t1 = tcg_temp_new_i32(); 1133 1134 tcg_gen_trunc_tl_i32(t0, arg1); 1135 tcg_gen_trunc_tl_i32(t1, arg2); 1136 if (sign) { 1137 TCGv_i32 t2 = tcg_temp_new_i32(); 1138 TCGv_i32 t3 = tcg_temp_new_i32(); 1139 tcg_gen_setcondi_i32(TCG_COND_EQ, t2, t0, INT_MIN); 1140 tcg_gen_setcondi_i32(TCG_COND_EQ, t3, t1, -1); 1141 tcg_gen_and_i32(t2, t2, t3); 1142 tcg_gen_setcondi_i32(TCG_COND_EQ, t3, t1, 0); 1143 tcg_gen_or_i32(t2, t2, t3); 1144 tcg_gen_movi_i32(t3, 0); 1145 tcg_gen_movcond_i32(TCG_COND_NE, t1, t2, t3, t2, t1); 1146 tcg_gen_rem_i32(t3, t0, t1); 1147 tcg_gen_ext_i32_tl(ret, t3); 1148 tcg_temp_free_i32(t2); 1149 tcg_temp_free_i32(t3); 1150 } else { 1151 TCGv_i32 t2 = tcg_const_i32(1); 1152 TCGv_i32 t3 = tcg_const_i32(0); 1153 tcg_gen_movcond_i32(TCG_COND_EQ, t1, t1, t3, t2, t1); 1154 tcg_gen_remu_i32(t3, t0, t1); 1155 tcg_gen_extu_i32_tl(ret, t3); 1156 tcg_temp_free_i32(t2); 1157 tcg_temp_free_i32(t3); 1158 } 1159 tcg_temp_free_i32(t0); 1160 tcg_temp_free_i32(t1); 1161 } 1162 1163 #define GEN_INT_ARITH_MODW(name, opc3, sign) \ 1164 static void glue(gen_, name)(DisasContext *ctx) \ 1165 { \ 1166 gen_op_arith_modw(ctx, cpu_gpr[rD(ctx->opcode)], \ 1167 cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \ 1168 sign); \ 1169 } 1170 1171 GEN_INT_ARITH_MODW(moduw, 0x08, 0); 1172 GEN_INT_ARITH_MODW(modsw, 0x18, 1); 1173 1174 #if defined(TARGET_PPC64) 1175 static inline void gen_op_arith_modd(DisasContext *ctx, TCGv ret, TCGv arg1, 1176 TCGv arg2, int sign) 1177 { 1178 TCGv_i64 t0 = tcg_temp_new_i64(); 1179 TCGv_i64 t1 = tcg_temp_new_i64(); 1180 1181 tcg_gen_mov_i64(t0, arg1); 1182 tcg_gen_mov_i64(t1, arg2); 1183 if (sign) { 1184 TCGv_i64 t2 = tcg_temp_new_i64(); 1185 TCGv_i64 t3 = tcg_temp_new_i64(); 1186 tcg_gen_setcondi_i64(TCG_COND_EQ, t2, t0, INT64_MIN); 1187 tcg_gen_setcondi_i64(TCG_COND_EQ, t3, t1, -1); 1188 tcg_gen_and_i64(t2, t2, t3); 1189 tcg_gen_setcondi_i64(TCG_COND_EQ, t3, t1, 0); 1190 tcg_gen_or_i64(t2, t2, t3); 1191 tcg_gen_movi_i64(t3, 0); 1192 tcg_gen_movcond_i64(TCG_COND_NE, t1, t2, t3, t2, t1); 1193 tcg_gen_rem_i64(ret, t0, t1); 1194 tcg_temp_free_i64(t2); 1195 tcg_temp_free_i64(t3); 1196 } else { 1197 TCGv_i64 t2 = tcg_const_i64(1); 1198 TCGv_i64 t3 = tcg_const_i64(0); 1199 tcg_gen_movcond_i64(TCG_COND_EQ, t1, t1, t3, t2, t1); 1200 tcg_gen_remu_i64(ret, t0, t1); 1201 tcg_temp_free_i64(t2); 1202 tcg_temp_free_i64(t3); 1203 } 1204 tcg_temp_free_i64(t0); 1205 tcg_temp_free_i64(t1); 1206 } 1207 1208 #define GEN_INT_ARITH_MODD(name, opc3, sign) \ 1209 static void glue(gen_, name)(DisasContext *ctx) \ 1210 { \ 1211 gen_op_arith_modd(ctx, cpu_gpr[rD(ctx->opcode)], \ 1212 cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \ 1213 sign); \ 1214 } 1215 1216 GEN_INT_ARITH_MODD(modud, 0x08, 0); 1217 GEN_INT_ARITH_MODD(modsd, 0x18, 1); 1218 #endif 1219 1220 /* mulhw mulhw. */ 1221 static void gen_mulhw(DisasContext *ctx) 1222 { 1223 TCGv_i32 t0 = tcg_temp_new_i32(); 1224 TCGv_i32 t1 = tcg_temp_new_i32(); 1225 1226 tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); 1227 tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]); 1228 tcg_gen_muls2_i32(t0, t1, t0, t1); 1229 tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t1); 1230 tcg_temp_free_i32(t0); 1231 tcg_temp_free_i32(t1); 1232 if (unlikely(Rc(ctx->opcode) != 0)) { 1233 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); 1234 } 1235 } 1236 1237 /* mulhwu mulhwu. */ 1238 static void gen_mulhwu(DisasContext *ctx) 1239 { 1240 TCGv_i32 t0 = tcg_temp_new_i32(); 1241 TCGv_i32 t1 = tcg_temp_new_i32(); 1242 1243 tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); 1244 tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]); 1245 tcg_gen_mulu2_i32(t0, t1, t0, t1); 1246 tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t1); 1247 tcg_temp_free_i32(t0); 1248 tcg_temp_free_i32(t1); 1249 if (unlikely(Rc(ctx->opcode) != 0)) { 1250 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); 1251 } 1252 } 1253 1254 /* mullw mullw. */ 1255 static void gen_mullw(DisasContext *ctx) 1256 { 1257 #if defined(TARGET_PPC64) 1258 TCGv_i64 t0, t1; 1259 t0 = tcg_temp_new_i64(); 1260 t1 = tcg_temp_new_i64(); 1261 tcg_gen_ext32s_tl(t0, cpu_gpr[rA(ctx->opcode)]); 1262 tcg_gen_ext32s_tl(t1, cpu_gpr[rB(ctx->opcode)]); 1263 tcg_gen_mul_i64(cpu_gpr[rD(ctx->opcode)], t0, t1); 1264 tcg_temp_free(t0); 1265 tcg_temp_free(t1); 1266 #else 1267 tcg_gen_mul_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 1268 cpu_gpr[rB(ctx->opcode)]); 1269 #endif 1270 if (unlikely(Rc(ctx->opcode) != 0)) { 1271 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); 1272 } 1273 } 1274 1275 /* mullwo mullwo. */ 1276 static void gen_mullwo(DisasContext *ctx) 1277 { 1278 TCGv_i32 t0 = tcg_temp_new_i32(); 1279 TCGv_i32 t1 = tcg_temp_new_i32(); 1280 1281 tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); 1282 tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]); 1283 tcg_gen_muls2_i32(t0, t1, t0, t1); 1284 #if defined(TARGET_PPC64) 1285 tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1); 1286 #else 1287 tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], t0); 1288 #endif 1289 1290 tcg_gen_sari_i32(t0, t0, 31); 1291 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t1); 1292 tcg_gen_extu_i32_tl(cpu_ov, t0); 1293 if (is_isa300(ctx)) { 1294 tcg_gen_mov_tl(cpu_ov32, cpu_ov); 1295 } 1296 tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov); 1297 1298 tcg_temp_free_i32(t0); 1299 tcg_temp_free_i32(t1); 1300 if (unlikely(Rc(ctx->opcode) != 0)) { 1301 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); 1302 } 1303 } 1304 1305 /* mulli */ 1306 static void gen_mulli(DisasContext *ctx) 1307 { 1308 tcg_gen_muli_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 1309 SIMM(ctx->opcode)); 1310 } 1311 1312 #if defined(TARGET_PPC64) 1313 /* mulhd mulhd. */ 1314 static void gen_mulhd(DisasContext *ctx) 1315 { 1316 TCGv lo = tcg_temp_new(); 1317 tcg_gen_muls2_tl(lo, cpu_gpr[rD(ctx->opcode)], 1318 cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); 1319 tcg_temp_free(lo); 1320 if (unlikely(Rc(ctx->opcode) != 0)) { 1321 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); 1322 } 1323 } 1324 1325 /* mulhdu mulhdu. */ 1326 static void gen_mulhdu(DisasContext *ctx) 1327 { 1328 TCGv lo = tcg_temp_new(); 1329 tcg_gen_mulu2_tl(lo, cpu_gpr[rD(ctx->opcode)], 1330 cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); 1331 tcg_temp_free(lo); 1332 if (unlikely(Rc(ctx->opcode) != 0)) { 1333 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); 1334 } 1335 } 1336 1337 /* mulld mulld. */ 1338 static void gen_mulld(DisasContext *ctx) 1339 { 1340 tcg_gen_mul_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 1341 cpu_gpr[rB(ctx->opcode)]); 1342 if (unlikely(Rc(ctx->opcode) != 0)) { 1343 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); 1344 } 1345 } 1346 1347 /* mulldo mulldo. */ 1348 static void gen_mulldo(DisasContext *ctx) 1349 { 1350 TCGv_i64 t0 = tcg_temp_new_i64(); 1351 TCGv_i64 t1 = tcg_temp_new_i64(); 1352 1353 tcg_gen_muls2_i64(t0, t1, cpu_gpr[rA(ctx->opcode)], 1354 cpu_gpr[rB(ctx->opcode)]); 1355 tcg_gen_mov_i64(cpu_gpr[rD(ctx->opcode)], t0); 1356 1357 tcg_gen_sari_i64(t0, t0, 63); 1358 tcg_gen_setcond_i64(TCG_COND_NE, cpu_ov, t0, t1); 1359 if (is_isa300(ctx)) { 1360 tcg_gen_mov_tl(cpu_ov32, cpu_ov); 1361 } 1362 tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov); 1363 1364 tcg_temp_free_i64(t0); 1365 tcg_temp_free_i64(t1); 1366 1367 if (unlikely(Rc(ctx->opcode) != 0)) { 1368 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); 1369 } 1370 } 1371 #endif 1372 1373 /* Common subf function */ 1374 static inline void gen_op_arith_subf(DisasContext *ctx, TCGv ret, TCGv arg1, 1375 TCGv arg2, bool add_ca, bool compute_ca, 1376 bool compute_ov, bool compute_rc0) 1377 { 1378 TCGv t0 = ret; 1379 1380 if (compute_ca || compute_ov) { 1381 t0 = tcg_temp_new(); 1382 } 1383 1384 if (compute_ca) { 1385 /* dest = ~arg1 + arg2 [+ ca]. */ 1386 if (NARROW_MODE(ctx)) { 1387 /* 1388 * Caution: a non-obvious corner case of the spec is that 1389 * we must produce the *entire* 64-bit addition, but 1390 * produce the carry into bit 32. 1391 */ 1392 TCGv inv1 = tcg_temp_new(); 1393 TCGv t1 = tcg_temp_new(); 1394 tcg_gen_not_tl(inv1, arg1); 1395 if (add_ca) { 1396 tcg_gen_add_tl(t0, arg2, cpu_ca); 1397 } else { 1398 tcg_gen_addi_tl(t0, arg2, 1); 1399 } 1400 tcg_gen_xor_tl(t1, arg2, inv1); /* add without carry */ 1401 tcg_gen_add_tl(t0, t0, inv1); 1402 tcg_temp_free(inv1); 1403 tcg_gen_xor_tl(cpu_ca, t0, t1); /* bits changes w/ carry */ 1404 tcg_temp_free(t1); 1405 tcg_gen_extract_tl(cpu_ca, cpu_ca, 32, 1); 1406 if (is_isa300(ctx)) { 1407 tcg_gen_mov_tl(cpu_ca32, cpu_ca); 1408 } 1409 } else if (add_ca) { 1410 TCGv zero, inv1 = tcg_temp_new(); 1411 tcg_gen_not_tl(inv1, arg1); 1412 zero = tcg_const_tl(0); 1413 tcg_gen_add2_tl(t0, cpu_ca, arg2, zero, cpu_ca, zero); 1414 tcg_gen_add2_tl(t0, cpu_ca, t0, cpu_ca, inv1, zero); 1415 gen_op_arith_compute_ca32(ctx, t0, inv1, arg2, cpu_ca32, 0); 1416 tcg_temp_free(zero); 1417 tcg_temp_free(inv1); 1418 } else { 1419 tcg_gen_setcond_tl(TCG_COND_GEU, cpu_ca, arg2, arg1); 1420 tcg_gen_sub_tl(t0, arg2, arg1); 1421 gen_op_arith_compute_ca32(ctx, t0, arg1, arg2, cpu_ca32, 1); 1422 } 1423 } else if (add_ca) { 1424 /* 1425 * Since we're ignoring carry-out, we can simplify the 1426 * standard ~arg1 + arg2 + ca to arg2 - arg1 + ca - 1. 1427 */ 1428 tcg_gen_sub_tl(t0, arg2, arg1); 1429 tcg_gen_add_tl(t0, t0, cpu_ca); 1430 tcg_gen_subi_tl(t0, t0, 1); 1431 } else { 1432 tcg_gen_sub_tl(t0, arg2, arg1); 1433 } 1434 1435 if (compute_ov) { 1436 gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 1); 1437 } 1438 if (unlikely(compute_rc0)) { 1439 gen_set_Rc0(ctx, t0); 1440 } 1441 1442 if (t0 != ret) { 1443 tcg_gen_mov_tl(ret, t0); 1444 tcg_temp_free(t0); 1445 } 1446 } 1447 /* Sub functions with Two operands functions */ 1448 #define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov) \ 1449 static void glue(gen_, name)(DisasContext *ctx) \ 1450 { \ 1451 gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)], \ 1452 cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \ 1453 add_ca, compute_ca, compute_ov, Rc(ctx->opcode)); \ 1454 } 1455 /* Sub functions with one operand and one immediate */ 1456 #define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val, \ 1457 add_ca, compute_ca, compute_ov) \ 1458 static void glue(gen_, name)(DisasContext *ctx) \ 1459 { \ 1460 TCGv t0 = tcg_const_tl(const_val); \ 1461 gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)], \ 1462 cpu_gpr[rA(ctx->opcode)], t0, \ 1463 add_ca, compute_ca, compute_ov, Rc(ctx->opcode)); \ 1464 tcg_temp_free(t0); \ 1465 } 1466 /* subf subf. subfo subfo. */ 1467 GEN_INT_ARITH_SUBF(subf, 0x01, 0, 0, 0) 1468 GEN_INT_ARITH_SUBF(subfo, 0x11, 0, 0, 1) 1469 /* subfc subfc. subfco subfco. */ 1470 GEN_INT_ARITH_SUBF(subfc, 0x00, 0, 1, 0) 1471 GEN_INT_ARITH_SUBF(subfco, 0x10, 0, 1, 1) 1472 /* subfe subfe. subfeo subfo. */ 1473 GEN_INT_ARITH_SUBF(subfe, 0x04, 1, 1, 0) 1474 GEN_INT_ARITH_SUBF(subfeo, 0x14, 1, 1, 1) 1475 /* subfme subfme. subfmeo subfmeo. */ 1476 GEN_INT_ARITH_SUBF_CONST(subfme, 0x07, -1LL, 1, 1, 0) 1477 GEN_INT_ARITH_SUBF_CONST(subfmeo, 0x17, -1LL, 1, 1, 1) 1478 /* subfze subfze. subfzeo subfzeo.*/ 1479 GEN_INT_ARITH_SUBF_CONST(subfze, 0x06, 0, 1, 1, 0) 1480 GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1) 1481 1482 /* subfic */ 1483 static void gen_subfic(DisasContext *ctx) 1484 { 1485 TCGv c = tcg_const_tl(SIMM(ctx->opcode)); 1486 gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 1487 c, 0, 1, 0, 0); 1488 tcg_temp_free(c); 1489 } 1490 1491 /* neg neg. nego nego. */ 1492 static inline void gen_op_arith_neg(DisasContext *ctx, bool compute_ov) 1493 { 1494 TCGv zero = tcg_const_tl(0); 1495 gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 1496 zero, 0, 0, compute_ov, Rc(ctx->opcode)); 1497 tcg_temp_free(zero); 1498 } 1499 1500 static void gen_neg(DisasContext *ctx) 1501 { 1502 tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); 1503 if (unlikely(Rc(ctx->opcode))) { 1504 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); 1505 } 1506 } 1507 1508 static void gen_nego(DisasContext *ctx) 1509 { 1510 gen_op_arith_neg(ctx, 1); 1511 } 1512 1513 /*** Integer logical ***/ 1514 #define GEN_LOGICAL2(name, tcg_op, opc, type) \ 1515 static void glue(gen_, name)(DisasContext *ctx) \ 1516 { \ 1517 tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], \ 1518 cpu_gpr[rB(ctx->opcode)]); \ 1519 if (unlikely(Rc(ctx->opcode) != 0)) \ 1520 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); \ 1521 } 1522 1523 #define GEN_LOGICAL1(name, tcg_op, opc, type) \ 1524 static void glue(gen_, name)(DisasContext *ctx) \ 1525 { \ 1526 tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]); \ 1527 if (unlikely(Rc(ctx->opcode) != 0)) \ 1528 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); \ 1529 } 1530 1531 /* and & and. */ 1532 GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER); 1533 /* andc & andc. */ 1534 GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER); 1535 1536 /* andi. */ 1537 static void gen_andi_(DisasContext *ctx) 1538 { 1539 tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], 1540 UIMM(ctx->opcode)); 1541 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 1542 } 1543 1544 /* andis. */ 1545 static void gen_andis_(DisasContext *ctx) 1546 { 1547 tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], 1548 UIMM(ctx->opcode) << 16); 1549 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 1550 } 1551 1552 /* cntlzw */ 1553 static void gen_cntlzw(DisasContext *ctx) 1554 { 1555 TCGv_i32 t = tcg_temp_new_i32(); 1556 1557 tcg_gen_trunc_tl_i32(t, cpu_gpr[rS(ctx->opcode)]); 1558 tcg_gen_clzi_i32(t, t, 32); 1559 tcg_gen_extu_i32_tl(cpu_gpr[rA(ctx->opcode)], t); 1560 tcg_temp_free_i32(t); 1561 1562 if (unlikely(Rc(ctx->opcode) != 0)) { 1563 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 1564 } 1565 } 1566 1567 /* cnttzw */ 1568 static void gen_cnttzw(DisasContext *ctx) 1569 { 1570 TCGv_i32 t = tcg_temp_new_i32(); 1571 1572 tcg_gen_trunc_tl_i32(t, cpu_gpr[rS(ctx->opcode)]); 1573 tcg_gen_ctzi_i32(t, t, 32); 1574 tcg_gen_extu_i32_tl(cpu_gpr[rA(ctx->opcode)], t); 1575 tcg_temp_free_i32(t); 1576 1577 if (unlikely(Rc(ctx->opcode) != 0)) { 1578 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 1579 } 1580 } 1581 1582 /* eqv & eqv. */ 1583 GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER); 1584 /* extsb & extsb. */ 1585 GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER); 1586 /* extsh & extsh. */ 1587 GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER); 1588 /* nand & nand. */ 1589 GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER); 1590 /* nor & nor. */ 1591 GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER); 1592 1593 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) 1594 static void gen_pause(DisasContext *ctx) 1595 { 1596 TCGv_i32 t0 = tcg_const_i32(0); 1597 tcg_gen_st_i32(t0, cpu_env, 1598 -offsetof(PowerPCCPU, env) + offsetof(CPUState, halted)); 1599 tcg_temp_free_i32(t0); 1600 1601 /* Stop translation, this gives other CPUs a chance to run */ 1602 gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next); 1603 } 1604 #endif /* defined(TARGET_PPC64) */ 1605 1606 /* or & or. */ 1607 static void gen_or(DisasContext *ctx) 1608 { 1609 int rs, ra, rb; 1610 1611 rs = rS(ctx->opcode); 1612 ra = rA(ctx->opcode); 1613 rb = rB(ctx->opcode); 1614 /* Optimisation for mr. ri case */ 1615 if (rs != ra || rs != rb) { 1616 if (rs != rb) { 1617 tcg_gen_or_tl(cpu_gpr[ra], cpu_gpr[rs], cpu_gpr[rb]); 1618 } else { 1619 tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rs]); 1620 } 1621 if (unlikely(Rc(ctx->opcode) != 0)) { 1622 gen_set_Rc0(ctx, cpu_gpr[ra]); 1623 } 1624 } else if (unlikely(Rc(ctx->opcode) != 0)) { 1625 gen_set_Rc0(ctx, cpu_gpr[rs]); 1626 #if defined(TARGET_PPC64) 1627 } else if (rs != 0) { /* 0 is nop */ 1628 int prio = 0; 1629 1630 switch (rs) { 1631 case 1: 1632 /* Set process priority to low */ 1633 prio = 2; 1634 break; 1635 case 6: 1636 /* Set process priority to medium-low */ 1637 prio = 3; 1638 break; 1639 case 2: 1640 /* Set process priority to normal */ 1641 prio = 4; 1642 break; 1643 #if !defined(CONFIG_USER_ONLY) 1644 case 31: 1645 if (!ctx->pr) { 1646 /* Set process priority to very low */ 1647 prio = 1; 1648 } 1649 break; 1650 case 5: 1651 if (!ctx->pr) { 1652 /* Set process priority to medium-hight */ 1653 prio = 5; 1654 } 1655 break; 1656 case 3: 1657 if (!ctx->pr) { 1658 /* Set process priority to high */ 1659 prio = 6; 1660 } 1661 break; 1662 case 7: 1663 if (ctx->hv && !ctx->pr) { 1664 /* Set process priority to very high */ 1665 prio = 7; 1666 } 1667 break; 1668 #endif 1669 default: 1670 break; 1671 } 1672 if (prio) { 1673 TCGv t0 = tcg_temp_new(); 1674 gen_load_spr(t0, SPR_PPR); 1675 tcg_gen_andi_tl(t0, t0, ~0x001C000000000000ULL); 1676 tcg_gen_ori_tl(t0, t0, ((uint64_t)prio) << 50); 1677 gen_store_spr(SPR_PPR, t0); 1678 tcg_temp_free(t0); 1679 } 1680 #if !defined(CONFIG_USER_ONLY) 1681 /* 1682 * Pause out of TCG otherwise spin loops with smt_low eat too 1683 * much CPU and the kernel hangs. This applies to all 1684 * encodings other than no-op, e.g., miso(rs=26), yield(27), 1685 * mdoio(29), mdoom(30), and all currently undefined. 1686 */ 1687 gen_pause(ctx); 1688 #endif 1689 #endif 1690 } 1691 } 1692 /* orc & orc. */ 1693 GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER); 1694 1695 /* xor & xor. */ 1696 static void gen_xor(DisasContext *ctx) 1697 { 1698 /* Optimisation for "set to zero" case */ 1699 if (rS(ctx->opcode) != rB(ctx->opcode)) { 1700 tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], 1701 cpu_gpr[rB(ctx->opcode)]); 1702 } else { 1703 tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0); 1704 } 1705 if (unlikely(Rc(ctx->opcode) != 0)) { 1706 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 1707 } 1708 } 1709 1710 /* ori */ 1711 static void gen_ori(DisasContext *ctx) 1712 { 1713 target_ulong uimm = UIMM(ctx->opcode); 1714 1715 if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) { 1716 return; 1717 } 1718 tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm); 1719 } 1720 1721 /* oris */ 1722 static void gen_oris(DisasContext *ctx) 1723 { 1724 target_ulong uimm = UIMM(ctx->opcode); 1725 1726 if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) { 1727 /* NOP */ 1728 return; 1729 } 1730 tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], 1731 uimm << 16); 1732 } 1733 1734 /* xori */ 1735 static void gen_xori(DisasContext *ctx) 1736 { 1737 target_ulong uimm = UIMM(ctx->opcode); 1738 1739 if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) { 1740 /* NOP */ 1741 return; 1742 } 1743 tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm); 1744 } 1745 1746 /* xoris */ 1747 static void gen_xoris(DisasContext *ctx) 1748 { 1749 target_ulong uimm = UIMM(ctx->opcode); 1750 1751 if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) { 1752 /* NOP */ 1753 return; 1754 } 1755 tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], 1756 uimm << 16); 1757 } 1758 1759 /* popcntb : PowerPC 2.03 specification */ 1760 static void gen_popcntb(DisasContext *ctx) 1761 { 1762 gen_helper_popcntb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]); 1763 } 1764 1765 static void gen_popcntw(DisasContext *ctx) 1766 { 1767 #if defined(TARGET_PPC64) 1768 gen_helper_popcntw(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]); 1769 #else 1770 tcg_gen_ctpop_i32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]); 1771 #endif 1772 } 1773 1774 #if defined(TARGET_PPC64) 1775 /* popcntd: PowerPC 2.06 specification */ 1776 static void gen_popcntd(DisasContext *ctx) 1777 { 1778 tcg_gen_ctpop_i64(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]); 1779 } 1780 #endif 1781 1782 /* prtyw: PowerPC 2.05 specification */ 1783 static void gen_prtyw(DisasContext *ctx) 1784 { 1785 TCGv ra = cpu_gpr[rA(ctx->opcode)]; 1786 TCGv rs = cpu_gpr[rS(ctx->opcode)]; 1787 TCGv t0 = tcg_temp_new(); 1788 tcg_gen_shri_tl(t0, rs, 16); 1789 tcg_gen_xor_tl(ra, rs, t0); 1790 tcg_gen_shri_tl(t0, ra, 8); 1791 tcg_gen_xor_tl(ra, ra, t0); 1792 tcg_gen_andi_tl(ra, ra, (target_ulong)0x100000001ULL); 1793 tcg_temp_free(t0); 1794 } 1795 1796 #if defined(TARGET_PPC64) 1797 /* prtyd: PowerPC 2.05 specification */ 1798 static void gen_prtyd(DisasContext *ctx) 1799 { 1800 TCGv ra = cpu_gpr[rA(ctx->opcode)]; 1801 TCGv rs = cpu_gpr[rS(ctx->opcode)]; 1802 TCGv t0 = tcg_temp_new(); 1803 tcg_gen_shri_tl(t0, rs, 32); 1804 tcg_gen_xor_tl(ra, rs, t0); 1805 tcg_gen_shri_tl(t0, ra, 16); 1806 tcg_gen_xor_tl(ra, ra, t0); 1807 tcg_gen_shri_tl(t0, ra, 8); 1808 tcg_gen_xor_tl(ra, ra, t0); 1809 tcg_gen_andi_tl(ra, ra, 1); 1810 tcg_temp_free(t0); 1811 } 1812 #endif 1813 1814 #if defined(TARGET_PPC64) 1815 /* bpermd */ 1816 static void gen_bpermd(DisasContext *ctx) 1817 { 1818 gen_helper_bpermd(cpu_gpr[rA(ctx->opcode)], 1819 cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); 1820 } 1821 #endif 1822 1823 #if defined(TARGET_PPC64) 1824 /* extsw & extsw. */ 1825 GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B); 1826 1827 /* cntlzd */ 1828 static void gen_cntlzd(DisasContext *ctx) 1829 { 1830 tcg_gen_clzi_i64(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], 64); 1831 if (unlikely(Rc(ctx->opcode) != 0)) { 1832 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 1833 } 1834 } 1835 1836 /* cnttzd */ 1837 static void gen_cnttzd(DisasContext *ctx) 1838 { 1839 tcg_gen_ctzi_i64(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], 64); 1840 if (unlikely(Rc(ctx->opcode) != 0)) { 1841 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 1842 } 1843 } 1844 1845 /* darn */ 1846 static void gen_darn(DisasContext *ctx) 1847 { 1848 int l = L(ctx->opcode); 1849 1850 if (l == 0) { 1851 gen_helper_darn32(cpu_gpr[rD(ctx->opcode)]); 1852 } else if (l <= 2) { 1853 /* Return 64-bit random for both CRN and RRN */ 1854 gen_helper_darn64(cpu_gpr[rD(ctx->opcode)]); 1855 } else { 1856 tcg_gen_movi_i64(cpu_gpr[rD(ctx->opcode)], -1); 1857 } 1858 } 1859 #endif 1860 1861 /*** Integer rotate ***/ 1862 1863 /* rlwimi & rlwimi. */ 1864 static void gen_rlwimi(DisasContext *ctx) 1865 { 1866 TCGv t_ra = cpu_gpr[rA(ctx->opcode)]; 1867 TCGv t_rs = cpu_gpr[rS(ctx->opcode)]; 1868 uint32_t sh = SH(ctx->opcode); 1869 uint32_t mb = MB(ctx->opcode); 1870 uint32_t me = ME(ctx->opcode); 1871 1872 if (sh == (31 - me) && mb <= me) { 1873 tcg_gen_deposit_tl(t_ra, t_ra, t_rs, sh, me - mb + 1); 1874 } else { 1875 target_ulong mask; 1876 TCGv t1; 1877 1878 #if defined(TARGET_PPC64) 1879 mb += 32; 1880 me += 32; 1881 #endif 1882 mask = MASK(mb, me); 1883 1884 t1 = tcg_temp_new(); 1885 if (mask <= 0xffffffffu) { 1886 TCGv_i32 t0 = tcg_temp_new_i32(); 1887 tcg_gen_trunc_tl_i32(t0, t_rs); 1888 tcg_gen_rotli_i32(t0, t0, sh); 1889 tcg_gen_extu_i32_tl(t1, t0); 1890 tcg_temp_free_i32(t0); 1891 } else { 1892 #if defined(TARGET_PPC64) 1893 tcg_gen_deposit_i64(t1, t_rs, t_rs, 32, 32); 1894 tcg_gen_rotli_i64(t1, t1, sh); 1895 #else 1896 g_assert_not_reached(); 1897 #endif 1898 } 1899 1900 tcg_gen_andi_tl(t1, t1, mask); 1901 tcg_gen_andi_tl(t_ra, t_ra, ~mask); 1902 tcg_gen_or_tl(t_ra, t_ra, t1); 1903 tcg_temp_free(t1); 1904 } 1905 if (unlikely(Rc(ctx->opcode) != 0)) { 1906 gen_set_Rc0(ctx, t_ra); 1907 } 1908 } 1909 1910 /* rlwinm & rlwinm. */ 1911 static void gen_rlwinm(DisasContext *ctx) 1912 { 1913 TCGv t_ra = cpu_gpr[rA(ctx->opcode)]; 1914 TCGv t_rs = cpu_gpr[rS(ctx->opcode)]; 1915 int sh = SH(ctx->opcode); 1916 int mb = MB(ctx->opcode); 1917 int me = ME(ctx->opcode); 1918 int len = me - mb + 1; 1919 int rsh = (32 - sh) & 31; 1920 1921 if (sh != 0 && len > 0 && me == (31 - sh)) { 1922 tcg_gen_deposit_z_tl(t_ra, t_rs, sh, len); 1923 } else if (me == 31 && rsh + len <= 32) { 1924 tcg_gen_extract_tl(t_ra, t_rs, rsh, len); 1925 } else { 1926 target_ulong mask; 1927 #if defined(TARGET_PPC64) 1928 mb += 32; 1929 me += 32; 1930 #endif 1931 mask = MASK(mb, me); 1932 if (sh == 0) { 1933 tcg_gen_andi_tl(t_ra, t_rs, mask); 1934 } else if (mask <= 0xffffffffu) { 1935 TCGv_i32 t0 = tcg_temp_new_i32(); 1936 tcg_gen_trunc_tl_i32(t0, t_rs); 1937 tcg_gen_rotli_i32(t0, t0, sh); 1938 tcg_gen_andi_i32(t0, t0, mask); 1939 tcg_gen_extu_i32_tl(t_ra, t0); 1940 tcg_temp_free_i32(t0); 1941 } else { 1942 #if defined(TARGET_PPC64) 1943 tcg_gen_deposit_i64(t_ra, t_rs, t_rs, 32, 32); 1944 tcg_gen_rotli_i64(t_ra, t_ra, sh); 1945 tcg_gen_andi_i64(t_ra, t_ra, mask); 1946 #else 1947 g_assert_not_reached(); 1948 #endif 1949 } 1950 } 1951 if (unlikely(Rc(ctx->opcode) != 0)) { 1952 gen_set_Rc0(ctx, t_ra); 1953 } 1954 } 1955 1956 /* rlwnm & rlwnm. */ 1957 static void gen_rlwnm(DisasContext *ctx) 1958 { 1959 TCGv t_ra = cpu_gpr[rA(ctx->opcode)]; 1960 TCGv t_rs = cpu_gpr[rS(ctx->opcode)]; 1961 TCGv t_rb = cpu_gpr[rB(ctx->opcode)]; 1962 uint32_t mb = MB(ctx->opcode); 1963 uint32_t me = ME(ctx->opcode); 1964 target_ulong mask; 1965 1966 #if defined(TARGET_PPC64) 1967 mb += 32; 1968 me += 32; 1969 #endif 1970 mask = MASK(mb, me); 1971 1972 if (mask <= 0xffffffffu) { 1973 TCGv_i32 t0 = tcg_temp_new_i32(); 1974 TCGv_i32 t1 = tcg_temp_new_i32(); 1975 tcg_gen_trunc_tl_i32(t0, t_rb); 1976 tcg_gen_trunc_tl_i32(t1, t_rs); 1977 tcg_gen_andi_i32(t0, t0, 0x1f); 1978 tcg_gen_rotl_i32(t1, t1, t0); 1979 tcg_gen_extu_i32_tl(t_ra, t1); 1980 tcg_temp_free_i32(t0); 1981 tcg_temp_free_i32(t1); 1982 } else { 1983 #if defined(TARGET_PPC64) 1984 TCGv_i64 t0 = tcg_temp_new_i64(); 1985 tcg_gen_andi_i64(t0, t_rb, 0x1f); 1986 tcg_gen_deposit_i64(t_ra, t_rs, t_rs, 32, 32); 1987 tcg_gen_rotl_i64(t_ra, t_ra, t0); 1988 tcg_temp_free_i64(t0); 1989 #else 1990 g_assert_not_reached(); 1991 #endif 1992 } 1993 1994 tcg_gen_andi_tl(t_ra, t_ra, mask); 1995 1996 if (unlikely(Rc(ctx->opcode) != 0)) { 1997 gen_set_Rc0(ctx, t_ra); 1998 } 1999 } 2000 2001 #if defined(TARGET_PPC64) 2002 #define GEN_PPC64_R2(name, opc1, opc2) \ 2003 static void glue(gen_, name##0)(DisasContext *ctx) \ 2004 { \ 2005 gen_##name(ctx, 0); \ 2006 } \ 2007 \ 2008 static void glue(gen_, name##1)(DisasContext *ctx) \ 2009 { \ 2010 gen_##name(ctx, 1); \ 2011 } 2012 #define GEN_PPC64_R4(name, opc1, opc2) \ 2013 static void glue(gen_, name##0)(DisasContext *ctx) \ 2014 { \ 2015 gen_##name(ctx, 0, 0); \ 2016 } \ 2017 \ 2018 static void glue(gen_, name##1)(DisasContext *ctx) \ 2019 { \ 2020 gen_##name(ctx, 0, 1); \ 2021 } \ 2022 \ 2023 static void glue(gen_, name##2)(DisasContext *ctx) \ 2024 { \ 2025 gen_##name(ctx, 1, 0); \ 2026 } \ 2027 \ 2028 static void glue(gen_, name##3)(DisasContext *ctx) \ 2029 { \ 2030 gen_##name(ctx, 1, 1); \ 2031 } 2032 2033 static void gen_rldinm(DisasContext *ctx, int mb, int me, int sh) 2034 { 2035 TCGv t_ra = cpu_gpr[rA(ctx->opcode)]; 2036 TCGv t_rs = cpu_gpr[rS(ctx->opcode)]; 2037 int len = me - mb + 1; 2038 int rsh = (64 - sh) & 63; 2039 2040 if (sh != 0 && len > 0 && me == (63 - sh)) { 2041 tcg_gen_deposit_z_tl(t_ra, t_rs, sh, len); 2042 } else if (me == 63 && rsh + len <= 64) { 2043 tcg_gen_extract_tl(t_ra, t_rs, rsh, len); 2044 } else { 2045 tcg_gen_rotli_tl(t_ra, t_rs, sh); 2046 tcg_gen_andi_tl(t_ra, t_ra, MASK(mb, me)); 2047 } 2048 if (unlikely(Rc(ctx->opcode) != 0)) { 2049 gen_set_Rc0(ctx, t_ra); 2050 } 2051 } 2052 2053 /* rldicl - rldicl. */ 2054 static inline void gen_rldicl(DisasContext *ctx, int mbn, int shn) 2055 { 2056 uint32_t sh, mb; 2057 2058 sh = SH(ctx->opcode) | (shn << 5); 2059 mb = MB(ctx->opcode) | (mbn << 5); 2060 gen_rldinm(ctx, mb, 63, sh); 2061 } 2062 GEN_PPC64_R4(rldicl, 0x1E, 0x00); 2063 2064 /* rldicr - rldicr. */ 2065 static inline void gen_rldicr(DisasContext *ctx, int men, int shn) 2066 { 2067 uint32_t sh, me; 2068 2069 sh = SH(ctx->opcode) | (shn << 5); 2070 me = MB(ctx->opcode) | (men << 5); 2071 gen_rldinm(ctx, 0, me, sh); 2072 } 2073 GEN_PPC64_R4(rldicr, 0x1E, 0x02); 2074 2075 /* rldic - rldic. */ 2076 static inline void gen_rldic(DisasContext *ctx, int mbn, int shn) 2077 { 2078 uint32_t sh, mb; 2079 2080 sh = SH(ctx->opcode) | (shn << 5); 2081 mb = MB(ctx->opcode) | (mbn << 5); 2082 gen_rldinm(ctx, mb, 63 - sh, sh); 2083 } 2084 GEN_PPC64_R4(rldic, 0x1E, 0x04); 2085 2086 static void gen_rldnm(DisasContext *ctx, int mb, int me) 2087 { 2088 TCGv t_ra = cpu_gpr[rA(ctx->opcode)]; 2089 TCGv t_rs = cpu_gpr[rS(ctx->opcode)]; 2090 TCGv t_rb = cpu_gpr[rB(ctx->opcode)]; 2091 TCGv t0; 2092 2093 t0 = tcg_temp_new(); 2094 tcg_gen_andi_tl(t0, t_rb, 0x3f); 2095 tcg_gen_rotl_tl(t_ra, t_rs, t0); 2096 tcg_temp_free(t0); 2097 2098 tcg_gen_andi_tl(t_ra, t_ra, MASK(mb, me)); 2099 if (unlikely(Rc(ctx->opcode) != 0)) { 2100 gen_set_Rc0(ctx, t_ra); 2101 } 2102 } 2103 2104 /* rldcl - rldcl. */ 2105 static inline void gen_rldcl(DisasContext *ctx, int mbn) 2106 { 2107 uint32_t mb; 2108 2109 mb = MB(ctx->opcode) | (mbn << 5); 2110 gen_rldnm(ctx, mb, 63); 2111 } 2112 GEN_PPC64_R2(rldcl, 0x1E, 0x08); 2113 2114 /* rldcr - rldcr. */ 2115 static inline void gen_rldcr(DisasContext *ctx, int men) 2116 { 2117 uint32_t me; 2118 2119 me = MB(ctx->opcode) | (men << 5); 2120 gen_rldnm(ctx, 0, me); 2121 } 2122 GEN_PPC64_R2(rldcr, 0x1E, 0x09); 2123 2124 /* rldimi - rldimi. */ 2125 static void gen_rldimi(DisasContext *ctx, int mbn, int shn) 2126 { 2127 TCGv t_ra = cpu_gpr[rA(ctx->opcode)]; 2128 TCGv t_rs = cpu_gpr[rS(ctx->opcode)]; 2129 uint32_t sh = SH(ctx->opcode) | (shn << 5); 2130 uint32_t mb = MB(ctx->opcode) | (mbn << 5); 2131 uint32_t me = 63 - sh; 2132 2133 if (mb <= me) { 2134 tcg_gen_deposit_tl(t_ra, t_ra, t_rs, sh, me - mb + 1); 2135 } else { 2136 target_ulong mask = MASK(mb, me); 2137 TCGv t1 = tcg_temp_new(); 2138 2139 tcg_gen_rotli_tl(t1, t_rs, sh); 2140 tcg_gen_andi_tl(t1, t1, mask); 2141 tcg_gen_andi_tl(t_ra, t_ra, ~mask); 2142 tcg_gen_or_tl(t_ra, t_ra, t1); 2143 tcg_temp_free(t1); 2144 } 2145 if (unlikely(Rc(ctx->opcode) != 0)) { 2146 gen_set_Rc0(ctx, t_ra); 2147 } 2148 } 2149 GEN_PPC64_R4(rldimi, 0x1E, 0x06); 2150 #endif 2151 2152 /*** Integer shift ***/ 2153 2154 /* slw & slw. */ 2155 static void gen_slw(DisasContext *ctx) 2156 { 2157 TCGv t0, t1; 2158 2159 t0 = tcg_temp_new(); 2160 /* AND rS with a mask that is 0 when rB >= 0x20 */ 2161 #if defined(TARGET_PPC64) 2162 tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3a); 2163 tcg_gen_sari_tl(t0, t0, 0x3f); 2164 #else 2165 tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1a); 2166 tcg_gen_sari_tl(t0, t0, 0x1f); 2167 #endif 2168 tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0); 2169 t1 = tcg_temp_new(); 2170 tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1f); 2171 tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], t0, t1); 2172 tcg_temp_free(t1); 2173 tcg_temp_free(t0); 2174 tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); 2175 if (unlikely(Rc(ctx->opcode) != 0)) { 2176 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 2177 } 2178 } 2179 2180 /* sraw & sraw. */ 2181 static void gen_sraw(DisasContext *ctx) 2182 { 2183 gen_helper_sraw(cpu_gpr[rA(ctx->opcode)], cpu_env, 2184 cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); 2185 if (unlikely(Rc(ctx->opcode) != 0)) { 2186 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 2187 } 2188 } 2189 2190 /* srawi & srawi. */ 2191 static void gen_srawi(DisasContext *ctx) 2192 { 2193 int sh = SH(ctx->opcode); 2194 TCGv dst = cpu_gpr[rA(ctx->opcode)]; 2195 TCGv src = cpu_gpr[rS(ctx->opcode)]; 2196 if (sh == 0) { 2197 tcg_gen_ext32s_tl(dst, src); 2198 tcg_gen_movi_tl(cpu_ca, 0); 2199 if (is_isa300(ctx)) { 2200 tcg_gen_movi_tl(cpu_ca32, 0); 2201 } 2202 } else { 2203 TCGv t0; 2204 tcg_gen_ext32s_tl(dst, src); 2205 tcg_gen_andi_tl(cpu_ca, dst, (1ULL << sh) - 1); 2206 t0 = tcg_temp_new(); 2207 tcg_gen_sari_tl(t0, dst, TARGET_LONG_BITS - 1); 2208 tcg_gen_and_tl(cpu_ca, cpu_ca, t0); 2209 tcg_temp_free(t0); 2210 tcg_gen_setcondi_tl(TCG_COND_NE, cpu_ca, cpu_ca, 0); 2211 if (is_isa300(ctx)) { 2212 tcg_gen_mov_tl(cpu_ca32, cpu_ca); 2213 } 2214 tcg_gen_sari_tl(dst, dst, sh); 2215 } 2216 if (unlikely(Rc(ctx->opcode) != 0)) { 2217 gen_set_Rc0(ctx, dst); 2218 } 2219 } 2220 2221 /* srw & srw. */ 2222 static void gen_srw(DisasContext *ctx) 2223 { 2224 TCGv t0, t1; 2225 2226 t0 = tcg_temp_new(); 2227 /* AND rS with a mask that is 0 when rB >= 0x20 */ 2228 #if defined(TARGET_PPC64) 2229 tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3a); 2230 tcg_gen_sari_tl(t0, t0, 0x3f); 2231 #else 2232 tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1a); 2233 tcg_gen_sari_tl(t0, t0, 0x1f); 2234 #endif 2235 tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0); 2236 tcg_gen_ext32u_tl(t0, t0); 2237 t1 = tcg_temp_new(); 2238 tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1f); 2239 tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], t0, t1); 2240 tcg_temp_free(t1); 2241 tcg_temp_free(t0); 2242 if (unlikely(Rc(ctx->opcode) != 0)) { 2243 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 2244 } 2245 } 2246 2247 #if defined(TARGET_PPC64) 2248 /* sld & sld. */ 2249 static void gen_sld(DisasContext *ctx) 2250 { 2251 TCGv t0, t1; 2252 2253 t0 = tcg_temp_new(); 2254 /* AND rS with a mask that is 0 when rB >= 0x40 */ 2255 tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x39); 2256 tcg_gen_sari_tl(t0, t0, 0x3f); 2257 tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0); 2258 t1 = tcg_temp_new(); 2259 tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x3f); 2260 tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], t0, t1); 2261 tcg_temp_free(t1); 2262 tcg_temp_free(t0); 2263 if (unlikely(Rc(ctx->opcode) != 0)) { 2264 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 2265 } 2266 } 2267 2268 /* srad & srad. */ 2269 static void gen_srad(DisasContext *ctx) 2270 { 2271 gen_helper_srad(cpu_gpr[rA(ctx->opcode)], cpu_env, 2272 cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); 2273 if (unlikely(Rc(ctx->opcode) != 0)) { 2274 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 2275 } 2276 } 2277 /* sradi & sradi. */ 2278 static inline void gen_sradi(DisasContext *ctx, int n) 2279 { 2280 int sh = SH(ctx->opcode) + (n << 5); 2281 TCGv dst = cpu_gpr[rA(ctx->opcode)]; 2282 TCGv src = cpu_gpr[rS(ctx->opcode)]; 2283 if (sh == 0) { 2284 tcg_gen_mov_tl(dst, src); 2285 tcg_gen_movi_tl(cpu_ca, 0); 2286 if (is_isa300(ctx)) { 2287 tcg_gen_movi_tl(cpu_ca32, 0); 2288 } 2289 } else { 2290 TCGv t0; 2291 tcg_gen_andi_tl(cpu_ca, src, (1ULL << sh) - 1); 2292 t0 = tcg_temp_new(); 2293 tcg_gen_sari_tl(t0, src, TARGET_LONG_BITS - 1); 2294 tcg_gen_and_tl(cpu_ca, cpu_ca, t0); 2295 tcg_temp_free(t0); 2296 tcg_gen_setcondi_tl(TCG_COND_NE, cpu_ca, cpu_ca, 0); 2297 if (is_isa300(ctx)) { 2298 tcg_gen_mov_tl(cpu_ca32, cpu_ca); 2299 } 2300 tcg_gen_sari_tl(dst, src, sh); 2301 } 2302 if (unlikely(Rc(ctx->opcode) != 0)) { 2303 gen_set_Rc0(ctx, dst); 2304 } 2305 } 2306 2307 static void gen_sradi0(DisasContext *ctx) 2308 { 2309 gen_sradi(ctx, 0); 2310 } 2311 2312 static void gen_sradi1(DisasContext *ctx) 2313 { 2314 gen_sradi(ctx, 1); 2315 } 2316 2317 /* extswsli & extswsli. */ 2318 static inline void gen_extswsli(DisasContext *ctx, int n) 2319 { 2320 int sh = SH(ctx->opcode) + (n << 5); 2321 TCGv dst = cpu_gpr[rA(ctx->opcode)]; 2322 TCGv src = cpu_gpr[rS(ctx->opcode)]; 2323 2324 tcg_gen_ext32s_tl(dst, src); 2325 tcg_gen_shli_tl(dst, dst, sh); 2326 if (unlikely(Rc(ctx->opcode) != 0)) { 2327 gen_set_Rc0(ctx, dst); 2328 } 2329 } 2330 2331 static void gen_extswsli0(DisasContext *ctx) 2332 { 2333 gen_extswsli(ctx, 0); 2334 } 2335 2336 static void gen_extswsli1(DisasContext *ctx) 2337 { 2338 gen_extswsli(ctx, 1); 2339 } 2340 2341 /* srd & srd. */ 2342 static void gen_srd(DisasContext *ctx) 2343 { 2344 TCGv t0, t1; 2345 2346 t0 = tcg_temp_new(); 2347 /* AND rS with a mask that is 0 when rB >= 0x40 */ 2348 tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x39); 2349 tcg_gen_sari_tl(t0, t0, 0x3f); 2350 tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0); 2351 t1 = tcg_temp_new(); 2352 tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x3f); 2353 tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], t0, t1); 2354 tcg_temp_free(t1); 2355 tcg_temp_free(t0); 2356 if (unlikely(Rc(ctx->opcode) != 0)) { 2357 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 2358 } 2359 } 2360 #endif 2361 2362 /*** Addressing modes ***/ 2363 /* Register indirect with immediate index : EA = (rA|0) + SIMM */ 2364 static inline void gen_addr_imm_index(DisasContext *ctx, TCGv EA, 2365 target_long maskl) 2366 { 2367 target_long simm = SIMM(ctx->opcode); 2368 2369 simm &= ~maskl; 2370 if (rA(ctx->opcode) == 0) { 2371 if (NARROW_MODE(ctx)) { 2372 simm = (uint32_t)simm; 2373 } 2374 tcg_gen_movi_tl(EA, simm); 2375 } else if (likely(simm != 0)) { 2376 tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], simm); 2377 if (NARROW_MODE(ctx)) { 2378 tcg_gen_ext32u_tl(EA, EA); 2379 } 2380 } else { 2381 if (NARROW_MODE(ctx)) { 2382 tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]); 2383 } else { 2384 tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]); 2385 } 2386 } 2387 } 2388 2389 static inline void gen_addr_reg_index(DisasContext *ctx, TCGv EA) 2390 { 2391 if (rA(ctx->opcode) == 0) { 2392 if (NARROW_MODE(ctx)) { 2393 tcg_gen_ext32u_tl(EA, cpu_gpr[rB(ctx->opcode)]); 2394 } else { 2395 tcg_gen_mov_tl(EA, cpu_gpr[rB(ctx->opcode)]); 2396 } 2397 } else { 2398 tcg_gen_add_tl(EA, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); 2399 if (NARROW_MODE(ctx)) { 2400 tcg_gen_ext32u_tl(EA, EA); 2401 } 2402 } 2403 } 2404 2405 static inline void gen_addr_register(DisasContext *ctx, TCGv EA) 2406 { 2407 if (rA(ctx->opcode) == 0) { 2408 tcg_gen_movi_tl(EA, 0); 2409 } else if (NARROW_MODE(ctx)) { 2410 tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]); 2411 } else { 2412 tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]); 2413 } 2414 } 2415 2416 static inline void gen_addr_add(DisasContext *ctx, TCGv ret, TCGv arg1, 2417 target_long val) 2418 { 2419 tcg_gen_addi_tl(ret, arg1, val); 2420 if (NARROW_MODE(ctx)) { 2421 tcg_gen_ext32u_tl(ret, ret); 2422 } 2423 } 2424 2425 static inline void gen_align_no_le(DisasContext *ctx) 2426 { 2427 gen_exception_err(ctx, POWERPC_EXCP_ALIGN, 2428 (ctx->opcode & 0x03FF0000) | POWERPC_EXCP_ALIGN_LE); 2429 } 2430 2431 /*** Integer load ***/ 2432 #define DEF_MEMOP(op) ((op) | ctx->default_tcg_memop_mask) 2433 #define BSWAP_MEMOP(op) ((op) | (ctx->default_tcg_memop_mask ^ MO_BSWAP)) 2434 2435 #define GEN_QEMU_LOAD_TL(ldop, op) \ 2436 static void glue(gen_qemu_, ldop)(DisasContext *ctx, \ 2437 TCGv val, \ 2438 TCGv addr) \ 2439 { \ 2440 tcg_gen_qemu_ld_tl(val, addr, ctx->mem_idx, op); \ 2441 } 2442 2443 GEN_QEMU_LOAD_TL(ld8u, DEF_MEMOP(MO_UB)) 2444 GEN_QEMU_LOAD_TL(ld16u, DEF_MEMOP(MO_UW)) 2445 GEN_QEMU_LOAD_TL(ld16s, DEF_MEMOP(MO_SW)) 2446 GEN_QEMU_LOAD_TL(ld32u, DEF_MEMOP(MO_UL)) 2447 GEN_QEMU_LOAD_TL(ld32s, DEF_MEMOP(MO_SL)) 2448 2449 GEN_QEMU_LOAD_TL(ld16ur, BSWAP_MEMOP(MO_UW)) 2450 GEN_QEMU_LOAD_TL(ld32ur, BSWAP_MEMOP(MO_UL)) 2451 2452 #define GEN_QEMU_LOAD_64(ldop, op) \ 2453 static void glue(gen_qemu_, glue(ldop, _i64))(DisasContext *ctx, \ 2454 TCGv_i64 val, \ 2455 TCGv addr) \ 2456 { \ 2457 tcg_gen_qemu_ld_i64(val, addr, ctx->mem_idx, op); \ 2458 } 2459 2460 GEN_QEMU_LOAD_64(ld8u, DEF_MEMOP(MO_UB)) 2461 GEN_QEMU_LOAD_64(ld16u, DEF_MEMOP(MO_UW)) 2462 GEN_QEMU_LOAD_64(ld32u, DEF_MEMOP(MO_UL)) 2463 GEN_QEMU_LOAD_64(ld32s, DEF_MEMOP(MO_SL)) 2464 GEN_QEMU_LOAD_64(ld64, DEF_MEMOP(MO_Q)) 2465 2466 #if defined(TARGET_PPC64) 2467 GEN_QEMU_LOAD_64(ld64ur, BSWAP_MEMOP(MO_Q)) 2468 #endif 2469 2470 #define GEN_QEMU_STORE_TL(stop, op) \ 2471 static void glue(gen_qemu_, stop)(DisasContext *ctx, \ 2472 TCGv val, \ 2473 TCGv addr) \ 2474 { \ 2475 tcg_gen_qemu_st_tl(val, addr, ctx->mem_idx, op); \ 2476 } 2477 2478 GEN_QEMU_STORE_TL(st8, DEF_MEMOP(MO_UB)) 2479 GEN_QEMU_STORE_TL(st16, DEF_MEMOP(MO_UW)) 2480 GEN_QEMU_STORE_TL(st32, DEF_MEMOP(MO_UL)) 2481 2482 GEN_QEMU_STORE_TL(st16r, BSWAP_MEMOP(MO_UW)) 2483 GEN_QEMU_STORE_TL(st32r, BSWAP_MEMOP(MO_UL)) 2484 2485 #define GEN_QEMU_STORE_64(stop, op) \ 2486 static void glue(gen_qemu_, glue(stop, _i64))(DisasContext *ctx, \ 2487 TCGv_i64 val, \ 2488 TCGv addr) \ 2489 { \ 2490 tcg_gen_qemu_st_i64(val, addr, ctx->mem_idx, op); \ 2491 } 2492 2493 GEN_QEMU_STORE_64(st8, DEF_MEMOP(MO_UB)) 2494 GEN_QEMU_STORE_64(st16, DEF_MEMOP(MO_UW)) 2495 GEN_QEMU_STORE_64(st32, DEF_MEMOP(MO_UL)) 2496 GEN_QEMU_STORE_64(st64, DEF_MEMOP(MO_Q)) 2497 2498 #if defined(TARGET_PPC64) 2499 GEN_QEMU_STORE_64(st64r, BSWAP_MEMOP(MO_Q)) 2500 #endif 2501 2502 #define GEN_LD(name, ldop, opc, type) \ 2503 static void glue(gen_, name)(DisasContext *ctx) \ 2504 { \ 2505 TCGv EA; \ 2506 gen_set_access_type(ctx, ACCESS_INT); \ 2507 EA = tcg_temp_new(); \ 2508 gen_addr_imm_index(ctx, EA, 0); \ 2509 gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA); \ 2510 tcg_temp_free(EA); \ 2511 } 2512 2513 #define GEN_LDU(name, ldop, opc, type) \ 2514 static void glue(gen_, name##u)(DisasContext *ctx) \ 2515 { \ 2516 TCGv EA; \ 2517 if (unlikely(rA(ctx->opcode) == 0 || \ 2518 rA(ctx->opcode) == rD(ctx->opcode))) { \ 2519 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \ 2520 return; \ 2521 } \ 2522 gen_set_access_type(ctx, ACCESS_INT); \ 2523 EA = tcg_temp_new(); \ 2524 if (type == PPC_64B) \ 2525 gen_addr_imm_index(ctx, EA, 0x03); \ 2526 else \ 2527 gen_addr_imm_index(ctx, EA, 0); \ 2528 gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA); \ 2529 tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \ 2530 tcg_temp_free(EA); \ 2531 } 2532 2533 #define GEN_LDUX(name, ldop, opc2, opc3, type) \ 2534 static void glue(gen_, name##ux)(DisasContext *ctx) \ 2535 { \ 2536 TCGv EA; \ 2537 if (unlikely(rA(ctx->opcode) == 0 || \ 2538 rA(ctx->opcode) == rD(ctx->opcode))) { \ 2539 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \ 2540 return; \ 2541 } \ 2542 gen_set_access_type(ctx, ACCESS_INT); \ 2543 EA = tcg_temp_new(); \ 2544 gen_addr_reg_index(ctx, EA); \ 2545 gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA); \ 2546 tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \ 2547 tcg_temp_free(EA); \ 2548 } 2549 2550 #define GEN_LDX_E(name, ldop, opc2, opc3, type, type2, chk) \ 2551 static void glue(gen_, name##x)(DisasContext *ctx) \ 2552 { \ 2553 TCGv EA; \ 2554 chk; \ 2555 gen_set_access_type(ctx, ACCESS_INT); \ 2556 EA = tcg_temp_new(); \ 2557 gen_addr_reg_index(ctx, EA); \ 2558 gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA); \ 2559 tcg_temp_free(EA); \ 2560 } 2561 2562 #define GEN_LDX(name, ldop, opc2, opc3, type) \ 2563 GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE, CHK_NONE) 2564 2565 #define GEN_LDX_HVRM(name, ldop, opc2, opc3, type) \ 2566 GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE, CHK_HVRM) 2567 2568 #define GEN_LDS(name, ldop, op, type) \ 2569 GEN_LD(name, ldop, op | 0x20, type); \ 2570 GEN_LDU(name, ldop, op | 0x21, type); \ 2571 GEN_LDUX(name, ldop, 0x17, op | 0x01, type); \ 2572 GEN_LDX(name, ldop, 0x17, op | 0x00, type) 2573 2574 /* lbz lbzu lbzux lbzx */ 2575 GEN_LDS(lbz, ld8u, 0x02, PPC_INTEGER); 2576 /* lha lhau lhaux lhax */ 2577 GEN_LDS(lha, ld16s, 0x0A, PPC_INTEGER); 2578 /* lhz lhzu lhzux lhzx */ 2579 GEN_LDS(lhz, ld16u, 0x08, PPC_INTEGER); 2580 /* lwz lwzu lwzux lwzx */ 2581 GEN_LDS(lwz, ld32u, 0x00, PPC_INTEGER); 2582 2583 #define GEN_LDEPX(name, ldop, opc2, opc3) \ 2584 static void glue(gen_, name##epx)(DisasContext *ctx) \ 2585 { \ 2586 TCGv EA; \ 2587 CHK_SV; \ 2588 gen_set_access_type(ctx, ACCESS_INT); \ 2589 EA = tcg_temp_new(); \ 2590 gen_addr_reg_index(ctx, EA); \ 2591 tcg_gen_qemu_ld_tl(cpu_gpr[rD(ctx->opcode)], EA, PPC_TLB_EPID_LOAD, ldop);\ 2592 tcg_temp_free(EA); \ 2593 } 2594 2595 GEN_LDEPX(lb, DEF_MEMOP(MO_UB), 0x1F, 0x02) 2596 GEN_LDEPX(lh, DEF_MEMOP(MO_UW), 0x1F, 0x08) 2597 GEN_LDEPX(lw, DEF_MEMOP(MO_UL), 0x1F, 0x00) 2598 #if defined(TARGET_PPC64) 2599 GEN_LDEPX(ld, DEF_MEMOP(MO_Q), 0x1D, 0x00) 2600 #endif 2601 2602 #if defined(TARGET_PPC64) 2603 /* lwaux */ 2604 GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B); 2605 /* lwax */ 2606 GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B); 2607 /* ldux */ 2608 GEN_LDUX(ld, ld64_i64, 0x15, 0x01, PPC_64B); 2609 /* ldx */ 2610 GEN_LDX(ld, ld64_i64, 0x15, 0x00, PPC_64B); 2611 2612 /* CI load/store variants */ 2613 GEN_LDX_HVRM(ldcix, ld64_i64, 0x15, 0x1b, PPC_CILDST) 2614 GEN_LDX_HVRM(lwzcix, ld32u, 0x15, 0x15, PPC_CILDST) 2615 GEN_LDX_HVRM(lhzcix, ld16u, 0x15, 0x19, PPC_CILDST) 2616 GEN_LDX_HVRM(lbzcix, ld8u, 0x15, 0x1a, PPC_CILDST) 2617 2618 static void gen_ld(DisasContext *ctx) 2619 { 2620 TCGv EA; 2621 if (Rc(ctx->opcode)) { 2622 if (unlikely(rA(ctx->opcode) == 0 || 2623 rA(ctx->opcode) == rD(ctx->opcode))) { 2624 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 2625 return; 2626 } 2627 } 2628 gen_set_access_type(ctx, ACCESS_INT); 2629 EA = tcg_temp_new(); 2630 gen_addr_imm_index(ctx, EA, 0x03); 2631 if (ctx->opcode & 0x02) { 2632 /* lwa (lwau is undefined) */ 2633 gen_qemu_ld32s(ctx, cpu_gpr[rD(ctx->opcode)], EA); 2634 } else { 2635 /* ld - ldu */ 2636 gen_qemu_ld64_i64(ctx, cpu_gpr[rD(ctx->opcode)], EA); 2637 } 2638 if (Rc(ctx->opcode)) { 2639 tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); 2640 } 2641 tcg_temp_free(EA); 2642 } 2643 2644 /* lq */ 2645 static void gen_lq(DisasContext *ctx) 2646 { 2647 int ra, rd; 2648 TCGv EA, hi, lo; 2649 2650 /* lq is a legal user mode instruction starting in ISA 2.07 */ 2651 bool legal_in_user_mode = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0; 2652 bool le_is_supported = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0; 2653 2654 if (!legal_in_user_mode && ctx->pr) { 2655 gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC); 2656 return; 2657 } 2658 2659 if (!le_is_supported && ctx->le_mode) { 2660 gen_align_no_le(ctx); 2661 return; 2662 } 2663 ra = rA(ctx->opcode); 2664 rd = rD(ctx->opcode); 2665 if (unlikely((rd & 1) || rd == ra)) { 2666 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 2667 return; 2668 } 2669 2670 gen_set_access_type(ctx, ACCESS_INT); 2671 EA = tcg_temp_new(); 2672 gen_addr_imm_index(ctx, EA, 0x0F); 2673 2674 /* Note that the low part is always in RD+1, even in LE mode. */ 2675 lo = cpu_gpr[rd + 1]; 2676 hi = cpu_gpr[rd]; 2677 2678 if (tb_cflags(ctx->base.tb) & CF_PARALLEL) { 2679 if (HAVE_ATOMIC128) { 2680 TCGv_i32 oi = tcg_temp_new_i32(); 2681 if (ctx->le_mode) { 2682 tcg_gen_movi_i32(oi, make_memop_idx(MO_LEQ, ctx->mem_idx)); 2683 gen_helper_lq_le_parallel(lo, cpu_env, EA, oi); 2684 } else { 2685 tcg_gen_movi_i32(oi, make_memop_idx(MO_BEQ, ctx->mem_idx)); 2686 gen_helper_lq_be_parallel(lo, cpu_env, EA, oi); 2687 } 2688 tcg_temp_free_i32(oi); 2689 tcg_gen_ld_i64(hi, cpu_env, offsetof(CPUPPCState, retxh)); 2690 } else { 2691 /* Restart with exclusive lock. */ 2692 gen_helper_exit_atomic(cpu_env); 2693 ctx->base.is_jmp = DISAS_NORETURN; 2694 } 2695 } else if (ctx->le_mode) { 2696 tcg_gen_qemu_ld_i64(lo, EA, ctx->mem_idx, MO_LEQ); 2697 gen_addr_add(ctx, EA, EA, 8); 2698 tcg_gen_qemu_ld_i64(hi, EA, ctx->mem_idx, MO_LEQ); 2699 } else { 2700 tcg_gen_qemu_ld_i64(hi, EA, ctx->mem_idx, MO_BEQ); 2701 gen_addr_add(ctx, EA, EA, 8); 2702 tcg_gen_qemu_ld_i64(lo, EA, ctx->mem_idx, MO_BEQ); 2703 } 2704 tcg_temp_free(EA); 2705 } 2706 #endif 2707 2708 /*** Integer store ***/ 2709 #define GEN_ST(name, stop, opc, type) \ 2710 static void glue(gen_, name)(DisasContext *ctx) \ 2711 { \ 2712 TCGv EA; \ 2713 gen_set_access_type(ctx, ACCESS_INT); \ 2714 EA = tcg_temp_new(); \ 2715 gen_addr_imm_index(ctx, EA, 0); \ 2716 gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA); \ 2717 tcg_temp_free(EA); \ 2718 } 2719 2720 #define GEN_STU(name, stop, opc, type) \ 2721 static void glue(gen_, stop##u)(DisasContext *ctx) \ 2722 { \ 2723 TCGv EA; \ 2724 if (unlikely(rA(ctx->opcode) == 0)) { \ 2725 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \ 2726 return; \ 2727 } \ 2728 gen_set_access_type(ctx, ACCESS_INT); \ 2729 EA = tcg_temp_new(); \ 2730 if (type == PPC_64B) \ 2731 gen_addr_imm_index(ctx, EA, 0x03); \ 2732 else \ 2733 gen_addr_imm_index(ctx, EA, 0); \ 2734 gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA); \ 2735 tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \ 2736 tcg_temp_free(EA); \ 2737 } 2738 2739 #define GEN_STUX(name, stop, opc2, opc3, type) \ 2740 static void glue(gen_, name##ux)(DisasContext *ctx) \ 2741 { \ 2742 TCGv EA; \ 2743 if (unlikely(rA(ctx->opcode) == 0)) { \ 2744 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \ 2745 return; \ 2746 } \ 2747 gen_set_access_type(ctx, ACCESS_INT); \ 2748 EA = tcg_temp_new(); \ 2749 gen_addr_reg_index(ctx, EA); \ 2750 gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA); \ 2751 tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \ 2752 tcg_temp_free(EA); \ 2753 } 2754 2755 #define GEN_STX_E(name, stop, opc2, opc3, type, type2, chk) \ 2756 static void glue(gen_, name##x)(DisasContext *ctx) \ 2757 { \ 2758 TCGv EA; \ 2759 chk; \ 2760 gen_set_access_type(ctx, ACCESS_INT); \ 2761 EA = tcg_temp_new(); \ 2762 gen_addr_reg_index(ctx, EA); \ 2763 gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA); \ 2764 tcg_temp_free(EA); \ 2765 } 2766 #define GEN_STX(name, stop, opc2, opc3, type) \ 2767 GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE, CHK_NONE) 2768 2769 #define GEN_STX_HVRM(name, stop, opc2, opc3, type) \ 2770 GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE, CHK_HVRM) 2771 2772 #define GEN_STS(name, stop, op, type) \ 2773 GEN_ST(name, stop, op | 0x20, type); \ 2774 GEN_STU(name, stop, op | 0x21, type); \ 2775 GEN_STUX(name, stop, 0x17, op | 0x01, type); \ 2776 GEN_STX(name, stop, 0x17, op | 0x00, type) 2777 2778 /* stb stbu stbux stbx */ 2779 GEN_STS(stb, st8, 0x06, PPC_INTEGER); 2780 /* sth sthu sthux sthx */ 2781 GEN_STS(sth, st16, 0x0C, PPC_INTEGER); 2782 /* stw stwu stwux stwx */ 2783 GEN_STS(stw, st32, 0x04, PPC_INTEGER); 2784 2785 #define GEN_STEPX(name, stop, opc2, opc3) \ 2786 static void glue(gen_, name##epx)(DisasContext *ctx) \ 2787 { \ 2788 TCGv EA; \ 2789 CHK_SV; \ 2790 gen_set_access_type(ctx, ACCESS_INT); \ 2791 EA = tcg_temp_new(); \ 2792 gen_addr_reg_index(ctx, EA); \ 2793 tcg_gen_qemu_st_tl( \ 2794 cpu_gpr[rD(ctx->opcode)], EA, PPC_TLB_EPID_STORE, stop); \ 2795 tcg_temp_free(EA); \ 2796 } 2797 2798 GEN_STEPX(stb, DEF_MEMOP(MO_UB), 0x1F, 0x06) 2799 GEN_STEPX(sth, DEF_MEMOP(MO_UW), 0x1F, 0x0C) 2800 GEN_STEPX(stw, DEF_MEMOP(MO_UL), 0x1F, 0x04) 2801 #if defined(TARGET_PPC64) 2802 GEN_STEPX(std, DEF_MEMOP(MO_Q), 0x1d, 0x04) 2803 #endif 2804 2805 #if defined(TARGET_PPC64) 2806 GEN_STUX(std, st64_i64, 0x15, 0x05, PPC_64B); 2807 GEN_STX(std, st64_i64, 0x15, 0x04, PPC_64B); 2808 GEN_STX_HVRM(stdcix, st64_i64, 0x15, 0x1f, PPC_CILDST) 2809 GEN_STX_HVRM(stwcix, st32, 0x15, 0x1c, PPC_CILDST) 2810 GEN_STX_HVRM(sthcix, st16, 0x15, 0x1d, PPC_CILDST) 2811 GEN_STX_HVRM(stbcix, st8, 0x15, 0x1e, PPC_CILDST) 2812 2813 static void gen_std(DisasContext *ctx) 2814 { 2815 int rs; 2816 TCGv EA; 2817 2818 rs = rS(ctx->opcode); 2819 if ((ctx->opcode & 0x3) == 0x2) { /* stq */ 2820 bool legal_in_user_mode = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0; 2821 bool le_is_supported = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0; 2822 TCGv hi, lo; 2823 2824 if (!(ctx->insns_flags & PPC_64BX)) { 2825 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 2826 } 2827 2828 if (!legal_in_user_mode && ctx->pr) { 2829 gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC); 2830 return; 2831 } 2832 2833 if (!le_is_supported && ctx->le_mode) { 2834 gen_align_no_le(ctx); 2835 return; 2836 } 2837 2838 if (unlikely(rs & 1)) { 2839 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 2840 return; 2841 } 2842 gen_set_access_type(ctx, ACCESS_INT); 2843 EA = tcg_temp_new(); 2844 gen_addr_imm_index(ctx, EA, 0x03); 2845 2846 /* Note that the low part is always in RS+1, even in LE mode. */ 2847 lo = cpu_gpr[rs + 1]; 2848 hi = cpu_gpr[rs]; 2849 2850 if (tb_cflags(ctx->base.tb) & CF_PARALLEL) { 2851 if (HAVE_ATOMIC128) { 2852 TCGv_i32 oi = tcg_temp_new_i32(); 2853 if (ctx->le_mode) { 2854 tcg_gen_movi_i32(oi, make_memop_idx(MO_LEQ, ctx->mem_idx)); 2855 gen_helper_stq_le_parallel(cpu_env, EA, lo, hi, oi); 2856 } else { 2857 tcg_gen_movi_i32(oi, make_memop_idx(MO_BEQ, ctx->mem_idx)); 2858 gen_helper_stq_be_parallel(cpu_env, EA, lo, hi, oi); 2859 } 2860 tcg_temp_free_i32(oi); 2861 } else { 2862 /* Restart with exclusive lock. */ 2863 gen_helper_exit_atomic(cpu_env); 2864 ctx->base.is_jmp = DISAS_NORETURN; 2865 } 2866 } else if (ctx->le_mode) { 2867 tcg_gen_qemu_st_i64(lo, EA, ctx->mem_idx, MO_LEQ); 2868 gen_addr_add(ctx, EA, EA, 8); 2869 tcg_gen_qemu_st_i64(hi, EA, ctx->mem_idx, MO_LEQ); 2870 } else { 2871 tcg_gen_qemu_st_i64(hi, EA, ctx->mem_idx, MO_BEQ); 2872 gen_addr_add(ctx, EA, EA, 8); 2873 tcg_gen_qemu_st_i64(lo, EA, ctx->mem_idx, MO_BEQ); 2874 } 2875 tcg_temp_free(EA); 2876 } else { 2877 /* std / stdu */ 2878 if (Rc(ctx->opcode)) { 2879 if (unlikely(rA(ctx->opcode) == 0)) { 2880 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 2881 return; 2882 } 2883 } 2884 gen_set_access_type(ctx, ACCESS_INT); 2885 EA = tcg_temp_new(); 2886 gen_addr_imm_index(ctx, EA, 0x03); 2887 gen_qemu_st64_i64(ctx, cpu_gpr[rs], EA); 2888 if (Rc(ctx->opcode)) { 2889 tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); 2890 } 2891 tcg_temp_free(EA); 2892 } 2893 } 2894 #endif 2895 /*** Integer load and store with byte reverse ***/ 2896 2897 /* lhbrx */ 2898 GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER); 2899 2900 /* lwbrx */ 2901 GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER); 2902 2903 #if defined(TARGET_PPC64) 2904 /* ldbrx */ 2905 GEN_LDX_E(ldbr, ld64ur_i64, 0x14, 0x10, PPC_NONE, PPC2_DBRX, CHK_NONE); 2906 /* stdbrx */ 2907 GEN_STX_E(stdbr, st64r_i64, 0x14, 0x14, PPC_NONE, PPC2_DBRX, CHK_NONE); 2908 #endif /* TARGET_PPC64 */ 2909 2910 /* sthbrx */ 2911 GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER); 2912 /* stwbrx */ 2913 GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER); 2914 2915 /*** Integer load and store multiple ***/ 2916 2917 /* lmw */ 2918 static void gen_lmw(DisasContext *ctx) 2919 { 2920 TCGv t0; 2921 TCGv_i32 t1; 2922 2923 if (ctx->le_mode) { 2924 gen_align_no_le(ctx); 2925 return; 2926 } 2927 gen_set_access_type(ctx, ACCESS_INT); 2928 t0 = tcg_temp_new(); 2929 t1 = tcg_const_i32(rD(ctx->opcode)); 2930 gen_addr_imm_index(ctx, t0, 0); 2931 gen_helper_lmw(cpu_env, t0, t1); 2932 tcg_temp_free(t0); 2933 tcg_temp_free_i32(t1); 2934 } 2935 2936 /* stmw */ 2937 static void gen_stmw(DisasContext *ctx) 2938 { 2939 TCGv t0; 2940 TCGv_i32 t1; 2941 2942 if (ctx->le_mode) { 2943 gen_align_no_le(ctx); 2944 return; 2945 } 2946 gen_set_access_type(ctx, ACCESS_INT); 2947 t0 = tcg_temp_new(); 2948 t1 = tcg_const_i32(rS(ctx->opcode)); 2949 gen_addr_imm_index(ctx, t0, 0); 2950 gen_helper_stmw(cpu_env, t0, t1); 2951 tcg_temp_free(t0); 2952 tcg_temp_free_i32(t1); 2953 } 2954 2955 /*** Integer load and store strings ***/ 2956 2957 /* lswi */ 2958 /* 2959 * PowerPC32 specification says we must generate an exception if rA is 2960 * in the range of registers to be loaded. In an other hand, IBM says 2961 * this is valid, but rA won't be loaded. For now, I'll follow the 2962 * spec... 2963 */ 2964 static void gen_lswi(DisasContext *ctx) 2965 { 2966 TCGv t0; 2967 TCGv_i32 t1, t2; 2968 int nb = NB(ctx->opcode); 2969 int start = rD(ctx->opcode); 2970 int ra = rA(ctx->opcode); 2971 int nr; 2972 2973 if (ctx->le_mode) { 2974 gen_align_no_le(ctx); 2975 return; 2976 } 2977 if (nb == 0) { 2978 nb = 32; 2979 } 2980 nr = DIV_ROUND_UP(nb, 4); 2981 if (unlikely(lsw_reg_in_range(start, nr, ra))) { 2982 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX); 2983 return; 2984 } 2985 gen_set_access_type(ctx, ACCESS_INT); 2986 t0 = tcg_temp_new(); 2987 gen_addr_register(ctx, t0); 2988 t1 = tcg_const_i32(nb); 2989 t2 = tcg_const_i32(start); 2990 gen_helper_lsw(cpu_env, t0, t1, t2); 2991 tcg_temp_free(t0); 2992 tcg_temp_free_i32(t1); 2993 tcg_temp_free_i32(t2); 2994 } 2995 2996 /* lswx */ 2997 static void gen_lswx(DisasContext *ctx) 2998 { 2999 TCGv t0; 3000 TCGv_i32 t1, t2, t3; 3001 3002 if (ctx->le_mode) { 3003 gen_align_no_le(ctx); 3004 return; 3005 } 3006 gen_set_access_type(ctx, ACCESS_INT); 3007 t0 = tcg_temp_new(); 3008 gen_addr_reg_index(ctx, t0); 3009 t1 = tcg_const_i32(rD(ctx->opcode)); 3010 t2 = tcg_const_i32(rA(ctx->opcode)); 3011 t3 = tcg_const_i32(rB(ctx->opcode)); 3012 gen_helper_lswx(cpu_env, t0, t1, t2, t3); 3013 tcg_temp_free(t0); 3014 tcg_temp_free_i32(t1); 3015 tcg_temp_free_i32(t2); 3016 tcg_temp_free_i32(t3); 3017 } 3018 3019 /* stswi */ 3020 static void gen_stswi(DisasContext *ctx) 3021 { 3022 TCGv t0; 3023 TCGv_i32 t1, t2; 3024 int nb = NB(ctx->opcode); 3025 3026 if (ctx->le_mode) { 3027 gen_align_no_le(ctx); 3028 return; 3029 } 3030 gen_set_access_type(ctx, ACCESS_INT); 3031 t0 = tcg_temp_new(); 3032 gen_addr_register(ctx, t0); 3033 if (nb == 0) { 3034 nb = 32; 3035 } 3036 t1 = tcg_const_i32(nb); 3037 t2 = tcg_const_i32(rS(ctx->opcode)); 3038 gen_helper_stsw(cpu_env, t0, t1, t2); 3039 tcg_temp_free(t0); 3040 tcg_temp_free_i32(t1); 3041 tcg_temp_free_i32(t2); 3042 } 3043 3044 /* stswx */ 3045 static void gen_stswx(DisasContext *ctx) 3046 { 3047 TCGv t0; 3048 TCGv_i32 t1, t2; 3049 3050 if (ctx->le_mode) { 3051 gen_align_no_le(ctx); 3052 return; 3053 } 3054 gen_set_access_type(ctx, ACCESS_INT); 3055 t0 = tcg_temp_new(); 3056 gen_addr_reg_index(ctx, t0); 3057 t1 = tcg_temp_new_i32(); 3058 tcg_gen_trunc_tl_i32(t1, cpu_xer); 3059 tcg_gen_andi_i32(t1, t1, 0x7F); 3060 t2 = tcg_const_i32(rS(ctx->opcode)); 3061 gen_helper_stsw(cpu_env, t0, t1, t2); 3062 tcg_temp_free(t0); 3063 tcg_temp_free_i32(t1); 3064 tcg_temp_free_i32(t2); 3065 } 3066 3067 /*** Memory synchronisation ***/ 3068 /* eieio */ 3069 static void gen_eieio(DisasContext *ctx) 3070 { 3071 TCGBar bar = TCG_MO_LD_ST; 3072 3073 /* 3074 * POWER9 has a eieio instruction variant using bit 6 as a hint to 3075 * tell the CPU it is a store-forwarding barrier. 3076 */ 3077 if (ctx->opcode & 0x2000000) { 3078 /* 3079 * ISA says that "Reserved fields in instructions are ignored 3080 * by the processor". So ignore the bit 6 on non-POWER9 CPU but 3081 * as this is not an instruction software should be using, 3082 * complain to the user. 3083 */ 3084 if (!(ctx->insns_flags2 & PPC2_ISA300)) { 3085 qemu_log_mask(LOG_GUEST_ERROR, "invalid eieio using bit 6 at @" 3086 TARGET_FMT_lx "\n", ctx->base.pc_next - 4); 3087 } else { 3088 bar = TCG_MO_ST_LD; 3089 } 3090 } 3091 3092 tcg_gen_mb(bar | TCG_BAR_SC); 3093 } 3094 3095 #if !defined(CONFIG_USER_ONLY) 3096 static inline void gen_check_tlb_flush(DisasContext *ctx, bool global) 3097 { 3098 TCGv_i32 t; 3099 TCGLabel *l; 3100 3101 if (!ctx->lazy_tlb_flush) { 3102 return; 3103 } 3104 l = gen_new_label(); 3105 t = tcg_temp_new_i32(); 3106 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUPPCState, tlb_need_flush)); 3107 tcg_gen_brcondi_i32(TCG_COND_EQ, t, 0, l); 3108 if (global) { 3109 gen_helper_check_tlb_flush_global(cpu_env); 3110 } else { 3111 gen_helper_check_tlb_flush_local(cpu_env); 3112 } 3113 gen_set_label(l); 3114 tcg_temp_free_i32(t); 3115 } 3116 #else 3117 static inline void gen_check_tlb_flush(DisasContext *ctx, bool global) { } 3118 #endif 3119 3120 /* isync */ 3121 static void gen_isync(DisasContext *ctx) 3122 { 3123 /* 3124 * We need to check for a pending TLB flush. This can only happen in 3125 * kernel mode however so check MSR_PR 3126 */ 3127 if (!ctx->pr) { 3128 gen_check_tlb_flush(ctx, false); 3129 } 3130 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC); 3131 gen_stop_exception(ctx); 3132 } 3133 3134 #define MEMOP_GET_SIZE(x) (1 << ((x) & MO_SIZE)) 3135 3136 static void gen_load_locked(DisasContext *ctx, TCGMemOp memop) 3137 { 3138 TCGv gpr = cpu_gpr[rD(ctx->opcode)]; 3139 TCGv t0 = tcg_temp_new(); 3140 3141 gen_set_access_type(ctx, ACCESS_RES); 3142 gen_addr_reg_index(ctx, t0); 3143 tcg_gen_qemu_ld_tl(gpr, t0, ctx->mem_idx, memop | MO_ALIGN); 3144 tcg_gen_mov_tl(cpu_reserve, t0); 3145 tcg_gen_mov_tl(cpu_reserve_val, gpr); 3146 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ); 3147 tcg_temp_free(t0); 3148 } 3149 3150 #define LARX(name, memop) \ 3151 static void gen_##name(DisasContext *ctx) \ 3152 { \ 3153 gen_load_locked(ctx, memop); \ 3154 } 3155 3156 /* lwarx */ 3157 LARX(lbarx, DEF_MEMOP(MO_UB)) 3158 LARX(lharx, DEF_MEMOP(MO_UW)) 3159 LARX(lwarx, DEF_MEMOP(MO_UL)) 3160 3161 static void gen_fetch_inc_conditional(DisasContext *ctx, TCGMemOp memop, 3162 TCGv EA, TCGCond cond, int addend) 3163 { 3164 TCGv t = tcg_temp_new(); 3165 TCGv t2 = tcg_temp_new(); 3166 TCGv u = tcg_temp_new(); 3167 3168 tcg_gen_qemu_ld_tl(t, EA, ctx->mem_idx, memop); 3169 tcg_gen_addi_tl(t2, EA, MEMOP_GET_SIZE(memop)); 3170 tcg_gen_qemu_ld_tl(t2, t2, ctx->mem_idx, memop); 3171 tcg_gen_addi_tl(u, t, addend); 3172 3173 /* E.g. for fetch and increment bounded... */ 3174 /* mem(EA,s) = (t != t2 ? u = t + 1 : t) */ 3175 tcg_gen_movcond_tl(cond, u, t, t2, u, t); 3176 tcg_gen_qemu_st_tl(u, EA, ctx->mem_idx, memop); 3177 3178 /* RT = (t != t2 ? t : u = 1<<(s*8-1)) */ 3179 tcg_gen_movi_tl(u, 1 << (MEMOP_GET_SIZE(memop) * 8 - 1)); 3180 tcg_gen_movcond_tl(cond, cpu_gpr[rD(ctx->opcode)], t, t2, t, u); 3181 3182 tcg_temp_free(t); 3183 tcg_temp_free(t2); 3184 tcg_temp_free(u); 3185 } 3186 3187 static void gen_ld_atomic(DisasContext *ctx, TCGMemOp memop) 3188 { 3189 uint32_t gpr_FC = FC(ctx->opcode); 3190 TCGv EA = tcg_temp_new(); 3191 int rt = rD(ctx->opcode); 3192 bool need_serial; 3193 TCGv src, dst; 3194 3195 gen_addr_register(ctx, EA); 3196 dst = cpu_gpr[rt]; 3197 src = cpu_gpr[(rt + 1) & 31]; 3198 3199 need_serial = false; 3200 memop |= MO_ALIGN; 3201 switch (gpr_FC) { 3202 case 0: /* Fetch and add */ 3203 tcg_gen_atomic_fetch_add_tl(dst, EA, src, ctx->mem_idx, memop); 3204 break; 3205 case 1: /* Fetch and xor */ 3206 tcg_gen_atomic_fetch_xor_tl(dst, EA, src, ctx->mem_idx, memop); 3207 break; 3208 case 2: /* Fetch and or */ 3209 tcg_gen_atomic_fetch_or_tl(dst, EA, src, ctx->mem_idx, memop); 3210 break; 3211 case 3: /* Fetch and 'and' */ 3212 tcg_gen_atomic_fetch_and_tl(dst, EA, src, ctx->mem_idx, memop); 3213 break; 3214 case 4: /* Fetch and max unsigned */ 3215 tcg_gen_atomic_fetch_umax_tl(dst, EA, src, ctx->mem_idx, memop); 3216 break; 3217 case 5: /* Fetch and max signed */ 3218 tcg_gen_atomic_fetch_smax_tl(dst, EA, src, ctx->mem_idx, memop); 3219 break; 3220 case 6: /* Fetch and min unsigned */ 3221 tcg_gen_atomic_fetch_umin_tl(dst, EA, src, ctx->mem_idx, memop); 3222 break; 3223 case 7: /* Fetch and min signed */ 3224 tcg_gen_atomic_fetch_smin_tl(dst, EA, src, ctx->mem_idx, memop); 3225 break; 3226 case 8: /* Swap */ 3227 tcg_gen_atomic_xchg_tl(dst, EA, src, ctx->mem_idx, memop); 3228 break; 3229 3230 case 16: /* Compare and swap not equal */ 3231 if (tb_cflags(ctx->base.tb) & CF_PARALLEL) { 3232 need_serial = true; 3233 } else { 3234 TCGv t0 = tcg_temp_new(); 3235 TCGv t1 = tcg_temp_new(); 3236 3237 tcg_gen_qemu_ld_tl(t0, EA, ctx->mem_idx, memop); 3238 if ((memop & MO_SIZE) == MO_64 || TARGET_LONG_BITS == 32) { 3239 tcg_gen_mov_tl(t1, src); 3240 } else { 3241 tcg_gen_ext32u_tl(t1, src); 3242 } 3243 tcg_gen_movcond_tl(TCG_COND_NE, t1, t0, t1, 3244 cpu_gpr[(rt + 2) & 31], t0); 3245 tcg_gen_qemu_st_tl(t1, EA, ctx->mem_idx, memop); 3246 tcg_gen_mov_tl(dst, t0); 3247 3248 tcg_temp_free(t0); 3249 tcg_temp_free(t1); 3250 } 3251 break; 3252 3253 case 24: /* Fetch and increment bounded */ 3254 if (tb_cflags(ctx->base.tb) & CF_PARALLEL) { 3255 need_serial = true; 3256 } else { 3257 gen_fetch_inc_conditional(ctx, memop, EA, TCG_COND_NE, 1); 3258 } 3259 break; 3260 case 25: /* Fetch and increment equal */ 3261 if (tb_cflags(ctx->base.tb) & CF_PARALLEL) { 3262 need_serial = true; 3263 } else { 3264 gen_fetch_inc_conditional(ctx, memop, EA, TCG_COND_EQ, 1); 3265 } 3266 break; 3267 case 28: /* Fetch and decrement bounded */ 3268 if (tb_cflags(ctx->base.tb) & CF_PARALLEL) { 3269 need_serial = true; 3270 } else { 3271 gen_fetch_inc_conditional(ctx, memop, EA, TCG_COND_NE, -1); 3272 } 3273 break; 3274 3275 default: 3276 /* invoke data storage error handler */ 3277 gen_exception_err(ctx, POWERPC_EXCP_DSI, POWERPC_EXCP_INVAL); 3278 } 3279 tcg_temp_free(EA); 3280 3281 if (need_serial) { 3282 /* Restart with exclusive lock. */ 3283 gen_helper_exit_atomic(cpu_env); 3284 ctx->base.is_jmp = DISAS_NORETURN; 3285 } 3286 } 3287 3288 static void gen_lwat(DisasContext *ctx) 3289 { 3290 gen_ld_atomic(ctx, DEF_MEMOP(MO_UL)); 3291 } 3292 3293 #ifdef TARGET_PPC64 3294 static void gen_ldat(DisasContext *ctx) 3295 { 3296 gen_ld_atomic(ctx, DEF_MEMOP(MO_Q)); 3297 } 3298 #endif 3299 3300 static void gen_st_atomic(DisasContext *ctx, TCGMemOp memop) 3301 { 3302 uint32_t gpr_FC = FC(ctx->opcode); 3303 TCGv EA = tcg_temp_new(); 3304 TCGv src, discard; 3305 3306 gen_addr_register(ctx, EA); 3307 src = cpu_gpr[rD(ctx->opcode)]; 3308 discard = tcg_temp_new(); 3309 3310 memop |= MO_ALIGN; 3311 switch (gpr_FC) { 3312 case 0: /* add and Store */ 3313 tcg_gen_atomic_add_fetch_tl(discard, EA, src, ctx->mem_idx, memop); 3314 break; 3315 case 1: /* xor and Store */ 3316 tcg_gen_atomic_xor_fetch_tl(discard, EA, src, ctx->mem_idx, memop); 3317 break; 3318 case 2: /* Or and Store */ 3319 tcg_gen_atomic_or_fetch_tl(discard, EA, src, ctx->mem_idx, memop); 3320 break; 3321 case 3: /* 'and' and Store */ 3322 tcg_gen_atomic_and_fetch_tl(discard, EA, src, ctx->mem_idx, memop); 3323 break; 3324 case 4: /* Store max unsigned */ 3325 tcg_gen_atomic_umax_fetch_tl(discard, EA, src, ctx->mem_idx, memop); 3326 break; 3327 case 5: /* Store max signed */ 3328 tcg_gen_atomic_smax_fetch_tl(discard, EA, src, ctx->mem_idx, memop); 3329 break; 3330 case 6: /* Store min unsigned */ 3331 tcg_gen_atomic_umin_fetch_tl(discard, EA, src, ctx->mem_idx, memop); 3332 break; 3333 case 7: /* Store min signed */ 3334 tcg_gen_atomic_smin_fetch_tl(discard, EA, src, ctx->mem_idx, memop); 3335 break; 3336 case 24: /* Store twin */ 3337 if (tb_cflags(ctx->base.tb) & CF_PARALLEL) { 3338 /* Restart with exclusive lock. */ 3339 gen_helper_exit_atomic(cpu_env); 3340 ctx->base.is_jmp = DISAS_NORETURN; 3341 } else { 3342 TCGv t = tcg_temp_new(); 3343 TCGv t2 = tcg_temp_new(); 3344 TCGv s = tcg_temp_new(); 3345 TCGv s2 = tcg_temp_new(); 3346 TCGv ea_plus_s = tcg_temp_new(); 3347 3348 tcg_gen_qemu_ld_tl(t, EA, ctx->mem_idx, memop); 3349 tcg_gen_addi_tl(ea_plus_s, EA, MEMOP_GET_SIZE(memop)); 3350 tcg_gen_qemu_ld_tl(t2, ea_plus_s, ctx->mem_idx, memop); 3351 tcg_gen_movcond_tl(TCG_COND_EQ, s, t, t2, src, t); 3352 tcg_gen_movcond_tl(TCG_COND_EQ, s2, t, t2, src, t2); 3353 tcg_gen_qemu_st_tl(s, EA, ctx->mem_idx, memop); 3354 tcg_gen_qemu_st_tl(s2, ea_plus_s, ctx->mem_idx, memop); 3355 3356 tcg_temp_free(ea_plus_s); 3357 tcg_temp_free(s2); 3358 tcg_temp_free(s); 3359 tcg_temp_free(t2); 3360 tcg_temp_free(t); 3361 } 3362 break; 3363 default: 3364 /* invoke data storage error handler */ 3365 gen_exception_err(ctx, POWERPC_EXCP_DSI, POWERPC_EXCP_INVAL); 3366 } 3367 tcg_temp_free(discard); 3368 tcg_temp_free(EA); 3369 } 3370 3371 static void gen_stwat(DisasContext *ctx) 3372 { 3373 gen_st_atomic(ctx, DEF_MEMOP(MO_UL)); 3374 } 3375 3376 #ifdef TARGET_PPC64 3377 static void gen_stdat(DisasContext *ctx) 3378 { 3379 gen_st_atomic(ctx, DEF_MEMOP(MO_Q)); 3380 } 3381 #endif 3382 3383 static void gen_conditional_store(DisasContext *ctx, TCGMemOp memop) 3384 { 3385 TCGLabel *l1 = gen_new_label(); 3386 TCGLabel *l2 = gen_new_label(); 3387 TCGv t0 = tcg_temp_new(); 3388 int reg = rS(ctx->opcode); 3389 3390 gen_set_access_type(ctx, ACCESS_RES); 3391 gen_addr_reg_index(ctx, t0); 3392 tcg_gen_brcond_tl(TCG_COND_NE, t0, cpu_reserve, l1); 3393 tcg_temp_free(t0); 3394 3395 t0 = tcg_temp_new(); 3396 tcg_gen_atomic_cmpxchg_tl(t0, cpu_reserve, cpu_reserve_val, 3397 cpu_gpr[reg], ctx->mem_idx, 3398 DEF_MEMOP(memop) | MO_ALIGN); 3399 tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_reserve_val); 3400 tcg_gen_shli_tl(t0, t0, CRF_EQ_BIT); 3401 tcg_gen_or_tl(t0, t0, cpu_so); 3402 tcg_gen_trunc_tl_i32(cpu_crf[0], t0); 3403 tcg_temp_free(t0); 3404 tcg_gen_br(l2); 3405 3406 gen_set_label(l1); 3407 3408 /* 3409 * Address mismatch implies failure. But we still need to provide 3410 * the memory barrier semantics of the instruction. 3411 */ 3412 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL); 3413 tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so); 3414 3415 gen_set_label(l2); 3416 tcg_gen_movi_tl(cpu_reserve, -1); 3417 } 3418 3419 #define STCX(name, memop) \ 3420 static void gen_##name(DisasContext *ctx) \ 3421 { \ 3422 gen_conditional_store(ctx, memop); \ 3423 } 3424 3425 STCX(stbcx_, DEF_MEMOP(MO_UB)) 3426 STCX(sthcx_, DEF_MEMOP(MO_UW)) 3427 STCX(stwcx_, DEF_MEMOP(MO_UL)) 3428 3429 #if defined(TARGET_PPC64) 3430 /* ldarx */ 3431 LARX(ldarx, DEF_MEMOP(MO_Q)) 3432 /* stdcx. */ 3433 STCX(stdcx_, DEF_MEMOP(MO_Q)) 3434 3435 /* lqarx */ 3436 static void gen_lqarx(DisasContext *ctx) 3437 { 3438 int rd = rD(ctx->opcode); 3439 TCGv EA, hi, lo; 3440 3441 if (unlikely((rd & 1) || (rd == rA(ctx->opcode)) || 3442 (rd == rB(ctx->opcode)))) { 3443 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 3444 return; 3445 } 3446 3447 gen_set_access_type(ctx, ACCESS_RES); 3448 EA = tcg_temp_new(); 3449 gen_addr_reg_index(ctx, EA); 3450 3451 /* Note that the low part is always in RD+1, even in LE mode. */ 3452 lo = cpu_gpr[rd + 1]; 3453 hi = cpu_gpr[rd]; 3454 3455 if (tb_cflags(ctx->base.tb) & CF_PARALLEL) { 3456 if (HAVE_ATOMIC128) { 3457 TCGv_i32 oi = tcg_temp_new_i32(); 3458 if (ctx->le_mode) { 3459 tcg_gen_movi_i32(oi, make_memop_idx(MO_LEQ | MO_ALIGN_16, 3460 ctx->mem_idx)); 3461 gen_helper_lq_le_parallel(lo, cpu_env, EA, oi); 3462 } else { 3463 tcg_gen_movi_i32(oi, make_memop_idx(MO_BEQ | MO_ALIGN_16, 3464 ctx->mem_idx)); 3465 gen_helper_lq_be_parallel(lo, cpu_env, EA, oi); 3466 } 3467 tcg_temp_free_i32(oi); 3468 tcg_gen_ld_i64(hi, cpu_env, offsetof(CPUPPCState, retxh)); 3469 } else { 3470 /* Restart with exclusive lock. */ 3471 gen_helper_exit_atomic(cpu_env); 3472 ctx->base.is_jmp = DISAS_NORETURN; 3473 tcg_temp_free(EA); 3474 return; 3475 } 3476 } else if (ctx->le_mode) { 3477 tcg_gen_qemu_ld_i64(lo, EA, ctx->mem_idx, MO_LEQ | MO_ALIGN_16); 3478 tcg_gen_mov_tl(cpu_reserve, EA); 3479 gen_addr_add(ctx, EA, EA, 8); 3480 tcg_gen_qemu_ld_i64(hi, EA, ctx->mem_idx, MO_LEQ); 3481 } else { 3482 tcg_gen_qemu_ld_i64(hi, EA, ctx->mem_idx, MO_BEQ | MO_ALIGN_16); 3483 tcg_gen_mov_tl(cpu_reserve, EA); 3484 gen_addr_add(ctx, EA, EA, 8); 3485 tcg_gen_qemu_ld_i64(lo, EA, ctx->mem_idx, MO_BEQ); 3486 } 3487 tcg_temp_free(EA); 3488 3489 tcg_gen_st_tl(hi, cpu_env, offsetof(CPUPPCState, reserve_val)); 3490 tcg_gen_st_tl(lo, cpu_env, offsetof(CPUPPCState, reserve_val2)); 3491 } 3492 3493 /* stqcx. */ 3494 static void gen_stqcx_(DisasContext *ctx) 3495 { 3496 int rs = rS(ctx->opcode); 3497 TCGv EA, hi, lo; 3498 3499 if (unlikely(rs & 1)) { 3500 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 3501 return; 3502 } 3503 3504 gen_set_access_type(ctx, ACCESS_RES); 3505 EA = tcg_temp_new(); 3506 gen_addr_reg_index(ctx, EA); 3507 3508 /* Note that the low part is always in RS+1, even in LE mode. */ 3509 lo = cpu_gpr[rs + 1]; 3510 hi = cpu_gpr[rs]; 3511 3512 if (tb_cflags(ctx->base.tb) & CF_PARALLEL) { 3513 if (HAVE_CMPXCHG128) { 3514 TCGv_i32 oi = tcg_const_i32(DEF_MEMOP(MO_Q) | MO_ALIGN_16); 3515 if (ctx->le_mode) { 3516 gen_helper_stqcx_le_parallel(cpu_crf[0], cpu_env, 3517 EA, lo, hi, oi); 3518 } else { 3519 gen_helper_stqcx_be_parallel(cpu_crf[0], cpu_env, 3520 EA, lo, hi, oi); 3521 } 3522 tcg_temp_free_i32(oi); 3523 } else { 3524 /* Restart with exclusive lock. */ 3525 gen_helper_exit_atomic(cpu_env); 3526 ctx->base.is_jmp = DISAS_NORETURN; 3527 } 3528 tcg_temp_free(EA); 3529 } else { 3530 TCGLabel *lab_fail = gen_new_label(); 3531 TCGLabel *lab_over = gen_new_label(); 3532 TCGv_i64 t0 = tcg_temp_new_i64(); 3533 TCGv_i64 t1 = tcg_temp_new_i64(); 3534 3535 tcg_gen_brcond_tl(TCG_COND_NE, EA, cpu_reserve, lab_fail); 3536 tcg_temp_free(EA); 3537 3538 gen_qemu_ld64_i64(ctx, t0, cpu_reserve); 3539 tcg_gen_ld_i64(t1, cpu_env, (ctx->le_mode 3540 ? offsetof(CPUPPCState, reserve_val2) 3541 : offsetof(CPUPPCState, reserve_val))); 3542 tcg_gen_brcond_i64(TCG_COND_NE, t0, t1, lab_fail); 3543 3544 tcg_gen_addi_i64(t0, cpu_reserve, 8); 3545 gen_qemu_ld64_i64(ctx, t0, t0); 3546 tcg_gen_ld_i64(t1, cpu_env, (ctx->le_mode 3547 ? offsetof(CPUPPCState, reserve_val) 3548 : offsetof(CPUPPCState, reserve_val2))); 3549 tcg_gen_brcond_i64(TCG_COND_NE, t0, t1, lab_fail); 3550 3551 /* Success */ 3552 gen_qemu_st64_i64(ctx, ctx->le_mode ? lo : hi, cpu_reserve); 3553 tcg_gen_addi_i64(t0, cpu_reserve, 8); 3554 gen_qemu_st64_i64(ctx, ctx->le_mode ? hi : lo, t0); 3555 3556 tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so); 3557 tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], CRF_EQ); 3558 tcg_gen_br(lab_over); 3559 3560 gen_set_label(lab_fail); 3561 tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so); 3562 3563 gen_set_label(lab_over); 3564 tcg_gen_movi_tl(cpu_reserve, -1); 3565 tcg_temp_free_i64(t0); 3566 tcg_temp_free_i64(t1); 3567 } 3568 } 3569 #endif /* defined(TARGET_PPC64) */ 3570 3571 /* sync */ 3572 static void gen_sync(DisasContext *ctx) 3573 { 3574 uint32_t l = (ctx->opcode >> 21) & 3; 3575 3576 /* 3577 * We may need to check for a pending TLB flush. 3578 * 3579 * We do this on ptesync (l == 2) on ppc64 and any sync pn ppc32. 3580 * 3581 * Additionally, this can only happen in kernel mode however so 3582 * check MSR_PR as well. 3583 */ 3584 if (((l == 2) || !(ctx->insns_flags & PPC_64B)) && !ctx->pr) { 3585 gen_check_tlb_flush(ctx, true); 3586 } 3587 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC); 3588 } 3589 3590 /* wait */ 3591 static void gen_wait(DisasContext *ctx) 3592 { 3593 TCGv_i32 t0 = tcg_const_i32(1); 3594 tcg_gen_st_i32(t0, cpu_env, 3595 -offsetof(PowerPCCPU, env) + offsetof(CPUState, halted)); 3596 tcg_temp_free_i32(t0); 3597 /* Stop translation, as the CPU is supposed to sleep from now */ 3598 gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next); 3599 } 3600 3601 #if defined(TARGET_PPC64) 3602 static void gen_doze(DisasContext *ctx) 3603 { 3604 #if defined(CONFIG_USER_ONLY) 3605 GEN_PRIV; 3606 #else 3607 TCGv_i32 t; 3608 3609 CHK_HV; 3610 t = tcg_const_i32(PPC_PM_DOZE); 3611 gen_helper_pminsn(cpu_env, t); 3612 tcg_temp_free_i32(t); 3613 /* Stop translation, as the CPU is supposed to sleep from now */ 3614 gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next); 3615 #endif /* defined(CONFIG_USER_ONLY) */ 3616 } 3617 3618 static void gen_nap(DisasContext *ctx) 3619 { 3620 #if defined(CONFIG_USER_ONLY) 3621 GEN_PRIV; 3622 #else 3623 TCGv_i32 t; 3624 3625 CHK_HV; 3626 t = tcg_const_i32(PPC_PM_NAP); 3627 gen_helper_pminsn(cpu_env, t); 3628 tcg_temp_free_i32(t); 3629 /* Stop translation, as the CPU is supposed to sleep from now */ 3630 gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next); 3631 #endif /* defined(CONFIG_USER_ONLY) */ 3632 } 3633 3634 static void gen_stop(DisasContext *ctx) 3635 { 3636 #if defined(CONFIG_USER_ONLY) 3637 GEN_PRIV; 3638 #else 3639 TCGv_i32 t; 3640 3641 CHK_HV; 3642 t = tcg_const_i32(PPC_PM_STOP); 3643 gen_helper_pminsn(cpu_env, t); 3644 tcg_temp_free_i32(t); 3645 /* Stop translation, as the CPU is supposed to sleep from now */ 3646 gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next); 3647 #endif /* defined(CONFIG_USER_ONLY) */ 3648 } 3649 3650 static void gen_sleep(DisasContext *ctx) 3651 { 3652 #if defined(CONFIG_USER_ONLY) 3653 GEN_PRIV; 3654 #else 3655 TCGv_i32 t; 3656 3657 CHK_HV; 3658 t = tcg_const_i32(PPC_PM_SLEEP); 3659 gen_helper_pminsn(cpu_env, t); 3660 tcg_temp_free_i32(t); 3661 /* Stop translation, as the CPU is supposed to sleep from now */ 3662 gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next); 3663 #endif /* defined(CONFIG_USER_ONLY) */ 3664 } 3665 3666 static void gen_rvwinkle(DisasContext *ctx) 3667 { 3668 #if defined(CONFIG_USER_ONLY) 3669 GEN_PRIV; 3670 #else 3671 TCGv_i32 t; 3672 3673 CHK_HV; 3674 t = tcg_const_i32(PPC_PM_RVWINKLE); 3675 gen_helper_pminsn(cpu_env, t); 3676 tcg_temp_free_i32(t); 3677 /* Stop translation, as the CPU is supposed to sleep from now */ 3678 gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next); 3679 #endif /* defined(CONFIG_USER_ONLY) */ 3680 } 3681 #endif /* #if defined(TARGET_PPC64) */ 3682 3683 static inline void gen_update_cfar(DisasContext *ctx, target_ulong nip) 3684 { 3685 #if defined(TARGET_PPC64) 3686 if (ctx->has_cfar) { 3687 tcg_gen_movi_tl(cpu_cfar, nip); 3688 } 3689 #endif 3690 } 3691 3692 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest) 3693 { 3694 if (unlikely(ctx->singlestep_enabled)) { 3695 return false; 3696 } 3697 3698 #ifndef CONFIG_USER_ONLY 3699 return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK); 3700 #else 3701 return true; 3702 #endif 3703 } 3704 3705 static void gen_lookup_and_goto_ptr(DisasContext *ctx) 3706 { 3707 int sse = ctx->singlestep_enabled; 3708 if (unlikely(sse)) { 3709 if (sse & GDBSTUB_SINGLE_STEP) { 3710 gen_debug_exception(ctx); 3711 } else if (sse & (CPU_SINGLE_STEP | CPU_BRANCH_STEP)) { 3712 uint32_t excp = gen_prep_dbgex(ctx); 3713 gen_exception(ctx, excp); 3714 } 3715 tcg_gen_exit_tb(NULL, 0); 3716 } else { 3717 tcg_gen_lookup_and_goto_ptr(); 3718 } 3719 } 3720 3721 /*** Branch ***/ 3722 static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) 3723 { 3724 if (NARROW_MODE(ctx)) { 3725 dest = (uint32_t) dest; 3726 } 3727 if (use_goto_tb(ctx, dest)) { 3728 tcg_gen_goto_tb(n); 3729 tcg_gen_movi_tl(cpu_nip, dest & ~3); 3730 tcg_gen_exit_tb(ctx->base.tb, n); 3731 } else { 3732 tcg_gen_movi_tl(cpu_nip, dest & ~3); 3733 gen_lookup_and_goto_ptr(ctx); 3734 } 3735 } 3736 3737 static inline void gen_setlr(DisasContext *ctx, target_ulong nip) 3738 { 3739 if (NARROW_MODE(ctx)) { 3740 nip = (uint32_t)nip; 3741 } 3742 tcg_gen_movi_tl(cpu_lr, nip); 3743 } 3744 3745 /* b ba bl bla */ 3746 static void gen_b(DisasContext *ctx) 3747 { 3748 target_ulong li, target; 3749 3750 ctx->exception = POWERPC_EXCP_BRANCH; 3751 /* sign extend LI */ 3752 li = LI(ctx->opcode); 3753 li = (li ^ 0x02000000) - 0x02000000; 3754 if (likely(AA(ctx->opcode) == 0)) { 3755 target = ctx->base.pc_next + li - 4; 3756 } else { 3757 target = li; 3758 } 3759 if (LK(ctx->opcode)) { 3760 gen_setlr(ctx, ctx->base.pc_next); 3761 } 3762 gen_update_cfar(ctx, ctx->base.pc_next - 4); 3763 gen_goto_tb(ctx, 0, target); 3764 } 3765 3766 #define BCOND_IM 0 3767 #define BCOND_LR 1 3768 #define BCOND_CTR 2 3769 #define BCOND_TAR 3 3770 3771 static void gen_bcond(DisasContext *ctx, int type) 3772 { 3773 uint32_t bo = BO(ctx->opcode); 3774 TCGLabel *l1; 3775 TCGv target; 3776 ctx->exception = POWERPC_EXCP_BRANCH; 3777 3778 if (type == BCOND_LR || type == BCOND_CTR || type == BCOND_TAR) { 3779 target = tcg_temp_local_new(); 3780 if (type == BCOND_CTR) { 3781 tcg_gen_mov_tl(target, cpu_ctr); 3782 } else if (type == BCOND_TAR) { 3783 gen_load_spr(target, SPR_TAR); 3784 } else { 3785 tcg_gen_mov_tl(target, cpu_lr); 3786 } 3787 } else { 3788 target = NULL; 3789 } 3790 if (LK(ctx->opcode)) { 3791 gen_setlr(ctx, ctx->base.pc_next); 3792 } 3793 l1 = gen_new_label(); 3794 if ((bo & 0x4) == 0) { 3795 /* Decrement and test CTR */ 3796 TCGv temp = tcg_temp_new(); 3797 3798 if (type == BCOND_CTR) { 3799 /* 3800 * All ISAs up to v3 describe this form of bcctr as invalid but 3801 * some processors, ie. 64-bit server processors compliant with 3802 * arch 2.x, do implement a "test and decrement" logic instead, 3803 * as described in their respective UMs. This logic involves CTR 3804 * to act as both the branch target and a counter, which makes 3805 * it basically useless and thus never used in real code. 3806 * 3807 * This form was hence chosen to trigger extra micro-architectural 3808 * side-effect on real HW needed for the Spectre v2 workaround. 3809 * It is up to guests that implement such workaround, ie. linux, to 3810 * use this form in a way it just triggers the side-effect without 3811 * doing anything else harmful. 3812 */ 3813 if (unlikely(!is_book3s_arch2x(ctx))) { 3814 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 3815 tcg_temp_free(temp); 3816 tcg_temp_free(target); 3817 return; 3818 } 3819 3820 if (NARROW_MODE(ctx)) { 3821 tcg_gen_ext32u_tl(temp, cpu_ctr); 3822 } else { 3823 tcg_gen_mov_tl(temp, cpu_ctr); 3824 } 3825 if (bo & 0x2) { 3826 tcg_gen_brcondi_tl(TCG_COND_NE, temp, 0, l1); 3827 } else { 3828 tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1); 3829 } 3830 tcg_gen_subi_tl(cpu_ctr, cpu_ctr, 1); 3831 } else { 3832 tcg_gen_subi_tl(cpu_ctr, cpu_ctr, 1); 3833 if (NARROW_MODE(ctx)) { 3834 tcg_gen_ext32u_tl(temp, cpu_ctr); 3835 } else { 3836 tcg_gen_mov_tl(temp, cpu_ctr); 3837 } 3838 if (bo & 0x2) { 3839 tcg_gen_brcondi_tl(TCG_COND_NE, temp, 0, l1); 3840 } else { 3841 tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1); 3842 } 3843 } 3844 tcg_temp_free(temp); 3845 } 3846 if ((bo & 0x10) == 0) { 3847 /* Test CR */ 3848 uint32_t bi = BI(ctx->opcode); 3849 uint32_t mask = 0x08 >> (bi & 0x03); 3850 TCGv_i32 temp = tcg_temp_new_i32(); 3851 3852 if (bo & 0x8) { 3853 tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask); 3854 tcg_gen_brcondi_i32(TCG_COND_EQ, temp, 0, l1); 3855 } else { 3856 tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask); 3857 tcg_gen_brcondi_i32(TCG_COND_NE, temp, 0, l1); 3858 } 3859 tcg_temp_free_i32(temp); 3860 } 3861 gen_update_cfar(ctx, ctx->base.pc_next - 4); 3862 if (type == BCOND_IM) { 3863 target_ulong li = (target_long)((int16_t)(BD(ctx->opcode))); 3864 if (likely(AA(ctx->opcode) == 0)) { 3865 gen_goto_tb(ctx, 0, ctx->base.pc_next + li - 4); 3866 } else { 3867 gen_goto_tb(ctx, 0, li); 3868 } 3869 } else { 3870 if (NARROW_MODE(ctx)) { 3871 tcg_gen_andi_tl(cpu_nip, target, (uint32_t)~3); 3872 } else { 3873 tcg_gen_andi_tl(cpu_nip, target, ~3); 3874 } 3875 gen_lookup_and_goto_ptr(ctx); 3876 tcg_temp_free(target); 3877 } 3878 if ((bo & 0x14) != 0x14) { 3879 /* fallthrough case */ 3880 gen_set_label(l1); 3881 gen_goto_tb(ctx, 1, ctx->base.pc_next); 3882 } 3883 } 3884 3885 static void gen_bc(DisasContext *ctx) 3886 { 3887 gen_bcond(ctx, BCOND_IM); 3888 } 3889 3890 static void gen_bcctr(DisasContext *ctx) 3891 { 3892 gen_bcond(ctx, BCOND_CTR); 3893 } 3894 3895 static void gen_bclr(DisasContext *ctx) 3896 { 3897 gen_bcond(ctx, BCOND_LR); 3898 } 3899 3900 static void gen_bctar(DisasContext *ctx) 3901 { 3902 gen_bcond(ctx, BCOND_TAR); 3903 } 3904 3905 /*** Condition register logical ***/ 3906 #define GEN_CRLOGIC(name, tcg_op, opc) \ 3907 static void glue(gen_, name)(DisasContext *ctx) \ 3908 { \ 3909 uint8_t bitmask; \ 3910 int sh; \ 3911 TCGv_i32 t0, t1; \ 3912 sh = (crbD(ctx->opcode) & 0x03) - (crbA(ctx->opcode) & 0x03); \ 3913 t0 = tcg_temp_new_i32(); \ 3914 if (sh > 0) \ 3915 tcg_gen_shri_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], sh); \ 3916 else if (sh < 0) \ 3917 tcg_gen_shli_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], -sh); \ 3918 else \ 3919 tcg_gen_mov_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2]); \ 3920 t1 = tcg_temp_new_i32(); \ 3921 sh = (crbD(ctx->opcode) & 0x03) - (crbB(ctx->opcode) & 0x03); \ 3922 if (sh > 0) \ 3923 tcg_gen_shri_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], sh); \ 3924 else if (sh < 0) \ 3925 tcg_gen_shli_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], -sh); \ 3926 else \ 3927 tcg_gen_mov_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2]); \ 3928 tcg_op(t0, t0, t1); \ 3929 bitmask = 0x08 >> (crbD(ctx->opcode) & 0x03); \ 3930 tcg_gen_andi_i32(t0, t0, bitmask); \ 3931 tcg_gen_andi_i32(t1, cpu_crf[crbD(ctx->opcode) >> 2], ~bitmask); \ 3932 tcg_gen_or_i32(cpu_crf[crbD(ctx->opcode) >> 2], t0, t1); \ 3933 tcg_temp_free_i32(t0); \ 3934 tcg_temp_free_i32(t1); \ 3935 } 3936 3937 /* crand */ 3938 GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08); 3939 /* crandc */ 3940 GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04); 3941 /* creqv */ 3942 GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09); 3943 /* crnand */ 3944 GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07); 3945 /* crnor */ 3946 GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01); 3947 /* cror */ 3948 GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E); 3949 /* crorc */ 3950 GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D); 3951 /* crxor */ 3952 GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06); 3953 3954 /* mcrf */ 3955 static void gen_mcrf(DisasContext *ctx) 3956 { 3957 tcg_gen_mov_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfS(ctx->opcode)]); 3958 } 3959 3960 /*** System linkage ***/ 3961 3962 /* rfi (supervisor only) */ 3963 static void gen_rfi(DisasContext *ctx) 3964 { 3965 #if defined(CONFIG_USER_ONLY) 3966 GEN_PRIV; 3967 #else 3968 /* 3969 * This instruction doesn't exist anymore on 64-bit server 3970 * processors compliant with arch 2.x 3971 */ 3972 if (is_book3s_arch2x(ctx)) { 3973 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 3974 return; 3975 } 3976 /* Restore CPU state */ 3977 CHK_SV; 3978 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 3979 gen_io_start(); 3980 } 3981 gen_update_cfar(ctx, ctx->base.pc_next - 4); 3982 gen_helper_rfi(cpu_env); 3983 gen_sync_exception(ctx); 3984 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 3985 gen_io_end(); 3986 } 3987 #endif 3988 } 3989 3990 #if defined(TARGET_PPC64) 3991 static void gen_rfid(DisasContext *ctx) 3992 { 3993 #if defined(CONFIG_USER_ONLY) 3994 GEN_PRIV; 3995 #else 3996 /* Restore CPU state */ 3997 CHK_SV; 3998 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 3999 gen_io_start(); 4000 } 4001 gen_update_cfar(ctx, ctx->base.pc_next - 4); 4002 gen_helper_rfid(cpu_env); 4003 gen_sync_exception(ctx); 4004 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 4005 gen_io_end(); 4006 } 4007 #endif 4008 } 4009 4010 static void gen_hrfid(DisasContext *ctx) 4011 { 4012 #if defined(CONFIG_USER_ONLY) 4013 GEN_PRIV; 4014 #else 4015 /* Restore CPU state */ 4016 CHK_HV; 4017 gen_helper_hrfid(cpu_env); 4018 gen_sync_exception(ctx); 4019 #endif 4020 } 4021 #endif 4022 4023 /* sc */ 4024 #if defined(CONFIG_USER_ONLY) 4025 #define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER 4026 #else 4027 #define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL 4028 #endif 4029 static void gen_sc(DisasContext *ctx) 4030 { 4031 uint32_t lev; 4032 4033 lev = (ctx->opcode >> 5) & 0x7F; 4034 gen_exception_err(ctx, POWERPC_SYSCALL, lev); 4035 } 4036 4037 /*** Trap ***/ 4038 4039 /* Check for unconditional traps (always or never) */ 4040 static bool check_unconditional_trap(DisasContext *ctx) 4041 { 4042 /* Trap never */ 4043 if (TO(ctx->opcode) == 0) { 4044 return true; 4045 } 4046 /* Trap always */ 4047 if (TO(ctx->opcode) == 31) { 4048 gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_TRAP); 4049 return true; 4050 } 4051 return false; 4052 } 4053 4054 /* tw */ 4055 static void gen_tw(DisasContext *ctx) 4056 { 4057 TCGv_i32 t0; 4058 4059 if (check_unconditional_trap(ctx)) { 4060 return; 4061 } 4062 t0 = tcg_const_i32(TO(ctx->opcode)); 4063 gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], 4064 t0); 4065 tcg_temp_free_i32(t0); 4066 } 4067 4068 /* twi */ 4069 static void gen_twi(DisasContext *ctx) 4070 { 4071 TCGv t0; 4072 TCGv_i32 t1; 4073 4074 if (check_unconditional_trap(ctx)) { 4075 return; 4076 } 4077 t0 = tcg_const_tl(SIMM(ctx->opcode)); 4078 t1 = tcg_const_i32(TO(ctx->opcode)); 4079 gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1); 4080 tcg_temp_free(t0); 4081 tcg_temp_free_i32(t1); 4082 } 4083 4084 #if defined(TARGET_PPC64) 4085 /* td */ 4086 static void gen_td(DisasContext *ctx) 4087 { 4088 TCGv_i32 t0; 4089 4090 if (check_unconditional_trap(ctx)) { 4091 return; 4092 } 4093 t0 = tcg_const_i32(TO(ctx->opcode)); 4094 gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], 4095 t0); 4096 tcg_temp_free_i32(t0); 4097 } 4098 4099 /* tdi */ 4100 static void gen_tdi(DisasContext *ctx) 4101 { 4102 TCGv t0; 4103 TCGv_i32 t1; 4104 4105 if (check_unconditional_trap(ctx)) { 4106 return; 4107 } 4108 t0 = tcg_const_tl(SIMM(ctx->opcode)); 4109 t1 = tcg_const_i32(TO(ctx->opcode)); 4110 gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1); 4111 tcg_temp_free(t0); 4112 tcg_temp_free_i32(t1); 4113 } 4114 #endif 4115 4116 /*** Processor control ***/ 4117 4118 static void gen_read_xer(DisasContext *ctx, TCGv dst) 4119 { 4120 TCGv t0 = tcg_temp_new(); 4121 TCGv t1 = tcg_temp_new(); 4122 TCGv t2 = tcg_temp_new(); 4123 tcg_gen_mov_tl(dst, cpu_xer); 4124 tcg_gen_shli_tl(t0, cpu_so, XER_SO); 4125 tcg_gen_shli_tl(t1, cpu_ov, XER_OV); 4126 tcg_gen_shli_tl(t2, cpu_ca, XER_CA); 4127 tcg_gen_or_tl(t0, t0, t1); 4128 tcg_gen_or_tl(dst, dst, t2); 4129 tcg_gen_or_tl(dst, dst, t0); 4130 if (is_isa300(ctx)) { 4131 tcg_gen_shli_tl(t0, cpu_ov32, XER_OV32); 4132 tcg_gen_or_tl(dst, dst, t0); 4133 tcg_gen_shli_tl(t0, cpu_ca32, XER_CA32); 4134 tcg_gen_or_tl(dst, dst, t0); 4135 } 4136 tcg_temp_free(t0); 4137 tcg_temp_free(t1); 4138 tcg_temp_free(t2); 4139 } 4140 4141 static void gen_write_xer(TCGv src) 4142 { 4143 /* Write all flags, while reading back check for isa300 */ 4144 tcg_gen_andi_tl(cpu_xer, src, 4145 ~((1u << XER_SO) | 4146 (1u << XER_OV) | (1u << XER_OV32) | 4147 (1u << XER_CA) | (1u << XER_CA32))); 4148 tcg_gen_extract_tl(cpu_ov32, src, XER_OV32, 1); 4149 tcg_gen_extract_tl(cpu_ca32, src, XER_CA32, 1); 4150 tcg_gen_extract_tl(cpu_so, src, XER_SO, 1); 4151 tcg_gen_extract_tl(cpu_ov, src, XER_OV, 1); 4152 tcg_gen_extract_tl(cpu_ca, src, XER_CA, 1); 4153 } 4154 4155 /* mcrxr */ 4156 static void gen_mcrxr(DisasContext *ctx) 4157 { 4158 TCGv_i32 t0 = tcg_temp_new_i32(); 4159 TCGv_i32 t1 = tcg_temp_new_i32(); 4160 TCGv_i32 dst = cpu_crf[crfD(ctx->opcode)]; 4161 4162 tcg_gen_trunc_tl_i32(t0, cpu_so); 4163 tcg_gen_trunc_tl_i32(t1, cpu_ov); 4164 tcg_gen_trunc_tl_i32(dst, cpu_ca); 4165 tcg_gen_shli_i32(t0, t0, 3); 4166 tcg_gen_shli_i32(t1, t1, 2); 4167 tcg_gen_shli_i32(dst, dst, 1); 4168 tcg_gen_or_i32(dst, dst, t0); 4169 tcg_gen_or_i32(dst, dst, t1); 4170 tcg_temp_free_i32(t0); 4171 tcg_temp_free_i32(t1); 4172 4173 tcg_gen_movi_tl(cpu_so, 0); 4174 tcg_gen_movi_tl(cpu_ov, 0); 4175 tcg_gen_movi_tl(cpu_ca, 0); 4176 } 4177 4178 #ifdef TARGET_PPC64 4179 /* mcrxrx */ 4180 static void gen_mcrxrx(DisasContext *ctx) 4181 { 4182 TCGv t0 = tcg_temp_new(); 4183 TCGv t1 = tcg_temp_new(); 4184 TCGv_i32 dst = cpu_crf[crfD(ctx->opcode)]; 4185 4186 /* copy OV and OV32 */ 4187 tcg_gen_shli_tl(t0, cpu_ov, 1); 4188 tcg_gen_or_tl(t0, t0, cpu_ov32); 4189 tcg_gen_shli_tl(t0, t0, 2); 4190 /* copy CA and CA32 */ 4191 tcg_gen_shli_tl(t1, cpu_ca, 1); 4192 tcg_gen_or_tl(t1, t1, cpu_ca32); 4193 tcg_gen_or_tl(t0, t0, t1); 4194 tcg_gen_trunc_tl_i32(dst, t0); 4195 tcg_temp_free(t0); 4196 tcg_temp_free(t1); 4197 } 4198 #endif 4199 4200 /* mfcr mfocrf */ 4201 static void gen_mfcr(DisasContext *ctx) 4202 { 4203 uint32_t crm, crn; 4204 4205 if (likely(ctx->opcode & 0x00100000)) { 4206 crm = CRM(ctx->opcode); 4207 if (likely(crm && ((crm & (crm - 1)) == 0))) { 4208 crn = ctz32(crm); 4209 tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], cpu_crf[7 - crn]); 4210 tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], 4211 cpu_gpr[rD(ctx->opcode)], crn * 4); 4212 } 4213 } else { 4214 TCGv_i32 t0 = tcg_temp_new_i32(); 4215 tcg_gen_mov_i32(t0, cpu_crf[0]); 4216 tcg_gen_shli_i32(t0, t0, 4); 4217 tcg_gen_or_i32(t0, t0, cpu_crf[1]); 4218 tcg_gen_shli_i32(t0, t0, 4); 4219 tcg_gen_or_i32(t0, t0, cpu_crf[2]); 4220 tcg_gen_shli_i32(t0, t0, 4); 4221 tcg_gen_or_i32(t0, t0, cpu_crf[3]); 4222 tcg_gen_shli_i32(t0, t0, 4); 4223 tcg_gen_or_i32(t0, t0, cpu_crf[4]); 4224 tcg_gen_shli_i32(t0, t0, 4); 4225 tcg_gen_or_i32(t0, t0, cpu_crf[5]); 4226 tcg_gen_shli_i32(t0, t0, 4); 4227 tcg_gen_or_i32(t0, t0, cpu_crf[6]); 4228 tcg_gen_shli_i32(t0, t0, 4); 4229 tcg_gen_or_i32(t0, t0, cpu_crf[7]); 4230 tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); 4231 tcg_temp_free_i32(t0); 4232 } 4233 } 4234 4235 /* mfmsr */ 4236 static void gen_mfmsr(DisasContext *ctx) 4237 { 4238 CHK_SV; 4239 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_msr); 4240 } 4241 4242 static void spr_noaccess(DisasContext *ctx, int gprn, int sprn) 4243 { 4244 #if 0 4245 sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5); 4246 printf("ERROR: try to access SPR %d !\n", sprn); 4247 #endif 4248 } 4249 #define SPR_NOACCESS (&spr_noaccess) 4250 4251 /* mfspr */ 4252 static inline void gen_op_mfspr(DisasContext *ctx) 4253 { 4254 void (*read_cb)(DisasContext *ctx, int gprn, int sprn); 4255 uint32_t sprn = SPR(ctx->opcode); 4256 4257 #if defined(CONFIG_USER_ONLY) 4258 read_cb = ctx->spr_cb[sprn].uea_read; 4259 #else 4260 if (ctx->pr) { 4261 read_cb = ctx->spr_cb[sprn].uea_read; 4262 } else if (ctx->hv) { 4263 read_cb = ctx->spr_cb[sprn].hea_read; 4264 } else { 4265 read_cb = ctx->spr_cb[sprn].oea_read; 4266 } 4267 #endif 4268 if (likely(read_cb != NULL)) { 4269 if (likely(read_cb != SPR_NOACCESS)) { 4270 (*read_cb)(ctx, rD(ctx->opcode), sprn); 4271 } else { 4272 /* Privilege exception */ 4273 /* 4274 * This is a hack to avoid warnings when running Linux: 4275 * this OS breaks the PowerPC virtualisation model, 4276 * allowing userland application to read the PVR 4277 */ 4278 if (sprn != SPR_PVR) { 4279 qemu_log_mask(LOG_GUEST_ERROR, "Trying to read privileged spr " 4280 "%d (0x%03x) at " TARGET_FMT_lx "\n", sprn, sprn, 4281 ctx->base.pc_next - 4); 4282 } 4283 gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG); 4284 } 4285 } else { 4286 /* ISA 2.07 defines these as no-ops */ 4287 if ((ctx->insns_flags2 & PPC2_ISA207S) && 4288 (sprn >= 808 && sprn <= 811)) { 4289 /* This is a nop */ 4290 return; 4291 } 4292 /* Not defined */ 4293 qemu_log_mask(LOG_GUEST_ERROR, 4294 "Trying to read invalid spr %d (0x%03x) at " 4295 TARGET_FMT_lx "\n", sprn, sprn, ctx->base.pc_next - 4); 4296 4297 /* 4298 * The behaviour depends on MSR:PR and SPR# bit 0x10, it can 4299 * generate a priv, a hv emu or a no-op 4300 */ 4301 if (sprn & 0x10) { 4302 if (ctx->pr) { 4303 gen_priv_exception(ctx, POWERPC_EXCP_INVAL_SPR); 4304 } 4305 } else { 4306 if (ctx->pr || sprn == 0 || sprn == 4 || sprn == 5 || sprn == 6) { 4307 gen_hvpriv_exception(ctx, POWERPC_EXCP_INVAL_SPR); 4308 } 4309 } 4310 } 4311 } 4312 4313 static void gen_mfspr(DisasContext *ctx) 4314 { 4315 gen_op_mfspr(ctx); 4316 } 4317 4318 /* mftb */ 4319 static void gen_mftb(DisasContext *ctx) 4320 { 4321 gen_op_mfspr(ctx); 4322 } 4323 4324 /* mtcrf mtocrf*/ 4325 static void gen_mtcrf(DisasContext *ctx) 4326 { 4327 uint32_t crm, crn; 4328 4329 crm = CRM(ctx->opcode); 4330 if (likely((ctx->opcode & 0x00100000))) { 4331 if (crm && ((crm & (crm - 1)) == 0)) { 4332 TCGv_i32 temp = tcg_temp_new_i32(); 4333 crn = ctz32(crm); 4334 tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]); 4335 tcg_gen_shri_i32(temp, temp, crn * 4); 4336 tcg_gen_andi_i32(cpu_crf[7 - crn], temp, 0xf); 4337 tcg_temp_free_i32(temp); 4338 } 4339 } else { 4340 TCGv_i32 temp = tcg_temp_new_i32(); 4341 tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]); 4342 for (crn = 0 ; crn < 8 ; crn++) { 4343 if (crm & (1 << crn)) { 4344 tcg_gen_shri_i32(cpu_crf[7 - crn], temp, crn * 4); 4345 tcg_gen_andi_i32(cpu_crf[7 - crn], cpu_crf[7 - crn], 0xf); 4346 } 4347 } 4348 tcg_temp_free_i32(temp); 4349 } 4350 } 4351 4352 /* mtmsr */ 4353 #if defined(TARGET_PPC64) 4354 static void gen_mtmsrd(DisasContext *ctx) 4355 { 4356 CHK_SV; 4357 4358 #if !defined(CONFIG_USER_ONLY) 4359 if (ctx->opcode & 0x00010000) { 4360 /* Special form that does not need any synchronisation */ 4361 TCGv t0 = tcg_temp_new(); 4362 tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], 4363 (1 << MSR_RI) | (1 << MSR_EE)); 4364 tcg_gen_andi_tl(cpu_msr, cpu_msr, 4365 ~(target_ulong)((1 << MSR_RI) | (1 << MSR_EE))); 4366 tcg_gen_or_tl(cpu_msr, cpu_msr, t0); 4367 tcg_temp_free(t0); 4368 } else { 4369 /* 4370 * XXX: we need to update nip before the store if we enter 4371 * power saving mode, we will exit the loop directly from 4372 * ppc_store_msr 4373 */ 4374 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 4375 gen_io_start(); 4376 } 4377 gen_update_nip(ctx, ctx->base.pc_next); 4378 gen_helper_store_msr(cpu_env, cpu_gpr[rS(ctx->opcode)]); 4379 /* Must stop the translation as machine state (may have) changed */ 4380 /* Note that mtmsr is not always defined as context-synchronizing */ 4381 gen_stop_exception(ctx); 4382 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 4383 gen_io_end(); 4384 } 4385 } 4386 #endif /* !defined(CONFIG_USER_ONLY) */ 4387 } 4388 #endif /* defined(TARGET_PPC64) */ 4389 4390 static void gen_mtmsr(DisasContext *ctx) 4391 { 4392 CHK_SV; 4393 4394 #if !defined(CONFIG_USER_ONLY) 4395 if (ctx->opcode & 0x00010000) { 4396 /* Special form that does not need any synchronisation */ 4397 TCGv t0 = tcg_temp_new(); 4398 tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], 4399 (1 << MSR_RI) | (1 << MSR_EE)); 4400 tcg_gen_andi_tl(cpu_msr, cpu_msr, 4401 ~(target_ulong)((1 << MSR_RI) | (1 << MSR_EE))); 4402 tcg_gen_or_tl(cpu_msr, cpu_msr, t0); 4403 tcg_temp_free(t0); 4404 } else { 4405 TCGv msr = tcg_temp_new(); 4406 4407 /* 4408 * XXX: we need to update nip before the store if we enter 4409 * power saving mode, we will exit the loop directly from 4410 * ppc_store_msr 4411 */ 4412 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 4413 gen_io_start(); 4414 } 4415 gen_update_nip(ctx, ctx->base.pc_next); 4416 #if defined(TARGET_PPC64) 4417 tcg_gen_deposit_tl(msr, cpu_msr, cpu_gpr[rS(ctx->opcode)], 0, 32); 4418 #else 4419 tcg_gen_mov_tl(msr, cpu_gpr[rS(ctx->opcode)]); 4420 #endif 4421 gen_helper_store_msr(cpu_env, msr); 4422 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { 4423 gen_io_end(); 4424 } 4425 tcg_temp_free(msr); 4426 /* Must stop the translation as machine state (may have) changed */ 4427 /* Note that mtmsr is not always defined as context-synchronizing */ 4428 gen_stop_exception(ctx); 4429 } 4430 #endif 4431 } 4432 4433 /* mtspr */ 4434 static void gen_mtspr(DisasContext *ctx) 4435 { 4436 void (*write_cb)(DisasContext *ctx, int sprn, int gprn); 4437 uint32_t sprn = SPR(ctx->opcode); 4438 4439 #if defined(CONFIG_USER_ONLY) 4440 write_cb = ctx->spr_cb[sprn].uea_write; 4441 #else 4442 if (ctx->pr) { 4443 write_cb = ctx->spr_cb[sprn].uea_write; 4444 } else if (ctx->hv) { 4445 write_cb = ctx->spr_cb[sprn].hea_write; 4446 } else { 4447 write_cb = ctx->spr_cb[sprn].oea_write; 4448 } 4449 #endif 4450 if (likely(write_cb != NULL)) { 4451 if (likely(write_cb != SPR_NOACCESS)) { 4452 (*write_cb)(ctx, sprn, rS(ctx->opcode)); 4453 } else { 4454 /* Privilege exception */ 4455 qemu_log_mask(LOG_GUEST_ERROR, "Trying to write privileged spr " 4456 "%d (0x%03x) at " TARGET_FMT_lx "\n", sprn, sprn, 4457 ctx->base.pc_next - 4); 4458 gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG); 4459 } 4460 } else { 4461 /* ISA 2.07 defines these as no-ops */ 4462 if ((ctx->insns_flags2 & PPC2_ISA207S) && 4463 (sprn >= 808 && sprn <= 811)) { 4464 /* This is a nop */ 4465 return; 4466 } 4467 4468 /* Not defined */ 4469 qemu_log_mask(LOG_GUEST_ERROR, 4470 "Trying to write invalid spr %d (0x%03x) at " 4471 TARGET_FMT_lx "\n", sprn, sprn, ctx->base.pc_next - 4); 4472 4473 4474 /* 4475 * The behaviour depends on MSR:PR and SPR# bit 0x10, it can 4476 * generate a priv, a hv emu or a no-op 4477 */ 4478 if (sprn & 0x10) { 4479 if (ctx->pr) { 4480 gen_priv_exception(ctx, POWERPC_EXCP_INVAL_SPR); 4481 } 4482 } else { 4483 if (ctx->pr || sprn == 0) { 4484 gen_hvpriv_exception(ctx, POWERPC_EXCP_INVAL_SPR); 4485 } 4486 } 4487 } 4488 } 4489 4490 #if defined(TARGET_PPC64) 4491 /* setb */ 4492 static void gen_setb(DisasContext *ctx) 4493 { 4494 TCGv_i32 t0 = tcg_temp_new_i32(); 4495 TCGv_i32 t8 = tcg_temp_new_i32(); 4496 TCGv_i32 tm1 = tcg_temp_new_i32(); 4497 int crf = crfS(ctx->opcode); 4498 4499 tcg_gen_setcondi_i32(TCG_COND_GEU, t0, cpu_crf[crf], 4); 4500 tcg_gen_movi_i32(t8, 8); 4501 tcg_gen_movi_i32(tm1, -1); 4502 tcg_gen_movcond_i32(TCG_COND_GEU, t0, cpu_crf[crf], t8, tm1, t0); 4503 tcg_gen_ext_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); 4504 4505 tcg_temp_free_i32(t0); 4506 tcg_temp_free_i32(t8); 4507 tcg_temp_free_i32(tm1); 4508 } 4509 #endif 4510 4511 /*** Cache management ***/ 4512 4513 /* dcbf */ 4514 static void gen_dcbf(DisasContext *ctx) 4515 { 4516 /* XXX: specification says this is treated as a load by the MMU */ 4517 TCGv t0; 4518 gen_set_access_type(ctx, ACCESS_CACHE); 4519 t0 = tcg_temp_new(); 4520 gen_addr_reg_index(ctx, t0); 4521 gen_qemu_ld8u(ctx, t0, t0); 4522 tcg_temp_free(t0); 4523 } 4524 4525 /* dcbfep (external PID dcbf) */ 4526 static void gen_dcbfep(DisasContext *ctx) 4527 { 4528 /* XXX: specification says this is treated as a load by the MMU */ 4529 TCGv t0; 4530 CHK_SV; 4531 gen_set_access_type(ctx, ACCESS_CACHE); 4532 t0 = tcg_temp_new(); 4533 gen_addr_reg_index(ctx, t0); 4534 tcg_gen_qemu_ld_tl(t0, t0, PPC_TLB_EPID_LOAD, DEF_MEMOP(MO_UB)); 4535 tcg_temp_free(t0); 4536 } 4537 4538 /* dcbi (Supervisor only) */ 4539 static void gen_dcbi(DisasContext *ctx) 4540 { 4541 #if defined(CONFIG_USER_ONLY) 4542 GEN_PRIV; 4543 #else 4544 TCGv EA, val; 4545 4546 CHK_SV; 4547 EA = tcg_temp_new(); 4548 gen_set_access_type(ctx, ACCESS_CACHE); 4549 gen_addr_reg_index(ctx, EA); 4550 val = tcg_temp_new(); 4551 /* XXX: specification says this should be treated as a store by the MMU */ 4552 gen_qemu_ld8u(ctx, val, EA); 4553 gen_qemu_st8(ctx, val, EA); 4554 tcg_temp_free(val); 4555 tcg_temp_free(EA); 4556 #endif /* defined(CONFIG_USER_ONLY) */ 4557 } 4558 4559 /* dcdst */ 4560 static void gen_dcbst(DisasContext *ctx) 4561 { 4562 /* XXX: specification say this is treated as a load by the MMU */ 4563 TCGv t0; 4564 gen_set_access_type(ctx, ACCESS_CACHE); 4565 t0 = tcg_temp_new(); 4566 gen_addr_reg_index(ctx, t0); 4567 gen_qemu_ld8u(ctx, t0, t0); 4568 tcg_temp_free(t0); 4569 } 4570 4571 /* dcbstep (dcbstep External PID version) */ 4572 static void gen_dcbstep(DisasContext *ctx) 4573 { 4574 /* XXX: specification say this is treated as a load by the MMU */ 4575 TCGv t0; 4576 gen_set_access_type(ctx, ACCESS_CACHE); 4577 t0 = tcg_temp_new(); 4578 gen_addr_reg_index(ctx, t0); 4579 tcg_gen_qemu_ld_tl(t0, t0, PPC_TLB_EPID_LOAD, DEF_MEMOP(MO_UB)); 4580 tcg_temp_free(t0); 4581 } 4582 4583 /* dcbt */ 4584 static void gen_dcbt(DisasContext *ctx) 4585 { 4586 /* 4587 * interpreted as no-op 4588 * XXX: specification say this is treated as a load by the MMU but 4589 * does not generate any exception 4590 */ 4591 } 4592 4593 /* dcbtep */ 4594 static void gen_dcbtep(DisasContext *ctx) 4595 { 4596 /* 4597 * interpreted as no-op 4598 * XXX: specification say this is treated as a load by the MMU but 4599 * does not generate any exception 4600 */ 4601 } 4602 4603 /* dcbtst */ 4604 static void gen_dcbtst(DisasContext *ctx) 4605 { 4606 /* 4607 * interpreted as no-op 4608 * XXX: specification say this is treated as a load by the MMU but 4609 * does not generate any exception 4610 */ 4611 } 4612 4613 /* dcbtstep */ 4614 static void gen_dcbtstep(DisasContext *ctx) 4615 { 4616 /* 4617 * interpreted as no-op 4618 * XXX: specification say this is treated as a load by the MMU but 4619 * does not generate any exception 4620 */ 4621 } 4622 4623 /* dcbtls */ 4624 static void gen_dcbtls(DisasContext *ctx) 4625 { 4626 /* Always fails locking the cache */ 4627 TCGv t0 = tcg_temp_new(); 4628 gen_load_spr(t0, SPR_Exxx_L1CSR0); 4629 tcg_gen_ori_tl(t0, t0, L1CSR0_CUL); 4630 gen_store_spr(SPR_Exxx_L1CSR0, t0); 4631 tcg_temp_free(t0); 4632 } 4633 4634 /* dcbz */ 4635 static void gen_dcbz(DisasContext *ctx) 4636 { 4637 TCGv tcgv_addr; 4638 TCGv_i32 tcgv_op; 4639 4640 gen_set_access_type(ctx, ACCESS_CACHE); 4641 tcgv_addr = tcg_temp_new(); 4642 tcgv_op = tcg_const_i32(ctx->opcode & 0x03FF000); 4643 gen_addr_reg_index(ctx, tcgv_addr); 4644 gen_helper_dcbz(cpu_env, tcgv_addr, tcgv_op); 4645 tcg_temp_free(tcgv_addr); 4646 tcg_temp_free_i32(tcgv_op); 4647 } 4648 4649 /* dcbzep */ 4650 static void gen_dcbzep(DisasContext *ctx) 4651 { 4652 TCGv tcgv_addr; 4653 TCGv_i32 tcgv_op; 4654 4655 gen_set_access_type(ctx, ACCESS_CACHE); 4656 tcgv_addr = tcg_temp_new(); 4657 tcgv_op = tcg_const_i32(ctx->opcode & 0x03FF000); 4658 gen_addr_reg_index(ctx, tcgv_addr); 4659 gen_helper_dcbzep(cpu_env, tcgv_addr, tcgv_op); 4660 tcg_temp_free(tcgv_addr); 4661 tcg_temp_free_i32(tcgv_op); 4662 } 4663 4664 /* dst / dstt */ 4665 static void gen_dst(DisasContext *ctx) 4666 { 4667 if (rA(ctx->opcode) == 0) { 4668 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 4669 } else { 4670 /* interpreted as no-op */ 4671 } 4672 } 4673 4674 /* dstst /dststt */ 4675 static void gen_dstst(DisasContext *ctx) 4676 { 4677 if (rA(ctx->opcode) == 0) { 4678 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 4679 } else { 4680 /* interpreted as no-op */ 4681 } 4682 4683 } 4684 4685 /* dss / dssall */ 4686 static void gen_dss(DisasContext *ctx) 4687 { 4688 /* interpreted as no-op */ 4689 } 4690 4691 /* icbi */ 4692 static void gen_icbi(DisasContext *ctx) 4693 { 4694 TCGv t0; 4695 gen_set_access_type(ctx, ACCESS_CACHE); 4696 t0 = tcg_temp_new(); 4697 gen_addr_reg_index(ctx, t0); 4698 gen_helper_icbi(cpu_env, t0); 4699 tcg_temp_free(t0); 4700 } 4701 4702 /* icbiep */ 4703 static void gen_icbiep(DisasContext *ctx) 4704 { 4705 TCGv t0; 4706 gen_set_access_type(ctx, ACCESS_CACHE); 4707 t0 = tcg_temp_new(); 4708 gen_addr_reg_index(ctx, t0); 4709 gen_helper_icbiep(cpu_env, t0); 4710 tcg_temp_free(t0); 4711 } 4712 4713 /* Optional: */ 4714 /* dcba */ 4715 static void gen_dcba(DisasContext *ctx) 4716 { 4717 /* 4718 * interpreted as no-op 4719 * XXX: specification say this is treated as a store by the MMU 4720 * but does not generate any exception 4721 */ 4722 } 4723 4724 /*** Segment register manipulation ***/ 4725 /* Supervisor only: */ 4726 4727 /* mfsr */ 4728 static void gen_mfsr(DisasContext *ctx) 4729 { 4730 #if defined(CONFIG_USER_ONLY) 4731 GEN_PRIV; 4732 #else 4733 TCGv t0; 4734 4735 CHK_SV; 4736 t0 = tcg_const_tl(SR(ctx->opcode)); 4737 gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0); 4738 tcg_temp_free(t0); 4739 #endif /* defined(CONFIG_USER_ONLY) */ 4740 } 4741 4742 /* mfsrin */ 4743 static void gen_mfsrin(DisasContext *ctx) 4744 { 4745 #if defined(CONFIG_USER_ONLY) 4746 GEN_PRIV; 4747 #else 4748 TCGv t0; 4749 4750 CHK_SV; 4751 t0 = tcg_temp_new(); 4752 tcg_gen_extract_tl(t0, cpu_gpr[rB(ctx->opcode)], 28, 4); 4753 gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0); 4754 tcg_temp_free(t0); 4755 #endif /* defined(CONFIG_USER_ONLY) */ 4756 } 4757 4758 /* mtsr */ 4759 static void gen_mtsr(DisasContext *ctx) 4760 { 4761 #if defined(CONFIG_USER_ONLY) 4762 GEN_PRIV; 4763 #else 4764 TCGv t0; 4765 4766 CHK_SV; 4767 t0 = tcg_const_tl(SR(ctx->opcode)); 4768 gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]); 4769 tcg_temp_free(t0); 4770 #endif /* defined(CONFIG_USER_ONLY) */ 4771 } 4772 4773 /* mtsrin */ 4774 static void gen_mtsrin(DisasContext *ctx) 4775 { 4776 #if defined(CONFIG_USER_ONLY) 4777 GEN_PRIV; 4778 #else 4779 TCGv t0; 4780 CHK_SV; 4781 4782 t0 = tcg_temp_new(); 4783 tcg_gen_extract_tl(t0, cpu_gpr[rB(ctx->opcode)], 28, 4); 4784 gen_helper_store_sr(cpu_env, t0, cpu_gpr[rD(ctx->opcode)]); 4785 tcg_temp_free(t0); 4786 #endif /* defined(CONFIG_USER_ONLY) */ 4787 } 4788 4789 #if defined(TARGET_PPC64) 4790 /* Specific implementation for PowerPC 64 "bridge" emulation using SLB */ 4791 4792 /* mfsr */ 4793 static void gen_mfsr_64b(DisasContext *ctx) 4794 { 4795 #if defined(CONFIG_USER_ONLY) 4796 GEN_PRIV; 4797 #else 4798 TCGv t0; 4799 4800 CHK_SV; 4801 t0 = tcg_const_tl(SR(ctx->opcode)); 4802 gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0); 4803 tcg_temp_free(t0); 4804 #endif /* defined(CONFIG_USER_ONLY) */ 4805 } 4806 4807 /* mfsrin */ 4808 static void gen_mfsrin_64b(DisasContext *ctx) 4809 { 4810 #if defined(CONFIG_USER_ONLY) 4811 GEN_PRIV; 4812 #else 4813 TCGv t0; 4814 4815 CHK_SV; 4816 t0 = tcg_temp_new(); 4817 tcg_gen_extract_tl(t0, cpu_gpr[rB(ctx->opcode)], 28, 4); 4818 gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0); 4819 tcg_temp_free(t0); 4820 #endif /* defined(CONFIG_USER_ONLY) */ 4821 } 4822 4823 /* mtsr */ 4824 static void gen_mtsr_64b(DisasContext *ctx) 4825 { 4826 #if defined(CONFIG_USER_ONLY) 4827 GEN_PRIV; 4828 #else 4829 TCGv t0; 4830 4831 CHK_SV; 4832 t0 = tcg_const_tl(SR(ctx->opcode)); 4833 gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]); 4834 tcg_temp_free(t0); 4835 #endif /* defined(CONFIG_USER_ONLY) */ 4836 } 4837 4838 /* mtsrin */ 4839 static void gen_mtsrin_64b(DisasContext *ctx) 4840 { 4841 #if defined(CONFIG_USER_ONLY) 4842 GEN_PRIV; 4843 #else 4844 TCGv t0; 4845 4846 CHK_SV; 4847 t0 = tcg_temp_new(); 4848 tcg_gen_extract_tl(t0, cpu_gpr[rB(ctx->opcode)], 28, 4); 4849 gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]); 4850 tcg_temp_free(t0); 4851 #endif /* defined(CONFIG_USER_ONLY) */ 4852 } 4853 4854 /* slbmte */ 4855 static void gen_slbmte(DisasContext *ctx) 4856 { 4857 #if defined(CONFIG_USER_ONLY) 4858 GEN_PRIV; 4859 #else 4860 CHK_SV; 4861 4862 gen_helper_store_slb(cpu_env, cpu_gpr[rB(ctx->opcode)], 4863 cpu_gpr[rS(ctx->opcode)]); 4864 #endif /* defined(CONFIG_USER_ONLY) */ 4865 } 4866 4867 static void gen_slbmfee(DisasContext *ctx) 4868 { 4869 #if defined(CONFIG_USER_ONLY) 4870 GEN_PRIV; 4871 #else 4872 CHK_SV; 4873 4874 gen_helper_load_slb_esid(cpu_gpr[rS(ctx->opcode)], cpu_env, 4875 cpu_gpr[rB(ctx->opcode)]); 4876 #endif /* defined(CONFIG_USER_ONLY) */ 4877 } 4878 4879 static void gen_slbmfev(DisasContext *ctx) 4880 { 4881 #if defined(CONFIG_USER_ONLY) 4882 GEN_PRIV; 4883 #else 4884 CHK_SV; 4885 4886 gen_helper_load_slb_vsid(cpu_gpr[rS(ctx->opcode)], cpu_env, 4887 cpu_gpr[rB(ctx->opcode)]); 4888 #endif /* defined(CONFIG_USER_ONLY) */ 4889 } 4890 4891 static void gen_slbfee_(DisasContext *ctx) 4892 { 4893 #if defined(CONFIG_USER_ONLY) 4894 gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG); 4895 #else 4896 TCGLabel *l1, *l2; 4897 4898 if (unlikely(ctx->pr)) { 4899 gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG); 4900 return; 4901 } 4902 gen_helper_find_slb_vsid(cpu_gpr[rS(ctx->opcode)], cpu_env, 4903 cpu_gpr[rB(ctx->opcode)]); 4904 l1 = gen_new_label(); 4905 l2 = gen_new_label(); 4906 tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so); 4907 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rS(ctx->opcode)], -1, l1); 4908 tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], CRF_EQ); 4909 tcg_gen_br(l2); 4910 gen_set_label(l1); 4911 tcg_gen_movi_tl(cpu_gpr[rS(ctx->opcode)], 0); 4912 gen_set_label(l2); 4913 #endif 4914 } 4915 #endif /* defined(TARGET_PPC64) */ 4916 4917 /*** Lookaside buffer management ***/ 4918 /* Optional & supervisor only: */ 4919 4920 /* tlbia */ 4921 static void gen_tlbia(DisasContext *ctx) 4922 { 4923 #if defined(CONFIG_USER_ONLY) 4924 GEN_PRIV; 4925 #else 4926 CHK_HV; 4927 4928 gen_helper_tlbia(cpu_env); 4929 #endif /* defined(CONFIG_USER_ONLY) */ 4930 } 4931 4932 /* tlbiel */ 4933 static void gen_tlbiel(DisasContext *ctx) 4934 { 4935 #if defined(CONFIG_USER_ONLY) 4936 GEN_PRIV; 4937 #else 4938 CHK_SV; 4939 4940 gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]); 4941 #endif /* defined(CONFIG_USER_ONLY) */ 4942 } 4943 4944 /* tlbie */ 4945 static void gen_tlbie(DisasContext *ctx) 4946 { 4947 #if defined(CONFIG_USER_ONLY) 4948 GEN_PRIV; 4949 #else 4950 TCGv_i32 t1; 4951 4952 if (ctx->gtse) { 4953 CHK_SV; /* If gtse is set then tlbie is supervisor privileged */ 4954 } else { 4955 CHK_HV; /* Else hypervisor privileged */ 4956 } 4957 4958 if (NARROW_MODE(ctx)) { 4959 TCGv t0 = tcg_temp_new(); 4960 tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]); 4961 gen_helper_tlbie(cpu_env, t0); 4962 tcg_temp_free(t0); 4963 } else { 4964 gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]); 4965 } 4966 t1 = tcg_temp_new_i32(); 4967 tcg_gen_ld_i32(t1, cpu_env, offsetof(CPUPPCState, tlb_need_flush)); 4968 tcg_gen_ori_i32(t1, t1, TLB_NEED_GLOBAL_FLUSH); 4969 tcg_gen_st_i32(t1, cpu_env, offsetof(CPUPPCState, tlb_need_flush)); 4970 tcg_temp_free_i32(t1); 4971 #endif /* defined(CONFIG_USER_ONLY) */ 4972 } 4973 4974 /* tlbsync */ 4975 static void gen_tlbsync(DisasContext *ctx) 4976 { 4977 #if defined(CONFIG_USER_ONLY) 4978 GEN_PRIV; 4979 #else 4980 4981 if (ctx->gtse) { 4982 CHK_SV; /* If gtse is set then tlbsync is supervisor privileged */ 4983 } else { 4984 CHK_HV; /* Else hypervisor privileged */ 4985 } 4986 4987 /* BookS does both ptesync and tlbsync make tlbsync a nop for server */ 4988 if (ctx->insns_flags & PPC_BOOKE) { 4989 gen_check_tlb_flush(ctx, true); 4990 } 4991 #endif /* defined(CONFIG_USER_ONLY) */ 4992 } 4993 4994 #if defined(TARGET_PPC64) 4995 /* slbia */ 4996 static void gen_slbia(DisasContext *ctx) 4997 { 4998 #if defined(CONFIG_USER_ONLY) 4999 GEN_PRIV; 5000 #else 5001 CHK_SV; 5002 5003 gen_helper_slbia(cpu_env); 5004 #endif /* defined(CONFIG_USER_ONLY) */ 5005 } 5006 5007 /* slbie */ 5008 static void gen_slbie(DisasContext *ctx) 5009 { 5010 #if defined(CONFIG_USER_ONLY) 5011 GEN_PRIV; 5012 #else 5013 CHK_SV; 5014 5015 gen_helper_slbie(cpu_env, cpu_gpr[rB(ctx->opcode)]); 5016 #endif /* defined(CONFIG_USER_ONLY) */ 5017 } 5018 5019 /* slbieg */ 5020 static void gen_slbieg(DisasContext *ctx) 5021 { 5022 #if defined(CONFIG_USER_ONLY) 5023 GEN_PRIV; 5024 #else 5025 CHK_SV; 5026 5027 gen_helper_slbieg(cpu_env, cpu_gpr[rB(ctx->opcode)]); 5028 #endif /* defined(CONFIG_USER_ONLY) */ 5029 } 5030 5031 /* slbsync */ 5032 static void gen_slbsync(DisasContext *ctx) 5033 { 5034 #if defined(CONFIG_USER_ONLY) 5035 GEN_PRIV; 5036 #else 5037 CHK_SV; 5038 gen_check_tlb_flush(ctx, true); 5039 #endif /* defined(CONFIG_USER_ONLY) */ 5040 } 5041 5042 #endif /* defined(TARGET_PPC64) */ 5043 5044 /*** External control ***/ 5045 /* Optional: */ 5046 5047 /* eciwx */ 5048 static void gen_eciwx(DisasContext *ctx) 5049 { 5050 TCGv t0; 5051 /* Should check EAR[E] ! */ 5052 gen_set_access_type(ctx, ACCESS_EXT); 5053 t0 = tcg_temp_new(); 5054 gen_addr_reg_index(ctx, t0); 5055 tcg_gen_qemu_ld_tl(cpu_gpr[rD(ctx->opcode)], t0, ctx->mem_idx, 5056 DEF_MEMOP(MO_UL | MO_ALIGN)); 5057 tcg_temp_free(t0); 5058 } 5059 5060 /* ecowx */ 5061 static void gen_ecowx(DisasContext *ctx) 5062 { 5063 TCGv t0; 5064 /* Should check EAR[E] ! */ 5065 gen_set_access_type(ctx, ACCESS_EXT); 5066 t0 = tcg_temp_new(); 5067 gen_addr_reg_index(ctx, t0); 5068 tcg_gen_qemu_st_tl(cpu_gpr[rD(ctx->opcode)], t0, ctx->mem_idx, 5069 DEF_MEMOP(MO_UL | MO_ALIGN)); 5070 tcg_temp_free(t0); 5071 } 5072 5073 /* PowerPC 601 specific instructions */ 5074 5075 /* abs - abs. */ 5076 static void gen_abs(DisasContext *ctx) 5077 { 5078 TCGv d = cpu_gpr[rD(ctx->opcode)]; 5079 TCGv a = cpu_gpr[rA(ctx->opcode)]; 5080 5081 tcg_gen_abs_tl(d, a); 5082 if (unlikely(Rc(ctx->opcode) != 0)) { 5083 gen_set_Rc0(ctx, d); 5084 } 5085 } 5086 5087 /* abso - abso. */ 5088 static void gen_abso(DisasContext *ctx) 5089 { 5090 TCGv d = cpu_gpr[rD(ctx->opcode)]; 5091 TCGv a = cpu_gpr[rA(ctx->opcode)]; 5092 5093 tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_ov, a, 0x80000000); 5094 tcg_gen_abs_tl(d, a); 5095 tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov); 5096 if (unlikely(Rc(ctx->opcode) != 0)) { 5097 gen_set_Rc0(ctx, d); 5098 } 5099 } 5100 5101 /* clcs */ 5102 static void gen_clcs(DisasContext *ctx) 5103 { 5104 TCGv_i32 t0 = tcg_const_i32(rA(ctx->opcode)); 5105 gen_helper_clcs(cpu_gpr[rD(ctx->opcode)], cpu_env, t0); 5106 tcg_temp_free_i32(t0); 5107 /* Rc=1 sets CR0 to an undefined state */ 5108 } 5109 5110 /* div - div. */ 5111 static void gen_div(DisasContext *ctx) 5112 { 5113 gen_helper_div(cpu_gpr[rD(ctx->opcode)], cpu_env, cpu_gpr[rA(ctx->opcode)], 5114 cpu_gpr[rB(ctx->opcode)]); 5115 if (unlikely(Rc(ctx->opcode) != 0)) { 5116 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); 5117 } 5118 } 5119 5120 /* divo - divo. */ 5121 static void gen_divo(DisasContext *ctx) 5122 { 5123 gen_helper_divo(cpu_gpr[rD(ctx->opcode)], cpu_env, cpu_gpr[rA(ctx->opcode)], 5124 cpu_gpr[rB(ctx->opcode)]); 5125 if (unlikely(Rc(ctx->opcode) != 0)) { 5126 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); 5127 } 5128 } 5129 5130 /* divs - divs. */ 5131 static void gen_divs(DisasContext *ctx) 5132 { 5133 gen_helper_divs(cpu_gpr[rD(ctx->opcode)], cpu_env, cpu_gpr[rA(ctx->opcode)], 5134 cpu_gpr[rB(ctx->opcode)]); 5135 if (unlikely(Rc(ctx->opcode) != 0)) { 5136 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); 5137 } 5138 } 5139 5140 /* divso - divso. */ 5141 static void gen_divso(DisasContext *ctx) 5142 { 5143 gen_helper_divso(cpu_gpr[rD(ctx->opcode)], cpu_env, 5144 cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); 5145 if (unlikely(Rc(ctx->opcode) != 0)) { 5146 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); 5147 } 5148 } 5149 5150 /* doz - doz. */ 5151 static void gen_doz(DisasContext *ctx) 5152 { 5153 TCGLabel *l1 = gen_new_label(); 5154 TCGLabel *l2 = gen_new_label(); 5155 tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], 5156 cpu_gpr[rA(ctx->opcode)], l1); 5157 tcg_gen_sub_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], 5158 cpu_gpr[rA(ctx->opcode)]); 5159 tcg_gen_br(l2); 5160 gen_set_label(l1); 5161 tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0); 5162 gen_set_label(l2); 5163 if (unlikely(Rc(ctx->opcode) != 0)) { 5164 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); 5165 } 5166 } 5167 5168 /* dozo - dozo. */ 5169 static void gen_dozo(DisasContext *ctx) 5170 { 5171 TCGLabel *l1 = gen_new_label(); 5172 TCGLabel *l2 = gen_new_label(); 5173 TCGv t0 = tcg_temp_new(); 5174 TCGv t1 = tcg_temp_new(); 5175 TCGv t2 = tcg_temp_new(); 5176 /* Start with XER OV disabled, the most likely case */ 5177 tcg_gen_movi_tl(cpu_ov, 0); 5178 tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], 5179 cpu_gpr[rA(ctx->opcode)], l1); 5180 tcg_gen_sub_tl(t0, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); 5181 tcg_gen_xor_tl(t1, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); 5182 tcg_gen_xor_tl(t2, cpu_gpr[rA(ctx->opcode)], t0); 5183 tcg_gen_andc_tl(t1, t1, t2); 5184 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0); 5185 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2); 5186 tcg_gen_movi_tl(cpu_ov, 1); 5187 tcg_gen_movi_tl(cpu_so, 1); 5188 tcg_gen_br(l2); 5189 gen_set_label(l1); 5190 tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0); 5191 gen_set_label(l2); 5192 tcg_temp_free(t0); 5193 tcg_temp_free(t1); 5194 tcg_temp_free(t2); 5195 if (unlikely(Rc(ctx->opcode) != 0)) { 5196 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); 5197 } 5198 } 5199 5200 /* dozi */ 5201 static void gen_dozi(DisasContext *ctx) 5202 { 5203 target_long simm = SIMM(ctx->opcode); 5204 TCGLabel *l1 = gen_new_label(); 5205 TCGLabel *l2 = gen_new_label(); 5206 tcg_gen_brcondi_tl(TCG_COND_LT, cpu_gpr[rA(ctx->opcode)], simm, l1); 5207 tcg_gen_subfi_tl(cpu_gpr[rD(ctx->opcode)], simm, cpu_gpr[rA(ctx->opcode)]); 5208 tcg_gen_br(l2); 5209 gen_set_label(l1); 5210 tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0); 5211 gen_set_label(l2); 5212 if (unlikely(Rc(ctx->opcode) != 0)) { 5213 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); 5214 } 5215 } 5216 5217 /* lscbx - lscbx. */ 5218 static void gen_lscbx(DisasContext *ctx) 5219 { 5220 TCGv t0 = tcg_temp_new(); 5221 TCGv_i32 t1 = tcg_const_i32(rD(ctx->opcode)); 5222 TCGv_i32 t2 = tcg_const_i32(rA(ctx->opcode)); 5223 TCGv_i32 t3 = tcg_const_i32(rB(ctx->opcode)); 5224 5225 gen_addr_reg_index(ctx, t0); 5226 gen_helper_lscbx(t0, cpu_env, t0, t1, t2, t3); 5227 tcg_temp_free_i32(t1); 5228 tcg_temp_free_i32(t2); 5229 tcg_temp_free_i32(t3); 5230 tcg_gen_andi_tl(cpu_xer, cpu_xer, ~0x7F); 5231 tcg_gen_or_tl(cpu_xer, cpu_xer, t0); 5232 if (unlikely(Rc(ctx->opcode) != 0)) { 5233 gen_set_Rc0(ctx, t0); 5234 } 5235 tcg_temp_free(t0); 5236 } 5237 5238 /* maskg - maskg. */ 5239 static void gen_maskg(DisasContext *ctx) 5240 { 5241 TCGLabel *l1 = gen_new_label(); 5242 TCGv t0 = tcg_temp_new(); 5243 TCGv t1 = tcg_temp_new(); 5244 TCGv t2 = tcg_temp_new(); 5245 TCGv t3 = tcg_temp_new(); 5246 tcg_gen_movi_tl(t3, 0xFFFFFFFF); 5247 tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F); 5248 tcg_gen_andi_tl(t1, cpu_gpr[rS(ctx->opcode)], 0x1F); 5249 tcg_gen_addi_tl(t2, t0, 1); 5250 tcg_gen_shr_tl(t2, t3, t2); 5251 tcg_gen_shr_tl(t3, t3, t1); 5252 tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], t2, t3); 5253 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1); 5254 tcg_gen_neg_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); 5255 gen_set_label(l1); 5256 tcg_temp_free(t0); 5257 tcg_temp_free(t1); 5258 tcg_temp_free(t2); 5259 tcg_temp_free(t3); 5260 if (unlikely(Rc(ctx->opcode) != 0)) { 5261 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 5262 } 5263 } 5264 5265 /* maskir - maskir. */ 5266 static void gen_maskir(DisasContext *ctx) 5267 { 5268 TCGv t0 = tcg_temp_new(); 5269 TCGv t1 = tcg_temp_new(); 5270 tcg_gen_and_tl(t0, cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); 5271 tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); 5272 tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1); 5273 tcg_temp_free(t0); 5274 tcg_temp_free(t1); 5275 if (unlikely(Rc(ctx->opcode) != 0)) { 5276 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 5277 } 5278 } 5279 5280 /* mul - mul. */ 5281 static void gen_mul(DisasContext *ctx) 5282 { 5283 TCGv_i64 t0 = tcg_temp_new_i64(); 5284 TCGv_i64 t1 = tcg_temp_new_i64(); 5285 TCGv t2 = tcg_temp_new(); 5286 tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]); 5287 tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]); 5288 tcg_gen_mul_i64(t0, t0, t1); 5289 tcg_gen_trunc_i64_tl(t2, t0); 5290 gen_store_spr(SPR_MQ, t2); 5291 tcg_gen_shri_i64(t1, t0, 32); 5292 tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1); 5293 tcg_temp_free_i64(t0); 5294 tcg_temp_free_i64(t1); 5295 tcg_temp_free(t2); 5296 if (unlikely(Rc(ctx->opcode) != 0)) { 5297 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); 5298 } 5299 } 5300 5301 /* mulo - mulo. */ 5302 static void gen_mulo(DisasContext *ctx) 5303 { 5304 TCGLabel *l1 = gen_new_label(); 5305 TCGv_i64 t0 = tcg_temp_new_i64(); 5306 TCGv_i64 t1 = tcg_temp_new_i64(); 5307 TCGv t2 = tcg_temp_new(); 5308 /* Start with XER OV disabled, the most likely case */ 5309 tcg_gen_movi_tl(cpu_ov, 0); 5310 tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]); 5311 tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]); 5312 tcg_gen_mul_i64(t0, t0, t1); 5313 tcg_gen_trunc_i64_tl(t2, t0); 5314 gen_store_spr(SPR_MQ, t2); 5315 tcg_gen_shri_i64(t1, t0, 32); 5316 tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1); 5317 tcg_gen_ext32s_i64(t1, t0); 5318 tcg_gen_brcond_i64(TCG_COND_EQ, t0, t1, l1); 5319 tcg_gen_movi_tl(cpu_ov, 1); 5320 tcg_gen_movi_tl(cpu_so, 1); 5321 gen_set_label(l1); 5322 tcg_temp_free_i64(t0); 5323 tcg_temp_free_i64(t1); 5324 tcg_temp_free(t2); 5325 if (unlikely(Rc(ctx->opcode) != 0)) { 5326 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); 5327 } 5328 } 5329 5330 /* nabs - nabs. */ 5331 static void gen_nabs(DisasContext *ctx) 5332 { 5333 TCGv d = cpu_gpr[rD(ctx->opcode)]; 5334 TCGv a = cpu_gpr[rA(ctx->opcode)]; 5335 5336 tcg_gen_abs_tl(d, a); 5337 tcg_gen_neg_tl(d, d); 5338 if (unlikely(Rc(ctx->opcode) != 0)) { 5339 gen_set_Rc0(ctx, d); 5340 } 5341 } 5342 5343 /* nabso - nabso. */ 5344 static void gen_nabso(DisasContext *ctx) 5345 { 5346 TCGv d = cpu_gpr[rD(ctx->opcode)]; 5347 TCGv a = cpu_gpr[rA(ctx->opcode)]; 5348 5349 tcg_gen_abs_tl(d, a); 5350 tcg_gen_neg_tl(d, d); 5351 /* nabs never overflows */ 5352 tcg_gen_movi_tl(cpu_ov, 0); 5353 if (unlikely(Rc(ctx->opcode) != 0)) { 5354 gen_set_Rc0(ctx, d); 5355 } 5356 } 5357 5358 /* rlmi - rlmi. */ 5359 static void gen_rlmi(DisasContext *ctx) 5360 { 5361 uint32_t mb = MB(ctx->opcode); 5362 uint32_t me = ME(ctx->opcode); 5363 TCGv t0 = tcg_temp_new(); 5364 tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F); 5365 tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0); 5366 tcg_gen_andi_tl(t0, t0, MASK(mb, me)); 5367 tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 5368 ~MASK(mb, me)); 5369 tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], t0); 5370 tcg_temp_free(t0); 5371 if (unlikely(Rc(ctx->opcode) != 0)) { 5372 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 5373 } 5374 } 5375 5376 /* rrib - rrib. */ 5377 static void gen_rrib(DisasContext *ctx) 5378 { 5379 TCGv t0 = tcg_temp_new(); 5380 TCGv t1 = tcg_temp_new(); 5381 tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F); 5382 tcg_gen_movi_tl(t1, 0x80000000); 5383 tcg_gen_shr_tl(t1, t1, t0); 5384 tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0); 5385 tcg_gen_and_tl(t0, t0, t1); 5386 tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], t1); 5387 tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1); 5388 tcg_temp_free(t0); 5389 tcg_temp_free(t1); 5390 if (unlikely(Rc(ctx->opcode) != 0)) { 5391 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 5392 } 5393 } 5394 5395 /* sle - sle. */ 5396 static void gen_sle(DisasContext *ctx) 5397 { 5398 TCGv t0 = tcg_temp_new(); 5399 TCGv t1 = tcg_temp_new(); 5400 tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F); 5401 tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1); 5402 tcg_gen_subfi_tl(t1, 32, t1); 5403 tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1); 5404 tcg_gen_or_tl(t1, t0, t1); 5405 tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0); 5406 gen_store_spr(SPR_MQ, t1); 5407 tcg_temp_free(t0); 5408 tcg_temp_free(t1); 5409 if (unlikely(Rc(ctx->opcode) != 0)) { 5410 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 5411 } 5412 } 5413 5414 /* sleq - sleq. */ 5415 static void gen_sleq(DisasContext *ctx) 5416 { 5417 TCGv t0 = tcg_temp_new(); 5418 TCGv t1 = tcg_temp_new(); 5419 TCGv t2 = tcg_temp_new(); 5420 tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F); 5421 tcg_gen_movi_tl(t2, 0xFFFFFFFF); 5422 tcg_gen_shl_tl(t2, t2, t0); 5423 tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0); 5424 gen_load_spr(t1, SPR_MQ); 5425 gen_store_spr(SPR_MQ, t0); 5426 tcg_gen_and_tl(t0, t0, t2); 5427 tcg_gen_andc_tl(t1, t1, t2); 5428 tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1); 5429 tcg_temp_free(t0); 5430 tcg_temp_free(t1); 5431 tcg_temp_free(t2); 5432 if (unlikely(Rc(ctx->opcode) != 0)) { 5433 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 5434 } 5435 } 5436 5437 /* sliq - sliq. */ 5438 static void gen_sliq(DisasContext *ctx) 5439 { 5440 int sh = SH(ctx->opcode); 5441 TCGv t0 = tcg_temp_new(); 5442 TCGv t1 = tcg_temp_new(); 5443 tcg_gen_shli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh); 5444 tcg_gen_shri_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh); 5445 tcg_gen_or_tl(t1, t0, t1); 5446 tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0); 5447 gen_store_spr(SPR_MQ, t1); 5448 tcg_temp_free(t0); 5449 tcg_temp_free(t1); 5450 if (unlikely(Rc(ctx->opcode) != 0)) { 5451 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 5452 } 5453 } 5454 5455 /* slliq - slliq. */ 5456 static void gen_slliq(DisasContext *ctx) 5457 { 5458 int sh = SH(ctx->opcode); 5459 TCGv t0 = tcg_temp_new(); 5460 TCGv t1 = tcg_temp_new(); 5461 tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh); 5462 gen_load_spr(t1, SPR_MQ); 5463 gen_store_spr(SPR_MQ, t0); 5464 tcg_gen_andi_tl(t0, t0, (0xFFFFFFFFU << sh)); 5465 tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU << sh)); 5466 tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1); 5467 tcg_temp_free(t0); 5468 tcg_temp_free(t1); 5469 if (unlikely(Rc(ctx->opcode) != 0)) { 5470 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 5471 } 5472 } 5473 5474 /* sllq - sllq. */ 5475 static void gen_sllq(DisasContext *ctx) 5476 { 5477 TCGLabel *l1 = gen_new_label(); 5478 TCGLabel *l2 = gen_new_label(); 5479 TCGv t0 = tcg_temp_local_new(); 5480 TCGv t1 = tcg_temp_local_new(); 5481 TCGv t2 = tcg_temp_local_new(); 5482 tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F); 5483 tcg_gen_movi_tl(t1, 0xFFFFFFFF); 5484 tcg_gen_shl_tl(t1, t1, t2); 5485 tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20); 5486 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); 5487 gen_load_spr(t0, SPR_MQ); 5488 tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t1); 5489 tcg_gen_br(l2); 5490 gen_set_label(l1); 5491 tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t2); 5492 gen_load_spr(t2, SPR_MQ); 5493 tcg_gen_andc_tl(t1, t2, t1); 5494 tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1); 5495 gen_set_label(l2); 5496 tcg_temp_free(t0); 5497 tcg_temp_free(t1); 5498 tcg_temp_free(t2); 5499 if (unlikely(Rc(ctx->opcode) != 0)) { 5500 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 5501 } 5502 } 5503 5504 /* slq - slq. */ 5505 static void gen_slq(DisasContext *ctx) 5506 { 5507 TCGLabel *l1 = gen_new_label(); 5508 TCGv t0 = tcg_temp_new(); 5509 TCGv t1 = tcg_temp_new(); 5510 tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F); 5511 tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1); 5512 tcg_gen_subfi_tl(t1, 32, t1); 5513 tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1); 5514 tcg_gen_or_tl(t1, t0, t1); 5515 gen_store_spr(SPR_MQ, t1); 5516 tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20); 5517 tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0); 5518 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); 5519 tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0); 5520 gen_set_label(l1); 5521 tcg_temp_free(t0); 5522 tcg_temp_free(t1); 5523 if (unlikely(Rc(ctx->opcode) != 0)) { 5524 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 5525 } 5526 } 5527 5528 /* sraiq - sraiq. */ 5529 static void gen_sraiq(DisasContext *ctx) 5530 { 5531 int sh = SH(ctx->opcode); 5532 TCGLabel *l1 = gen_new_label(); 5533 TCGv t0 = tcg_temp_new(); 5534 TCGv t1 = tcg_temp_new(); 5535 tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh); 5536 tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh); 5537 tcg_gen_or_tl(t0, t0, t1); 5538 gen_store_spr(SPR_MQ, t0); 5539 tcg_gen_movi_tl(cpu_ca, 0); 5540 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); 5541 tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1); 5542 tcg_gen_movi_tl(cpu_ca, 1); 5543 gen_set_label(l1); 5544 tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh); 5545 tcg_temp_free(t0); 5546 tcg_temp_free(t1); 5547 if (unlikely(Rc(ctx->opcode) != 0)) { 5548 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 5549 } 5550 } 5551 5552 /* sraq - sraq. */ 5553 static void gen_sraq(DisasContext *ctx) 5554 { 5555 TCGLabel *l1 = gen_new_label(); 5556 TCGLabel *l2 = gen_new_label(); 5557 TCGv t0 = tcg_temp_new(); 5558 TCGv t1 = tcg_temp_local_new(); 5559 TCGv t2 = tcg_temp_local_new(); 5560 tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F); 5561 tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2); 5562 tcg_gen_sar_tl(t1, cpu_gpr[rS(ctx->opcode)], t2); 5563 tcg_gen_subfi_tl(t2, 32, t2); 5564 tcg_gen_shl_tl(t2, cpu_gpr[rS(ctx->opcode)], t2); 5565 tcg_gen_or_tl(t0, t0, t2); 5566 gen_store_spr(SPR_MQ, t0); 5567 tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20); 5568 tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l1); 5569 tcg_gen_mov_tl(t2, cpu_gpr[rS(ctx->opcode)]); 5570 tcg_gen_sari_tl(t1, cpu_gpr[rS(ctx->opcode)], 31); 5571 gen_set_label(l1); 5572 tcg_temp_free(t0); 5573 tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t1); 5574 tcg_gen_movi_tl(cpu_ca, 0); 5575 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2); 5576 tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l2); 5577 tcg_gen_movi_tl(cpu_ca, 1); 5578 gen_set_label(l2); 5579 tcg_temp_free(t1); 5580 tcg_temp_free(t2); 5581 if (unlikely(Rc(ctx->opcode) != 0)) { 5582 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 5583 } 5584 } 5585 5586 /* sre - sre. */ 5587 static void gen_sre(DisasContext *ctx) 5588 { 5589 TCGv t0 = tcg_temp_new(); 5590 TCGv t1 = tcg_temp_new(); 5591 tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F); 5592 tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1); 5593 tcg_gen_subfi_tl(t1, 32, t1); 5594 tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t1); 5595 tcg_gen_or_tl(t1, t0, t1); 5596 tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0); 5597 gen_store_spr(SPR_MQ, t1); 5598 tcg_temp_free(t0); 5599 tcg_temp_free(t1); 5600 if (unlikely(Rc(ctx->opcode) != 0)) { 5601 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 5602 } 5603 } 5604 5605 /* srea - srea. */ 5606 static void gen_srea(DisasContext *ctx) 5607 { 5608 TCGv t0 = tcg_temp_new(); 5609 TCGv t1 = tcg_temp_new(); 5610 tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F); 5611 tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1); 5612 gen_store_spr(SPR_MQ, t0); 5613 tcg_gen_sar_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], t1); 5614 tcg_temp_free(t0); 5615 tcg_temp_free(t1); 5616 if (unlikely(Rc(ctx->opcode) != 0)) { 5617 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 5618 } 5619 } 5620 5621 /* sreq */ 5622 static void gen_sreq(DisasContext *ctx) 5623 { 5624 TCGv t0 = tcg_temp_new(); 5625 TCGv t1 = tcg_temp_new(); 5626 TCGv t2 = tcg_temp_new(); 5627 tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F); 5628 tcg_gen_movi_tl(t1, 0xFFFFFFFF); 5629 tcg_gen_shr_tl(t1, t1, t0); 5630 tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0); 5631 gen_load_spr(t2, SPR_MQ); 5632 gen_store_spr(SPR_MQ, t0); 5633 tcg_gen_and_tl(t0, t0, t1); 5634 tcg_gen_andc_tl(t2, t2, t1); 5635 tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t2); 5636 tcg_temp_free(t0); 5637 tcg_temp_free(t1); 5638 tcg_temp_free(t2); 5639 if (unlikely(Rc(ctx->opcode) != 0)) { 5640 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 5641 } 5642 } 5643 5644 /* sriq */ 5645 static void gen_sriq(DisasContext *ctx) 5646 { 5647 int sh = SH(ctx->opcode); 5648 TCGv t0 = tcg_temp_new(); 5649 TCGv t1 = tcg_temp_new(); 5650 tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh); 5651 tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh); 5652 tcg_gen_or_tl(t1, t0, t1); 5653 tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0); 5654 gen_store_spr(SPR_MQ, t1); 5655 tcg_temp_free(t0); 5656 tcg_temp_free(t1); 5657 if (unlikely(Rc(ctx->opcode) != 0)) { 5658 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 5659 } 5660 } 5661 5662 /* srliq */ 5663 static void gen_srliq(DisasContext *ctx) 5664 { 5665 int sh = SH(ctx->opcode); 5666 TCGv t0 = tcg_temp_new(); 5667 TCGv t1 = tcg_temp_new(); 5668 tcg_gen_rotri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh); 5669 gen_load_spr(t1, SPR_MQ); 5670 gen_store_spr(SPR_MQ, t0); 5671 tcg_gen_andi_tl(t0, t0, (0xFFFFFFFFU >> sh)); 5672 tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU >> sh)); 5673 tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1); 5674 tcg_temp_free(t0); 5675 tcg_temp_free(t1); 5676 if (unlikely(Rc(ctx->opcode) != 0)) { 5677 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 5678 } 5679 } 5680 5681 /* srlq */ 5682 static void gen_srlq(DisasContext *ctx) 5683 { 5684 TCGLabel *l1 = gen_new_label(); 5685 TCGLabel *l2 = gen_new_label(); 5686 TCGv t0 = tcg_temp_local_new(); 5687 TCGv t1 = tcg_temp_local_new(); 5688 TCGv t2 = tcg_temp_local_new(); 5689 tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F); 5690 tcg_gen_movi_tl(t1, 0xFFFFFFFF); 5691 tcg_gen_shr_tl(t2, t1, t2); 5692 tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20); 5693 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); 5694 gen_load_spr(t0, SPR_MQ); 5695 tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t2); 5696 tcg_gen_br(l2); 5697 gen_set_label(l1); 5698 tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2); 5699 tcg_gen_and_tl(t0, t0, t2); 5700 gen_load_spr(t1, SPR_MQ); 5701 tcg_gen_andc_tl(t1, t1, t2); 5702 tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1); 5703 gen_set_label(l2); 5704 tcg_temp_free(t0); 5705 tcg_temp_free(t1); 5706 tcg_temp_free(t2); 5707 if (unlikely(Rc(ctx->opcode) != 0)) { 5708 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 5709 } 5710 } 5711 5712 /* srq */ 5713 static void gen_srq(DisasContext *ctx) 5714 { 5715 TCGLabel *l1 = gen_new_label(); 5716 TCGv t0 = tcg_temp_new(); 5717 TCGv t1 = tcg_temp_new(); 5718 tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F); 5719 tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1); 5720 tcg_gen_subfi_tl(t1, 32, t1); 5721 tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t1); 5722 tcg_gen_or_tl(t1, t0, t1); 5723 gen_store_spr(SPR_MQ, t1); 5724 tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20); 5725 tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0); 5726 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); 5727 tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0); 5728 gen_set_label(l1); 5729 tcg_temp_free(t0); 5730 tcg_temp_free(t1); 5731 if (unlikely(Rc(ctx->opcode) != 0)) { 5732 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); 5733 } 5734 } 5735 5736 /* PowerPC 602 specific instructions */ 5737 5738 /* dsa */ 5739 static void gen_dsa(DisasContext *ctx) 5740 { 5741 /* XXX: TODO */ 5742 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 5743 } 5744 5745 /* esa */ 5746 static void gen_esa(DisasContext *ctx) 5747 { 5748 /* XXX: TODO */ 5749 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 5750 } 5751 5752 /* mfrom */ 5753 static void gen_mfrom(DisasContext *ctx) 5754 { 5755 #if defined(CONFIG_USER_ONLY) 5756 GEN_PRIV; 5757 #else 5758 CHK_SV; 5759 gen_helper_602_mfrom(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); 5760 #endif /* defined(CONFIG_USER_ONLY) */ 5761 } 5762 5763 /* 602 - 603 - G2 TLB management */ 5764 5765 /* tlbld */ 5766 static void gen_tlbld_6xx(DisasContext *ctx) 5767 { 5768 #if defined(CONFIG_USER_ONLY) 5769 GEN_PRIV; 5770 #else 5771 CHK_SV; 5772 gen_helper_6xx_tlbd(cpu_env, cpu_gpr[rB(ctx->opcode)]); 5773 #endif /* defined(CONFIG_USER_ONLY) */ 5774 } 5775 5776 /* tlbli */ 5777 static void gen_tlbli_6xx(DisasContext *ctx) 5778 { 5779 #if defined(CONFIG_USER_ONLY) 5780 GEN_PRIV; 5781 #else 5782 CHK_SV; 5783 gen_helper_6xx_tlbi(cpu_env, cpu_gpr[rB(ctx->opcode)]); 5784 #endif /* defined(CONFIG_USER_ONLY) */ 5785 } 5786 5787 /* 74xx TLB management */ 5788 5789 /* tlbld */ 5790 static void gen_tlbld_74xx(DisasContext *ctx) 5791 { 5792 #if defined(CONFIG_USER_ONLY) 5793 GEN_PRIV; 5794 #else 5795 CHK_SV; 5796 gen_helper_74xx_tlbd(cpu_env, cpu_gpr[rB(ctx->opcode)]); 5797 #endif /* defined(CONFIG_USER_ONLY) */ 5798 } 5799 5800 /* tlbli */ 5801 static void gen_tlbli_74xx(DisasContext *ctx) 5802 { 5803 #if defined(CONFIG_USER_ONLY) 5804 GEN_PRIV; 5805 #else 5806 CHK_SV; 5807 gen_helper_74xx_tlbi(cpu_env, cpu_gpr[rB(ctx->opcode)]); 5808 #endif /* defined(CONFIG_USER_ONLY) */ 5809 } 5810 5811 /* POWER instructions not in PowerPC 601 */ 5812 5813 /* clf */ 5814 static void gen_clf(DisasContext *ctx) 5815 { 5816 /* Cache line flush: implemented as no-op */ 5817 } 5818 5819 /* cli */ 5820 static void gen_cli(DisasContext *ctx) 5821 { 5822 #if defined(CONFIG_USER_ONLY) 5823 GEN_PRIV; 5824 #else 5825 /* Cache line invalidate: privileged and treated as no-op */ 5826 CHK_SV; 5827 #endif /* defined(CONFIG_USER_ONLY) */ 5828 } 5829 5830 /* dclst */ 5831 static void gen_dclst(DisasContext *ctx) 5832 { 5833 /* Data cache line store: treated as no-op */ 5834 } 5835 5836 static void gen_mfsri(DisasContext *ctx) 5837 { 5838 #if defined(CONFIG_USER_ONLY) 5839 GEN_PRIV; 5840 #else 5841 int ra = rA(ctx->opcode); 5842 int rd = rD(ctx->opcode); 5843 TCGv t0; 5844 5845 CHK_SV; 5846 t0 = tcg_temp_new(); 5847 gen_addr_reg_index(ctx, t0); 5848 tcg_gen_extract_tl(t0, t0, 28, 4); 5849 gen_helper_load_sr(cpu_gpr[rd], cpu_env, t0); 5850 tcg_temp_free(t0); 5851 if (ra != 0 && ra != rd) { 5852 tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rd]); 5853 } 5854 #endif /* defined(CONFIG_USER_ONLY) */ 5855 } 5856 5857 static void gen_rac(DisasContext *ctx) 5858 { 5859 #if defined(CONFIG_USER_ONLY) 5860 GEN_PRIV; 5861 #else 5862 TCGv t0; 5863 5864 CHK_SV; 5865 t0 = tcg_temp_new(); 5866 gen_addr_reg_index(ctx, t0); 5867 gen_helper_rac(cpu_gpr[rD(ctx->opcode)], cpu_env, t0); 5868 tcg_temp_free(t0); 5869 #endif /* defined(CONFIG_USER_ONLY) */ 5870 } 5871 5872 static void gen_rfsvc(DisasContext *ctx) 5873 { 5874 #if defined(CONFIG_USER_ONLY) 5875 GEN_PRIV; 5876 #else 5877 CHK_SV; 5878 5879 gen_helper_rfsvc(cpu_env); 5880 gen_sync_exception(ctx); 5881 #endif /* defined(CONFIG_USER_ONLY) */ 5882 } 5883 5884 /* svc is not implemented for now */ 5885 5886 /* BookE specific instructions */ 5887 5888 /* XXX: not implemented on 440 ? */ 5889 static void gen_mfapidi(DisasContext *ctx) 5890 { 5891 /* XXX: TODO */ 5892 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 5893 } 5894 5895 /* XXX: not implemented on 440 ? */ 5896 static void gen_tlbiva(DisasContext *ctx) 5897 { 5898 #if defined(CONFIG_USER_ONLY) 5899 GEN_PRIV; 5900 #else 5901 TCGv t0; 5902 5903 CHK_SV; 5904 t0 = tcg_temp_new(); 5905 gen_addr_reg_index(ctx, t0); 5906 gen_helper_tlbiva(cpu_env, cpu_gpr[rB(ctx->opcode)]); 5907 tcg_temp_free(t0); 5908 #endif /* defined(CONFIG_USER_ONLY) */ 5909 } 5910 5911 /* All 405 MAC instructions are translated here */ 5912 static inline void gen_405_mulladd_insn(DisasContext *ctx, int opc2, int opc3, 5913 int ra, int rb, int rt, int Rc) 5914 { 5915 TCGv t0, t1; 5916 5917 t0 = tcg_temp_local_new(); 5918 t1 = tcg_temp_local_new(); 5919 5920 switch (opc3 & 0x0D) { 5921 case 0x05: 5922 /* macchw - macchw. - macchwo - macchwo. */ 5923 /* macchws - macchws. - macchwso - macchwso. */ 5924 /* nmacchw - nmacchw. - nmacchwo - nmacchwo. */ 5925 /* nmacchws - nmacchws. - nmacchwso - nmacchwso. */ 5926 /* mulchw - mulchw. */ 5927 tcg_gen_ext16s_tl(t0, cpu_gpr[ra]); 5928 tcg_gen_sari_tl(t1, cpu_gpr[rb], 16); 5929 tcg_gen_ext16s_tl(t1, t1); 5930 break; 5931 case 0x04: 5932 /* macchwu - macchwu. - macchwuo - macchwuo. */ 5933 /* macchwsu - macchwsu. - macchwsuo - macchwsuo. */ 5934 /* mulchwu - mulchwu. */ 5935 tcg_gen_ext16u_tl(t0, cpu_gpr[ra]); 5936 tcg_gen_shri_tl(t1, cpu_gpr[rb], 16); 5937 tcg_gen_ext16u_tl(t1, t1); 5938 break; 5939 case 0x01: 5940 /* machhw - machhw. - machhwo - machhwo. */ 5941 /* machhws - machhws. - machhwso - machhwso. */ 5942 /* nmachhw - nmachhw. - nmachhwo - nmachhwo. */ 5943 /* nmachhws - nmachhws. - nmachhwso - nmachhwso. */ 5944 /* mulhhw - mulhhw. */ 5945 tcg_gen_sari_tl(t0, cpu_gpr[ra], 16); 5946 tcg_gen_ext16s_tl(t0, t0); 5947 tcg_gen_sari_tl(t1, cpu_gpr[rb], 16); 5948 tcg_gen_ext16s_tl(t1, t1); 5949 break; 5950 case 0x00: 5951 /* machhwu - machhwu. - machhwuo - machhwuo. */ 5952 /* machhwsu - machhwsu. - machhwsuo - machhwsuo. */ 5953 /* mulhhwu - mulhhwu. */ 5954 tcg_gen_shri_tl(t0, cpu_gpr[ra], 16); 5955 tcg_gen_ext16u_tl(t0, t0); 5956 tcg_gen_shri_tl(t1, cpu_gpr[rb], 16); 5957 tcg_gen_ext16u_tl(t1, t1); 5958 break; 5959 case 0x0D: 5960 /* maclhw - maclhw. - maclhwo - maclhwo. */ 5961 /* maclhws - maclhws. - maclhwso - maclhwso. */ 5962 /* nmaclhw - nmaclhw. - nmaclhwo - nmaclhwo. */ 5963 /* nmaclhws - nmaclhws. - nmaclhwso - nmaclhwso. */ 5964 /* mullhw - mullhw. */ 5965 tcg_gen_ext16s_tl(t0, cpu_gpr[ra]); 5966 tcg_gen_ext16s_tl(t1, cpu_gpr[rb]); 5967 break; 5968 case 0x0C: 5969 /* maclhwu - maclhwu. - maclhwuo - maclhwuo. */ 5970 /* maclhwsu - maclhwsu. - maclhwsuo - maclhwsuo. */ 5971 /* mullhwu - mullhwu. */ 5972 tcg_gen_ext16u_tl(t0, cpu_gpr[ra]); 5973 tcg_gen_ext16u_tl(t1, cpu_gpr[rb]); 5974 break; 5975 } 5976 if (opc2 & 0x04) { 5977 /* (n)multiply-and-accumulate (0x0C / 0x0E) */ 5978 tcg_gen_mul_tl(t1, t0, t1); 5979 if (opc2 & 0x02) { 5980 /* nmultiply-and-accumulate (0x0E) */ 5981 tcg_gen_sub_tl(t0, cpu_gpr[rt], t1); 5982 } else { 5983 /* multiply-and-accumulate (0x0C) */ 5984 tcg_gen_add_tl(t0, cpu_gpr[rt], t1); 5985 } 5986 5987 if (opc3 & 0x12) { 5988 /* Check overflow and/or saturate */ 5989 TCGLabel *l1 = gen_new_label(); 5990 5991 if (opc3 & 0x10) { 5992 /* Start with XER OV disabled, the most likely case */ 5993 tcg_gen_movi_tl(cpu_ov, 0); 5994 } 5995 if (opc3 & 0x01) { 5996 /* Signed */ 5997 tcg_gen_xor_tl(t1, cpu_gpr[rt], t1); 5998 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); 5999 tcg_gen_xor_tl(t1, cpu_gpr[rt], t0); 6000 tcg_gen_brcondi_tl(TCG_COND_LT, t1, 0, l1); 6001 if (opc3 & 0x02) { 6002 /* Saturate */ 6003 tcg_gen_sari_tl(t0, cpu_gpr[rt], 31); 6004 tcg_gen_xori_tl(t0, t0, 0x7fffffff); 6005 } 6006 } else { 6007 /* Unsigned */ 6008 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1); 6009 if (opc3 & 0x02) { 6010 /* Saturate */ 6011 tcg_gen_movi_tl(t0, UINT32_MAX); 6012 } 6013 } 6014 if (opc3 & 0x10) { 6015 /* Check overflow */ 6016 tcg_gen_movi_tl(cpu_ov, 1); 6017 tcg_gen_movi_tl(cpu_so, 1); 6018 } 6019 gen_set_label(l1); 6020 tcg_gen_mov_tl(cpu_gpr[rt], t0); 6021 } 6022 } else { 6023 tcg_gen_mul_tl(cpu_gpr[rt], t0, t1); 6024 } 6025 tcg_temp_free(t0); 6026 tcg_temp_free(t1); 6027 if (unlikely(Rc) != 0) { 6028 /* Update Rc0 */ 6029 gen_set_Rc0(ctx, cpu_gpr[rt]); 6030 } 6031 } 6032 6033 #define GEN_MAC_HANDLER(name, opc2, opc3) \ 6034 static void glue(gen_, name)(DisasContext *ctx) \ 6035 { \ 6036 gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode), \ 6037 rD(ctx->opcode), Rc(ctx->opcode)); \ 6038 } 6039 6040 /* macchw - macchw. */ 6041 GEN_MAC_HANDLER(macchw, 0x0C, 0x05); 6042 /* macchwo - macchwo. */ 6043 GEN_MAC_HANDLER(macchwo, 0x0C, 0x15); 6044 /* macchws - macchws. */ 6045 GEN_MAC_HANDLER(macchws, 0x0C, 0x07); 6046 /* macchwso - macchwso. */ 6047 GEN_MAC_HANDLER(macchwso, 0x0C, 0x17); 6048 /* macchwsu - macchwsu. */ 6049 GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06); 6050 /* macchwsuo - macchwsuo. */ 6051 GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16); 6052 /* macchwu - macchwu. */ 6053 GEN_MAC_HANDLER(macchwu, 0x0C, 0x04); 6054 /* macchwuo - macchwuo. */ 6055 GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14); 6056 /* machhw - machhw. */ 6057 GEN_MAC_HANDLER(machhw, 0x0C, 0x01); 6058 /* machhwo - machhwo. */ 6059 GEN_MAC_HANDLER(machhwo, 0x0C, 0x11); 6060 /* machhws - machhws. */ 6061 GEN_MAC_HANDLER(machhws, 0x0C, 0x03); 6062 /* machhwso - machhwso. */ 6063 GEN_MAC_HANDLER(machhwso, 0x0C, 0x13); 6064 /* machhwsu - machhwsu. */ 6065 GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02); 6066 /* machhwsuo - machhwsuo. */ 6067 GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12); 6068 /* machhwu - machhwu. */ 6069 GEN_MAC_HANDLER(machhwu, 0x0C, 0x00); 6070 /* machhwuo - machhwuo. */ 6071 GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10); 6072 /* maclhw - maclhw. */ 6073 GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D); 6074 /* maclhwo - maclhwo. */ 6075 GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D); 6076 /* maclhws - maclhws. */ 6077 GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F); 6078 /* maclhwso - maclhwso. */ 6079 GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F); 6080 /* maclhwu - maclhwu. */ 6081 GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C); 6082 /* maclhwuo - maclhwuo. */ 6083 GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C); 6084 /* maclhwsu - maclhwsu. */ 6085 GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E); 6086 /* maclhwsuo - maclhwsuo. */ 6087 GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E); 6088 /* nmacchw - nmacchw. */ 6089 GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05); 6090 /* nmacchwo - nmacchwo. */ 6091 GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15); 6092 /* nmacchws - nmacchws. */ 6093 GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07); 6094 /* nmacchwso - nmacchwso. */ 6095 GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17); 6096 /* nmachhw - nmachhw. */ 6097 GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01); 6098 /* nmachhwo - nmachhwo. */ 6099 GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11); 6100 /* nmachhws - nmachhws. */ 6101 GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03); 6102 /* nmachhwso - nmachhwso. */ 6103 GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13); 6104 /* nmaclhw - nmaclhw. */ 6105 GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D); 6106 /* nmaclhwo - nmaclhwo. */ 6107 GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D); 6108 /* nmaclhws - nmaclhws. */ 6109 GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F); 6110 /* nmaclhwso - nmaclhwso. */ 6111 GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F); 6112 6113 /* mulchw - mulchw. */ 6114 GEN_MAC_HANDLER(mulchw, 0x08, 0x05); 6115 /* mulchwu - mulchwu. */ 6116 GEN_MAC_HANDLER(mulchwu, 0x08, 0x04); 6117 /* mulhhw - mulhhw. */ 6118 GEN_MAC_HANDLER(mulhhw, 0x08, 0x01); 6119 /* mulhhwu - mulhhwu. */ 6120 GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00); 6121 /* mullhw - mullhw. */ 6122 GEN_MAC_HANDLER(mullhw, 0x08, 0x0D); 6123 /* mullhwu - mullhwu. */ 6124 GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C); 6125 6126 /* mfdcr */ 6127 static void gen_mfdcr(DisasContext *ctx) 6128 { 6129 #if defined(CONFIG_USER_ONLY) 6130 GEN_PRIV; 6131 #else 6132 TCGv dcrn; 6133 6134 CHK_SV; 6135 dcrn = tcg_const_tl(SPR(ctx->opcode)); 6136 gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env, dcrn); 6137 tcg_temp_free(dcrn); 6138 #endif /* defined(CONFIG_USER_ONLY) */ 6139 } 6140 6141 /* mtdcr */ 6142 static void gen_mtdcr(DisasContext *ctx) 6143 { 6144 #if defined(CONFIG_USER_ONLY) 6145 GEN_PRIV; 6146 #else 6147 TCGv dcrn; 6148 6149 CHK_SV; 6150 dcrn = tcg_const_tl(SPR(ctx->opcode)); 6151 gen_helper_store_dcr(cpu_env, dcrn, cpu_gpr[rS(ctx->opcode)]); 6152 tcg_temp_free(dcrn); 6153 #endif /* defined(CONFIG_USER_ONLY) */ 6154 } 6155 6156 /* mfdcrx */ 6157 /* XXX: not implemented on 440 ? */ 6158 static void gen_mfdcrx(DisasContext *ctx) 6159 { 6160 #if defined(CONFIG_USER_ONLY) 6161 GEN_PRIV; 6162 #else 6163 CHK_SV; 6164 gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env, 6165 cpu_gpr[rA(ctx->opcode)]); 6166 /* Note: Rc update flag set leads to undefined state of Rc0 */ 6167 #endif /* defined(CONFIG_USER_ONLY) */ 6168 } 6169 6170 /* mtdcrx */ 6171 /* XXX: not implemented on 440 ? */ 6172 static void gen_mtdcrx(DisasContext *ctx) 6173 { 6174 #if defined(CONFIG_USER_ONLY) 6175 GEN_PRIV; 6176 #else 6177 CHK_SV; 6178 gen_helper_store_dcr(cpu_env, cpu_gpr[rA(ctx->opcode)], 6179 cpu_gpr[rS(ctx->opcode)]); 6180 /* Note: Rc update flag set leads to undefined state of Rc0 */ 6181 #endif /* defined(CONFIG_USER_ONLY) */ 6182 } 6183 6184 /* mfdcrux (PPC 460) : user-mode access to DCR */ 6185 static void gen_mfdcrux(DisasContext *ctx) 6186 { 6187 gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env, 6188 cpu_gpr[rA(ctx->opcode)]); 6189 /* Note: Rc update flag set leads to undefined state of Rc0 */ 6190 } 6191 6192 /* mtdcrux (PPC 460) : user-mode access to DCR */ 6193 static void gen_mtdcrux(DisasContext *ctx) 6194 { 6195 gen_helper_store_dcr(cpu_env, cpu_gpr[rA(ctx->opcode)], 6196 cpu_gpr[rS(ctx->opcode)]); 6197 /* Note: Rc update flag set leads to undefined state of Rc0 */ 6198 } 6199 6200 /* dccci */ 6201 static void gen_dccci(DisasContext *ctx) 6202 { 6203 CHK_SV; 6204 /* interpreted as no-op */ 6205 } 6206 6207 /* dcread */ 6208 static void gen_dcread(DisasContext *ctx) 6209 { 6210 #if defined(CONFIG_USER_ONLY) 6211 GEN_PRIV; 6212 #else 6213 TCGv EA, val; 6214 6215 CHK_SV; 6216 gen_set_access_type(ctx, ACCESS_CACHE); 6217 EA = tcg_temp_new(); 6218 gen_addr_reg_index(ctx, EA); 6219 val = tcg_temp_new(); 6220 gen_qemu_ld32u(ctx, val, EA); 6221 tcg_temp_free(val); 6222 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], EA); 6223 tcg_temp_free(EA); 6224 #endif /* defined(CONFIG_USER_ONLY) */ 6225 } 6226 6227 /* icbt */ 6228 static void gen_icbt_40x(DisasContext *ctx) 6229 { 6230 /* 6231 * interpreted as no-op 6232 * XXX: specification say this is treated as a load by the MMU but 6233 * does not generate any exception 6234 */ 6235 } 6236 6237 /* iccci */ 6238 static void gen_iccci(DisasContext *ctx) 6239 { 6240 CHK_SV; 6241 /* interpreted as no-op */ 6242 } 6243 6244 /* icread */ 6245 static void gen_icread(DisasContext *ctx) 6246 { 6247 CHK_SV; 6248 /* interpreted as no-op */ 6249 } 6250 6251 /* rfci (supervisor only) */ 6252 static void gen_rfci_40x(DisasContext *ctx) 6253 { 6254 #if defined(CONFIG_USER_ONLY) 6255 GEN_PRIV; 6256 #else 6257 CHK_SV; 6258 /* Restore CPU state */ 6259 gen_helper_40x_rfci(cpu_env); 6260 gen_sync_exception(ctx); 6261 #endif /* defined(CONFIG_USER_ONLY) */ 6262 } 6263 6264 static void gen_rfci(DisasContext *ctx) 6265 { 6266 #if defined(CONFIG_USER_ONLY) 6267 GEN_PRIV; 6268 #else 6269 CHK_SV; 6270 /* Restore CPU state */ 6271 gen_helper_rfci(cpu_env); 6272 gen_sync_exception(ctx); 6273 #endif /* defined(CONFIG_USER_ONLY) */ 6274 } 6275 6276 /* BookE specific */ 6277 6278 /* XXX: not implemented on 440 ? */ 6279 static void gen_rfdi(DisasContext *ctx) 6280 { 6281 #if defined(CONFIG_USER_ONLY) 6282 GEN_PRIV; 6283 #else 6284 CHK_SV; 6285 /* Restore CPU state */ 6286 gen_helper_rfdi(cpu_env); 6287 gen_sync_exception(ctx); 6288 #endif /* defined(CONFIG_USER_ONLY) */ 6289 } 6290 6291 /* XXX: not implemented on 440 ? */ 6292 static void gen_rfmci(DisasContext *ctx) 6293 { 6294 #if defined(CONFIG_USER_ONLY) 6295 GEN_PRIV; 6296 #else 6297 CHK_SV; 6298 /* Restore CPU state */ 6299 gen_helper_rfmci(cpu_env); 6300 gen_sync_exception(ctx); 6301 #endif /* defined(CONFIG_USER_ONLY) */ 6302 } 6303 6304 /* TLB management - PowerPC 405 implementation */ 6305 6306 /* tlbre */ 6307 static void gen_tlbre_40x(DisasContext *ctx) 6308 { 6309 #if defined(CONFIG_USER_ONLY) 6310 GEN_PRIV; 6311 #else 6312 CHK_SV; 6313 switch (rB(ctx->opcode)) { 6314 case 0: 6315 gen_helper_4xx_tlbre_hi(cpu_gpr[rD(ctx->opcode)], cpu_env, 6316 cpu_gpr[rA(ctx->opcode)]); 6317 break; 6318 case 1: 6319 gen_helper_4xx_tlbre_lo(cpu_gpr[rD(ctx->opcode)], cpu_env, 6320 cpu_gpr[rA(ctx->opcode)]); 6321 break; 6322 default: 6323 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 6324 break; 6325 } 6326 #endif /* defined(CONFIG_USER_ONLY) */ 6327 } 6328 6329 /* tlbsx - tlbsx. */ 6330 static void gen_tlbsx_40x(DisasContext *ctx) 6331 { 6332 #if defined(CONFIG_USER_ONLY) 6333 GEN_PRIV; 6334 #else 6335 TCGv t0; 6336 6337 CHK_SV; 6338 t0 = tcg_temp_new(); 6339 gen_addr_reg_index(ctx, t0); 6340 gen_helper_4xx_tlbsx(cpu_gpr[rD(ctx->opcode)], cpu_env, t0); 6341 tcg_temp_free(t0); 6342 if (Rc(ctx->opcode)) { 6343 TCGLabel *l1 = gen_new_label(); 6344 tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so); 6345 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1); 6346 tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02); 6347 gen_set_label(l1); 6348 } 6349 #endif /* defined(CONFIG_USER_ONLY) */ 6350 } 6351 6352 /* tlbwe */ 6353 static void gen_tlbwe_40x(DisasContext *ctx) 6354 { 6355 #if defined(CONFIG_USER_ONLY) 6356 GEN_PRIV; 6357 #else 6358 CHK_SV; 6359 6360 switch (rB(ctx->opcode)) { 6361 case 0: 6362 gen_helper_4xx_tlbwe_hi(cpu_env, cpu_gpr[rA(ctx->opcode)], 6363 cpu_gpr[rS(ctx->opcode)]); 6364 break; 6365 case 1: 6366 gen_helper_4xx_tlbwe_lo(cpu_env, cpu_gpr[rA(ctx->opcode)], 6367 cpu_gpr[rS(ctx->opcode)]); 6368 break; 6369 default: 6370 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 6371 break; 6372 } 6373 #endif /* defined(CONFIG_USER_ONLY) */ 6374 } 6375 6376 /* TLB management - PowerPC 440 implementation */ 6377 6378 /* tlbre */ 6379 static void gen_tlbre_440(DisasContext *ctx) 6380 { 6381 #if defined(CONFIG_USER_ONLY) 6382 GEN_PRIV; 6383 #else 6384 CHK_SV; 6385 6386 switch (rB(ctx->opcode)) { 6387 case 0: 6388 case 1: 6389 case 2: 6390 { 6391 TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode)); 6392 gen_helper_440_tlbre(cpu_gpr[rD(ctx->opcode)], cpu_env, 6393 t0, cpu_gpr[rA(ctx->opcode)]); 6394 tcg_temp_free_i32(t0); 6395 } 6396 break; 6397 default: 6398 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 6399 break; 6400 } 6401 #endif /* defined(CONFIG_USER_ONLY) */ 6402 } 6403 6404 /* tlbsx - tlbsx. */ 6405 static void gen_tlbsx_440(DisasContext *ctx) 6406 { 6407 #if defined(CONFIG_USER_ONLY) 6408 GEN_PRIV; 6409 #else 6410 TCGv t0; 6411 6412 CHK_SV; 6413 t0 = tcg_temp_new(); 6414 gen_addr_reg_index(ctx, t0); 6415 gen_helper_440_tlbsx(cpu_gpr[rD(ctx->opcode)], cpu_env, t0); 6416 tcg_temp_free(t0); 6417 if (Rc(ctx->opcode)) { 6418 TCGLabel *l1 = gen_new_label(); 6419 tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so); 6420 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1); 6421 tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02); 6422 gen_set_label(l1); 6423 } 6424 #endif /* defined(CONFIG_USER_ONLY) */ 6425 } 6426 6427 /* tlbwe */ 6428 static void gen_tlbwe_440(DisasContext *ctx) 6429 { 6430 #if defined(CONFIG_USER_ONLY) 6431 GEN_PRIV; 6432 #else 6433 CHK_SV; 6434 switch (rB(ctx->opcode)) { 6435 case 0: 6436 case 1: 6437 case 2: 6438 { 6439 TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode)); 6440 gen_helper_440_tlbwe(cpu_env, t0, cpu_gpr[rA(ctx->opcode)], 6441 cpu_gpr[rS(ctx->opcode)]); 6442 tcg_temp_free_i32(t0); 6443 } 6444 break; 6445 default: 6446 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 6447 break; 6448 } 6449 #endif /* defined(CONFIG_USER_ONLY) */ 6450 } 6451 6452 /* TLB management - PowerPC BookE 2.06 implementation */ 6453 6454 /* tlbre */ 6455 static void gen_tlbre_booke206(DisasContext *ctx) 6456 { 6457 #if defined(CONFIG_USER_ONLY) 6458 GEN_PRIV; 6459 #else 6460 CHK_SV; 6461 gen_helper_booke206_tlbre(cpu_env); 6462 #endif /* defined(CONFIG_USER_ONLY) */ 6463 } 6464 6465 /* tlbsx - tlbsx. */ 6466 static void gen_tlbsx_booke206(DisasContext *ctx) 6467 { 6468 #if defined(CONFIG_USER_ONLY) 6469 GEN_PRIV; 6470 #else 6471 TCGv t0; 6472 6473 CHK_SV; 6474 if (rA(ctx->opcode)) { 6475 t0 = tcg_temp_new(); 6476 tcg_gen_mov_tl(t0, cpu_gpr[rD(ctx->opcode)]); 6477 } else { 6478 t0 = tcg_const_tl(0); 6479 } 6480 6481 tcg_gen_add_tl(t0, t0, cpu_gpr[rB(ctx->opcode)]); 6482 gen_helper_booke206_tlbsx(cpu_env, t0); 6483 tcg_temp_free(t0); 6484 #endif /* defined(CONFIG_USER_ONLY) */ 6485 } 6486 6487 /* tlbwe */ 6488 static void gen_tlbwe_booke206(DisasContext *ctx) 6489 { 6490 #if defined(CONFIG_USER_ONLY) 6491 GEN_PRIV; 6492 #else 6493 CHK_SV; 6494 gen_helper_booke206_tlbwe(cpu_env); 6495 #endif /* defined(CONFIG_USER_ONLY) */ 6496 } 6497 6498 static void gen_tlbivax_booke206(DisasContext *ctx) 6499 { 6500 #if defined(CONFIG_USER_ONLY) 6501 GEN_PRIV; 6502 #else 6503 TCGv t0; 6504 6505 CHK_SV; 6506 t0 = tcg_temp_new(); 6507 gen_addr_reg_index(ctx, t0); 6508 gen_helper_booke206_tlbivax(cpu_env, t0); 6509 tcg_temp_free(t0); 6510 #endif /* defined(CONFIG_USER_ONLY) */ 6511 } 6512 6513 static void gen_tlbilx_booke206(DisasContext *ctx) 6514 { 6515 #if defined(CONFIG_USER_ONLY) 6516 GEN_PRIV; 6517 #else 6518 TCGv t0; 6519 6520 CHK_SV; 6521 t0 = tcg_temp_new(); 6522 gen_addr_reg_index(ctx, t0); 6523 6524 switch ((ctx->opcode >> 21) & 0x3) { 6525 case 0: 6526 gen_helper_booke206_tlbilx0(cpu_env, t0); 6527 break; 6528 case 1: 6529 gen_helper_booke206_tlbilx1(cpu_env, t0); 6530 break; 6531 case 3: 6532 gen_helper_booke206_tlbilx3(cpu_env, t0); 6533 break; 6534 default: 6535 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 6536 break; 6537 } 6538 6539 tcg_temp_free(t0); 6540 #endif /* defined(CONFIG_USER_ONLY) */ 6541 } 6542 6543 6544 /* wrtee */ 6545 static void gen_wrtee(DisasContext *ctx) 6546 { 6547 #if defined(CONFIG_USER_ONLY) 6548 GEN_PRIV; 6549 #else 6550 TCGv t0; 6551 6552 CHK_SV; 6553 t0 = tcg_temp_new(); 6554 tcg_gen_andi_tl(t0, cpu_gpr[rD(ctx->opcode)], (1 << MSR_EE)); 6555 tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE)); 6556 tcg_gen_or_tl(cpu_msr, cpu_msr, t0); 6557 tcg_temp_free(t0); 6558 /* 6559 * Stop translation to have a chance to raise an exception if we 6560 * just set msr_ee to 1 6561 */ 6562 gen_stop_exception(ctx); 6563 #endif /* defined(CONFIG_USER_ONLY) */ 6564 } 6565 6566 /* wrteei */ 6567 static void gen_wrteei(DisasContext *ctx) 6568 { 6569 #if defined(CONFIG_USER_ONLY) 6570 GEN_PRIV; 6571 #else 6572 CHK_SV; 6573 if (ctx->opcode & 0x00008000) { 6574 tcg_gen_ori_tl(cpu_msr, cpu_msr, (1 << MSR_EE)); 6575 /* Stop translation to have a chance to raise an exception */ 6576 gen_stop_exception(ctx); 6577 } else { 6578 tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE)); 6579 } 6580 #endif /* defined(CONFIG_USER_ONLY) */ 6581 } 6582 6583 /* PowerPC 440 specific instructions */ 6584 6585 /* dlmzb */ 6586 static void gen_dlmzb(DisasContext *ctx) 6587 { 6588 TCGv_i32 t0 = tcg_const_i32(Rc(ctx->opcode)); 6589 gen_helper_dlmzb(cpu_gpr[rA(ctx->opcode)], cpu_env, 6590 cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], t0); 6591 tcg_temp_free_i32(t0); 6592 } 6593 6594 /* mbar replaces eieio on 440 */ 6595 static void gen_mbar(DisasContext *ctx) 6596 { 6597 /* interpreted as no-op */ 6598 } 6599 6600 /* msync replaces sync on 440 */ 6601 static void gen_msync_4xx(DisasContext *ctx) 6602 { 6603 /* Only e500 seems to treat reserved bits as invalid */ 6604 if ((ctx->insns_flags2 & PPC2_BOOKE206) && 6605 (ctx->opcode & 0x03FFF801)) { 6606 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 6607 } 6608 /* otherwise interpreted as no-op */ 6609 } 6610 6611 /* icbt */ 6612 static void gen_icbt_440(DisasContext *ctx) 6613 { 6614 /* 6615 * interpreted as no-op 6616 * XXX: specification say this is treated as a load by the MMU but 6617 * does not generate any exception 6618 */ 6619 } 6620 6621 /* Embedded.Processor Control */ 6622 6623 static void gen_msgclr(DisasContext *ctx) 6624 { 6625 #if defined(CONFIG_USER_ONLY) 6626 GEN_PRIV; 6627 #else 6628 CHK_HV; 6629 if (is_book3s_arch2x(ctx)) { 6630 gen_helper_book3s_msgclr(cpu_env, cpu_gpr[rB(ctx->opcode)]); 6631 } else { 6632 gen_helper_msgclr(cpu_env, cpu_gpr[rB(ctx->opcode)]); 6633 } 6634 #endif /* defined(CONFIG_USER_ONLY) */ 6635 } 6636 6637 static void gen_msgsnd(DisasContext *ctx) 6638 { 6639 #if defined(CONFIG_USER_ONLY) 6640 GEN_PRIV; 6641 #else 6642 CHK_HV; 6643 if (is_book3s_arch2x(ctx)) { 6644 gen_helper_book3s_msgsnd(cpu_gpr[rB(ctx->opcode)]); 6645 } else { 6646 gen_helper_msgsnd(cpu_gpr[rB(ctx->opcode)]); 6647 } 6648 #endif /* defined(CONFIG_USER_ONLY) */ 6649 } 6650 6651 static void gen_msgsync(DisasContext *ctx) 6652 { 6653 #if defined(CONFIG_USER_ONLY) 6654 GEN_PRIV; 6655 #else 6656 CHK_HV; 6657 #endif /* defined(CONFIG_USER_ONLY) */ 6658 /* interpreted as no-op */ 6659 } 6660 6661 #if defined(TARGET_PPC64) 6662 static void gen_maddld(DisasContext *ctx) 6663 { 6664 TCGv_i64 t1 = tcg_temp_new_i64(); 6665 6666 tcg_gen_mul_i64(t1, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); 6667 tcg_gen_add_i64(cpu_gpr[rD(ctx->opcode)], t1, cpu_gpr[rC(ctx->opcode)]); 6668 tcg_temp_free_i64(t1); 6669 } 6670 6671 /* maddhd maddhdu */ 6672 static void gen_maddhd_maddhdu(DisasContext *ctx) 6673 { 6674 TCGv_i64 lo = tcg_temp_new_i64(); 6675 TCGv_i64 hi = tcg_temp_new_i64(); 6676 TCGv_i64 t1 = tcg_temp_new_i64(); 6677 6678 if (Rc(ctx->opcode)) { 6679 tcg_gen_mulu2_i64(lo, hi, cpu_gpr[rA(ctx->opcode)], 6680 cpu_gpr[rB(ctx->opcode)]); 6681 tcg_gen_movi_i64(t1, 0); 6682 } else { 6683 tcg_gen_muls2_i64(lo, hi, cpu_gpr[rA(ctx->opcode)], 6684 cpu_gpr[rB(ctx->opcode)]); 6685 tcg_gen_sari_i64(t1, cpu_gpr[rC(ctx->opcode)], 63); 6686 } 6687 tcg_gen_add2_i64(t1, cpu_gpr[rD(ctx->opcode)], lo, hi, 6688 cpu_gpr[rC(ctx->opcode)], t1); 6689 tcg_temp_free_i64(lo); 6690 tcg_temp_free_i64(hi); 6691 tcg_temp_free_i64(t1); 6692 } 6693 #endif /* defined(TARGET_PPC64) */ 6694 6695 static void gen_tbegin(DisasContext *ctx) 6696 { 6697 if (unlikely(!ctx->tm_enabled)) { 6698 gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM); 6699 return; 6700 } 6701 gen_helper_tbegin(cpu_env); 6702 } 6703 6704 #define GEN_TM_NOOP(name) \ 6705 static inline void gen_##name(DisasContext *ctx) \ 6706 { \ 6707 if (unlikely(!ctx->tm_enabled)) { \ 6708 gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM); \ 6709 return; \ 6710 } \ 6711 /* \ 6712 * Because tbegin always fails in QEMU, these user \ 6713 * space instructions all have a simple implementation: \ 6714 * \ 6715 * CR[0] = 0b0 || MSR[TS] || 0b0 \ 6716 * = 0b0 || 0b00 || 0b0 \ 6717 */ \ 6718 tcg_gen_movi_i32(cpu_crf[0], 0); \ 6719 } 6720 6721 GEN_TM_NOOP(tend); 6722 GEN_TM_NOOP(tabort); 6723 GEN_TM_NOOP(tabortwc); 6724 GEN_TM_NOOP(tabortwci); 6725 GEN_TM_NOOP(tabortdc); 6726 GEN_TM_NOOP(tabortdci); 6727 GEN_TM_NOOP(tsr); 6728 6729 static inline void gen_cp_abort(DisasContext *ctx) 6730 { 6731 /* Do Nothing */ 6732 } 6733 6734 #define GEN_CP_PASTE_NOOP(name) \ 6735 static inline void gen_##name(DisasContext *ctx) \ 6736 { \ 6737 /* \ 6738 * Generate invalid exception until we have an \ 6739 * implementation of the copy paste facility \ 6740 */ \ 6741 gen_invalid(ctx); \ 6742 } 6743 6744 GEN_CP_PASTE_NOOP(copy) 6745 GEN_CP_PASTE_NOOP(paste) 6746 6747 static void gen_tcheck(DisasContext *ctx) 6748 { 6749 if (unlikely(!ctx->tm_enabled)) { 6750 gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM); 6751 return; 6752 } 6753 /* 6754 * Because tbegin always fails, the tcheck implementation is 6755 * simple: 6756 * 6757 * CR[CRF] = TDOOMED || MSR[TS] || 0b0 6758 * = 0b1 || 0b00 || 0b0 6759 */ 6760 tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], 0x8); 6761 } 6762 6763 #if defined(CONFIG_USER_ONLY) 6764 #define GEN_TM_PRIV_NOOP(name) \ 6765 static inline void gen_##name(DisasContext *ctx) \ 6766 { \ 6767 gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC); \ 6768 } 6769 6770 #else 6771 6772 #define GEN_TM_PRIV_NOOP(name) \ 6773 static inline void gen_##name(DisasContext *ctx) \ 6774 { \ 6775 CHK_SV; \ 6776 if (unlikely(!ctx->tm_enabled)) { \ 6777 gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM); \ 6778 return; \ 6779 } \ 6780 /* \ 6781 * Because tbegin always fails, the implementation is \ 6782 * simple: \ 6783 * \ 6784 * CR[0] = 0b0 || MSR[TS] || 0b0 \ 6785 * = 0b0 || 0b00 | 0b0 \ 6786 */ \ 6787 tcg_gen_movi_i32(cpu_crf[0], 0); \ 6788 } 6789 6790 #endif 6791 6792 GEN_TM_PRIV_NOOP(treclaim); 6793 GEN_TM_PRIV_NOOP(trechkpt); 6794 6795 static inline void get_fpr(TCGv_i64 dst, int regno) 6796 { 6797 tcg_gen_ld_i64(dst, cpu_env, fpr_offset(regno)); 6798 } 6799 6800 static inline void set_fpr(int regno, TCGv_i64 src) 6801 { 6802 tcg_gen_st_i64(src, cpu_env, fpr_offset(regno)); 6803 } 6804 6805 static inline void get_avr64(TCGv_i64 dst, int regno, bool high) 6806 { 6807 tcg_gen_ld_i64(dst, cpu_env, avr64_offset(regno, high)); 6808 } 6809 6810 static inline void set_avr64(int regno, TCGv_i64 src, bool high) 6811 { 6812 tcg_gen_st_i64(src, cpu_env, avr64_offset(regno, high)); 6813 } 6814 6815 #include "translate/fp-impl.inc.c" 6816 6817 #include "translate/vmx-impl.inc.c" 6818 6819 #include "translate/vsx-impl.inc.c" 6820 6821 #include "translate/dfp-impl.inc.c" 6822 6823 #include "translate/spe-impl.inc.c" 6824 6825 /* Handles lfdp, lxsd, lxssp */ 6826 static void gen_dform39(DisasContext *ctx) 6827 { 6828 switch (ctx->opcode & 0x3) { 6829 case 0: /* lfdp */ 6830 if (ctx->insns_flags2 & PPC2_ISA205) { 6831 return gen_lfdp(ctx); 6832 } 6833 break; 6834 case 2: /* lxsd */ 6835 if (ctx->insns_flags2 & PPC2_ISA300) { 6836 return gen_lxsd(ctx); 6837 } 6838 break; 6839 case 3: /* lxssp */ 6840 if (ctx->insns_flags2 & PPC2_ISA300) { 6841 return gen_lxssp(ctx); 6842 } 6843 break; 6844 } 6845 return gen_invalid(ctx); 6846 } 6847 6848 /* handles stfdp, lxv, stxsd, stxssp lxvx */ 6849 static void gen_dform3D(DisasContext *ctx) 6850 { 6851 if ((ctx->opcode & 3) == 1) { /* DQ-FORM */ 6852 switch (ctx->opcode & 0x7) { 6853 case 1: /* lxv */ 6854 if (ctx->insns_flags2 & PPC2_ISA300) { 6855 return gen_lxv(ctx); 6856 } 6857 break; 6858 case 5: /* stxv */ 6859 if (ctx->insns_flags2 & PPC2_ISA300) { 6860 return gen_stxv(ctx); 6861 } 6862 break; 6863 } 6864 } else { /* DS-FORM */ 6865 switch (ctx->opcode & 0x3) { 6866 case 0: /* stfdp */ 6867 if (ctx->insns_flags2 & PPC2_ISA205) { 6868 return gen_stfdp(ctx); 6869 } 6870 break; 6871 case 2: /* stxsd */ 6872 if (ctx->insns_flags2 & PPC2_ISA300) { 6873 return gen_stxsd(ctx); 6874 } 6875 break; 6876 case 3: /* stxssp */ 6877 if (ctx->insns_flags2 & PPC2_ISA300) { 6878 return gen_stxssp(ctx); 6879 } 6880 break; 6881 } 6882 } 6883 return gen_invalid(ctx); 6884 } 6885 6886 static opcode_t opcodes[] = { 6887 GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE), 6888 GEN_HANDLER(cmp, 0x1F, 0x00, 0x00, 0x00400000, PPC_INTEGER), 6889 GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER), 6890 GEN_HANDLER(cmpl, 0x1F, 0x00, 0x01, 0x00400001, PPC_INTEGER), 6891 GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER), 6892 #if defined(TARGET_PPC64) 6893 GEN_HANDLER_E(cmpeqb, 0x1F, 0x00, 0x07, 0x00600000, PPC_NONE, PPC2_ISA300), 6894 #endif 6895 GEN_HANDLER_E(cmpb, 0x1F, 0x1C, 0x0F, 0x00000001, PPC_NONE, PPC2_ISA205), 6896 GEN_HANDLER_E(cmprb, 0x1F, 0x00, 0x06, 0x00400001, PPC_NONE, PPC2_ISA300), 6897 GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL), 6898 GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), 6899 GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), 6900 GEN_HANDLER2(addic_, "addic.", 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), 6901 GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), 6902 GEN_HANDLER_E(addpcis, 0x13, 0x2, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA300), 6903 GEN_HANDLER(mulhw, 0x1F, 0x0B, 0x02, 0x00000400, PPC_INTEGER), 6904 GEN_HANDLER(mulhwu, 0x1F, 0x0B, 0x00, 0x00000400, PPC_INTEGER), 6905 GEN_HANDLER(mullw, 0x1F, 0x0B, 0x07, 0x00000000, PPC_INTEGER), 6906 GEN_HANDLER(mullwo, 0x1F, 0x0B, 0x17, 0x00000000, PPC_INTEGER), 6907 GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), 6908 #if defined(TARGET_PPC64) 6909 GEN_HANDLER(mulld, 0x1F, 0x09, 0x07, 0x00000000, PPC_64B), 6910 #endif 6911 GEN_HANDLER(neg, 0x1F, 0x08, 0x03, 0x0000F800, PPC_INTEGER), 6912 GEN_HANDLER(nego, 0x1F, 0x08, 0x13, 0x0000F800, PPC_INTEGER), 6913 GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), 6914 GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), 6915 GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), 6916 GEN_HANDLER(cntlzw, 0x1F, 0x1A, 0x00, 0x00000000, PPC_INTEGER), 6917 GEN_HANDLER_E(cnttzw, 0x1F, 0x1A, 0x10, 0x00000000, PPC_NONE, PPC2_ISA300), 6918 GEN_HANDLER_E(copy, 0x1F, 0x06, 0x18, 0x03C00001, PPC_NONE, PPC2_ISA300), 6919 GEN_HANDLER_E(cp_abort, 0x1F, 0x06, 0x1A, 0x03FFF801, PPC_NONE, PPC2_ISA300), 6920 GEN_HANDLER_E(paste, 0x1F, 0x06, 0x1C, 0x03C00000, PPC_NONE, PPC2_ISA300), 6921 GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER), 6922 GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER), 6923 GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), 6924 GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), 6925 GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), 6926 GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), 6927 GEN_HANDLER(popcntb, 0x1F, 0x1A, 0x03, 0x0000F801, PPC_POPCNTB), 6928 GEN_HANDLER(popcntw, 0x1F, 0x1A, 0x0b, 0x0000F801, PPC_POPCNTWD), 6929 GEN_HANDLER_E(prtyw, 0x1F, 0x1A, 0x04, 0x0000F801, PPC_NONE, PPC2_ISA205), 6930 #if defined(TARGET_PPC64) 6931 GEN_HANDLER(popcntd, 0x1F, 0x1A, 0x0F, 0x0000F801, PPC_POPCNTWD), 6932 GEN_HANDLER(cntlzd, 0x1F, 0x1A, 0x01, 0x00000000, PPC_64B), 6933 GEN_HANDLER_E(cnttzd, 0x1F, 0x1A, 0x11, 0x00000000, PPC_NONE, PPC2_ISA300), 6934 GEN_HANDLER_E(darn, 0x1F, 0x13, 0x17, 0x001CF801, PPC_NONE, PPC2_ISA300), 6935 GEN_HANDLER_E(prtyd, 0x1F, 0x1A, 0x05, 0x0000F801, PPC_NONE, PPC2_ISA205), 6936 GEN_HANDLER_E(bpermd, 0x1F, 0x1C, 0x07, 0x00000001, PPC_NONE, PPC2_PERM_ISA206), 6937 #endif 6938 GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), 6939 GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), 6940 GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), 6941 GEN_HANDLER(slw, 0x1F, 0x18, 0x00, 0x00000000, PPC_INTEGER), 6942 GEN_HANDLER(sraw, 0x1F, 0x18, 0x18, 0x00000000, PPC_INTEGER), 6943 GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER), 6944 GEN_HANDLER(srw, 0x1F, 0x18, 0x10, 0x00000000, PPC_INTEGER), 6945 #if defined(TARGET_PPC64) 6946 GEN_HANDLER(sld, 0x1F, 0x1B, 0x00, 0x00000000, PPC_64B), 6947 GEN_HANDLER(srad, 0x1F, 0x1A, 0x18, 0x00000000, PPC_64B), 6948 GEN_HANDLER2(sradi0, "sradi", 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B), 6949 GEN_HANDLER2(sradi1, "sradi", 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B), 6950 GEN_HANDLER(srd, 0x1F, 0x1B, 0x10, 0x00000000, PPC_64B), 6951 GEN_HANDLER2_E(extswsli0, "extswsli", 0x1F, 0x1A, 0x1B, 0x00000000, 6952 PPC_NONE, PPC2_ISA300), 6953 GEN_HANDLER2_E(extswsli1, "extswsli", 0x1F, 0x1B, 0x1B, 0x00000000, 6954 PPC_NONE, PPC2_ISA300), 6955 #endif 6956 #if defined(TARGET_PPC64) 6957 GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B), 6958 GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX), 6959 GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B), 6960 #endif 6961 /* handles lfdp, lxsd, lxssp */ 6962 GEN_HANDLER_E(dform39, 0x39, 0xFF, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA205), 6963 /* handles stfdp, lxv, stxsd, stxssp, stxv */ 6964 GEN_HANDLER_E(dform3D, 0x3D, 0xFF, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA205), 6965 GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), 6966 GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER), 6967 GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING), 6968 GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING), 6969 GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING), 6970 GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING), 6971 GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x01FFF801, PPC_MEM_EIEIO), 6972 GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM), 6973 GEN_HANDLER_E(lbarx, 0x1F, 0x14, 0x01, 0, PPC_NONE, PPC2_ATOMIC_ISA206), 6974 GEN_HANDLER_E(lharx, 0x1F, 0x14, 0x03, 0, PPC_NONE, PPC2_ATOMIC_ISA206), 6975 GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000000, PPC_RES), 6976 GEN_HANDLER_E(lwat, 0x1F, 0x06, 0x12, 0x00000001, PPC_NONE, PPC2_ISA300), 6977 GEN_HANDLER_E(stwat, 0x1F, 0x06, 0x16, 0x00000001, PPC_NONE, PPC2_ISA300), 6978 GEN_HANDLER_E(stbcx_, 0x1F, 0x16, 0x15, 0, PPC_NONE, PPC2_ATOMIC_ISA206), 6979 GEN_HANDLER_E(sthcx_, 0x1F, 0x16, 0x16, 0, PPC_NONE, PPC2_ATOMIC_ISA206), 6980 GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES), 6981 #if defined(TARGET_PPC64) 6982 GEN_HANDLER_E(ldat, 0x1F, 0x06, 0x13, 0x00000001, PPC_NONE, PPC2_ISA300), 6983 GEN_HANDLER_E(stdat, 0x1F, 0x06, 0x17, 0x00000001, PPC_NONE, PPC2_ISA300), 6984 GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000000, PPC_64B), 6985 GEN_HANDLER_E(lqarx, 0x1F, 0x14, 0x08, 0, PPC_NONE, PPC2_LSQ_ISA207), 6986 GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B), 6987 GEN_HANDLER_E(stqcx_, 0x1F, 0x16, 0x05, 0, PPC_NONE, PPC2_LSQ_ISA207), 6988 #endif 6989 GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x039FF801, PPC_MEM_SYNC), 6990 GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT), 6991 GEN_HANDLER_E(wait, 0x1F, 0x1E, 0x00, 0x039FF801, PPC_NONE, PPC2_ISA300), 6992 GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW), 6993 GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW), 6994 GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW), 6995 GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW), 6996 GEN_HANDLER_E(bctar, 0x13, 0x10, 0x11, 0x0000E000, PPC_NONE, PPC2_BCTAR_ISA207), 6997 GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER), 6998 GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW), 6999 #if defined(TARGET_PPC64) 7000 GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B), 7001 GEN_HANDLER_E(stop, 0x13, 0x12, 0x0b, 0x03FFF801, PPC_NONE, PPC2_ISA300), 7002 GEN_HANDLER_E(doze, 0x13, 0x12, 0x0c, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206), 7003 GEN_HANDLER_E(nap, 0x13, 0x12, 0x0d, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206), 7004 GEN_HANDLER_E(sleep, 0x13, 0x12, 0x0e, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206), 7005 GEN_HANDLER_E(rvwinkle, 0x13, 0x12, 0x0f, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206), 7006 GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H), 7007 #endif 7008 GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW), 7009 GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW), 7010 GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW), 7011 #if defined(TARGET_PPC64) 7012 GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B), 7013 GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B), 7014 #endif 7015 GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC), 7016 GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC), 7017 GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC), 7018 GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC), 7019 GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB), 7020 GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC), 7021 #if defined(TARGET_PPC64) 7022 GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B), 7023 GEN_HANDLER_E(setb, 0x1F, 0x00, 0x04, 0x0003F801, PPC_NONE, PPC2_ISA300), 7024 GEN_HANDLER_E(mcrxrx, 0x1F, 0x00, 0x12, 0x007FF801, PPC_NONE, PPC2_ISA300), 7025 #endif 7026 GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001EF801, PPC_MISC), 7027 GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000000, PPC_MISC), 7028 GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE), 7029 GEN_HANDLER_E(dcbfep, 0x1F, 0x1F, 0x03, 0x03C00001, PPC_NONE, PPC2_BOOKE206), 7030 GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE), 7031 GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE), 7032 GEN_HANDLER_E(dcbstep, 0x1F, 0x1F, 0x01, 0x03E00001, PPC_NONE, PPC2_BOOKE206), 7033 GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x00000001, PPC_CACHE), 7034 GEN_HANDLER_E(dcbtep, 0x1F, 0x1F, 0x09, 0x00000001, PPC_NONE, PPC2_BOOKE206), 7035 GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x00000001, PPC_CACHE), 7036 GEN_HANDLER_E(dcbtstep, 0x1F, 0x1F, 0x07, 0x00000001, PPC_NONE, PPC2_BOOKE206), 7037 GEN_HANDLER_E(dcbtls, 0x1F, 0x06, 0x05, 0x02000001, PPC_BOOKE, PPC2_BOOKE206), 7038 GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZ), 7039 GEN_HANDLER_E(dcbzep, 0x1F, 0x1F, 0x1F, 0x03C00001, PPC_NONE, PPC2_BOOKE206), 7040 GEN_HANDLER(dst, 0x1F, 0x16, 0x0A, 0x01800001, PPC_ALTIVEC), 7041 GEN_HANDLER(dstst, 0x1F, 0x16, 0x0B, 0x01800001, PPC_ALTIVEC), 7042 GEN_HANDLER(dss, 0x1F, 0x16, 0x19, 0x019FF801, PPC_ALTIVEC), 7043 GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI), 7044 GEN_HANDLER_E(icbiep, 0x1F, 0x1F, 0x1E, 0x03E00001, PPC_NONE, PPC2_BOOKE206), 7045 GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA), 7046 GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT), 7047 GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT), 7048 GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT), 7049 GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT), 7050 #if defined(TARGET_PPC64) 7051 GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B), 7052 GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001, 7053 PPC_SEGMENT_64B), 7054 GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B), 7055 GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001, 7056 PPC_SEGMENT_64B), 7057 GEN_HANDLER2(slbmte, "slbmte", 0x1F, 0x12, 0x0C, 0x001F0001, PPC_SEGMENT_64B), 7058 GEN_HANDLER2(slbmfee, "slbmfee", 0x1F, 0x13, 0x1C, 0x001F0001, PPC_SEGMENT_64B), 7059 GEN_HANDLER2(slbmfev, "slbmfev", 0x1F, 0x13, 0x1A, 0x001F0001, PPC_SEGMENT_64B), 7060 GEN_HANDLER2(slbfee_, "slbfee.", 0x1F, 0x13, 0x1E, 0x001F0000, PPC_SEGMENT_64B), 7061 #endif 7062 GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA), 7063 /* 7064 * XXX Those instructions will need to be handled differently for 7065 * different ISA versions 7066 */ 7067 GEN_HANDLER(tlbiel, 0x1F, 0x12, 0x08, 0x001F0001, PPC_MEM_TLBIE), 7068 GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x001F0001, PPC_MEM_TLBIE), 7069 GEN_HANDLER_E(tlbiel, 0x1F, 0x12, 0x08, 0x00100001, PPC_NONE, PPC2_ISA300), 7070 GEN_HANDLER_E(tlbie, 0x1F, 0x12, 0x09, 0x00100001, PPC_NONE, PPC2_ISA300), 7071 GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC), 7072 #if defined(TARGET_PPC64) 7073 GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x031FFC01, PPC_SLBI), 7074 GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI), 7075 GEN_HANDLER_E(slbieg, 0x1F, 0x12, 0x0E, 0x001F0001, PPC_NONE, PPC2_ISA300), 7076 GEN_HANDLER_E(slbsync, 0x1F, 0x12, 0x0A, 0x03FFF801, PPC_NONE, PPC2_ISA300), 7077 #endif 7078 GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN), 7079 GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN), 7080 GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR), 7081 GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR), 7082 GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR), 7083 GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR), 7084 GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR), 7085 GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR), 7086 GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR), 7087 GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR), 7088 GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR), 7089 GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR), 7090 GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR), 7091 GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR), 7092 GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR), 7093 GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR), 7094 GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR), 7095 GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR), 7096 GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR), 7097 GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR), 7098 GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR), 7099 GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR), 7100 GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR), 7101 GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR), 7102 GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR), 7103 GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR), 7104 GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR), 7105 GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR), 7106 GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR), 7107 GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR), 7108 GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR), 7109 GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR), 7110 GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR), 7111 GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR), 7112 GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR), 7113 GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR), 7114 GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC), 7115 GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC), 7116 GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC), 7117 GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB), 7118 GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB), 7119 GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB), 7120 GEN_HANDLER2(tlbli_74xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB), 7121 GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER), 7122 GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER), 7123 GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER), 7124 GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER), 7125 GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER), 7126 GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER), 7127 GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2), 7128 GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2), 7129 GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2), 7130 GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2), 7131 GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2), 7132 GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2), 7133 GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2), 7134 GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2), 7135 GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_MFAPIDI), 7136 GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_TLBIVA), 7137 GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_DCR), 7138 GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_DCR), 7139 GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_DCRX), 7140 GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_DCRX), 7141 GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX), 7142 GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX), 7143 GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON), 7144 GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON), 7145 GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT), 7146 GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON), 7147 GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON), 7148 GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP), 7149 GEN_HANDLER_E(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE, PPC2_BOOKE206), 7150 GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI), 7151 GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI), 7152 GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB), 7153 GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB), 7154 GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB), 7155 GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE), 7156 GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE), 7157 GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE), 7158 GEN_HANDLER2_E(tlbre_booke206, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, 7159 PPC_NONE, PPC2_BOOKE206), 7160 GEN_HANDLER2_E(tlbsx_booke206, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, 7161 PPC_NONE, PPC2_BOOKE206), 7162 GEN_HANDLER2_E(tlbwe_booke206, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, 7163 PPC_NONE, PPC2_BOOKE206), 7164 GEN_HANDLER2_E(tlbivax_booke206, "tlbivax", 0x1F, 0x12, 0x18, 0x00000001, 7165 PPC_NONE, PPC2_BOOKE206), 7166 GEN_HANDLER2_E(tlbilx_booke206, "tlbilx", 0x1F, 0x12, 0x00, 0x03800001, 7167 PPC_NONE, PPC2_BOOKE206), 7168 GEN_HANDLER2_E(msgsnd, "msgsnd", 0x1F, 0x0E, 0x06, 0x03ff0001, 7169 PPC_NONE, PPC2_PRCNTL), 7170 GEN_HANDLER2_E(msgclr, "msgclr", 0x1F, 0x0E, 0x07, 0x03ff0001, 7171 PPC_NONE, PPC2_PRCNTL), 7172 GEN_HANDLER2_E(msgsync, "msgsync", 0x1F, 0x16, 0x1B, 0x00000000, 7173 PPC_NONE, PPC2_PRCNTL), 7174 GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE), 7175 GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000E7C01, PPC_WRTEE), 7176 GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC), 7177 GEN_HANDLER_E(mbar, 0x1F, 0x16, 0x1a, 0x001FF801, 7178 PPC_BOOKE, PPC2_BOOKE206), 7179 GEN_HANDLER(msync_4xx, 0x1F, 0x16, 0x12, 0x039FF801, PPC_BOOKE), 7180 GEN_HANDLER2_E(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001, 7181 PPC_BOOKE, PPC2_BOOKE206), 7182 GEN_HANDLER2(icbt_440, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, 7183 PPC_440_SPEC), 7184 GEN_HANDLER(lvsl, 0x1f, 0x06, 0x00, 0x00000001, PPC_ALTIVEC), 7185 GEN_HANDLER(lvsr, 0x1f, 0x06, 0x01, 0x00000001, PPC_ALTIVEC), 7186 GEN_HANDLER(mfvscr, 0x04, 0x2, 0x18, 0x001ff800, PPC_ALTIVEC), 7187 GEN_HANDLER(mtvscr, 0x04, 0x2, 0x19, 0x03ff0000, PPC_ALTIVEC), 7188 GEN_HANDLER(vmladduhm, 0x04, 0x11, 0xFF, 0x00000000, PPC_ALTIVEC), 7189 #if defined(TARGET_PPC64) 7190 GEN_HANDLER_E(maddhd_maddhdu, 0x04, 0x18, 0xFF, 0x00000000, PPC_NONE, 7191 PPC2_ISA300), 7192 GEN_HANDLER_E(maddld, 0x04, 0x19, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA300), 7193 #endif 7194 7195 #undef GEN_INT_ARITH_ADD 7196 #undef GEN_INT_ARITH_ADD_CONST 7197 #define GEN_INT_ARITH_ADD(name, opc3, add_ca, compute_ca, compute_ov) \ 7198 GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x00000000, PPC_INTEGER), 7199 #define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val, \ 7200 add_ca, compute_ca, compute_ov) \ 7201 GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x0000F800, PPC_INTEGER), 7202 GEN_INT_ARITH_ADD(add, 0x08, 0, 0, 0) 7203 GEN_INT_ARITH_ADD(addo, 0x18, 0, 0, 1) 7204 GEN_INT_ARITH_ADD(addc, 0x00, 0, 1, 0) 7205 GEN_INT_ARITH_ADD(addco, 0x10, 0, 1, 1) 7206 GEN_INT_ARITH_ADD(adde, 0x04, 1, 1, 0) 7207 GEN_INT_ARITH_ADD(addeo, 0x14, 1, 1, 1) 7208 GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, 1, 1, 0) 7209 GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, 1, 1, 1) 7210 GEN_HANDLER_E(addex, 0x1F, 0x0A, 0x05, 0x00000000, PPC_NONE, PPC2_ISA300), 7211 GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, 1, 1, 0) 7212 GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, 1, 1, 1) 7213 7214 #undef GEN_INT_ARITH_DIVW 7215 #define GEN_INT_ARITH_DIVW(name, opc3, sign, compute_ov) \ 7216 GEN_HANDLER(name, 0x1F, 0x0B, opc3, 0x00000000, PPC_INTEGER) 7217 GEN_INT_ARITH_DIVW(divwu, 0x0E, 0, 0), 7218 GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1), 7219 GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0), 7220 GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1), 7221 GEN_HANDLER_E(divwe, 0x1F, 0x0B, 0x0D, 0, PPC_NONE, PPC2_DIVE_ISA206), 7222 GEN_HANDLER_E(divweo, 0x1F, 0x0B, 0x1D, 0, PPC_NONE, PPC2_DIVE_ISA206), 7223 GEN_HANDLER_E(divweu, 0x1F, 0x0B, 0x0C, 0, PPC_NONE, PPC2_DIVE_ISA206), 7224 GEN_HANDLER_E(divweuo, 0x1F, 0x0B, 0x1C, 0, PPC_NONE, PPC2_DIVE_ISA206), 7225 GEN_HANDLER_E(modsw, 0x1F, 0x0B, 0x18, 0x00000001, PPC_NONE, PPC2_ISA300), 7226 GEN_HANDLER_E(moduw, 0x1F, 0x0B, 0x08, 0x00000001, PPC_NONE, PPC2_ISA300), 7227 7228 #if defined(TARGET_PPC64) 7229 #undef GEN_INT_ARITH_DIVD 7230 #define GEN_INT_ARITH_DIVD(name, opc3, sign, compute_ov) \ 7231 GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B) 7232 GEN_INT_ARITH_DIVD(divdu, 0x0E, 0, 0), 7233 GEN_INT_ARITH_DIVD(divduo, 0x1E, 0, 1), 7234 GEN_INT_ARITH_DIVD(divd, 0x0F, 1, 0), 7235 GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1), 7236 7237 GEN_HANDLER_E(divdeu, 0x1F, 0x09, 0x0C, 0, PPC_NONE, PPC2_DIVE_ISA206), 7238 GEN_HANDLER_E(divdeuo, 0x1F, 0x09, 0x1C, 0, PPC_NONE, PPC2_DIVE_ISA206), 7239 GEN_HANDLER_E(divde, 0x1F, 0x09, 0x0D, 0, PPC_NONE, PPC2_DIVE_ISA206), 7240 GEN_HANDLER_E(divdeo, 0x1F, 0x09, 0x1D, 0, PPC_NONE, PPC2_DIVE_ISA206), 7241 GEN_HANDLER_E(modsd, 0x1F, 0x09, 0x18, 0x00000001, PPC_NONE, PPC2_ISA300), 7242 GEN_HANDLER_E(modud, 0x1F, 0x09, 0x08, 0x00000001, PPC_NONE, PPC2_ISA300), 7243 7244 #undef GEN_INT_ARITH_MUL_HELPER 7245 #define GEN_INT_ARITH_MUL_HELPER(name, opc3) \ 7246 GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B) 7247 GEN_INT_ARITH_MUL_HELPER(mulhdu, 0x00), 7248 GEN_INT_ARITH_MUL_HELPER(mulhd, 0x02), 7249 GEN_INT_ARITH_MUL_HELPER(mulldo, 0x17), 7250 #endif 7251 7252 #undef GEN_INT_ARITH_SUBF 7253 #undef GEN_INT_ARITH_SUBF_CONST 7254 #define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov) \ 7255 GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x00000000, PPC_INTEGER), 7256 #define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val, \ 7257 add_ca, compute_ca, compute_ov) \ 7258 GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x0000F800, PPC_INTEGER), 7259 GEN_INT_ARITH_SUBF(subf, 0x01, 0, 0, 0) 7260 GEN_INT_ARITH_SUBF(subfo, 0x11, 0, 0, 1) 7261 GEN_INT_ARITH_SUBF(subfc, 0x00, 0, 1, 0) 7262 GEN_INT_ARITH_SUBF(subfco, 0x10, 0, 1, 1) 7263 GEN_INT_ARITH_SUBF(subfe, 0x04, 1, 1, 0) 7264 GEN_INT_ARITH_SUBF(subfeo, 0x14, 1, 1, 1) 7265 GEN_INT_ARITH_SUBF_CONST(subfme, 0x07, -1LL, 1, 1, 0) 7266 GEN_INT_ARITH_SUBF_CONST(subfmeo, 0x17, -1LL, 1, 1, 1) 7267 GEN_INT_ARITH_SUBF_CONST(subfze, 0x06, 0, 1, 1, 0) 7268 GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1) 7269 7270 #undef GEN_LOGICAL1 7271 #undef GEN_LOGICAL2 7272 #define GEN_LOGICAL2(name, tcg_op, opc, type) \ 7273 GEN_HANDLER(name, 0x1F, 0x1C, opc, 0x00000000, type) 7274 #define GEN_LOGICAL1(name, tcg_op, opc, type) \ 7275 GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type) 7276 GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER), 7277 GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER), 7278 GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER), 7279 GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER), 7280 GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER), 7281 GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER), 7282 GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER), 7283 GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER), 7284 #if defined(TARGET_PPC64) 7285 GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B), 7286 #endif 7287 7288 #if defined(TARGET_PPC64) 7289 #undef GEN_PPC64_R2 7290 #undef GEN_PPC64_R4 7291 #define GEN_PPC64_R2(name, opc1, opc2) \ 7292 GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\ 7293 GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000, \ 7294 PPC_64B) 7295 #define GEN_PPC64_R4(name, opc1, opc2) \ 7296 GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\ 7297 GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x01, 0xFF, 0x00000000, \ 7298 PPC_64B), \ 7299 GEN_HANDLER2(name##2, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000, \ 7300 PPC_64B), \ 7301 GEN_HANDLER2(name##3, stringify(name), opc1, opc2 | 0x11, 0xFF, 0x00000000, \ 7302 PPC_64B) 7303 GEN_PPC64_R4(rldicl, 0x1E, 0x00), 7304 GEN_PPC64_R4(rldicr, 0x1E, 0x02), 7305 GEN_PPC64_R4(rldic, 0x1E, 0x04), 7306 GEN_PPC64_R2(rldcl, 0x1E, 0x08), 7307 GEN_PPC64_R2(rldcr, 0x1E, 0x09), 7308 GEN_PPC64_R4(rldimi, 0x1E, 0x06), 7309 #endif 7310 7311 #undef GEN_LD 7312 #undef GEN_LDU 7313 #undef GEN_LDUX 7314 #undef GEN_LDX_E 7315 #undef GEN_LDS 7316 #define GEN_LD(name, ldop, opc, type) \ 7317 GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type), 7318 #define GEN_LDU(name, ldop, opc, type) \ 7319 GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type), 7320 #define GEN_LDUX(name, ldop, opc2, opc3, type) \ 7321 GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type), 7322 #define GEN_LDX_E(name, ldop, opc2, opc3, type, type2, chk) \ 7323 GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2), 7324 #define GEN_LDS(name, ldop, op, type) \ 7325 GEN_LD(name, ldop, op | 0x20, type) \ 7326 GEN_LDU(name, ldop, op | 0x21, type) \ 7327 GEN_LDUX(name, ldop, 0x17, op | 0x01, type) \ 7328 GEN_LDX(name, ldop, 0x17, op | 0x00, type) 7329 7330 GEN_LDS(lbz, ld8u, 0x02, PPC_INTEGER) 7331 GEN_LDS(lha, ld16s, 0x0A, PPC_INTEGER) 7332 GEN_LDS(lhz, ld16u, 0x08, PPC_INTEGER) 7333 GEN_LDS(lwz, ld32u, 0x00, PPC_INTEGER) 7334 #if defined(TARGET_PPC64) 7335 GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B) 7336 GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B) 7337 GEN_LDUX(ld, ld64_i64, 0x15, 0x01, PPC_64B) 7338 GEN_LDX(ld, ld64_i64, 0x15, 0x00, PPC_64B) 7339 GEN_LDX_E(ldbr, ld64ur_i64, 0x14, 0x10, PPC_NONE, PPC2_DBRX, CHK_NONE) 7340 7341 /* HV/P7 and later only */ 7342 GEN_LDX_HVRM(ldcix, ld64_i64, 0x15, 0x1b, PPC_CILDST) 7343 GEN_LDX_HVRM(lwzcix, ld32u, 0x15, 0x18, PPC_CILDST) 7344 GEN_LDX_HVRM(lhzcix, ld16u, 0x15, 0x19, PPC_CILDST) 7345 GEN_LDX_HVRM(lbzcix, ld8u, 0x15, 0x1a, PPC_CILDST) 7346 #endif 7347 GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER) 7348 GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER) 7349 7350 /* External PID based load */ 7351 #undef GEN_LDEPX 7352 #define GEN_LDEPX(name, ldop, opc2, opc3) \ 7353 GEN_HANDLER_E(name##epx, 0x1F, opc2, opc3, \ 7354 0x00000001, PPC_NONE, PPC2_BOOKE206), 7355 7356 GEN_LDEPX(lb, DEF_MEMOP(MO_UB), 0x1F, 0x02) 7357 GEN_LDEPX(lh, DEF_MEMOP(MO_UW), 0x1F, 0x08) 7358 GEN_LDEPX(lw, DEF_MEMOP(MO_UL), 0x1F, 0x00) 7359 #if defined(TARGET_PPC64) 7360 GEN_LDEPX(ld, DEF_MEMOP(MO_Q), 0x1D, 0x00) 7361 #endif 7362 7363 #undef GEN_ST 7364 #undef GEN_STU 7365 #undef GEN_STUX 7366 #undef GEN_STX_E 7367 #undef GEN_STS 7368 #define GEN_ST(name, stop, opc, type) \ 7369 GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type), 7370 #define GEN_STU(name, stop, opc, type) \ 7371 GEN_HANDLER(stop##u, opc, 0xFF, 0xFF, 0x00000000, type), 7372 #define GEN_STUX(name, stop, opc2, opc3, type) \ 7373 GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type), 7374 #define GEN_STX_E(name, stop, opc2, opc3, type, type2, chk) \ 7375 GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000000, type, type2), 7376 #define GEN_STS(name, stop, op, type) \ 7377 GEN_ST(name, stop, op | 0x20, type) \ 7378 GEN_STU(name, stop, op | 0x21, type) \ 7379 GEN_STUX(name, stop, 0x17, op | 0x01, type) \ 7380 GEN_STX(name, stop, 0x17, op | 0x00, type) 7381 7382 GEN_STS(stb, st8, 0x06, PPC_INTEGER) 7383 GEN_STS(sth, st16, 0x0C, PPC_INTEGER) 7384 GEN_STS(stw, st32, 0x04, PPC_INTEGER) 7385 #if defined(TARGET_PPC64) 7386 GEN_STUX(std, st64_i64, 0x15, 0x05, PPC_64B) 7387 GEN_STX(std, st64_i64, 0x15, 0x04, PPC_64B) 7388 GEN_STX_E(stdbr, st64r_i64, 0x14, 0x14, PPC_NONE, PPC2_DBRX, CHK_NONE) 7389 GEN_STX_HVRM(stdcix, st64_i64, 0x15, 0x1f, PPC_CILDST) 7390 GEN_STX_HVRM(stwcix, st32, 0x15, 0x1c, PPC_CILDST) 7391 GEN_STX_HVRM(sthcix, st16, 0x15, 0x1d, PPC_CILDST) 7392 GEN_STX_HVRM(stbcix, st8, 0x15, 0x1e, PPC_CILDST) 7393 #endif 7394 GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER) 7395 GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER) 7396 7397 #undef GEN_STEPX 7398 #define GEN_STEPX(name, ldop, opc2, opc3) \ 7399 GEN_HANDLER_E(name##epx, 0x1F, opc2, opc3, \ 7400 0x00000001, PPC_NONE, PPC2_BOOKE206), 7401 7402 GEN_STEPX(stb, DEF_MEMOP(MO_UB), 0x1F, 0x06) 7403 GEN_STEPX(sth, DEF_MEMOP(MO_UW), 0x1F, 0x0C) 7404 GEN_STEPX(stw, DEF_MEMOP(MO_UL), 0x1F, 0x04) 7405 #if defined(TARGET_PPC64) 7406 GEN_STEPX(std, DEF_MEMOP(MO_Q), 0x1D, 0x04) 7407 #endif 7408 7409 #undef GEN_CRLOGIC 7410 #define GEN_CRLOGIC(name, tcg_op, opc) \ 7411 GEN_HANDLER(name, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER) 7412 GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08), 7413 GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04), 7414 GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09), 7415 GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07), 7416 GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01), 7417 GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E), 7418 GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D), 7419 GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06), 7420 7421 #undef GEN_MAC_HANDLER 7422 #define GEN_MAC_HANDLER(name, opc2, opc3) \ 7423 GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC) 7424 GEN_MAC_HANDLER(macchw, 0x0C, 0x05), 7425 GEN_MAC_HANDLER(macchwo, 0x0C, 0x15), 7426 GEN_MAC_HANDLER(macchws, 0x0C, 0x07), 7427 GEN_MAC_HANDLER(macchwso, 0x0C, 0x17), 7428 GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06), 7429 GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16), 7430 GEN_MAC_HANDLER(macchwu, 0x0C, 0x04), 7431 GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14), 7432 GEN_MAC_HANDLER(machhw, 0x0C, 0x01), 7433 GEN_MAC_HANDLER(machhwo, 0x0C, 0x11), 7434 GEN_MAC_HANDLER(machhws, 0x0C, 0x03), 7435 GEN_MAC_HANDLER(machhwso, 0x0C, 0x13), 7436 GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02), 7437 GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12), 7438 GEN_MAC_HANDLER(machhwu, 0x0C, 0x00), 7439 GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10), 7440 GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D), 7441 GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D), 7442 GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F), 7443 GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F), 7444 GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C), 7445 GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C), 7446 GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E), 7447 GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E), 7448 GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05), 7449 GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15), 7450 GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07), 7451 GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17), 7452 GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01), 7453 GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11), 7454 GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03), 7455 GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13), 7456 GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D), 7457 GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D), 7458 GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F), 7459 GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F), 7460 GEN_MAC_HANDLER(mulchw, 0x08, 0x05), 7461 GEN_MAC_HANDLER(mulchwu, 0x08, 0x04), 7462 GEN_MAC_HANDLER(mulhhw, 0x08, 0x01), 7463 GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00), 7464 GEN_MAC_HANDLER(mullhw, 0x08, 0x0D), 7465 GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C), 7466 7467 GEN_HANDLER2_E(tbegin, "tbegin", 0x1F, 0x0E, 0x14, 0x01DFF800, \ 7468 PPC_NONE, PPC2_TM), 7469 GEN_HANDLER2_E(tend, "tend", 0x1F, 0x0E, 0x15, 0x01FFF800, \ 7470 PPC_NONE, PPC2_TM), 7471 GEN_HANDLER2_E(tabort, "tabort", 0x1F, 0x0E, 0x1C, 0x03E0F800, \ 7472 PPC_NONE, PPC2_TM), 7473 GEN_HANDLER2_E(tabortwc, "tabortwc", 0x1F, 0x0E, 0x18, 0x00000000, \ 7474 PPC_NONE, PPC2_TM), 7475 GEN_HANDLER2_E(tabortwci, "tabortwci", 0x1F, 0x0E, 0x1A, 0x00000000, \ 7476 PPC_NONE, PPC2_TM), 7477 GEN_HANDLER2_E(tabortdc, "tabortdc", 0x1F, 0x0E, 0x19, 0x00000000, \ 7478 PPC_NONE, PPC2_TM), 7479 GEN_HANDLER2_E(tabortdci, "tabortdci", 0x1F, 0x0E, 0x1B, 0x00000000, \ 7480 PPC_NONE, PPC2_TM), 7481 GEN_HANDLER2_E(tsr, "tsr", 0x1F, 0x0E, 0x17, 0x03DFF800, \ 7482 PPC_NONE, PPC2_TM), 7483 GEN_HANDLER2_E(tcheck, "tcheck", 0x1F, 0x0E, 0x16, 0x007FF800, \ 7484 PPC_NONE, PPC2_TM), 7485 GEN_HANDLER2_E(treclaim, "treclaim", 0x1F, 0x0E, 0x1D, 0x03E0F800, \ 7486 PPC_NONE, PPC2_TM), 7487 GEN_HANDLER2_E(trechkpt, "trechkpt", 0x1F, 0x0E, 0x1F, 0x03FFF800, \ 7488 PPC_NONE, PPC2_TM), 7489 7490 #include "translate/fp-ops.inc.c" 7491 7492 #include "translate/vmx-ops.inc.c" 7493 7494 #include "translate/vsx-ops.inc.c" 7495 7496 #include "translate/dfp-ops.inc.c" 7497 7498 #include "translate/spe-ops.inc.c" 7499 }; 7500 7501 #include "helper_regs.h" 7502 #include "translate_init.inc.c" 7503 7504 /*****************************************************************************/ 7505 /* Misc PowerPC helpers */ 7506 void ppc_cpu_dump_state(CPUState *cs, FILE *f, int flags) 7507 { 7508 #define RGPL 4 7509 #define RFPL 4 7510 7511 PowerPCCPU *cpu = POWERPC_CPU(cs); 7512 CPUPPCState *env = &cpu->env; 7513 int i; 7514 7515 qemu_fprintf(f, "NIP " TARGET_FMT_lx " LR " TARGET_FMT_lx " CTR " 7516 TARGET_FMT_lx " XER " TARGET_FMT_lx " CPU#%d\n", 7517 env->nip, env->lr, env->ctr, cpu_read_xer(env), 7518 cs->cpu_index); 7519 qemu_fprintf(f, "MSR " TARGET_FMT_lx " HID0 " TARGET_FMT_lx " HF " 7520 TARGET_FMT_lx " iidx %d didx %d\n", 7521 env->msr, env->spr[SPR_HID0], 7522 env->hflags, env->immu_idx, env->dmmu_idx); 7523 #if !defined(NO_TIMER_DUMP) 7524 qemu_fprintf(f, "TB %08" PRIu32 " %08" PRIu64 7525 #if !defined(CONFIG_USER_ONLY) 7526 " DECR " TARGET_FMT_lu 7527 #endif 7528 "\n", 7529 cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env) 7530 #if !defined(CONFIG_USER_ONLY) 7531 , cpu_ppc_load_decr(env) 7532 #endif 7533 ); 7534 #endif 7535 for (i = 0; i < 32; i++) { 7536 if ((i & (RGPL - 1)) == 0) { 7537 qemu_fprintf(f, "GPR%02d", i); 7538 } 7539 qemu_fprintf(f, " %016" PRIx64, ppc_dump_gpr(env, i)); 7540 if ((i & (RGPL - 1)) == (RGPL - 1)) { 7541 qemu_fprintf(f, "\n"); 7542 } 7543 } 7544 qemu_fprintf(f, "CR "); 7545 for (i = 0; i < 8; i++) 7546 qemu_fprintf(f, "%01x", env->crf[i]); 7547 qemu_fprintf(f, " ["); 7548 for (i = 0; i < 8; i++) { 7549 char a = '-'; 7550 if (env->crf[i] & 0x08) { 7551 a = 'L'; 7552 } else if (env->crf[i] & 0x04) { 7553 a = 'G'; 7554 } else if (env->crf[i] & 0x02) { 7555 a = 'E'; 7556 } 7557 qemu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' '); 7558 } 7559 qemu_fprintf(f, " ] RES " TARGET_FMT_lx "\n", 7560 env->reserve_addr); 7561 7562 if (flags & CPU_DUMP_FPU) { 7563 for (i = 0; i < 32; i++) { 7564 if ((i & (RFPL - 1)) == 0) { 7565 qemu_fprintf(f, "FPR%02d", i); 7566 } 7567 qemu_fprintf(f, " %016" PRIx64, *cpu_fpr_ptr(env, i)); 7568 if ((i & (RFPL - 1)) == (RFPL - 1)) { 7569 qemu_fprintf(f, "\n"); 7570 } 7571 } 7572 qemu_fprintf(f, "FPSCR " TARGET_FMT_lx "\n", env->fpscr); 7573 } 7574 7575 #if !defined(CONFIG_USER_ONLY) 7576 qemu_fprintf(f, " SRR0 " TARGET_FMT_lx " SRR1 " TARGET_FMT_lx 7577 " PVR " TARGET_FMT_lx " VRSAVE " TARGET_FMT_lx "\n", 7578 env->spr[SPR_SRR0], env->spr[SPR_SRR1], 7579 env->spr[SPR_PVR], env->spr[SPR_VRSAVE]); 7580 7581 qemu_fprintf(f, "SPRG0 " TARGET_FMT_lx " SPRG1 " TARGET_FMT_lx 7582 " SPRG2 " TARGET_FMT_lx " SPRG3 " TARGET_FMT_lx "\n", 7583 env->spr[SPR_SPRG0], env->spr[SPR_SPRG1], 7584 env->spr[SPR_SPRG2], env->spr[SPR_SPRG3]); 7585 7586 qemu_fprintf(f, "SPRG4 " TARGET_FMT_lx " SPRG5 " TARGET_FMT_lx 7587 " SPRG6 " TARGET_FMT_lx " SPRG7 " TARGET_FMT_lx "\n", 7588 env->spr[SPR_SPRG4], env->spr[SPR_SPRG5], 7589 env->spr[SPR_SPRG6], env->spr[SPR_SPRG7]); 7590 7591 #if defined(TARGET_PPC64) 7592 if (env->excp_model == POWERPC_EXCP_POWER7 || 7593 env->excp_model == POWERPC_EXCP_POWER8 || 7594 env->excp_model == POWERPC_EXCP_POWER9) { 7595 qemu_fprintf(f, "HSRR0 " TARGET_FMT_lx " HSRR1 " TARGET_FMT_lx "\n", 7596 env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]); 7597 } 7598 #endif 7599 if (env->excp_model == POWERPC_EXCP_BOOKE) { 7600 qemu_fprintf(f, "CSRR0 " TARGET_FMT_lx " CSRR1 " TARGET_FMT_lx 7601 " MCSRR0 " TARGET_FMT_lx " MCSRR1 " TARGET_FMT_lx "\n", 7602 env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1], 7603 env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]); 7604 7605 qemu_fprintf(f, " TCR " TARGET_FMT_lx " TSR " TARGET_FMT_lx 7606 " ESR " TARGET_FMT_lx " DEAR " TARGET_FMT_lx "\n", 7607 env->spr[SPR_BOOKE_TCR], env->spr[SPR_BOOKE_TSR], 7608 env->spr[SPR_BOOKE_ESR], env->spr[SPR_BOOKE_DEAR]); 7609 7610 qemu_fprintf(f, " PIR " TARGET_FMT_lx " DECAR " TARGET_FMT_lx 7611 " IVPR " TARGET_FMT_lx " EPCR " TARGET_FMT_lx "\n", 7612 env->spr[SPR_BOOKE_PIR], env->spr[SPR_BOOKE_DECAR], 7613 env->spr[SPR_BOOKE_IVPR], env->spr[SPR_BOOKE_EPCR]); 7614 7615 qemu_fprintf(f, " MCSR " TARGET_FMT_lx " SPRG8 " TARGET_FMT_lx 7616 " EPR " TARGET_FMT_lx "\n", 7617 env->spr[SPR_BOOKE_MCSR], env->spr[SPR_BOOKE_SPRG8], 7618 env->spr[SPR_BOOKE_EPR]); 7619 7620 /* FSL-specific */ 7621 qemu_fprintf(f, " MCAR " TARGET_FMT_lx " PID1 " TARGET_FMT_lx 7622 " PID2 " TARGET_FMT_lx " SVR " TARGET_FMT_lx "\n", 7623 env->spr[SPR_Exxx_MCAR], env->spr[SPR_BOOKE_PID1], 7624 env->spr[SPR_BOOKE_PID2], env->spr[SPR_E500_SVR]); 7625 7626 /* 7627 * IVORs are left out as they are large and do not change often -- 7628 * they can be read with "p $ivor0", "p $ivor1", etc. 7629 */ 7630 } 7631 7632 #if defined(TARGET_PPC64) 7633 if (env->flags & POWERPC_FLAG_CFAR) { 7634 qemu_fprintf(f, " CFAR " TARGET_FMT_lx"\n", env->cfar); 7635 } 7636 #endif 7637 7638 if (env->spr_cb[SPR_LPCR].name) { 7639 qemu_fprintf(f, " LPCR " TARGET_FMT_lx "\n", env->spr[SPR_LPCR]); 7640 } 7641 7642 switch (env->mmu_model) { 7643 case POWERPC_MMU_32B: 7644 case POWERPC_MMU_601: 7645 case POWERPC_MMU_SOFT_6xx: 7646 case POWERPC_MMU_SOFT_74xx: 7647 #if defined(TARGET_PPC64) 7648 case POWERPC_MMU_64B: 7649 case POWERPC_MMU_2_03: 7650 case POWERPC_MMU_2_06: 7651 case POWERPC_MMU_2_07: 7652 case POWERPC_MMU_3_00: 7653 #endif 7654 if (env->spr_cb[SPR_SDR1].name) { /* SDR1 Exists */ 7655 qemu_fprintf(f, " SDR1 " TARGET_FMT_lx " ", env->spr[SPR_SDR1]); 7656 } 7657 if (env->spr_cb[SPR_PTCR].name) { /* PTCR Exists */ 7658 qemu_fprintf(f, " PTCR " TARGET_FMT_lx " ", env->spr[SPR_PTCR]); 7659 } 7660 qemu_fprintf(f, " DAR " TARGET_FMT_lx " DSISR " TARGET_FMT_lx "\n", 7661 env->spr[SPR_DAR], env->spr[SPR_DSISR]); 7662 break; 7663 case POWERPC_MMU_BOOKE206: 7664 qemu_fprintf(f, " MAS0 " TARGET_FMT_lx " MAS1 " TARGET_FMT_lx 7665 " MAS2 " TARGET_FMT_lx " MAS3 " TARGET_FMT_lx "\n", 7666 env->spr[SPR_BOOKE_MAS0], env->spr[SPR_BOOKE_MAS1], 7667 env->spr[SPR_BOOKE_MAS2], env->spr[SPR_BOOKE_MAS3]); 7668 7669 qemu_fprintf(f, " MAS4 " TARGET_FMT_lx " MAS6 " TARGET_FMT_lx 7670 " MAS7 " TARGET_FMT_lx " PID " TARGET_FMT_lx "\n", 7671 env->spr[SPR_BOOKE_MAS4], env->spr[SPR_BOOKE_MAS6], 7672 env->spr[SPR_BOOKE_MAS7], env->spr[SPR_BOOKE_PID]); 7673 7674 qemu_fprintf(f, "MMUCFG " TARGET_FMT_lx " TLB0CFG " TARGET_FMT_lx 7675 " TLB1CFG " TARGET_FMT_lx "\n", 7676 env->spr[SPR_MMUCFG], env->spr[SPR_BOOKE_TLB0CFG], 7677 env->spr[SPR_BOOKE_TLB1CFG]); 7678 break; 7679 default: 7680 break; 7681 } 7682 #endif 7683 7684 #undef RGPL 7685 #undef RFPL 7686 } 7687 7688 void ppc_cpu_dump_statistics(CPUState *cs, int flags) 7689 { 7690 #if defined(DO_PPC_STATISTICS) 7691 PowerPCCPU *cpu = POWERPC_CPU(cs); 7692 opc_handler_t **t1, **t2, **t3, *handler; 7693 int op1, op2, op3; 7694 7695 t1 = cpu->env.opcodes; 7696 for (op1 = 0; op1 < 64; op1++) { 7697 handler = t1[op1]; 7698 if (is_indirect_opcode(handler)) { 7699 t2 = ind_table(handler); 7700 for (op2 = 0; op2 < 32; op2++) { 7701 handler = t2[op2]; 7702 if (is_indirect_opcode(handler)) { 7703 t3 = ind_table(handler); 7704 for (op3 = 0; op3 < 32; op3++) { 7705 handler = t3[op3]; 7706 if (handler->count == 0) { 7707 continue; 7708 } 7709 qemu_printf("%02x %02x %02x (%02x %04d) %16s: " 7710 "%016" PRIx64 " %" PRId64 "\n", 7711 op1, op2, op3, op1, (op3 << 5) | op2, 7712 handler->oname, 7713 handler->count, handler->count); 7714 } 7715 } else { 7716 if (handler->count == 0) { 7717 continue; 7718 } 7719 qemu_printf("%02x %02x (%02x %04d) %16s: " 7720 "%016" PRIx64 " %" PRId64 "\n", 7721 op1, op2, op1, op2, handler->oname, 7722 handler->count, handler->count); 7723 } 7724 } 7725 } else { 7726 if (handler->count == 0) { 7727 continue; 7728 } 7729 qemu_printf("%02x (%02x ) %16s: %016" PRIx64 7730 " %" PRId64 "\n", 7731 op1, op1, handler->oname, 7732 handler->count, handler->count); 7733 } 7734 } 7735 #endif 7736 } 7737 7738 static void ppc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) 7739 { 7740 DisasContext *ctx = container_of(dcbase, DisasContext, base); 7741 CPUPPCState *env = cs->env_ptr; 7742 int bound; 7743 7744 ctx->exception = POWERPC_EXCP_NONE; 7745 ctx->spr_cb = env->spr_cb; 7746 ctx->pr = msr_pr; 7747 ctx->mem_idx = env->dmmu_idx; 7748 ctx->dr = msr_dr; 7749 #if !defined(CONFIG_USER_ONLY) 7750 ctx->hv = msr_hv || !env->has_hv_mode; 7751 #endif 7752 ctx->insns_flags = env->insns_flags; 7753 ctx->insns_flags2 = env->insns_flags2; 7754 ctx->access_type = -1; 7755 ctx->need_access_type = !(env->mmu_model & POWERPC_MMU_64B); 7756 ctx->le_mode = !!(env->hflags & (1 << MSR_LE)); 7757 ctx->default_tcg_memop_mask = ctx->le_mode ? MO_LE : MO_BE; 7758 ctx->flags = env->flags; 7759 #if defined(TARGET_PPC64) 7760 ctx->sf_mode = msr_is_64bit(env, env->msr); 7761 ctx->has_cfar = !!(env->flags & POWERPC_FLAG_CFAR); 7762 #endif 7763 ctx->lazy_tlb_flush = env->mmu_model == POWERPC_MMU_32B 7764 || env->mmu_model == POWERPC_MMU_601 7765 || (env->mmu_model & POWERPC_MMU_64B); 7766 7767 ctx->fpu_enabled = !!msr_fp; 7768 if ((env->flags & POWERPC_FLAG_SPE) && msr_spe) { 7769 ctx->spe_enabled = !!msr_spe; 7770 } else { 7771 ctx->spe_enabled = false; 7772 } 7773 if ((env->flags & POWERPC_FLAG_VRE) && msr_vr) { 7774 ctx->altivec_enabled = !!msr_vr; 7775 } else { 7776 ctx->altivec_enabled = false; 7777 } 7778 if ((env->flags & POWERPC_FLAG_VSX) && msr_vsx) { 7779 ctx->vsx_enabled = !!msr_vsx; 7780 } else { 7781 ctx->vsx_enabled = false; 7782 } 7783 #if defined(TARGET_PPC64) 7784 if ((env->flags & POWERPC_FLAG_TM) && msr_tm) { 7785 ctx->tm_enabled = !!msr_tm; 7786 } else { 7787 ctx->tm_enabled = false; 7788 } 7789 #endif 7790 ctx->gtse = !!(env->spr[SPR_LPCR] & LPCR_GTSE); 7791 if ((env->flags & POWERPC_FLAG_SE) && msr_se) { 7792 ctx->singlestep_enabled = CPU_SINGLE_STEP; 7793 } else { 7794 ctx->singlestep_enabled = 0; 7795 } 7796 if ((env->flags & POWERPC_FLAG_BE) && msr_be) { 7797 ctx->singlestep_enabled |= CPU_BRANCH_STEP; 7798 } 7799 if ((env->flags & POWERPC_FLAG_DE) && msr_de) { 7800 ctx->singlestep_enabled = 0; 7801 target_ulong dbcr0 = env->spr[SPR_BOOKE_DBCR0]; 7802 if (dbcr0 & DBCR0_ICMP) { 7803 ctx->singlestep_enabled |= CPU_SINGLE_STEP; 7804 } 7805 if (dbcr0 & DBCR0_BRT) { 7806 ctx->singlestep_enabled |= CPU_BRANCH_STEP; 7807 } 7808 7809 } 7810 if (unlikely(ctx->base.singlestep_enabled)) { 7811 ctx->singlestep_enabled |= GDBSTUB_SINGLE_STEP; 7812 } 7813 #if defined(DO_SINGLE_STEP) && 0 7814 /* Single step trace mode */ 7815 msr_se = 1; 7816 #endif 7817 7818 bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4; 7819 ctx->base.max_insns = MIN(ctx->base.max_insns, bound); 7820 } 7821 7822 static void ppc_tr_tb_start(DisasContextBase *db, CPUState *cs) 7823 { 7824 } 7825 7826 static void ppc_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) 7827 { 7828 tcg_gen_insn_start(dcbase->pc_next); 7829 } 7830 7831 static bool ppc_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs, 7832 const CPUBreakpoint *bp) 7833 { 7834 DisasContext *ctx = container_of(dcbase, DisasContext, base); 7835 7836 gen_debug_exception(ctx); 7837 dcbase->is_jmp = DISAS_NORETURN; 7838 /* 7839 * The address covered by the breakpoint must be included in 7840 * [tb->pc, tb->pc + tb->size) in order to for it to be properly 7841 * cleared -- thus we increment the PC here so that the logic 7842 * setting tb->size below does the right thing. 7843 */ 7844 ctx->base.pc_next += 4; 7845 return true; 7846 } 7847 7848 static void ppc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) 7849 { 7850 DisasContext *ctx = container_of(dcbase, DisasContext, base); 7851 CPUPPCState *env = cs->env_ptr; 7852 opc_handler_t **table, *handler; 7853 7854 LOG_DISAS("----------------\n"); 7855 LOG_DISAS("nip=" TARGET_FMT_lx " super=%d ir=%d\n", 7856 ctx->base.pc_next, ctx->mem_idx, (int)msr_ir); 7857 7858 if (unlikely(need_byteswap(ctx))) { 7859 ctx->opcode = bswap32(cpu_ldl_code(env, ctx->base.pc_next)); 7860 } else { 7861 ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next); 7862 } 7863 LOG_DISAS("translate opcode %08x (%02x %02x %02x %02x) (%s)\n", 7864 ctx->opcode, opc1(ctx->opcode), opc2(ctx->opcode), 7865 opc3(ctx->opcode), opc4(ctx->opcode), 7866 ctx->le_mode ? "little" : "big"); 7867 ctx->base.pc_next += 4; 7868 table = env->opcodes; 7869 handler = table[opc1(ctx->opcode)]; 7870 if (is_indirect_opcode(handler)) { 7871 table = ind_table(handler); 7872 handler = table[opc2(ctx->opcode)]; 7873 if (is_indirect_opcode(handler)) { 7874 table = ind_table(handler); 7875 handler = table[opc3(ctx->opcode)]; 7876 if (is_indirect_opcode(handler)) { 7877 table = ind_table(handler); 7878 handler = table[opc4(ctx->opcode)]; 7879 } 7880 } 7881 } 7882 /* Is opcode *REALLY* valid ? */ 7883 if (unlikely(handler->handler == &gen_invalid)) { 7884 qemu_log_mask(LOG_GUEST_ERROR, "invalid/unsupported opcode: " 7885 "%02x - %02x - %02x - %02x (%08x) " 7886 TARGET_FMT_lx " %d\n", 7887 opc1(ctx->opcode), opc2(ctx->opcode), 7888 opc3(ctx->opcode), opc4(ctx->opcode), 7889 ctx->opcode, ctx->base.pc_next - 4, (int)msr_ir); 7890 } else { 7891 uint32_t inval; 7892 7893 if (unlikely(handler->type & (PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE) 7894 && Rc(ctx->opcode))) { 7895 inval = handler->inval2; 7896 } else { 7897 inval = handler->inval1; 7898 } 7899 7900 if (unlikely((ctx->opcode & inval) != 0)) { 7901 qemu_log_mask(LOG_GUEST_ERROR, "invalid bits: %08x for opcode: " 7902 "%02x - %02x - %02x - %02x (%08x) " 7903 TARGET_FMT_lx "\n", ctx->opcode & inval, 7904 opc1(ctx->opcode), opc2(ctx->opcode), 7905 opc3(ctx->opcode), opc4(ctx->opcode), 7906 ctx->opcode, ctx->base.pc_next - 4); 7907 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); 7908 ctx->base.is_jmp = DISAS_NORETURN; 7909 return; 7910 } 7911 } 7912 (*(handler->handler))(ctx); 7913 #if defined(DO_PPC_STATISTICS) 7914 handler->count++; 7915 #endif 7916 /* Check trace mode exceptions */ 7917 if (unlikely(ctx->singlestep_enabled & CPU_SINGLE_STEP && 7918 (ctx->base.pc_next <= 0x100 || ctx->base.pc_next > 0xF00) && 7919 ctx->exception != POWERPC_SYSCALL && 7920 ctx->exception != POWERPC_EXCP_TRAP && 7921 ctx->exception != POWERPC_EXCP_BRANCH)) { 7922 uint32_t excp = gen_prep_dbgex(ctx); 7923 gen_exception_nip(ctx, excp, ctx->base.pc_next); 7924 } 7925 7926 if (tcg_check_temp_count()) { 7927 qemu_log("Opcode %02x %02x %02x %02x (%08x) leaked " 7928 "temporaries\n", opc1(ctx->opcode), opc2(ctx->opcode), 7929 opc3(ctx->opcode), opc4(ctx->opcode), ctx->opcode); 7930 } 7931 7932 ctx->base.is_jmp = ctx->exception == POWERPC_EXCP_NONE ? 7933 DISAS_NEXT : DISAS_NORETURN; 7934 } 7935 7936 static void ppc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) 7937 { 7938 DisasContext *ctx = container_of(dcbase, DisasContext, base); 7939 7940 if (ctx->exception == POWERPC_EXCP_NONE) { 7941 gen_goto_tb(ctx, 0, ctx->base.pc_next); 7942 } else if (ctx->exception != POWERPC_EXCP_BRANCH) { 7943 if (unlikely(ctx->base.singlestep_enabled)) { 7944 gen_debug_exception(ctx); 7945 } 7946 /* Generate the return instruction */ 7947 tcg_gen_exit_tb(NULL, 0); 7948 } 7949 } 7950 7951 static void ppc_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs) 7952 { 7953 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first)); 7954 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size); 7955 } 7956 7957 static const TranslatorOps ppc_tr_ops = { 7958 .init_disas_context = ppc_tr_init_disas_context, 7959 .tb_start = ppc_tr_tb_start, 7960 .insn_start = ppc_tr_insn_start, 7961 .breakpoint_check = ppc_tr_breakpoint_check, 7962 .translate_insn = ppc_tr_translate_insn, 7963 .tb_stop = ppc_tr_tb_stop, 7964 .disas_log = ppc_tr_disas_log, 7965 }; 7966 7967 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns) 7968 { 7969 DisasContext ctx; 7970 7971 translator_loop(&ppc_tr_ops, &ctx.base, cs, tb, max_insns); 7972 } 7973 7974 void restore_state_to_opc(CPUPPCState *env, TranslationBlock *tb, 7975 target_ulong *data) 7976 { 7977 env->nip = data[0]; 7978 } 7979