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