1 2 /*---------------------------------------------------------------*/ 3 /*--- begin host_ppc_defs.c ---*/ 4 /*---------------------------------------------------------------*/ 5 6 /* 7 This file is part of Valgrind, a dynamic binary instrumentation 8 framework. 9 10 Copyright (C) 2004-2015 OpenWorks LLP 11 info (at) open-works.net 12 13 This program is free software; you can redistribute it and/or 14 modify it under the terms of the GNU General Public License as 15 published by the Free Software Foundation; either version 2 of the 16 License, or (at your option) any later version. 17 18 This program is distributed in the hope that it will be useful, but 19 WITHOUT ANY WARRANTY; without even the implied warranty of 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 General Public License for more details. 22 23 You should have received a copy of the GNU General Public License 24 along with this program; if not, write to the Free Software 25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 26 02110-1301, USA. 27 28 The GNU General Public License is contained in the file COPYING. 29 30 Neither the names of the U.S. Department of Energy nor the 31 University of California nor the names of its contributors may be 32 used to endorse or promote products derived from this software 33 without prior written permission. 34 */ 35 36 #include "libvex_basictypes.h" 37 #include "libvex.h" 38 #include "libvex_trc_values.h" 39 40 #include "main_util.h" 41 #include "host_generic_regs.h" 42 #include "host_ppc_defs.h" 43 44 45 /* --------- Registers. --------- */ 46 47 const RRegUniverse* getRRegUniverse_PPC ( Bool mode64 ) 48 { 49 /* The real-register universe is a big constant, so we just want to 50 initialise it once. rRegUniverse_PPC_initted values: 0=not initted, 51 1=initted for 32-bit-mode, 2=initted for 64-bit-mode */ 52 static RRegUniverse rRegUniverse_PPC; 53 static UInt rRegUniverse_PPC_initted = 0; 54 55 /* Handy shorthand, nothing more */ 56 RRegUniverse* ru = &rRegUniverse_PPC; 57 58 /* This isn't thread-safe. Sigh. */ 59 UInt howNeeded = mode64 ? 2 : 1; 60 if (LIKELY(rRegUniverse_PPC_initted == howNeeded)) 61 return ru; 62 63 RRegUniverse__init(ru); 64 65 /* Add the registers. The initial segment of this array must be 66 those available for allocation by reg-alloc, and those that 67 follow are not available for allocation. */ 68 // GPR0 = scratch reg where poss. - some ops interpret as value zero 69 // GPR1 = stack pointer 70 // GPR2 = TOC pointer 71 ru->regs[ru->size++] = hregPPC_GPR3(mode64); 72 ru->regs[ru->size++] = hregPPC_GPR4(mode64); 73 ru->regs[ru->size++] = hregPPC_GPR5(mode64); 74 ru->regs[ru->size++] = hregPPC_GPR6(mode64); 75 ru->regs[ru->size++] = hregPPC_GPR7(mode64); 76 ru->regs[ru->size++] = hregPPC_GPR8(mode64); 77 ru->regs[ru->size++] = hregPPC_GPR9(mode64); 78 ru->regs[ru->size++] = hregPPC_GPR10(mode64); 79 if (!mode64) { 80 /* in mode64: 81 r11 used for calls by ptr / env ptr for some langs 82 r12 used for exception handling and global linkage code */ 83 ru->regs[ru->size++] = hregPPC_GPR11(mode64); 84 ru->regs[ru->size++] = hregPPC_GPR12(mode64); 85 } 86 // GPR13 = thread specific pointer 87 // GPR14 and above are callee save. Yay. 88 ru->regs[ru->size++] = hregPPC_GPR14(mode64); 89 ru->regs[ru->size++] = hregPPC_GPR15(mode64); 90 ru->regs[ru->size++] = hregPPC_GPR16(mode64); 91 ru->regs[ru->size++] = hregPPC_GPR17(mode64); 92 ru->regs[ru->size++] = hregPPC_GPR18(mode64); 93 ru->regs[ru->size++] = hregPPC_GPR19(mode64); 94 ru->regs[ru->size++] = hregPPC_GPR20(mode64); 95 ru->regs[ru->size++] = hregPPC_GPR21(mode64); 96 ru->regs[ru->size++] = hregPPC_GPR22(mode64); 97 ru->regs[ru->size++] = hregPPC_GPR23(mode64); 98 ru->regs[ru->size++] = hregPPC_GPR24(mode64); 99 ru->regs[ru->size++] = hregPPC_GPR25(mode64); 100 ru->regs[ru->size++] = hregPPC_GPR26(mode64); 101 ru->regs[ru->size++] = hregPPC_GPR27(mode64); 102 ru->regs[ru->size++] = hregPPC_GPR28(mode64); 103 // GPR29 is reserved for the dispatcher 104 // GPR30 is reserved as AltiVec spill reg temporary 105 // GPR31 is reserved for the GuestStatePtr 106 107 /* Don't waste the reg-allocs's time trawling through zillions of 108 FP registers - they mostly will never be used. We'll tolerate 109 the occasional extra spill instead. */ 110 /* For both ppc32-linux and ppc64-linux, f14-f31 are callee save. 111 So use them. */ 112 ru->regs[ru->size++] = hregPPC_FPR14(mode64); 113 ru->regs[ru->size++] = hregPPC_FPR15(mode64); 114 ru->regs[ru->size++] = hregPPC_FPR16(mode64); 115 ru->regs[ru->size++] = hregPPC_FPR17(mode64); 116 ru->regs[ru->size++] = hregPPC_FPR18(mode64); 117 ru->regs[ru->size++] = hregPPC_FPR19(mode64); 118 ru->regs[ru->size++] = hregPPC_FPR20(mode64); 119 ru->regs[ru->size++] = hregPPC_FPR21(mode64); 120 121 /* Same deal re Altivec */ 122 /* For both ppc32-linux and ppc64-linux, v20-v31 are callee save. 123 So use them. */ 124 /* NB, vr29 is used as a scratch temporary -- do not allocate */ 125 ru->regs[ru->size++] = hregPPC_VR20(mode64); 126 ru->regs[ru->size++] = hregPPC_VR21(mode64); 127 ru->regs[ru->size++] = hregPPC_VR22(mode64); 128 ru->regs[ru->size++] = hregPPC_VR23(mode64); 129 ru->regs[ru->size++] = hregPPC_VR24(mode64); 130 ru->regs[ru->size++] = hregPPC_VR25(mode64); 131 ru->regs[ru->size++] = hregPPC_VR26(mode64); 132 ru->regs[ru->size++] = hregPPC_VR27(mode64); 133 ru->allocable = ru->size; 134 135 /* And other regs, not available to the allocator. */ 136 ru->regs[ru->size++] = hregPPC_GPR1(mode64); 137 ru->regs[ru->size++] = hregPPC_GPR29(mode64); 138 ru->regs[ru->size++] = hregPPC_GPR30(mode64); 139 ru->regs[ru->size++] = hregPPC_GPR31(mode64); 140 ru->regs[ru->size++] = hregPPC_VR29(mode64); 141 142 rRegUniverse_PPC_initted = howNeeded; 143 144 RRegUniverse__check_is_sane(ru); 145 return ru; 146 } 147 148 149 void ppHRegPPC ( HReg reg ) 150 { 151 Int r; 152 static const HChar* ireg32_names[32] 153 = { "%r0", "%r1", "%r2", "%r3", 154 "%r4", "%r5", "%r6", "%r7", 155 "%r8", "%r9", "%r10", "%r11", 156 "%r12", "%r13", "%r14", "%r15", 157 "%r16", "%r17", "%r18", "%r19", 158 "%r20", "%r21", "%r22", "%r23", 159 "%r24", "%r25", "%r26", "%r27", 160 "%r28", "%r29", "%r30", "%r31" }; 161 /* Be generic for all virtual regs. */ 162 if (hregIsVirtual(reg)) { 163 ppHReg(reg); 164 return; 165 } 166 /* But specific for real regs. */ 167 switch (hregClass(reg)) { 168 case HRcInt64: 169 r = hregEncoding(reg); 170 vassert(r >= 0 && r < 32); 171 vex_printf("%s", ireg32_names[r]); 172 return; 173 case HRcInt32: 174 r = hregEncoding(reg); 175 vassert(r >= 0 && r < 32); 176 vex_printf("%s", ireg32_names[r]); 177 return; 178 case HRcFlt64: 179 r = hregEncoding(reg); 180 vassert(r >= 0 && r < 32); 181 vex_printf("%%fr%d", r); 182 return; 183 case HRcVec128: 184 r = hregEncoding(reg); 185 vassert(r >= 0 && r < 32); 186 vex_printf("%%v%d", r); 187 return; 188 default: 189 vpanic("ppHRegPPC"); 190 } 191 } 192 193 194 /* --------- Condition codes, Intel encoding. --------- */ 195 196 const HChar* showPPCCondCode ( PPCCondCode cond ) 197 { 198 if (cond.test == Pct_ALWAYS) return "always"; 199 200 switch (cond.flag) { 201 case Pcf_7SO: 202 return (cond.test == Pct_TRUE) ? "cr7.so=1" : "cr7.so=0"; 203 case Pcf_7EQ: 204 return (cond.test == Pct_TRUE) ? "cr7.eq=1" : "cr7.eq=0"; 205 case Pcf_7GT: 206 return (cond.test == Pct_TRUE) ? "cr7.gt=1" : "cr7.gt=0"; 207 case Pcf_7LT: 208 return (cond.test == Pct_TRUE) ? "cr7.lt=1" : "cr7.lt=0"; 209 case Pcf_NONE: 210 return "no-flag"; 211 default: vpanic("ppPPCCondCode"); 212 } 213 } 214 215 /* construct condition code */ 216 PPCCondCode mk_PPCCondCode ( PPCCondTest test, PPCCondFlag flag ) 217 { 218 PPCCondCode cc; 219 cc.flag = flag; 220 cc.test = test; 221 if (test == Pct_ALWAYS) { 222 vassert(flag == Pcf_NONE); 223 } else { 224 vassert(flag != Pcf_NONE); 225 } 226 return cc; 227 } 228 229 /* false->true, true->false */ 230 PPCCondTest invertCondTest ( PPCCondTest ct ) 231 { 232 vassert(ct != Pct_ALWAYS); 233 return (ct == Pct_TRUE) ? Pct_FALSE : Pct_TRUE; 234 } 235 236 237 /* --------- PPCAMode: memory address expressions. --------- */ 238 239 PPCAMode* PPCAMode_IR ( Int idx, HReg base ) { 240 PPCAMode* am = LibVEX_Alloc_inline(sizeof(PPCAMode)); 241 vassert(idx >= -0x8000 && idx < 0x8000); 242 am->tag = Pam_IR; 243 am->Pam.IR.base = base; 244 am->Pam.IR.index = idx; 245 return am; 246 } 247 PPCAMode* PPCAMode_RR ( HReg idx, HReg base ) { 248 PPCAMode* am = LibVEX_Alloc_inline(sizeof(PPCAMode)); 249 am->tag = Pam_RR; 250 am->Pam.RR.base = base; 251 am->Pam.RR.index = idx; 252 return am; 253 } 254 255 PPCAMode* dopyPPCAMode ( PPCAMode* am ) { 256 switch (am->tag) { 257 case Pam_IR: 258 return PPCAMode_IR( am->Pam.IR.index, am->Pam.IR.base ); 259 case Pam_RR: 260 return PPCAMode_RR( am->Pam.RR.index, am->Pam.RR.base ); 261 default: 262 vpanic("dopyPPCAMode"); 263 } 264 } 265 266 void ppPPCAMode ( PPCAMode* am ) { 267 switch (am->tag) { 268 case Pam_IR: 269 if (am->Pam.IR.index == 0) 270 vex_printf("0("); 271 else 272 vex_printf("%d(", (Int)am->Pam.IR.index); 273 ppHRegPPC(am->Pam.IR.base); 274 vex_printf(")"); 275 return; 276 case Pam_RR: 277 ppHRegPPC(am->Pam.RR.base); 278 vex_printf(","); 279 ppHRegPPC(am->Pam.RR.index); 280 return; 281 default: 282 vpanic("ppPPCAMode"); 283 } 284 } 285 286 static void addRegUsage_PPCAMode ( HRegUsage* u, PPCAMode* am ) { 287 switch (am->tag) { 288 case Pam_IR: 289 addHRegUse(u, HRmRead, am->Pam.IR.base); 290 return; 291 case Pam_RR: 292 addHRegUse(u, HRmRead, am->Pam.RR.base); 293 addHRegUse(u, HRmRead, am->Pam.RR.index); 294 return; 295 default: 296 vpanic("addRegUsage_PPCAMode"); 297 } 298 } 299 300 static void mapRegs_PPCAMode ( HRegRemap* m, PPCAMode* am ) { 301 switch (am->tag) { 302 case Pam_IR: 303 am->Pam.IR.base = lookupHRegRemap(m, am->Pam.IR.base); 304 return; 305 case Pam_RR: 306 am->Pam.RR.base = lookupHRegRemap(m, am->Pam.RR.base); 307 am->Pam.RR.index = lookupHRegRemap(m, am->Pam.RR.index); 308 return; 309 default: 310 vpanic("mapRegs_PPCAMode"); 311 } 312 } 313 314 /* --------- Operand, which can be a reg or a u16/s16. --------- */ 315 316 PPCRH* PPCRH_Imm ( Bool syned, UShort imm16 ) { 317 PPCRH* op = LibVEX_Alloc_inline(sizeof(PPCRH)); 318 op->tag = Prh_Imm; 319 op->Prh.Imm.syned = syned; 320 op->Prh.Imm.imm16 = imm16; 321 /* If this is a signed value, ensure it's not -32768, so that we 322 are guaranteed always to be able to negate if needed. */ 323 if (syned) 324 vassert(imm16 != 0x8000); 325 vassert(syned == True || syned == False); 326 return op; 327 } 328 PPCRH* PPCRH_Reg ( HReg reg ) { 329 PPCRH* op = LibVEX_Alloc_inline(sizeof(PPCRH)); 330 op->tag = Prh_Reg; 331 op->Prh.Reg.reg = reg; 332 return op; 333 } 334 335 void ppPPCRH ( PPCRH* op ) { 336 switch (op->tag) { 337 case Prh_Imm: 338 if (op->Prh.Imm.syned) 339 vex_printf("%d", (Int)(Short)op->Prh.Imm.imm16); 340 else 341 vex_printf("%u", (UInt)(UShort)op->Prh.Imm.imm16); 342 return; 343 case Prh_Reg: 344 ppHRegPPC(op->Prh.Reg.reg); 345 return; 346 default: 347 vpanic("ppPPCRH"); 348 } 349 } 350 351 /* An PPCRH can only be used in a "read" context (what would it mean 352 to write or modify a literal?) and so we enumerate its registers 353 accordingly. */ 354 static void addRegUsage_PPCRH ( HRegUsage* u, PPCRH* op ) { 355 switch (op->tag) { 356 case Prh_Imm: 357 return; 358 case Prh_Reg: 359 addHRegUse(u, HRmRead, op->Prh.Reg.reg); 360 return; 361 default: 362 vpanic("addRegUsage_PPCRH"); 363 } 364 } 365 366 static void mapRegs_PPCRH ( HRegRemap* m, PPCRH* op ) { 367 switch (op->tag) { 368 case Prh_Imm: 369 return; 370 case Prh_Reg: 371 op->Prh.Reg.reg = lookupHRegRemap(m, op->Prh.Reg.reg); 372 return; 373 default: 374 vpanic("mapRegs_PPCRH"); 375 } 376 } 377 378 379 /* --------- Operand, which can be a reg or a u32/64. --------- */ 380 381 PPCRI* PPCRI_Imm ( ULong imm64 ) { 382 PPCRI* op = LibVEX_Alloc_inline(sizeof(PPCRI)); 383 op->tag = Pri_Imm; 384 op->Pri.Imm = imm64; 385 return op; 386 } 387 PPCRI* PPCRI_Reg ( HReg reg ) { 388 PPCRI* op = LibVEX_Alloc_inline(sizeof(PPCRI)); 389 op->tag = Pri_Reg; 390 op->Pri.Reg = reg; 391 return op; 392 } 393 394 void ppPPCRI ( PPCRI* dst ) { 395 switch (dst->tag) { 396 case Pri_Imm: 397 vex_printf("0x%llx", dst->Pri.Imm); 398 break; 399 case Pri_Reg: 400 ppHRegPPC(dst->Pri.Reg); 401 break; 402 default: 403 vpanic("ppPPCRI"); 404 } 405 } 406 407 /* An PPCRI can only be used in a "read" context (what would it 408 mean to write or modify a literal?) and so we enumerate its 409 registers accordingly. */ 410 static void addRegUsage_PPCRI ( HRegUsage* u, PPCRI* dst ) { 411 switch (dst->tag) { 412 case Pri_Imm: 413 return; 414 case Pri_Reg: 415 addHRegUse(u, HRmRead, dst->Pri.Reg); 416 return; 417 default: 418 vpanic("addRegUsage_PPCRI"); 419 } 420 } 421 422 static void mapRegs_PPCRI ( HRegRemap* m, PPCRI* dst ) { 423 switch (dst->tag) { 424 case Pri_Imm: 425 return; 426 case Pri_Reg: 427 dst->Pri.Reg = lookupHRegRemap(m, dst->Pri.Reg); 428 return; 429 default: 430 vpanic("mapRegs_PPCRI"); 431 } 432 } 433 434 435 /* --------- Operand, which can be a vector reg or a simm5. --------- */ 436 437 PPCVI5s* PPCVI5s_Imm ( Char simm5 ) { 438 PPCVI5s* op = LibVEX_Alloc_inline(sizeof(PPCVI5s)); 439 op->tag = Pvi_Imm; 440 op->Pvi.Imm5s = simm5; 441 vassert(simm5 >= -16 && simm5 <= 15); 442 return op; 443 } 444 PPCVI5s* PPCVI5s_Reg ( HReg reg ) { 445 PPCVI5s* op = LibVEX_Alloc_inline(sizeof(PPCVI5s)); 446 op->tag = Pvi_Reg; 447 op->Pvi.Reg = reg; 448 vassert(hregClass(reg) == HRcVec128); 449 return op; 450 } 451 452 void ppPPCVI5s ( PPCVI5s* src ) { 453 switch (src->tag) { 454 case Pvi_Imm: 455 vex_printf("%d", (Int)src->Pvi.Imm5s); 456 break; 457 case Pvi_Reg: 458 ppHRegPPC(src->Pvi.Reg); 459 break; 460 default: 461 vpanic("ppPPCVI5s"); 462 } 463 } 464 465 /* An PPCVI5s can only be used in a "read" context (what would it 466 mean to write or modify a literal?) and so we enumerate its 467 registers accordingly. */ 468 static void addRegUsage_PPCVI5s ( HRegUsage* u, PPCVI5s* dst ) { 469 switch (dst->tag) { 470 case Pvi_Imm: 471 return; 472 case Pvi_Reg: 473 addHRegUse(u, HRmRead, dst->Pvi.Reg); 474 return; 475 default: 476 vpanic("addRegUsage_PPCVI5s"); 477 } 478 } 479 480 static void mapRegs_PPCVI5s ( HRegRemap* m, PPCVI5s* dst ) { 481 switch (dst->tag) { 482 case Pvi_Imm: 483 return; 484 case Pvi_Reg: 485 dst->Pvi.Reg = lookupHRegRemap(m, dst->Pvi.Reg); 486 return; 487 default: 488 vpanic("mapRegs_PPCVI5s"); 489 } 490 } 491 492 493 /* --------- Instructions. --------- */ 494 495 const HChar* showPPCUnaryOp ( PPCUnaryOp op ) { 496 switch (op) { 497 case Pun_NOT: return "not"; 498 case Pun_NEG: return "neg"; 499 case Pun_CLZ32: return "cntlzw"; 500 case Pun_CLZ64: return "cntlzd"; 501 case Pun_EXTSW: return "extsw"; 502 default: vpanic("showPPCUnaryOp"); 503 } 504 } 505 506 const HChar* showPPCAluOp ( PPCAluOp op, Bool immR ) { 507 switch (op) { 508 case Palu_ADD: return immR ? "addi" : "add"; 509 case Palu_SUB: return immR ? "subi" : "sub"; 510 case Palu_AND: return immR ? "andi." : "and"; 511 case Palu_OR: return immR ? "ori" : "or"; 512 case Palu_XOR: return immR ? "xori" : "xor"; 513 default: vpanic("showPPCAluOp"); 514 } 515 } 516 517 const HChar* showPPCShftOp ( PPCShftOp op, Bool immR, Bool sz32 ) { 518 switch (op) { 519 case Pshft_SHL: return sz32 ? (immR ? "slwi" : "slw") : 520 (immR ? "sldi" : "sld"); 521 case Pshft_SHR: return sz32 ? (immR ? "srwi" : "srw") : 522 (immR ? "srdi" : "srd"); 523 case Pshft_SAR: return sz32 ? (immR ? "srawi" : "sraw") : 524 (immR ? "sradi" : "srad"); 525 default: vpanic("showPPCShftOp"); 526 } 527 } 528 529 const HChar* showPPCFpOp ( PPCFpOp op ) { 530 switch (op) { 531 case Pfp_ADDD: return "fadd"; 532 case Pfp_SUBD: return "fsub"; 533 case Pfp_MULD: return "fmul"; 534 case Pfp_DIVD: return "fdiv"; 535 case Pfp_MADDD: return "fmadd"; 536 case Pfp_MSUBD: return "fmsub"; 537 case Pfp_MADDS: return "fmadds"; 538 case Pfp_MSUBS: return "fmsubs"; 539 case Pfp_ADDS: return "fadds"; 540 case Pfp_SUBS: return "fsubs"; 541 case Pfp_MULS: return "fmuls"; 542 case Pfp_DIVS: return "fdivs"; 543 case Pfp_SQRT: return "fsqrt"; 544 case Pfp_ABS: return "fabs"; 545 case Pfp_NEG: return "fneg"; 546 case Pfp_MOV: return "fmr"; 547 case Pfp_RES: return "fres"; 548 case Pfp_RSQRTE: return "frsqrte"; 549 case Pfp_FRIM: return "frim"; 550 case Pfp_FRIN: return "frin"; 551 case Pfp_FRIP: return "frip"; 552 case Pfp_FRIZ: return "friz"; 553 case Pfp_DFPADD: return "dadd"; 554 case Pfp_DFPADDQ: return "daddq"; 555 case Pfp_DFPSUB: return "dsub"; 556 case Pfp_DFPSUBQ: return "dsubq"; 557 case Pfp_DFPMUL: return "dmul"; 558 case Pfp_DFPMULQ: return "dmulq"; 559 case Pfp_DFPDIV: return "ddivd"; 560 case Pfp_DFPDIVQ: return "ddivq"; 561 case Pfp_DCTDP: return "dctdp"; 562 case Pfp_DRSP: return "drsp"; 563 case Pfp_DCTFIX: return "dctfix"; 564 case Pfp_DCFFIX: return "dcffix"; 565 case Pfp_DCTQPQ: return "dctqpq"; 566 case Pfp_DCFFIXQ: return "dcffixq"; 567 case Pfp_DQUA: return "dqua"; 568 case Pfp_DQUAQ: return "dquaq"; 569 case Pfp_DXEX: return "dxex"; 570 case Pfp_DXEXQ: return "dxexq"; 571 case Pfp_DIEX: return "diex"; 572 case Pfp_DIEXQ: return "diexq"; 573 case Pfp_RRDTR: return "rrdtr"; 574 default: vpanic("showPPCFpOp"); 575 } 576 } 577 578 const HChar* showPPCAvOp ( PPCAvOp op ) { 579 switch (op) { 580 581 /* Unary */ 582 case Pav_MOV: return "vmr"; /* Mov */ 583 584 case Pav_AND: return "vand"; /* Bitwise */ 585 case Pav_OR: return "vor"; 586 case Pav_XOR: return "vxor"; 587 case Pav_NOT: return "vnot"; 588 589 case Pav_UNPCKH8S: return "vupkhsb"; /* Unpack */ 590 case Pav_UNPCKH16S: return "vupkhsh"; 591 case Pav_UNPCKL8S: return "vupklsb"; 592 case Pav_UNPCKL16S: return "vupklsh"; 593 case Pav_UNPCKHPIX: return "vupkhpx"; 594 case Pav_UNPCKLPIX: return "vupklpx"; 595 596 /* Integer binary */ 597 case Pav_ADDU: return "vaddu_m"; // b,h,w,dw 598 case Pav_QADDU: return "vaddu_s"; // b,h,w,dw 599 case Pav_QADDS: return "vadds_s"; // b,h,w,dw 600 601 case Pav_SUBU: return "vsubu_m"; // b,h,w,dw 602 case Pav_QSUBU: return "vsubu_s"; // b,h,w,dw 603 case Pav_QSUBS: return "vsubs_s"; // b,h,w,dw 604 605 case Pav_MULU: return "vmulu"; // w 606 case Pav_OMULU: return "vmulou"; // b,h,w 607 case Pav_OMULS: return "vmulos"; // b,h,w 608 case Pav_EMULU: return "vmuleu"; // b,h,w 609 case Pav_EMULS: return "vmules"; // b,h,w 610 611 case Pav_AVGU: return "vavgu"; // b,h,w 612 case Pav_AVGS: return "vavgs"; // b,h,w 613 614 case Pav_MAXU: return "vmaxu"; // b,h,w 615 case Pav_MAXS: return "vmaxs"; // b,h,w 616 617 case Pav_MINU: return "vminu"; // b,h,w 618 case Pav_MINS: return "vmins"; // b,h,w 619 620 /* Compare (always affects CR field 6) */ 621 case Pav_CMPEQU: return "vcmpequ"; // b,h,w 622 case Pav_CMPGTU: return "vcmpgtu"; // b,h,w 623 case Pav_CMPGTS: return "vcmpgts"; // b,h,w 624 625 /* Shift */ 626 case Pav_SHL: return "vsl"; // ' ',b,h,w,dw 627 case Pav_SHR: return "vsr"; // ' ',b,h,w,dw 628 case Pav_SAR: return "vsra"; // b,h,w,dw 629 case Pav_ROTL: return "vrl"; // b,h,w,dw 630 631 /* Pack */ 632 case Pav_PACKUU: return "vpku_um"; // h,w,dw 633 case Pav_QPACKUU: return "vpku_us"; // h,w 634 case Pav_QPACKSU: return "vpks_us"; // h,w 635 case Pav_QPACKSS: return "vpks_ss"; // h,w 636 case Pav_PACKPXL: return "vpkpx"; 637 638 /* Merge */ 639 case Pav_MRGHI: return "vmrgh"; // b,h,w 640 case Pav_MRGLO: return "vmrgl"; // b,h,w 641 642 /* Concatenation */ 643 case Pav_CATODD: return "vmrgow"; // w 644 case Pav_CATEVEN: return "vmrgew"; // w 645 646 /* SHA */ 647 case Pav_SHA256: return "vshasigmaw"; // w 648 case Pav_SHA512: return "vshasigmaw"; // dw 649 650 /* BCD */ 651 case Pav_BCDAdd: return "bcdadd."; // qw 652 case Pav_BCDSub: return "bcdsub."; // qw 653 654 /* Polynomial arith */ 655 case Pav_POLYMULADD: return "vpmsum"; // b, h, w, d 656 657 /* Cipher */ 658 case Pav_CIPHERV128: case Pav_CIPHERLV128: 659 case Pav_NCIPHERV128: case Pav_NCIPHERLV128: 660 case Pav_CIPHERSUBV128: return "v_cipher_"; // qw 661 662 /* zero count */ 663 case Pav_ZEROCNTBYTE: case Pav_ZEROCNTWORD: 664 case Pav_ZEROCNTHALF: case Pav_ZEROCNTDBL: 665 return "vclz_"; // b, h, w, d 666 667 /* vector gather (byte-by-byte bit matrix transpose) */ 668 case Pav_BITMTXXPOSE: 669 return "vgbbd"; 670 671 default: vpanic("showPPCAvOp"); 672 } 673 } 674 675 const HChar* showPPCAvFpOp ( PPCAvFpOp op ) { 676 switch (op) { 677 /* Floating Point Binary */ 678 case Pavfp_ADDF: return "vaddfp"; 679 case Pavfp_SUBF: return "vsubfp"; 680 case Pavfp_MULF: return "vmaddfp"; 681 case Pavfp_MAXF: return "vmaxfp"; 682 case Pavfp_MINF: return "vminfp"; 683 case Pavfp_CMPEQF: return "vcmpeqfp"; 684 case Pavfp_CMPGTF: return "vcmpgtfp"; 685 case Pavfp_CMPGEF: return "vcmpgefp"; 686 687 /* Floating Point Unary */ 688 case Pavfp_RCPF: return "vrefp"; 689 case Pavfp_RSQRTF: return "vrsqrtefp"; 690 case Pavfp_CVTU2F: return "vcfux"; 691 case Pavfp_CVTS2F: return "vcfsx"; 692 case Pavfp_QCVTF2U: return "vctuxs"; 693 case Pavfp_QCVTF2S: return "vctsxs"; 694 case Pavfp_ROUNDM: return "vrfim"; 695 case Pavfp_ROUNDP: return "vrfip"; 696 case Pavfp_ROUNDN: return "vrfin"; 697 case Pavfp_ROUNDZ: return "vrfiz"; 698 699 default: vpanic("showPPCAvFpOp"); 700 } 701 } 702 703 PPCInstr* PPCInstr_LI ( HReg dst, ULong imm64, Bool mode64 ) 704 { 705 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 706 i->tag = Pin_LI; 707 i->Pin.LI.dst = dst; 708 i->Pin.LI.imm64 = imm64; 709 if (!mode64) 710 vassert( (Long)imm64 == (Long)(Int)(UInt)imm64 ); 711 return i; 712 } 713 PPCInstr* PPCInstr_Alu ( PPCAluOp op, HReg dst, 714 HReg srcL, PPCRH* srcR ) { 715 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 716 i->tag = Pin_Alu; 717 i->Pin.Alu.op = op; 718 i->Pin.Alu.dst = dst; 719 i->Pin.Alu.srcL = srcL; 720 i->Pin.Alu.srcR = srcR; 721 return i; 722 } 723 PPCInstr* PPCInstr_Shft ( PPCShftOp op, Bool sz32, 724 HReg dst, HReg srcL, PPCRH* srcR ) { 725 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 726 i->tag = Pin_Shft; 727 i->Pin.Shft.op = op; 728 i->Pin.Shft.sz32 = sz32; 729 i->Pin.Shft.dst = dst; 730 i->Pin.Shft.srcL = srcL; 731 i->Pin.Shft.srcR = srcR; 732 return i; 733 } 734 PPCInstr* PPCInstr_AddSubC ( Bool isAdd, Bool setC, 735 HReg dst, HReg srcL, HReg srcR ) { 736 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 737 i->tag = Pin_AddSubC; 738 i->Pin.AddSubC.isAdd = isAdd; 739 i->Pin.AddSubC.setC = setC; 740 i->Pin.AddSubC.dst = dst; 741 i->Pin.AddSubC.srcL = srcL; 742 i->Pin.AddSubC.srcR = srcR; 743 return i; 744 } 745 PPCInstr* PPCInstr_Cmp ( Bool syned, Bool sz32, 746 UInt crfD, HReg srcL, PPCRH* srcR ) { 747 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 748 i->tag = Pin_Cmp; 749 i->Pin.Cmp.syned = syned; 750 i->Pin.Cmp.sz32 = sz32; 751 i->Pin.Cmp.crfD = crfD; 752 i->Pin.Cmp.srcL = srcL; 753 i->Pin.Cmp.srcR = srcR; 754 return i; 755 } 756 PPCInstr* PPCInstr_Unary ( PPCUnaryOp op, HReg dst, HReg src ) { 757 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 758 i->tag = Pin_Unary; 759 i->Pin.Unary.op = op; 760 i->Pin.Unary.dst = dst; 761 i->Pin.Unary.src = src; 762 return i; 763 } 764 PPCInstr* PPCInstr_MulL ( Bool syned, Bool hi, Bool sz32, 765 HReg dst, HReg srcL, HReg srcR ) { 766 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 767 i->tag = Pin_MulL; 768 i->Pin.MulL.syned = syned; 769 i->Pin.MulL.hi = hi; 770 i->Pin.MulL.sz32 = sz32; 771 i->Pin.MulL.dst = dst; 772 i->Pin.MulL.srcL = srcL; 773 i->Pin.MulL.srcR = srcR; 774 /* if doing the low word, the signedness is irrelevant, but tie it 775 down anyway. */ 776 if (!hi) vassert(!syned); 777 return i; 778 } 779 PPCInstr* PPCInstr_Div ( Bool extended, Bool syned, Bool sz32, 780 HReg dst, HReg srcL, HReg srcR ) { 781 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 782 i->tag = Pin_Div; 783 i->Pin.Div.extended = extended; 784 i->Pin.Div.syned = syned; 785 i->Pin.Div.sz32 = sz32; 786 i->Pin.Div.dst = dst; 787 i->Pin.Div.srcL = srcL; 788 i->Pin.Div.srcR = srcR; 789 return i; 790 } 791 PPCInstr* PPCInstr_Call ( PPCCondCode cond, 792 Addr64 target, UInt argiregs, RetLoc rloc ) { 793 UInt mask; 794 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 795 i->tag = Pin_Call; 796 i->Pin.Call.cond = cond; 797 i->Pin.Call.target = target; 798 i->Pin.Call.argiregs = argiregs; 799 i->Pin.Call.rloc = rloc; 800 /* Only r3 .. r10 inclusive may be used as arg regs. Hence: */ 801 mask = (1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<9)|(1<<10); 802 vassert(0 == (argiregs & ~mask)); 803 vassert(is_sane_RetLoc(rloc)); 804 return i; 805 } 806 PPCInstr* PPCInstr_XDirect ( Addr64 dstGA, PPCAMode* amCIA, 807 PPCCondCode cond, Bool toFastEP ) { 808 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 809 i->tag = Pin_XDirect; 810 i->Pin.XDirect.dstGA = dstGA; 811 i->Pin.XDirect.amCIA = amCIA; 812 i->Pin.XDirect.cond = cond; 813 i->Pin.XDirect.toFastEP = toFastEP; 814 return i; 815 } 816 PPCInstr* PPCInstr_XIndir ( HReg dstGA, PPCAMode* amCIA, 817 PPCCondCode cond ) { 818 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 819 i->tag = Pin_XIndir; 820 i->Pin.XIndir.dstGA = dstGA; 821 i->Pin.XIndir.amCIA = amCIA; 822 i->Pin.XIndir.cond = cond; 823 return i; 824 } 825 PPCInstr* PPCInstr_XAssisted ( HReg dstGA, PPCAMode* amCIA, 826 PPCCondCode cond, IRJumpKind jk ) { 827 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 828 i->tag = Pin_XAssisted; 829 i->Pin.XAssisted.dstGA = dstGA; 830 i->Pin.XAssisted.amCIA = amCIA; 831 i->Pin.XAssisted.cond = cond; 832 i->Pin.XAssisted.jk = jk; 833 return i; 834 } 835 PPCInstr* PPCInstr_CMov ( PPCCondCode cond, 836 HReg dst, PPCRI* src ) { 837 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 838 i->tag = Pin_CMov; 839 i->Pin.CMov.cond = cond; 840 i->Pin.CMov.src = src; 841 i->Pin.CMov.dst = dst; 842 vassert(cond.test != Pct_ALWAYS); 843 return i; 844 } 845 PPCInstr* PPCInstr_Load ( UChar sz, 846 HReg dst, PPCAMode* src, Bool mode64 ) { 847 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 848 i->tag = Pin_Load; 849 i->Pin.Load.sz = sz; 850 i->Pin.Load.src = src; 851 i->Pin.Load.dst = dst; 852 vassert(sz == 1 || sz == 2 || sz == 4 || sz == 8); 853 if (sz == 8) vassert(mode64); 854 return i; 855 } 856 PPCInstr* PPCInstr_LoadL ( UChar sz, 857 HReg dst, HReg src, Bool mode64 ) 858 { 859 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 860 i->tag = Pin_LoadL; 861 i->Pin.LoadL.sz = sz; 862 i->Pin.LoadL.src = src; 863 i->Pin.LoadL.dst = dst; 864 vassert(sz == 1 || sz == 2 || sz == 4 || sz == 8); 865 if (sz == 8) vassert(mode64); 866 return i; 867 } 868 PPCInstr* PPCInstr_Store ( UChar sz, PPCAMode* dst, HReg src, 869 Bool mode64 ) { 870 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 871 i->tag = Pin_Store; 872 i->Pin.Store.sz = sz; 873 i->Pin.Store.src = src; 874 i->Pin.Store.dst = dst; 875 vassert(sz == 1 || sz == 2 || sz == 4 || sz == 8); 876 if (sz == 8) vassert(mode64); 877 return i; 878 } 879 PPCInstr* PPCInstr_StoreC ( UChar sz, HReg dst, HReg src, Bool mode64 ) { 880 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 881 i->tag = Pin_StoreC; 882 i->Pin.StoreC.sz = sz; 883 i->Pin.StoreC.src = src; 884 i->Pin.StoreC.dst = dst; 885 vassert(sz == 1 || sz == 2 || sz == 4 || sz == 8); 886 if (sz == 8) vassert(mode64); 887 return i; 888 } 889 PPCInstr* PPCInstr_Set ( PPCCondCode cond, HReg dst ) { 890 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 891 i->tag = Pin_Set; 892 i->Pin.Set.cond = cond; 893 i->Pin.Set.dst = dst; 894 return i; 895 } 896 PPCInstr* PPCInstr_MfCR ( HReg dst ) 897 { 898 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 899 i->tag = Pin_MfCR; 900 i->Pin.MfCR.dst = dst; 901 return i; 902 } 903 PPCInstr* PPCInstr_MFence ( void ) 904 { 905 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 906 i->tag = Pin_MFence; 907 return i; 908 } 909 910 PPCInstr* PPCInstr_FpUnary ( PPCFpOp op, HReg dst, HReg src ) { 911 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 912 i->tag = Pin_FpUnary; 913 i->Pin.FpUnary.op = op; 914 i->Pin.FpUnary.dst = dst; 915 i->Pin.FpUnary.src = src; 916 return i; 917 } 918 PPCInstr* PPCInstr_FpBinary ( PPCFpOp op, HReg dst, 919 HReg srcL, HReg srcR ) { 920 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 921 i->tag = Pin_FpBinary; 922 i->Pin.FpBinary.op = op; 923 i->Pin.FpBinary.dst = dst; 924 i->Pin.FpBinary.srcL = srcL; 925 i->Pin.FpBinary.srcR = srcR; 926 return i; 927 } 928 PPCInstr* PPCInstr_FpMulAcc ( PPCFpOp op, HReg dst, HReg srcML, 929 HReg srcMR, HReg srcAcc ) 930 { 931 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 932 i->tag = Pin_FpMulAcc; 933 i->Pin.FpMulAcc.op = op; 934 i->Pin.FpMulAcc.dst = dst; 935 i->Pin.FpMulAcc.srcML = srcML; 936 i->Pin.FpMulAcc.srcMR = srcMR; 937 i->Pin.FpMulAcc.srcAcc = srcAcc; 938 return i; 939 } 940 PPCInstr* PPCInstr_FpLdSt ( Bool isLoad, UChar sz, 941 HReg reg, PPCAMode* addr ) { 942 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 943 i->tag = Pin_FpLdSt; 944 i->Pin.FpLdSt.isLoad = isLoad; 945 i->Pin.FpLdSt.sz = sz; 946 i->Pin.FpLdSt.reg = reg; 947 i->Pin.FpLdSt.addr = addr; 948 vassert(sz == 4 || sz == 8); 949 return i; 950 } 951 PPCInstr* PPCInstr_FpSTFIW ( HReg addr, HReg data ) 952 { 953 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 954 i->tag = Pin_FpSTFIW; 955 i->Pin.FpSTFIW.addr = addr; 956 i->Pin.FpSTFIW.data = data; 957 return i; 958 } 959 PPCInstr* PPCInstr_FpRSP ( HReg dst, HReg src ) { 960 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 961 i->tag = Pin_FpRSP; 962 i->Pin.FpRSP.dst = dst; 963 i->Pin.FpRSP.src = src; 964 return i; 965 } 966 PPCInstr* PPCInstr_Dfp64Unary(PPCFpOp op, HReg dst, HReg src) { 967 PPCInstr* i = LibVEX_Alloc_inline( sizeof(PPCInstr) ); 968 i->tag = Pin_Dfp64Unary; 969 i->Pin.Dfp64Unary.op = op; 970 i->Pin.Dfp64Unary.dst = dst; 971 i->Pin.Dfp64Unary.src = src; 972 return i; 973 } 974 PPCInstr* PPCInstr_Dfp64Binary(PPCFpOp op, HReg dst, HReg srcL, HReg srcR) { 975 PPCInstr* i = LibVEX_Alloc_inline( sizeof(PPCInstr) ); 976 i->tag = Pin_Dfp64Binary; 977 i->Pin.Dfp64Binary.op = op; 978 i->Pin.Dfp64Binary.dst = dst; 979 i->Pin.Dfp64Binary.srcL = srcL; 980 i->Pin.Dfp64Binary.srcR = srcR; 981 return i; 982 } 983 PPCInstr* PPCInstr_DfpShift ( PPCFpOp op, HReg dst, HReg src, PPCRI* shift ) { 984 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 985 i->tag = Pin_DfpShift; 986 i->Pin.DfpShift.op = op; 987 i->Pin.DfpShift.shift = shift; 988 i->Pin.DfpShift.src = src; 989 i->Pin.DfpShift.dst = dst; 990 return i; 991 } 992 PPCInstr* PPCInstr_Dfp128Unary(PPCFpOp op, HReg dst_hi, HReg dst_lo, 993 HReg src_hi, HReg src_lo) { 994 PPCInstr* i = LibVEX_Alloc_inline( sizeof(PPCInstr) ); 995 i->tag = Pin_Dfp128Unary; 996 i->Pin.Dfp128Unary.op = op; 997 i->Pin.Dfp128Unary.dst_hi = dst_hi; 998 i->Pin.Dfp128Unary.dst_lo = dst_lo; 999 i->Pin.Dfp128Unary.src_hi = src_hi; 1000 i->Pin.Dfp128Unary.src_lo = src_lo; 1001 return i; 1002 } 1003 PPCInstr* PPCInstr_Dfp128Binary(PPCFpOp op, HReg dst_hi, HReg dst_lo, 1004 HReg srcR_hi, HReg srcR_lo) { 1005 /* dst is used to pass the srcL argument and return the result */ 1006 PPCInstr* i = LibVEX_Alloc_inline( sizeof(PPCInstr) ); 1007 i->tag = Pin_Dfp128Binary; 1008 i->Pin.Dfp128Binary.op = op; 1009 i->Pin.Dfp128Binary.dst_hi = dst_hi; 1010 i->Pin.Dfp128Binary.dst_lo = dst_lo; 1011 i->Pin.Dfp128Binary.srcR_hi = srcR_hi; 1012 i->Pin.Dfp128Binary.srcR_lo = srcR_lo; 1013 return i; 1014 } 1015 PPCInstr* PPCInstr_DfpShift128 ( PPCFpOp op, HReg dst_hi, HReg dst_lo, 1016 HReg src_hi, HReg src_lo, 1017 PPCRI* shift ) { 1018 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1019 i->tag = Pin_DfpShift128; 1020 i->Pin.DfpShift128.op = op; 1021 i->Pin.DfpShift128.shift = shift; 1022 i->Pin.DfpShift128.src_hi = src_hi; 1023 i->Pin.DfpShift128.src_lo = src_lo; 1024 i->Pin.DfpShift128.dst_hi = dst_hi; 1025 i->Pin.DfpShift128.dst_lo = dst_lo; 1026 return i; 1027 } 1028 PPCInstr* PPCInstr_DfpRound ( HReg dst, HReg src, PPCRI* r_rmc ) { 1029 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1030 i->tag = Pin_DfpRound; 1031 i->Pin.DfpRound.dst = dst; 1032 i->Pin.DfpRound.src = src; 1033 i->Pin.DfpRound.r_rmc = r_rmc; 1034 return i; 1035 } 1036 PPCInstr* PPCInstr_DfpRound128 ( HReg dst_hi, HReg dst_lo, HReg src_hi, 1037 HReg src_lo, PPCRI* r_rmc ) { 1038 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1039 i->tag = Pin_DfpRound128; 1040 i->Pin.DfpRound128.dst_hi = dst_hi; 1041 i->Pin.DfpRound128.dst_lo = dst_lo; 1042 i->Pin.DfpRound128.src_hi = src_hi; 1043 i->Pin.DfpRound128.src_lo = src_lo; 1044 i->Pin.DfpRound128.r_rmc = r_rmc; 1045 return i; 1046 } 1047 PPCInstr* PPCInstr_DfpQuantize ( PPCFpOp op, HReg dst, HReg srcL, HReg srcR, 1048 PPCRI* rmc ) { 1049 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1050 i->tag = Pin_DfpQuantize; 1051 i->Pin.DfpQuantize.op = op; 1052 i->Pin.DfpQuantize.dst = dst; 1053 i->Pin.DfpQuantize.srcL = srcL; 1054 i->Pin.DfpQuantize.srcR = srcR; 1055 i->Pin.DfpQuantize.rmc = rmc; 1056 return i; 1057 } 1058 PPCInstr* PPCInstr_DfpQuantize128 ( PPCFpOp op, HReg dst_hi, HReg dst_lo, 1059 HReg src_hi, HReg src_lo, PPCRI* rmc ) { 1060 /* dst is used to pass left operand in and return result */ 1061 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1062 i->tag = Pin_DfpQuantize128; 1063 i->Pin.DfpQuantize128.op = op; 1064 i->Pin.DfpQuantize128.dst_hi = dst_hi; 1065 i->Pin.DfpQuantize128.dst_lo = dst_lo; 1066 i->Pin.DfpQuantize128.src_hi = src_hi; 1067 i->Pin.DfpQuantize128.src_lo = src_lo; 1068 i->Pin.DfpQuantize128.rmc = rmc; 1069 return i; 1070 } 1071 PPCInstr* PPCInstr_DfpD128toD64 ( PPCFpOp op, HReg dst, 1072 HReg src_hi, HReg src_lo ) { 1073 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1074 i->tag = Pin_DfpD128toD64; 1075 i->Pin.DfpD128toD64.op = op; 1076 i->Pin.DfpD128toD64.src_hi = src_hi; 1077 i->Pin.DfpD128toD64.src_lo = src_lo; 1078 i->Pin.DfpD128toD64.dst = dst; 1079 return i; 1080 } 1081 PPCInstr* PPCInstr_DfpI64StoD128 ( PPCFpOp op, HReg dst_hi, 1082 HReg dst_lo, HReg src ) { 1083 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1084 i->tag = Pin_DfpI64StoD128; 1085 i->Pin.DfpI64StoD128.op = op; 1086 i->Pin.DfpI64StoD128.src = src; 1087 i->Pin.DfpI64StoD128.dst_hi = dst_hi; 1088 i->Pin.DfpI64StoD128.dst_lo = dst_lo; 1089 return i; 1090 } 1091 PPCInstr* PPCInstr_ExtractExpD128 ( PPCFpOp op, HReg dst, 1092 HReg src_hi, HReg src_lo ) { 1093 /* dst is used to pass the srcL argument */ 1094 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1095 i->tag = Pin_ExtractExpD128; 1096 i->Pin.ExtractExpD128.op = op; 1097 i->Pin.ExtractExpD128.dst = dst; 1098 i->Pin.ExtractExpD128.src_hi = src_hi; 1099 i->Pin.ExtractExpD128.src_lo = src_lo; 1100 return i; 1101 } 1102 PPCInstr* PPCInstr_InsertExpD128 ( PPCFpOp op, HReg dst_hi, HReg dst_lo, 1103 HReg srcL, HReg srcR_hi, HReg srcR_lo ) { 1104 /* dst is used to pass the srcL argument */ 1105 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1106 i->tag = Pin_InsertExpD128; 1107 i->Pin.InsertExpD128.op = op; 1108 i->Pin.InsertExpD128.dst_hi = dst_hi; 1109 i->Pin.InsertExpD128.dst_lo = dst_lo; 1110 i->Pin.InsertExpD128.srcL = srcL; 1111 i->Pin.InsertExpD128.srcR_hi = srcR_hi; 1112 i->Pin.InsertExpD128.srcR_lo = srcR_lo; 1113 return i; 1114 } 1115 PPCInstr* PPCInstr_Dfp64Cmp (/* UInt crfD,*/ HReg dst, HReg srcL, HReg srcR ) { 1116 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1117 i->tag = Pin_Dfp64Cmp; 1118 i->Pin.Dfp64Cmp.dst = dst; 1119 i->Pin.Dfp64Cmp.srcL = srcL; 1120 i->Pin.Dfp64Cmp.srcR = srcR; 1121 return i; 1122 } 1123 PPCInstr* PPCInstr_Dfp128Cmp ( HReg dst, HReg srcL_hi, HReg srcL_lo, 1124 HReg srcR_hi, HReg srcR_lo ) { 1125 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1126 i->tag = Pin_Dfp128Cmp; 1127 i->Pin.Dfp128Cmp.dst = dst; 1128 i->Pin.Dfp128Cmp.srcL_hi = srcL_hi; 1129 i->Pin.Dfp128Cmp.srcL_lo = srcL_lo; 1130 i->Pin.Dfp128Cmp.srcR_hi = srcR_hi; 1131 i->Pin.Dfp128Cmp.srcR_lo = srcR_lo; 1132 return i; 1133 } 1134 PPCInstr* PPCInstr_EvCheck ( PPCAMode* amCounter, 1135 PPCAMode* amFailAddr ) { 1136 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1137 i->tag = Pin_EvCheck; 1138 i->Pin.EvCheck.amCounter = amCounter; 1139 i->Pin.EvCheck.amFailAddr = amFailAddr; 1140 return i; 1141 } 1142 PPCInstr* PPCInstr_ProfInc ( void ) { 1143 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1144 i->tag = Pin_ProfInc; 1145 return i; 1146 } 1147 1148 /* 1149 Valid combo | fromI | int32 | syned | flt64 | 1150 -------------------------------------------- 1151 | n n n n | 1152 -------------------------------------------- 1153 F64->I64U | n n n y | 1154 -------------------------------------------- 1155 | n n y n | 1156 -------------------------------------------- 1157 F64->I64S | n n y y | 1158 -------------------------------------------- 1159 | n y n n | 1160 -------------------------------------------- 1161 F64->I32U | n y n y | 1162 -------------------------------------------- 1163 | n y y n | 1164 -------------------------------------------- 1165 F64->I32S | n y y y | 1166 -------------------------------------------- 1167 I64U->F32 | y n n n | 1168 -------------------------------------------- 1169 I64U->F64 | y n n y | 1170 -------------------------------------------- 1171 | y n y n | 1172 -------------------------------------------- 1173 I64S->F64 | y n y y | 1174 -------------------------------------------- 1175 | y y n n | 1176 -------------------------------------------- 1177 | y y n y | 1178 -------------------------------------------- 1179 | y y y n | 1180 -------------------------------------------- 1181 | y y y y | 1182 -------------------------------------------- 1183 */ 1184 PPCInstr* PPCInstr_FpCftI ( Bool fromI, Bool int32, Bool syned, 1185 Bool flt64, HReg dst, HReg src ) { 1186 Bool tmp = fromI | int32 | syned | flt64; 1187 vassert(tmp == True || tmp == False); // iow, no high bits set 1188 UShort conversion = 0; 1189 conversion = (fromI << 3) | (int32 << 2) | (syned << 1) | flt64; 1190 switch (conversion) { 1191 // Supported conversion operations 1192 case 1: case 3: case 5: case 7: 1193 case 8: case 9: case 11: 1194 break; 1195 default: 1196 vpanic("PPCInstr_FpCftI(ppc_host)"); 1197 } 1198 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1199 i->tag = Pin_FpCftI; 1200 i->Pin.FpCftI.fromI = fromI; 1201 i->Pin.FpCftI.int32 = int32; 1202 i->Pin.FpCftI.syned = syned; 1203 i->Pin.FpCftI.flt64 = flt64; 1204 i->Pin.FpCftI.dst = dst; 1205 i->Pin.FpCftI.src = src; 1206 return i; 1207 } 1208 PPCInstr* PPCInstr_FpCMov ( PPCCondCode cond, HReg dst, HReg src ) { 1209 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1210 i->tag = Pin_FpCMov; 1211 i->Pin.FpCMov.cond = cond; 1212 i->Pin.FpCMov.dst = dst; 1213 i->Pin.FpCMov.src = src; 1214 vassert(cond.test != Pct_ALWAYS); 1215 return i; 1216 } 1217 PPCInstr* PPCInstr_FpLdFPSCR ( HReg src, Bool dfp_rm ) { 1218 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1219 i->tag = Pin_FpLdFPSCR; 1220 i->Pin.FpLdFPSCR.src = src; 1221 i->Pin.FpLdFPSCR.dfp_rm = dfp_rm ? 1 : 0; 1222 return i; 1223 } 1224 PPCInstr* PPCInstr_FpCmp ( HReg dst, HReg srcL, HReg srcR ) { 1225 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1226 i->tag = Pin_FpCmp; 1227 i->Pin.FpCmp.dst = dst; 1228 i->Pin.FpCmp.srcL = srcL; 1229 i->Pin.FpCmp.srcR = srcR; 1230 return i; 1231 } 1232 1233 /* Read/Write Link Register */ 1234 PPCInstr* PPCInstr_RdWrLR ( Bool wrLR, HReg gpr ) { 1235 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1236 i->tag = Pin_RdWrLR; 1237 i->Pin.RdWrLR.wrLR = wrLR; 1238 i->Pin.RdWrLR.gpr = gpr; 1239 return i; 1240 } 1241 1242 /* AltiVec */ 1243 PPCInstr* PPCInstr_AvLdSt ( Bool isLoad, UChar sz, 1244 HReg reg, PPCAMode* addr ) { 1245 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1246 i->tag = Pin_AvLdSt; 1247 i->Pin.AvLdSt.isLoad = isLoad; 1248 i->Pin.AvLdSt.sz = sz; 1249 i->Pin.AvLdSt.reg = reg; 1250 i->Pin.AvLdSt.addr = addr; 1251 return i; 1252 } 1253 PPCInstr* PPCInstr_AvUnary ( PPCAvOp op, HReg dst, HReg src ) { 1254 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1255 i->tag = Pin_AvUnary; 1256 i->Pin.AvUnary.op = op; 1257 i->Pin.AvUnary.dst = dst; 1258 i->Pin.AvUnary.src = src; 1259 return i; 1260 } 1261 PPCInstr* PPCInstr_AvBinary ( PPCAvOp op, HReg dst, 1262 HReg srcL, HReg srcR ) { 1263 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1264 i->tag = Pin_AvBinary; 1265 i->Pin.AvBinary.op = op; 1266 i->Pin.AvBinary.dst = dst; 1267 i->Pin.AvBinary.srcL = srcL; 1268 i->Pin.AvBinary.srcR = srcR; 1269 return i; 1270 } 1271 PPCInstr* PPCInstr_AvBin8x16 ( PPCAvOp op, HReg dst, 1272 HReg srcL, HReg srcR ) { 1273 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1274 i->tag = Pin_AvBin8x16; 1275 i->Pin.AvBin8x16.op = op; 1276 i->Pin.AvBin8x16.dst = dst; 1277 i->Pin.AvBin8x16.srcL = srcL; 1278 i->Pin.AvBin8x16.srcR = srcR; 1279 return i; 1280 } 1281 PPCInstr* PPCInstr_AvBin16x8 ( PPCAvOp op, HReg dst, 1282 HReg srcL, HReg srcR ) { 1283 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1284 i->tag = Pin_AvBin16x8; 1285 i->Pin.AvBin16x8.op = op; 1286 i->Pin.AvBin16x8.dst = dst; 1287 i->Pin.AvBin16x8.srcL = srcL; 1288 i->Pin.AvBin16x8.srcR = srcR; 1289 return i; 1290 } 1291 PPCInstr* PPCInstr_AvBin32x4 ( PPCAvOp op, HReg dst, 1292 HReg srcL, HReg srcR ) { 1293 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1294 i->tag = Pin_AvBin32x4; 1295 i->Pin.AvBin32x4.op = op; 1296 i->Pin.AvBin32x4.dst = dst; 1297 i->Pin.AvBin32x4.srcL = srcL; 1298 i->Pin.AvBin32x4.srcR = srcR; 1299 return i; 1300 } 1301 PPCInstr* PPCInstr_AvBin64x2 ( PPCAvOp op, HReg dst, 1302 HReg srcL, HReg srcR ) { 1303 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1304 i->tag = Pin_AvBin64x2; 1305 i->Pin.AvBin64x2.op = op; 1306 i->Pin.AvBin64x2.dst = dst; 1307 i->Pin.AvBin64x2.srcL = srcL; 1308 i->Pin.AvBin64x2.srcR = srcR; 1309 return i; 1310 } 1311 1312 PPCInstr* PPCInstr_AvBin32Fx4 ( PPCAvFpOp op, HReg dst, 1313 HReg srcL, HReg srcR ) { 1314 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1315 i->tag = Pin_AvBin32Fx4; 1316 i->Pin.AvBin32Fx4.op = op; 1317 i->Pin.AvBin32Fx4.dst = dst; 1318 i->Pin.AvBin32Fx4.srcL = srcL; 1319 i->Pin.AvBin32Fx4.srcR = srcR; 1320 return i; 1321 } 1322 PPCInstr* PPCInstr_AvUn32Fx4 ( PPCAvFpOp op, HReg dst, HReg src ) { 1323 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1324 i->tag = Pin_AvUn32Fx4; 1325 i->Pin.AvUn32Fx4.op = op; 1326 i->Pin.AvUn32Fx4.dst = dst; 1327 i->Pin.AvUn32Fx4.src = src; 1328 return i; 1329 } 1330 PPCInstr* PPCInstr_AvPerm ( HReg dst, HReg srcL, HReg srcR, HReg ctl ) { 1331 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1332 i->tag = Pin_AvPerm; 1333 i->Pin.AvPerm.dst = dst; 1334 i->Pin.AvPerm.srcL = srcL; 1335 i->Pin.AvPerm.srcR = srcR; 1336 i->Pin.AvPerm.ctl = ctl; 1337 return i; 1338 } 1339 1340 PPCInstr* PPCInstr_AvSel ( HReg ctl, HReg dst, HReg srcL, HReg srcR ) { 1341 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1342 i->tag = Pin_AvSel; 1343 i->Pin.AvSel.ctl = ctl; 1344 i->Pin.AvSel.dst = dst; 1345 i->Pin.AvSel.srcL = srcL; 1346 i->Pin.AvSel.srcR = srcR; 1347 return i; 1348 } 1349 PPCInstr* PPCInstr_AvSh ( Bool shLeft, HReg dst, PPCAMode* addr ) { 1350 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1351 i->tag = Pin_AvSh; 1352 i->Pin.AvSh.shLeft = shLeft; 1353 i->Pin.AvSh.dst = dst; 1354 i->Pin.AvSh.addr = addr; 1355 return i; 1356 } 1357 PPCInstr* PPCInstr_AvShlDbl ( UChar shift, HReg dst, 1358 HReg srcL, HReg srcR ) { 1359 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1360 i->tag = Pin_AvShlDbl; 1361 i->Pin.AvShlDbl.shift = shift; 1362 i->Pin.AvShlDbl.dst = dst; 1363 i->Pin.AvShlDbl.srcL = srcL; 1364 i->Pin.AvShlDbl.srcR = srcR; 1365 return i; 1366 } 1367 PPCInstr* PPCInstr_AvSplat ( UChar sz, HReg dst, PPCVI5s* src ) { 1368 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1369 i->tag = Pin_AvSplat; 1370 i->Pin.AvSplat.sz = sz; 1371 i->Pin.AvSplat.dst = dst; 1372 i->Pin.AvSplat.src = src; 1373 return i; 1374 } 1375 PPCInstr* PPCInstr_AvCMov ( PPCCondCode cond, HReg dst, HReg src ) { 1376 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1377 i->tag = Pin_AvCMov; 1378 i->Pin.AvCMov.cond = cond; 1379 i->Pin.AvCMov.dst = dst; 1380 i->Pin.AvCMov.src = src; 1381 vassert(cond.test != Pct_ALWAYS); 1382 return i; 1383 } 1384 PPCInstr* PPCInstr_AvLdVSCR ( HReg src ) { 1385 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1386 i->tag = Pin_AvLdVSCR; 1387 i->Pin.AvLdVSCR.src = src; 1388 return i; 1389 } 1390 PPCInstr* PPCInstr_AvCipherV128Unary ( PPCAvOp op, HReg dst, HReg src ) { 1391 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1392 i->tag = Pin_AvCipherV128Unary; 1393 i->Pin.AvCipherV128Unary.op = op; 1394 i->Pin.AvCipherV128Unary.dst = dst; 1395 i->Pin.AvCipherV128Unary.src = src; 1396 return i; 1397 } 1398 PPCInstr* PPCInstr_AvCipherV128Binary ( PPCAvOp op, HReg dst, 1399 HReg srcL, HReg srcR ) { 1400 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1401 i->tag = Pin_AvCipherV128Binary; 1402 i->Pin.AvCipherV128Binary.op = op; 1403 i->Pin.AvCipherV128Binary.dst = dst; 1404 i->Pin.AvCipherV128Binary.srcL = srcL; 1405 i->Pin.AvCipherV128Binary.srcR = srcR; 1406 return i; 1407 } 1408 PPCInstr* PPCInstr_AvHashV128Binary ( PPCAvOp op, HReg dst, 1409 HReg src, PPCRI* s_field ) { 1410 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1411 i->tag = Pin_AvHashV128Binary; 1412 i->Pin.AvHashV128Binary.op = op; 1413 i->Pin.AvHashV128Binary.dst = dst; 1414 i->Pin.AvHashV128Binary.src = src; 1415 i->Pin.AvHashV128Binary.s_field = s_field; 1416 return i; 1417 } 1418 PPCInstr* PPCInstr_AvBCDV128Trinary ( PPCAvOp op, HReg dst, 1419 HReg src1, HReg src2, PPCRI* ps ) { 1420 PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr)); 1421 i->tag = Pin_AvBCDV128Trinary; 1422 i->Pin.AvBCDV128Trinary.op = op; 1423 i->Pin.AvBCDV128Trinary.dst = dst; 1424 i->Pin.AvBCDV128Trinary.src1 = src1; 1425 i->Pin.AvBCDV128Trinary.src2 = src2; 1426 i->Pin.AvBCDV128Trinary.ps = ps; 1427 return i; 1428 } 1429 1430 1431 /* Pretty Print instructions */ 1432 static void ppLoadImm ( HReg dst, ULong imm, Bool mode64 ) { 1433 vex_printf("li_word "); 1434 ppHRegPPC(dst); 1435 if (!mode64) { 1436 vex_printf(",0x%08x", (UInt)imm); 1437 } else { 1438 vex_printf(",0x%016llx", imm); 1439 } 1440 } 1441 1442 static void ppMovReg ( HReg dst, HReg src ) { 1443 if (!sameHReg(dst, src)) { 1444 vex_printf("mr "); 1445 ppHRegPPC(dst); 1446 vex_printf(","); 1447 ppHRegPPC(src); 1448 } 1449 } 1450 1451 void ppPPCInstr ( const PPCInstr* i, Bool mode64 ) 1452 { 1453 switch (i->tag) { 1454 case Pin_LI: 1455 ppLoadImm(i->Pin.LI.dst, i->Pin.LI.imm64, mode64); 1456 break; 1457 case Pin_Alu: { 1458 HReg r_srcL = i->Pin.Alu.srcL; 1459 PPCRH* rh_srcR = i->Pin.Alu.srcR; 1460 /* special-case "mr" */ 1461 if (i->Pin.Alu.op == Palu_OR && // or Rd,Rs,Rs == mr Rd,Rs 1462 rh_srcR->tag == Prh_Reg && 1463 sameHReg(rh_srcR->Prh.Reg.reg, r_srcL)) { 1464 vex_printf("mr "); 1465 ppHRegPPC(i->Pin.Alu.dst); 1466 vex_printf(","); 1467 ppHRegPPC(r_srcL); 1468 return; 1469 } 1470 /* special-case "li" */ 1471 if (i->Pin.Alu.op == Palu_ADD && // addi Rd,0,imm == li Rd,imm 1472 rh_srcR->tag == Prh_Imm && 1473 hregEncoding(r_srcL) == 0) { 1474 vex_printf("li "); 1475 ppHRegPPC(i->Pin.Alu.dst); 1476 vex_printf(","); 1477 ppPPCRH(rh_srcR); 1478 return; 1479 } 1480 /* generic */ 1481 vex_printf("%s ", showPPCAluOp(i->Pin.Alu.op, 1482 toBool(rh_srcR->tag == Prh_Imm))); 1483 ppHRegPPC(i->Pin.Alu.dst); 1484 vex_printf(","); 1485 ppHRegPPC(r_srcL); 1486 vex_printf(","); 1487 ppPPCRH(rh_srcR); 1488 return; 1489 } 1490 case Pin_Shft: { 1491 HReg r_srcL = i->Pin.Shft.srcL; 1492 PPCRH* rh_srcR = i->Pin.Shft.srcR; 1493 vex_printf("%s ", showPPCShftOp(i->Pin.Shft.op, 1494 toBool(rh_srcR->tag == Prh_Imm), 1495 i->Pin.Shft.sz32)); 1496 ppHRegPPC(i->Pin.Shft.dst); 1497 vex_printf(","); 1498 ppHRegPPC(r_srcL); 1499 vex_printf(","); 1500 ppPPCRH(rh_srcR); 1501 return; 1502 } 1503 case Pin_AddSubC: 1504 vex_printf("%s%s ", 1505 i->Pin.AddSubC.isAdd ? "add" : "sub", 1506 i->Pin.AddSubC.setC ? "c" : "e"); 1507 ppHRegPPC(i->Pin.AddSubC.dst); 1508 vex_printf(","); 1509 ppHRegPPC(i->Pin.AddSubC.srcL); 1510 vex_printf(","); 1511 ppHRegPPC(i->Pin.AddSubC.srcR); 1512 return; 1513 case Pin_Cmp: 1514 vex_printf("%s%c%s %%cr%u,", 1515 i->Pin.Cmp.syned ? "cmp" : "cmpl", 1516 i->Pin.Cmp.sz32 ? 'w' : 'd', 1517 i->Pin.Cmp.srcR->tag == Prh_Imm ? "i" : "", 1518 i->Pin.Cmp.crfD); 1519 ppHRegPPC(i->Pin.Cmp.srcL); 1520 vex_printf(","); 1521 ppPPCRH(i->Pin.Cmp.srcR); 1522 return; 1523 case Pin_Unary: 1524 vex_printf("%s ", showPPCUnaryOp(i->Pin.Unary.op)); 1525 ppHRegPPC(i->Pin.Unary.dst); 1526 vex_printf(","); 1527 ppHRegPPC(i->Pin.Unary.src); 1528 return; 1529 case Pin_MulL: 1530 vex_printf("mul%c%c%s ", 1531 i->Pin.MulL.hi ? 'h' : 'l', 1532 i->Pin.MulL.sz32 ? 'w' : 'd', 1533 i->Pin.MulL.hi ? (i->Pin.MulL.syned ? "s" : "u") : ""); 1534 ppHRegPPC(i->Pin.MulL.dst); 1535 vex_printf(","); 1536 ppHRegPPC(i->Pin.MulL.srcL); 1537 vex_printf(","); 1538 ppHRegPPC(i->Pin.MulL.srcR); 1539 return; 1540 case Pin_Div: 1541 vex_printf("div%c%s%s ", 1542 i->Pin.Div.sz32 ? 'w' : 'd', 1543 i->Pin.Div.extended ? "e" : "", 1544 i->Pin.Div.syned ? "" : "u"); 1545 ppHRegPPC(i->Pin.Div.dst); 1546 vex_printf(","); 1547 ppHRegPPC(i->Pin.Div.srcL); 1548 vex_printf(","); 1549 ppHRegPPC(i->Pin.Div.srcR); 1550 return; 1551 case Pin_Call: { 1552 Int n; 1553 vex_printf("call: "); 1554 if (i->Pin.Call.cond.test != Pct_ALWAYS) { 1555 vex_printf("if (%s) ", showPPCCondCode(i->Pin.Call.cond)); 1556 } 1557 vex_printf("{ "); 1558 ppLoadImm(hregPPC_GPR10(mode64), i->Pin.Call.target, mode64); 1559 vex_printf(" ; mtctr r10 ; bctrl ["); 1560 for (n = 0; n < 32; n++) { 1561 if (i->Pin.Call.argiregs & (1<<n)) { 1562 vex_printf("r%d", n); 1563 if ((i->Pin.Call.argiregs >> n) > 1) 1564 vex_printf(","); 1565 } 1566 } 1567 vex_printf(","); 1568 ppRetLoc(i->Pin.Call.rloc); 1569 vex_printf("] }"); 1570 break; 1571 } 1572 case Pin_XDirect: 1573 vex_printf("(xDirect) "); 1574 vex_printf("if (%s) { ", 1575 showPPCCondCode(i->Pin.XDirect.cond)); 1576 if (mode64) { 1577 vex_printf("imm64 r30,0x%llx; ", i->Pin.XDirect.dstGA); 1578 vex_printf("std r30,"); 1579 } else { 1580 vex_printf("imm32 r30,0x%llx; ", i->Pin.XDirect.dstGA); 1581 vex_printf("stw r30,"); 1582 } 1583 ppPPCAMode(i->Pin.XDirect.amCIA); 1584 vex_printf("; "); 1585 if (mode64) { 1586 vex_printf("imm64-fixed5 r30,$disp_cp_chain_me_to_%sEP; ", 1587 i->Pin.XDirect.toFastEP ? "fast" : "slow"); 1588 } else { 1589 vex_printf("imm32-fixed2 r30,$disp_cp_chain_me_to_%sEP; ", 1590 i->Pin.XDirect.toFastEP ? "fast" : "slow"); 1591 } 1592 vex_printf("mtctr r30; bctrl }"); 1593 return; 1594 case Pin_XIndir: 1595 vex_printf("(xIndir) "); 1596 vex_printf("if (%s) { ", 1597 showPPCCondCode(i->Pin.XIndir.cond)); 1598 vex_printf("%s ", mode64 ? "std" : "stw"); 1599 ppHRegPPC(i->Pin.XIndir.dstGA); 1600 vex_printf(","); 1601 ppPPCAMode(i->Pin.XIndir.amCIA); 1602 vex_printf("; "); 1603 vex_printf("imm%s r30,$disp_cp_xindir; ", mode64 ? "64" : "32"); 1604 vex_printf("mtctr r30; bctr }"); 1605 return; 1606 case Pin_XAssisted: 1607 vex_printf("(xAssisted) "); 1608 vex_printf("if (%s) { ", 1609 showPPCCondCode(i->Pin.XAssisted.cond)); 1610 vex_printf("%s ", mode64 ? "std" : "stw"); 1611 ppHRegPPC(i->Pin.XAssisted.dstGA); 1612 vex_printf(","); 1613 ppPPCAMode(i->Pin.XAssisted.amCIA); 1614 vex_printf("; "); 1615 vex_printf("li r31,$IRJumpKind_to_TRCVAL(%d); ", 1616 (Int)i->Pin.XAssisted.jk); 1617 vex_printf("imm%s r30,$disp_cp_xindir; ", mode64 ? "64" : "32"); 1618 vex_printf("mtctr r30; bctr }"); 1619 return; 1620 case Pin_CMov: 1621 vex_printf("cmov (%s) ", showPPCCondCode(i->Pin.CMov.cond)); 1622 ppHRegPPC(i->Pin.CMov.dst); 1623 vex_printf(","); 1624 ppPPCRI(i->Pin.CMov.src); 1625 vex_printf(": "); 1626 if (i->Pin.CMov.cond.test != Pct_ALWAYS) { 1627 vex_printf("if (%s) ", showPPCCondCode(i->Pin.CMov.cond)); 1628 } 1629 vex_printf("{ "); 1630 if (i->Pin.CMov.src->tag == Pri_Imm) { 1631 ppLoadImm(i->Pin.CMov.dst, i->Pin.CMov.src->Pri.Imm, mode64); 1632 } else { 1633 ppMovReg(i->Pin.CMov.dst, i->Pin.CMov.src->Pri.Reg); 1634 } 1635 vex_printf(" }"); 1636 return; 1637 case Pin_Load: { 1638 Bool idxd = toBool(i->Pin.Load.src->tag == Pam_RR); 1639 UChar sz = i->Pin.Load.sz; 1640 HChar c_sz = sz==1 ? 'b' : sz==2 ? 'h' : sz==4 ? 'w' : 'd'; 1641 vex_printf("l%c%s%s ", c_sz, sz==8 ? "" : "z", idxd ? "x" : "" ); 1642 ppHRegPPC(i->Pin.Load.dst); 1643 vex_printf(","); 1644 ppPPCAMode(i->Pin.Load.src); 1645 return; 1646 } 1647 case Pin_LoadL: { 1648 UChar sz = i->Pin.LoadL.sz; 1649 HChar c_sz = sz==1 ? 'b' : sz==2 ? 'h' : sz==4 ? 'w' : 'd'; 1650 vex_printf("l%carx ", c_sz); 1651 ppHRegPPC(i->Pin.LoadL.dst); 1652 vex_printf(",%%r0,"); 1653 ppHRegPPC(i->Pin.LoadL.src); 1654 return; 1655 } 1656 case Pin_Store: { 1657 UChar sz = i->Pin.Store.sz; 1658 Bool idxd = toBool(i->Pin.Store.dst->tag == Pam_RR); 1659 HChar c_sz = sz==1 ? 'b' : sz==2 ? 'h' : sz==4 ? 'w' : /*8*/ 'd'; 1660 vex_printf("st%c%s ", c_sz, idxd ? "x" : "" ); 1661 ppHRegPPC(i->Pin.Store.src); 1662 vex_printf(","); 1663 ppPPCAMode(i->Pin.Store.dst); 1664 return; 1665 } 1666 case Pin_StoreC: { 1667 UChar sz = i->Pin.StoreC.sz; 1668 HChar c_sz = sz==1 ? 'b' : sz==2 ? 'h' : sz==4 ? 'w' : 'd'; 1669 vex_printf("st%ccx. ", c_sz); 1670 ppHRegPPC(i->Pin.StoreC.src); 1671 vex_printf(",%%r0,"); 1672 ppHRegPPC(i->Pin.StoreC.dst); 1673 return; 1674 } 1675 case Pin_Set: { 1676 PPCCondCode cc = i->Pin.Set.cond; 1677 vex_printf("set (%s),", showPPCCondCode(cc)); 1678 ppHRegPPC(i->Pin.Set.dst); 1679 if (cc.test == Pct_ALWAYS) { 1680 vex_printf(": { li "); 1681 ppHRegPPC(i->Pin.Set.dst); 1682 vex_printf(",1 }"); 1683 } else { 1684 vex_printf(": { mfcr r0 ; rlwinm "); 1685 ppHRegPPC(i->Pin.Set.dst); 1686 vex_printf(",r0,%u,31,31", cc.flag+1); 1687 if (cc.test == Pct_FALSE) { 1688 vex_printf("; xori "); 1689 ppHRegPPC(i->Pin.Set.dst); 1690 vex_printf(","); 1691 ppHRegPPC(i->Pin.Set.dst); 1692 vex_printf(",1"); 1693 } 1694 vex_printf(" }"); 1695 } 1696 return; 1697 } 1698 case Pin_MfCR: 1699 vex_printf("mfcr "); 1700 ppHRegPPC(i->Pin.MfCR.dst); 1701 break; 1702 case Pin_MFence: 1703 vex_printf("mfence (=sync)"); 1704 return; 1705 1706 case Pin_FpUnary: 1707 vex_printf("%s ", showPPCFpOp(i->Pin.FpUnary.op)); 1708 ppHRegPPC(i->Pin.FpUnary.dst); 1709 vex_printf(","); 1710 ppHRegPPC(i->Pin.FpUnary.src); 1711 return; 1712 case Pin_FpBinary: 1713 vex_printf("%s ", showPPCFpOp(i->Pin.FpBinary.op)); 1714 ppHRegPPC(i->Pin.FpBinary.dst); 1715 vex_printf(","); 1716 ppHRegPPC(i->Pin.FpBinary.srcL); 1717 vex_printf(","); 1718 ppHRegPPC(i->Pin.FpBinary.srcR); 1719 return; 1720 case Pin_FpMulAcc: 1721 vex_printf("%s ", showPPCFpOp(i->Pin.FpMulAcc.op)); 1722 ppHRegPPC(i->Pin.FpMulAcc.dst); 1723 vex_printf(","); 1724 ppHRegPPC(i->Pin.FpMulAcc.srcML); 1725 vex_printf(","); 1726 ppHRegPPC(i->Pin.FpMulAcc.srcMR); 1727 vex_printf(","); 1728 ppHRegPPC(i->Pin.FpMulAcc.srcAcc); 1729 return; 1730 case Pin_FpLdSt: { 1731 UChar sz = i->Pin.FpLdSt.sz; 1732 Bool idxd = toBool(i->Pin.FpLdSt.addr->tag == Pam_RR); 1733 if (i->Pin.FpLdSt.isLoad) { 1734 vex_printf("lf%c%s ", 1735 (sz==4 ? 's' : 'd'), 1736 idxd ? "x" : "" ); 1737 ppHRegPPC(i->Pin.FpLdSt.reg); 1738 vex_printf(","); 1739 ppPPCAMode(i->Pin.FpLdSt.addr); 1740 } else { 1741 vex_printf("stf%c%s ", 1742 (sz==4 ? 's' : 'd'), 1743 idxd ? "x" : "" ); 1744 ppHRegPPC(i->Pin.FpLdSt.reg); 1745 vex_printf(","); 1746 ppPPCAMode(i->Pin.FpLdSt.addr); 1747 } 1748 return; 1749 } 1750 case Pin_FpSTFIW: 1751 vex_printf("stfiwz "); 1752 ppHRegPPC(i->Pin.FpSTFIW.data); 1753 vex_printf(",0("); 1754 ppHRegPPC(i->Pin.FpSTFIW.addr); 1755 vex_printf(")"); 1756 return; 1757 case Pin_FpRSP: 1758 vex_printf("frsp "); 1759 ppHRegPPC(i->Pin.FpRSP.dst); 1760 vex_printf(","); 1761 ppHRegPPC(i->Pin.FpRSP.src); 1762 return; 1763 case Pin_FpCftI: { 1764 const HChar* str = "fc?????"; 1765 /* Note that "fcfids" is missing from below. That instruction would 1766 * satisfy the predicate: 1767 * (i->Pin.FpCftI.fromI == True && i->Pin.FpCftI.int32 == False) 1768 * which would go into a final "else" clause to make this if-else 1769 * block balanced. But we're able to implement fcfids by leveraging 1770 * the fcfid implementation, so it wasn't necessary to include it here. 1771 */ 1772 if (i->Pin.FpCftI.fromI == False && i->Pin.FpCftI.int32 == False) 1773 if (i->Pin.FpCftI.syned == True) 1774 str = "fctid"; 1775 else 1776 str = "fctidu"; 1777 else if (i->Pin.FpCftI.fromI == False && i->Pin.FpCftI.int32 == True) 1778 if (i->Pin.FpCftI.syned == True) 1779 str = "fctiw"; 1780 else 1781 str = "fctiwu"; 1782 else if (i->Pin.FpCftI.fromI == True && i->Pin.FpCftI.int32 == False) { 1783 if (i->Pin.FpCftI.syned == True) { 1784 str = "fcfid"; 1785 } else { 1786 if (i->Pin.FpCftI.flt64 == True) 1787 str = "fcfidu"; 1788 else 1789 str = "fcfidus"; 1790 } 1791 } 1792 vex_printf("%s ", str); 1793 ppHRegPPC(i->Pin.FpCftI.dst); 1794 vex_printf(","); 1795 ppHRegPPC(i->Pin.FpCftI.src); 1796 return; 1797 } 1798 case Pin_FpCMov: 1799 vex_printf("fpcmov (%s) ", showPPCCondCode(i->Pin.FpCMov.cond)); 1800 ppHRegPPC(i->Pin.FpCMov.dst); 1801 vex_printf(","); 1802 ppHRegPPC(i->Pin.FpCMov.src); 1803 vex_printf(": "); 1804 vex_printf("if (fr_dst != fr_src) { "); 1805 if (i->Pin.FpCMov.cond.test != Pct_ALWAYS) { 1806 vex_printf("if (%s) { ", showPPCCondCode(i->Pin.FpCMov.cond)); 1807 } 1808 vex_printf("fmr "); 1809 ppHRegPPC(i->Pin.FpCMov.dst); 1810 vex_printf(","); 1811 ppHRegPPC(i->Pin.FpCMov.src); 1812 if (i->Pin.FpCMov.cond.test != Pct_ALWAYS) 1813 vex_printf(" }"); 1814 vex_printf(" }"); 1815 return; 1816 case Pin_FpLdFPSCR: 1817 vex_printf("mtfsf 0xFF,"); 1818 ppHRegPPC(i->Pin.FpLdFPSCR.src); 1819 vex_printf(",0, %s", i->Pin.FpLdFPSCR.dfp_rm ? "1" : "0"); 1820 return; 1821 case Pin_FpCmp: 1822 vex_printf("fcmpo %%cr1,"); 1823 ppHRegPPC(i->Pin.FpCmp.srcL); 1824 vex_printf(","); 1825 ppHRegPPC(i->Pin.FpCmp.srcR); 1826 vex_printf("; mfcr "); 1827 ppHRegPPC(i->Pin.FpCmp.dst); 1828 vex_printf("; rlwinm "); 1829 ppHRegPPC(i->Pin.FpCmp.dst); 1830 vex_printf(","); 1831 ppHRegPPC(i->Pin.FpCmp.dst); 1832 vex_printf(",8,28,31"); 1833 return; 1834 1835 case Pin_RdWrLR: 1836 vex_printf("%s ", i->Pin.RdWrLR.wrLR ? "mtlr" : "mflr"); 1837 ppHRegPPC(i->Pin.RdWrLR.gpr); 1838 return; 1839 1840 case Pin_AvLdSt: { 1841 UChar sz = i->Pin.AvLdSt.sz; 1842 const HChar* str_size; 1843 if (i->Pin.AvLdSt.addr->tag == Pam_IR) { 1844 ppLoadImm(hregPPC_GPR30(mode64), 1845 i->Pin.AvLdSt.addr->Pam.IR.index, mode64); 1846 vex_printf(" ; "); 1847 } 1848 str_size = sz==1 ? "eb" : sz==2 ? "eh" : sz==4 ? "ew" : ""; 1849 if (i->Pin.AvLdSt.isLoad) 1850 vex_printf("lv%sx ", str_size); 1851 else 1852 vex_printf("stv%sx ", str_size); 1853 ppHRegPPC(i->Pin.AvLdSt.reg); 1854 vex_printf(","); 1855 if (i->Pin.AvLdSt.addr->tag == Pam_IR) 1856 vex_printf("%%r30"); 1857 else 1858 ppHRegPPC(i->Pin.AvLdSt.addr->Pam.RR.index); 1859 vex_printf(","); 1860 ppHRegPPC(i->Pin.AvLdSt.addr->Pam.RR.base); 1861 return; 1862 } 1863 case Pin_AvUnary: 1864 vex_printf("%s ", showPPCAvOp(i->Pin.AvUnary.op)); 1865 ppHRegPPC(i->Pin.AvUnary.dst); 1866 vex_printf(","); 1867 ppHRegPPC(i->Pin.AvUnary.src); 1868 return; 1869 case Pin_AvBinary: 1870 vex_printf("%s ", showPPCAvOp(i->Pin.AvBinary.op)); 1871 ppHRegPPC(i->Pin.AvBinary.dst); 1872 vex_printf(","); 1873 ppHRegPPC(i->Pin.AvBinary.srcL); 1874 vex_printf(","); 1875 ppHRegPPC(i->Pin.AvBinary.srcR); 1876 return; 1877 case Pin_AvBin8x16: 1878 vex_printf("%s(b) ", showPPCAvOp(i->Pin.AvBin8x16.op)); 1879 ppHRegPPC(i->Pin.AvBin8x16.dst); 1880 vex_printf(","); 1881 ppHRegPPC(i->Pin.AvBin8x16.srcL); 1882 vex_printf(","); 1883 ppHRegPPC(i->Pin.AvBin8x16.srcR); 1884 return; 1885 case Pin_AvBin16x8: 1886 vex_printf("%s(h) ", showPPCAvOp(i->Pin.AvBin16x8.op)); 1887 ppHRegPPC(i->Pin.AvBin16x8.dst); 1888 vex_printf(","); 1889 ppHRegPPC(i->Pin.AvBin16x8.srcL); 1890 vex_printf(","); 1891 ppHRegPPC(i->Pin.AvBin16x8.srcR); 1892 return; 1893 case Pin_AvBin32x4: 1894 vex_printf("%s(w) ", showPPCAvOp(i->Pin.AvBin32x4.op)); 1895 ppHRegPPC(i->Pin.AvBin32x4.dst); 1896 vex_printf(","); 1897 ppHRegPPC(i->Pin.AvBin32x4.srcL); 1898 vex_printf(","); 1899 ppHRegPPC(i->Pin.AvBin32x4.srcR); 1900 return; 1901 case Pin_AvBin64x2: 1902 vex_printf("%s(w) ", showPPCAvOp(i->Pin.AvBin64x2.op)); 1903 ppHRegPPC(i->Pin.AvBin64x2.dst); 1904 vex_printf(","); 1905 ppHRegPPC(i->Pin.AvBin64x2.srcL); 1906 vex_printf(","); 1907 ppHRegPPC(i->Pin.AvBin64x2.srcR); 1908 return; 1909 case Pin_AvBin32Fx4: 1910 vex_printf("%s ", showPPCAvFpOp(i->Pin.AvBin32Fx4.op)); 1911 ppHRegPPC(i->Pin.AvBin32Fx4.dst); 1912 vex_printf(","); 1913 ppHRegPPC(i->Pin.AvBin32Fx4.srcL); 1914 vex_printf(","); 1915 ppHRegPPC(i->Pin.AvBin32Fx4.srcR); 1916 return; 1917 case Pin_AvUn32Fx4: 1918 vex_printf("%s ", showPPCAvFpOp(i->Pin.AvUn32Fx4.op)); 1919 ppHRegPPC(i->Pin.AvUn32Fx4.dst); 1920 vex_printf(","); 1921 ppHRegPPC(i->Pin.AvUn32Fx4.src); 1922 return; 1923 case Pin_AvPerm: 1924 vex_printf("vperm "); 1925 ppHRegPPC(i->Pin.AvPerm.dst); 1926 vex_printf(","); 1927 ppHRegPPC(i->Pin.AvPerm.srcL); 1928 vex_printf(","); 1929 ppHRegPPC(i->Pin.AvPerm.srcR); 1930 vex_printf(","); 1931 ppHRegPPC(i->Pin.AvPerm.ctl); 1932 return; 1933 1934 case Pin_AvSel: 1935 vex_printf("vsel "); 1936 ppHRegPPC(i->Pin.AvSel.dst); 1937 vex_printf(","); 1938 ppHRegPPC(i->Pin.AvSel.srcL); 1939 vex_printf(","); 1940 ppHRegPPC(i->Pin.AvSel.srcR); 1941 vex_printf(","); 1942 ppHRegPPC(i->Pin.AvSel.ctl); 1943 return; 1944 1945 case Pin_AvSh: 1946 /* This only generates the following instructions with RA 1947 * register number set to 0. 1948 */ 1949 if (i->Pin.AvSh.addr->tag == Pam_IR) { 1950 ppLoadImm(hregPPC_GPR30(mode64), 1951 i->Pin.AvSh.addr->Pam.IR.index, mode64); 1952 vex_printf(" ; "); 1953 } 1954 1955 if (i->Pin.AvSh.shLeft) 1956 vex_printf("lvsl "); 1957 else 1958 vex_printf("lvsr "); 1959 1960 ppHRegPPC(i->Pin.AvSh.dst); 1961 if (i->Pin.AvSh.addr->tag == Pam_IR) 1962 vex_printf("%%r30"); 1963 else 1964 ppHRegPPC(i->Pin.AvSh.addr->Pam.RR.index); 1965 vex_printf(","); 1966 ppHRegPPC(i->Pin.AvSh.addr->Pam.RR.base); 1967 return; 1968 1969 case Pin_AvShlDbl: 1970 vex_printf("vsldoi "); 1971 ppHRegPPC(i->Pin.AvShlDbl.dst); 1972 vex_printf(","); 1973 ppHRegPPC(i->Pin.AvShlDbl.srcL); 1974 vex_printf(","); 1975 ppHRegPPC(i->Pin.AvShlDbl.srcR); 1976 vex_printf(",%d", i->Pin.AvShlDbl.shift); 1977 return; 1978 1979 case Pin_AvSplat: { 1980 UChar sz = i->Pin.AvSplat.sz; 1981 HChar ch_sz = toUChar( (sz == 8) ? 'b' : (sz == 16) ? 'h' : 'w' ); 1982 vex_printf("vsplt%s%c ", 1983 i->Pin.AvSplat.src->tag == Pvi_Imm ? "is" : "", ch_sz); 1984 ppHRegPPC(i->Pin.AvSplat.dst); 1985 vex_printf(","); 1986 ppPPCVI5s(i->Pin.AvSplat.src); 1987 if (i->Pin.AvSplat.src->tag == Pvi_Reg) 1988 vex_printf(", %d", (128/sz)-1); /* louis lane */ 1989 return; 1990 } 1991 1992 case Pin_AvCMov: 1993 vex_printf("avcmov (%s) ", showPPCCondCode(i->Pin.AvCMov.cond)); 1994 ppHRegPPC(i->Pin.AvCMov.dst); 1995 vex_printf(","); 1996 ppHRegPPC(i->Pin.AvCMov.src); 1997 vex_printf(": "); 1998 vex_printf("if (v_dst != v_src) { "); 1999 if (i->Pin.AvCMov.cond.test != Pct_ALWAYS) { 2000 vex_printf("if (%s) { ", showPPCCondCode(i->Pin.AvCMov.cond)); 2001 } 2002 vex_printf("vmr "); 2003 ppHRegPPC(i->Pin.AvCMov.dst); 2004 vex_printf(","); 2005 ppHRegPPC(i->Pin.AvCMov.src); 2006 if (i->Pin.FpCMov.cond.test != Pct_ALWAYS) 2007 vex_printf(" }"); 2008 vex_printf(" }"); 2009 return; 2010 2011 case Pin_AvLdVSCR: 2012 vex_printf("mtvscr "); 2013 ppHRegPPC(i->Pin.AvLdVSCR.src); 2014 return; 2015 2016 case Pin_AvCipherV128Unary: 2017 vex_printf("%s(w) ", showPPCAvOp(i->Pin.AvCipherV128Unary.op)); 2018 ppHRegPPC(i->Pin.AvCipherV128Unary.dst); 2019 vex_printf(","); 2020 ppHRegPPC(i->Pin.AvCipherV128Unary.src); 2021 return; 2022 2023 case Pin_AvCipherV128Binary: 2024 vex_printf("%s(w) ", showPPCAvOp(i->Pin.AvCipherV128Binary.op)); 2025 ppHRegPPC(i->Pin.AvCipherV128Binary.dst); 2026 vex_printf(","); 2027 ppHRegPPC(i->Pin.AvCipherV128Binary.srcL); 2028 vex_printf(","); 2029 ppHRegPPC(i->Pin.AvCipherV128Binary.srcR); 2030 return; 2031 2032 case Pin_AvHashV128Binary: 2033 vex_printf("%s(w) ", showPPCAvOp(i->Pin.AvHashV128Binary.op)); 2034 ppHRegPPC(i->Pin.AvHashV128Binary.dst); 2035 vex_printf(","); 2036 ppHRegPPC(i->Pin.AvHashV128Binary.src); 2037 vex_printf(","); 2038 ppPPCRI(i->Pin.AvHashV128Binary.s_field); 2039 return; 2040 2041 case Pin_AvBCDV128Trinary: 2042 vex_printf("%s(w) ", showPPCAvOp(i->Pin.AvBCDV128Trinary.op)); 2043 ppHRegPPC(i->Pin.AvBCDV128Trinary.dst); 2044 vex_printf(","); 2045 ppHRegPPC(i->Pin.AvBCDV128Trinary.src1); 2046 vex_printf(","); 2047 ppHRegPPC(i->Pin.AvBCDV128Trinary.src2); 2048 vex_printf(","); 2049 ppPPCRI(i->Pin.AvBCDV128Trinary.ps); 2050 return; 2051 2052 case Pin_Dfp64Unary: 2053 vex_printf("%s ", showPPCFpOp(i->Pin.Dfp64Unary.op)); 2054 ppHRegPPC(i->Pin.Dfp64Unary.dst); 2055 vex_printf(","); 2056 ppHRegPPC(i->Pin.Dfp64Unary.src); 2057 return; 2058 2059 case Pin_Dfp64Binary: 2060 vex_printf("%s ", showPPCFpOp(i->Pin.Dfp64Binary.op)); 2061 ppHRegPPC(i->Pin.Dfp64Binary.dst); 2062 vex_printf(","); 2063 ppHRegPPC(i->Pin.Dfp64Binary.srcL); 2064 vex_printf(","); 2065 ppHRegPPC(i->Pin.Dfp64Binary.srcR); 2066 return; 2067 2068 case Pin_DfpShift: 2069 vex_printf("%s ", showPPCFpOp(i->Pin.DfpShift.op)); 2070 ppHRegPPC(i->Pin.DfpShift.dst); 2071 vex_printf(","); 2072 ppHRegPPC(i->Pin.DfpShift.src); 2073 vex_printf(","); 2074 ppPPCRI(i->Pin.DfpShift.shift); 2075 return; 2076 2077 case Pin_Dfp128Unary: 2078 vex_printf("%s ", showPPCFpOp(i->Pin.Dfp128Unary.op)); 2079 ppHRegPPC(i->Pin.Dfp128Unary.dst_hi); 2080 vex_printf(","); 2081 ppHRegPPC(i->Pin.Dfp128Unary.src_hi); 2082 return; 2083 2084 case Pin_Dfp128Binary: 2085 vex_printf("%s ", showPPCFpOp(i->Pin.Dfp128Binary.op)); 2086 ppHRegPPC(i->Pin.Dfp128Binary.dst_hi); 2087 vex_printf(","); 2088 ppHRegPPC(i->Pin.Dfp128Binary.srcR_hi); 2089 return; 2090 2091 case Pin_DfpShift128: 2092 vex_printf("%s ", showPPCFpOp(i->Pin.DfpShift128.op)); 2093 ppHRegPPC(i->Pin.DfpShift128.dst_hi); 2094 vex_printf(","); 2095 ppHRegPPC(i->Pin.DfpShift128.src_hi); 2096 vex_printf(","); 2097 ppPPCRI(i->Pin.DfpShift128.shift); 2098 return; 2099 2100 case Pin_DfpRound: 2101 vex_printf("drintx "); 2102 ppHRegPPC(i->Pin.DfpRound.dst); 2103 vex_printf(","); 2104 ppHRegPPC(i->Pin.DfpRound.src); 2105 vex_printf(","); 2106 ppPPCRI(i->Pin.DfpRound.r_rmc); /* R in bit 3 and RMC in bits 2:0 */ 2107 return; 2108 2109 case Pin_DfpRound128: 2110 vex_printf("drintxq "); 2111 ppHRegPPC(i->Pin.DfpRound128.dst_hi); 2112 vex_printf(","); 2113 ppHRegPPC(i->Pin.DfpRound128.src_hi); 2114 vex_printf(","); 2115 ppPPCRI(i->Pin.DfpRound128.r_rmc); /* R in bit 3 and RMC in bits 2:0 */ 2116 return; 2117 2118 case Pin_DfpQuantize: 2119 vex_printf("%s ", showPPCFpOp(i->Pin.DfpQuantize.op)); 2120 ppHRegPPC(i->Pin.DfpQuantize.dst); 2121 vex_printf(","); 2122 ppHRegPPC(i->Pin.DfpQuantize.srcL); 2123 vex_printf(","); 2124 ppHRegPPC(i->Pin.DfpQuantize.srcR); 2125 vex_printf(","); 2126 ppPPCRI(i->Pin.DfpQuantize.rmc); 2127 return; 2128 2129 case Pin_DfpQuantize128: 2130 /* Dst is used to pass in left source and return result */ 2131 vex_printf("dquaq "); 2132 ppHRegPPC(i->Pin.DfpQuantize128.dst_hi); 2133 vex_printf(","); 2134 ppHRegPPC(i->Pin.DfpQuantize128.dst_hi); 2135 vex_printf(","); 2136 ppHRegPPC(i->Pin.DfpQuantize128.src_hi); 2137 vex_printf(","); 2138 ppPPCRI(i->Pin.DfpQuantize128.rmc); 2139 return; 2140 2141 case Pin_DfpD128toD64: 2142 vex_printf("%s ", showPPCFpOp(i->Pin.DfpD128toD64.op)); 2143 ppHRegPPC(i->Pin.DfpD128toD64.dst); 2144 vex_printf(","); 2145 ppHRegPPC(i->Pin.DfpD128toD64.src_hi); 2146 vex_printf(","); 2147 return; 2148 2149 case Pin_DfpI64StoD128: 2150 vex_printf("%s ", showPPCFpOp(i->Pin.DfpI64StoD128.op)); 2151 ppHRegPPC(i->Pin.DfpI64StoD128.dst_hi); 2152 vex_printf(","); 2153 ppHRegPPC(i->Pin.DfpI64StoD128.src); 2154 vex_printf(","); 2155 return; 2156 case Pin_ExtractExpD128: 2157 vex_printf("dxexq "); 2158 ppHRegPPC(i->Pin.ExtractExpD128.dst); 2159 vex_printf(","); 2160 ppHRegPPC(i->Pin.ExtractExpD128.src_hi); 2161 return; 2162 case Pin_InsertExpD128: 2163 vex_printf("diexq "); 2164 ppHRegPPC(i->Pin.InsertExpD128.dst_hi); 2165 vex_printf(","); 2166 ppHRegPPC(i->Pin.InsertExpD128.srcL); 2167 vex_printf(","); 2168 ppHRegPPC(i->Pin.InsertExpD128.srcR_hi); 2169 return; 2170 case Pin_Dfp64Cmp: 2171 vex_printf("dcmpo %%cr1,"); 2172 ppHRegPPC(i->Pin.Dfp64Cmp.srcL); 2173 vex_printf(","); 2174 ppHRegPPC(i->Pin.Dfp64Cmp.srcR); 2175 vex_printf("; mfcr "); 2176 ppHRegPPC(i->Pin.Dfp64Cmp.dst); 2177 vex_printf("; rlwinm "); 2178 ppHRegPPC(i->Pin.Dfp64Cmp.dst); 2179 vex_printf(","); 2180 ppHRegPPC(i->Pin.Dfp64Cmp.dst); 2181 vex_printf(",8,28,31"); 2182 return; 2183 case Pin_Dfp128Cmp: 2184 vex_printf("dcmpoq %%cr1,"); 2185 ppHRegPPC(i->Pin.Dfp128Cmp.srcL_hi); 2186 vex_printf(","); 2187 ppHRegPPC(i->Pin.Dfp128Cmp.srcR_hi); 2188 vex_printf("; mfcr "); 2189 ppHRegPPC(i->Pin.Dfp128Cmp.dst); 2190 vex_printf("; rlwinm "); 2191 ppHRegPPC(i->Pin.Dfp128Cmp.dst); 2192 vex_printf(","); 2193 ppHRegPPC(i->Pin.Dfp128Cmp.dst); 2194 vex_printf(",8,28,31"); 2195 return; 2196 case Pin_EvCheck: 2197 /* Note that the counter dec is 32 bit even in 64-bit mode. */ 2198 vex_printf("(evCheck) "); 2199 vex_printf("lwz r30,"); 2200 ppPPCAMode(i->Pin.EvCheck.amCounter); 2201 vex_printf("; addic. r30,r30,-1; "); 2202 vex_printf("stw r30,"); 2203 ppPPCAMode(i->Pin.EvCheck.amCounter); 2204 vex_printf("; bge nofail; lwz r30,"); 2205 ppPPCAMode(i->Pin.EvCheck.amFailAddr); 2206 vex_printf("; mtctr r30; bctr; nofail:"); 2207 return; 2208 case Pin_ProfInc: 2209 if (mode64) { 2210 vex_printf("(profInc) imm64-fixed5 r30,$NotKnownYet; "); 2211 vex_printf("ld r29,(r30); addi r29,r29,1; std r29,(r30)"); 2212 } else { 2213 vex_printf("(profInc) imm32-fixed2 r30,$NotKnownYet; "); 2214 vex_printf("lwz r29,4(r30); addic. r29,r29,1; stw r29,4(r30)"); 2215 vex_printf("lwz r29,0(r30); addze r29,r29; stw r29,0(r30)"); 2216 } 2217 break; 2218 default: 2219 vex_printf("\nppPPCInstr: No such tag(%d)\n", (Int)i->tag); 2220 vpanic("ppPPCInstr"); 2221 } 2222 } 2223 2224 /* --------- Helpers for register allocation. --------- */ 2225 2226 void getRegUsage_PPCInstr ( HRegUsage* u, const PPCInstr* i, Bool mode64 ) 2227 { 2228 initHRegUsage(u); 2229 switch (i->tag) { 2230 case Pin_LI: 2231 addHRegUse(u, HRmWrite, i->Pin.LI.dst); 2232 break; 2233 case Pin_Alu: 2234 addHRegUse(u, HRmRead, i->Pin.Alu.srcL); 2235 addRegUsage_PPCRH(u, i->Pin.Alu.srcR); 2236 addHRegUse(u, HRmWrite, i->Pin.Alu.dst); 2237 return; 2238 case Pin_Shft: 2239 addHRegUse(u, HRmRead, i->Pin.Shft.srcL); 2240 addRegUsage_PPCRH(u, i->Pin.Shft.srcR); 2241 addHRegUse(u, HRmWrite, i->Pin.Shft.dst); 2242 return; 2243 case Pin_AddSubC: 2244 addHRegUse(u, HRmWrite, i->Pin.AddSubC.dst); 2245 addHRegUse(u, HRmRead, i->Pin.AddSubC.srcL); 2246 addHRegUse(u, HRmRead, i->Pin.AddSubC.srcR); 2247 return; 2248 case Pin_Cmp: 2249 addHRegUse(u, HRmRead, i->Pin.Cmp.srcL); 2250 addRegUsage_PPCRH(u, i->Pin.Cmp.srcR); 2251 return; 2252 case Pin_Unary: 2253 addHRegUse(u, HRmWrite, i->Pin.Unary.dst); 2254 addHRegUse(u, HRmRead, i->Pin.Unary.src); 2255 return; 2256 case Pin_MulL: 2257 addHRegUse(u, HRmWrite, i->Pin.MulL.dst); 2258 addHRegUse(u, HRmRead, i->Pin.MulL.srcL); 2259 addHRegUse(u, HRmRead, i->Pin.MulL.srcR); 2260 return; 2261 case Pin_Div: 2262 addHRegUse(u, HRmWrite, i->Pin.Div.dst); 2263 addHRegUse(u, HRmRead, i->Pin.Div.srcL); 2264 addHRegUse(u, HRmRead, i->Pin.Div.srcR); 2265 return; 2266 case Pin_Call: { 2267 UInt argir; 2268 /* This is a bit subtle. */ 2269 /* First off, claim it trashes all the caller-saved regs 2270 which fall within the register allocator's jurisdiction. 2271 These I believe to be: 2272 mode32: r3 to r12 2273 mode64: r3 to r10 2274 */ 2275 /* XXXXXXXXXXXXXXXXX BUG! This doesn't say anything about the FP 2276 or Altivec registers. We get away with this ONLY because 2277 getAllocatableRegs_PPC gives the allocator callee-saved fp 2278 and Altivec regs, and no caller-save ones. */ 2279 addHRegUse(u, HRmWrite, hregPPC_GPR3(mode64)); 2280 addHRegUse(u, HRmWrite, hregPPC_GPR4(mode64)); 2281 addHRegUse(u, HRmWrite, hregPPC_GPR5(mode64)); 2282 addHRegUse(u, HRmWrite, hregPPC_GPR6(mode64)); 2283 addHRegUse(u, HRmWrite, hregPPC_GPR7(mode64)); 2284 addHRegUse(u, HRmWrite, hregPPC_GPR8(mode64)); 2285 addHRegUse(u, HRmWrite, hregPPC_GPR9(mode64)); 2286 addHRegUse(u, HRmWrite, hregPPC_GPR10(mode64)); 2287 if (!mode64) { 2288 addHRegUse(u, HRmWrite, hregPPC_GPR11(mode64)); 2289 addHRegUse(u, HRmWrite, hregPPC_GPR12(mode64)); 2290 } 2291 2292 /* Now we have to state any parameter-carrying registers 2293 which might be read. This depends on the argiregs field. */ 2294 argir = i->Pin.Call.argiregs; 2295 if (argir &(1<<10)) addHRegUse(u, HRmRead, hregPPC_GPR10(mode64)); 2296 if (argir & (1<<9)) addHRegUse(u, HRmRead, hregPPC_GPR9(mode64)); 2297 if (argir & (1<<8)) addHRegUse(u, HRmRead, hregPPC_GPR8(mode64)); 2298 if (argir & (1<<7)) addHRegUse(u, HRmRead, hregPPC_GPR7(mode64)); 2299 if (argir & (1<<6)) addHRegUse(u, HRmRead, hregPPC_GPR6(mode64)); 2300 if (argir & (1<<5)) addHRegUse(u, HRmRead, hregPPC_GPR5(mode64)); 2301 if (argir & (1<<4)) addHRegUse(u, HRmRead, hregPPC_GPR4(mode64)); 2302 if (argir & (1<<3)) addHRegUse(u, HRmRead, hregPPC_GPR3(mode64)); 2303 2304 vassert(0 == (argir & ~((1<<3)|(1<<4)|(1<<5)|(1<<6) 2305 |(1<<7)|(1<<8)|(1<<9)|(1<<10)))); 2306 2307 /* Finally, there is the issue that the insn trashes a 2308 register because the literal target address has to be 2309 loaded into a register. %r10 seems a suitable victim. 2310 (Can't use %r0, as some insns interpret it as value zero). */ 2311 addHRegUse(u, HRmWrite, hregPPC_GPR10(mode64)); 2312 /* Upshot of this is that the assembler really must use %r10, 2313 and no other, as a destination temporary. */ 2314 return; 2315 } 2316 /* XDirect/XIndir/XAssisted are also a bit subtle. They 2317 conditionally exit the block. Hence we only need to list (1) 2318 the registers that they read, and (2) the registers that they 2319 write in the case where the block is not exited. (2) is empty, 2320 hence only (1) is relevant here. */ 2321 case Pin_XDirect: 2322 addRegUsage_PPCAMode(u, i->Pin.XDirect.amCIA); 2323 return; 2324 case Pin_XIndir: 2325 addHRegUse(u, HRmRead, i->Pin.XIndir.dstGA); 2326 addRegUsage_PPCAMode(u, i->Pin.XIndir.amCIA); 2327 return; 2328 case Pin_XAssisted: 2329 addHRegUse(u, HRmRead, i->Pin.XAssisted.dstGA); 2330 addRegUsage_PPCAMode(u, i->Pin.XAssisted.amCIA); 2331 return; 2332 case Pin_CMov: 2333 addRegUsage_PPCRI(u, i->Pin.CMov.src); 2334 addHRegUse(u, HRmWrite, i->Pin.CMov.dst); 2335 return; 2336 case Pin_Load: 2337 addRegUsage_PPCAMode(u, i->Pin.Load.src); 2338 addHRegUse(u, HRmWrite, i->Pin.Load.dst); 2339 return; 2340 case Pin_LoadL: 2341 addHRegUse(u, HRmRead, i->Pin.LoadL.src); 2342 addHRegUse(u, HRmWrite, i->Pin.LoadL.dst); 2343 return; 2344 case Pin_Store: 2345 addHRegUse(u, HRmRead, i->Pin.Store.src); 2346 addRegUsage_PPCAMode(u, i->Pin.Store.dst); 2347 return; 2348 case Pin_StoreC: 2349 addHRegUse(u, HRmRead, i->Pin.StoreC.src); 2350 addHRegUse(u, HRmRead, i->Pin.StoreC.dst); 2351 return; 2352 case Pin_Set: 2353 addHRegUse(u, HRmWrite, i->Pin.Set.dst); 2354 return; 2355 case Pin_MfCR: 2356 addHRegUse(u, HRmWrite, i->Pin.MfCR.dst); 2357 return; 2358 case Pin_MFence: 2359 return; 2360 2361 case Pin_FpUnary: 2362 addHRegUse(u, HRmWrite, i->Pin.FpUnary.dst); 2363 addHRegUse(u, HRmRead, i->Pin.FpUnary.src); 2364 return; 2365 case Pin_FpBinary: 2366 addHRegUse(u, HRmWrite, i->Pin.FpBinary.dst); 2367 addHRegUse(u, HRmRead, i->Pin.FpBinary.srcL); 2368 addHRegUse(u, HRmRead, i->Pin.FpBinary.srcR); 2369 return; 2370 case Pin_FpMulAcc: 2371 addHRegUse(u, HRmWrite, i->Pin.FpMulAcc.dst); 2372 addHRegUse(u, HRmRead, i->Pin.FpMulAcc.srcML); 2373 addHRegUse(u, HRmRead, i->Pin.FpMulAcc.srcMR); 2374 addHRegUse(u, HRmRead, i->Pin.FpMulAcc.srcAcc); 2375 return; 2376 case Pin_FpLdSt: 2377 addHRegUse(u, (i->Pin.FpLdSt.isLoad ? HRmWrite : HRmRead), 2378 i->Pin.FpLdSt.reg); 2379 addRegUsage_PPCAMode(u, i->Pin.FpLdSt.addr); 2380 return; 2381 case Pin_FpSTFIW: 2382 addHRegUse(u, HRmRead, i->Pin.FpSTFIW.addr); 2383 addHRegUse(u, HRmRead, i->Pin.FpSTFIW.data); 2384 return; 2385 case Pin_FpRSP: 2386 addHRegUse(u, HRmWrite, i->Pin.FpRSP.dst); 2387 addHRegUse(u, HRmRead, i->Pin.FpRSP.src); 2388 return; 2389 case Pin_FpCftI: 2390 addHRegUse(u, HRmWrite, i->Pin.FpCftI.dst); 2391 addHRegUse(u, HRmRead, i->Pin.FpCftI.src); 2392 return; 2393 case Pin_FpCMov: 2394 addHRegUse(u, HRmModify, i->Pin.FpCMov.dst); 2395 addHRegUse(u, HRmRead, i->Pin.FpCMov.src); 2396 return; 2397 case Pin_FpLdFPSCR: 2398 addHRegUse(u, HRmRead, i->Pin.FpLdFPSCR.src); 2399 return; 2400 case Pin_FpCmp: 2401 addHRegUse(u, HRmWrite, i->Pin.FpCmp.dst); 2402 addHRegUse(u, HRmRead, i->Pin.FpCmp.srcL); 2403 addHRegUse(u, HRmRead, i->Pin.FpCmp.srcR); 2404 return; 2405 2406 case Pin_RdWrLR: 2407 addHRegUse(u, (i->Pin.RdWrLR.wrLR ? HRmRead : HRmWrite), 2408 i->Pin.RdWrLR.gpr); 2409 return; 2410 2411 case Pin_AvLdSt: 2412 addHRegUse(u, (i->Pin.AvLdSt.isLoad ? HRmWrite : HRmRead), 2413 i->Pin.AvLdSt.reg); 2414 if (i->Pin.AvLdSt.addr->tag == Pam_IR) 2415 addHRegUse(u, HRmWrite, hregPPC_GPR30(mode64)); 2416 addRegUsage_PPCAMode(u, i->Pin.AvLdSt.addr); 2417 return; 2418 case Pin_AvUnary: 2419 addHRegUse(u, HRmWrite, i->Pin.AvUnary.dst); 2420 addHRegUse(u, HRmRead, i->Pin.AvUnary.src); 2421 return; 2422 case Pin_AvBinary: 2423 if (i->Pin.AvBinary.op == Pav_XOR 2424 && sameHReg(i->Pin.AvBinary.dst, i->Pin.AvBinary.srcL) 2425 && sameHReg(i->Pin.AvBinary.dst, i->Pin.AvBinary.srcR)) { 2426 /* reg-alloc needs to understand 'xor r,r,r' as a write of r */ 2427 /* (as opposed to a rite of passage :-) */ 2428 addHRegUse(u, HRmWrite, i->Pin.AvBinary.dst); 2429 } else { 2430 addHRegUse(u, HRmWrite, i->Pin.AvBinary.dst); 2431 addHRegUse(u, HRmRead, i->Pin.AvBinary.srcL); 2432 addHRegUse(u, HRmRead, i->Pin.AvBinary.srcR); 2433 } 2434 return; 2435 case Pin_AvBin8x16: 2436 addHRegUse(u, HRmWrite, i->Pin.AvBin8x16.dst); 2437 addHRegUse(u, HRmRead, i->Pin.AvBin8x16.srcL); 2438 addHRegUse(u, HRmRead, i->Pin.AvBin8x16.srcR); 2439 return; 2440 case Pin_AvBin16x8: 2441 addHRegUse(u, HRmWrite, i->Pin.AvBin16x8.dst); 2442 addHRegUse(u, HRmRead, i->Pin.AvBin16x8.srcL); 2443 addHRegUse(u, HRmRead, i->Pin.AvBin16x8.srcR); 2444 return; 2445 case Pin_AvBin32x4: 2446 addHRegUse(u, HRmWrite, i->Pin.AvBin32x4.dst); 2447 addHRegUse(u, HRmRead, i->Pin.AvBin32x4.srcL); 2448 addHRegUse(u, HRmRead, i->Pin.AvBin32x4.srcR); 2449 return; 2450 case Pin_AvBin64x2: 2451 addHRegUse(u, HRmWrite, i->Pin.AvBin64x2.dst); 2452 addHRegUse(u, HRmRead, i->Pin.AvBin64x2.srcL); 2453 addHRegUse(u, HRmRead, i->Pin.AvBin64x2.srcR); 2454 return; 2455 case Pin_AvBin32Fx4: 2456 addHRegUse(u, HRmWrite, i->Pin.AvBin32Fx4.dst); 2457 addHRegUse(u, HRmRead, i->Pin.AvBin32Fx4.srcL); 2458 addHRegUse(u, HRmRead, i->Pin.AvBin32Fx4.srcR); 2459 if (i->Pin.AvBin32Fx4.op == Pavfp_MULF) 2460 addHRegUse(u, HRmWrite, hregPPC_VR29(mode64)); 2461 return; 2462 case Pin_AvUn32Fx4: 2463 addHRegUse(u, HRmWrite, i->Pin.AvUn32Fx4.dst); 2464 addHRegUse(u, HRmRead, i->Pin.AvUn32Fx4.src); 2465 return; 2466 case Pin_AvPerm: 2467 addHRegUse(u, HRmWrite, i->Pin.AvPerm.dst); 2468 addHRegUse(u, HRmRead, i->Pin.AvPerm.srcL); 2469 addHRegUse(u, HRmRead, i->Pin.AvPerm.srcR); 2470 addHRegUse(u, HRmRead, i->Pin.AvPerm.ctl); 2471 return; 2472 case Pin_AvSel: 2473 addHRegUse(u, HRmWrite, i->Pin.AvSel.dst); 2474 addHRegUse(u, HRmRead, i->Pin.AvSel.ctl); 2475 addHRegUse(u, HRmRead, i->Pin.AvSel.srcL); 2476 addHRegUse(u, HRmRead, i->Pin.AvSel.srcR); 2477 return; 2478 case Pin_AvSh: 2479 addHRegUse(u, HRmWrite, i->Pin.AvSh.dst); 2480 if (i->Pin.AvSh.addr->tag == Pam_IR) 2481 addHRegUse(u, HRmWrite, hregPPC_GPR30(mode64)); 2482 addRegUsage_PPCAMode(u, i->Pin.AvSh.addr); 2483 return; 2484 case Pin_AvShlDbl: 2485 addHRegUse(u, HRmWrite, i->Pin.AvShlDbl.dst); 2486 addHRegUse(u, HRmRead, i->Pin.AvShlDbl.srcL); 2487 addHRegUse(u, HRmRead, i->Pin.AvShlDbl.srcR); 2488 return; 2489 case Pin_AvSplat: 2490 addHRegUse(u, HRmWrite, i->Pin.AvSplat.dst); 2491 addRegUsage_PPCVI5s(u, i->Pin.AvSplat.src); 2492 return; 2493 case Pin_AvCMov: 2494 addHRegUse(u, HRmModify, i->Pin.AvCMov.dst); 2495 addHRegUse(u, HRmRead, i->Pin.AvCMov.src); 2496 return; 2497 case Pin_AvLdVSCR: 2498 addHRegUse(u, HRmRead, i->Pin.AvLdVSCR.src); 2499 return; 2500 case Pin_AvCipherV128Unary: 2501 addHRegUse(u, HRmWrite, i->Pin.AvCipherV128Unary.dst); 2502 addHRegUse(u, HRmRead, i->Pin.AvCipherV128Unary.src); 2503 return; 2504 case Pin_AvCipherV128Binary: 2505 addHRegUse(u, HRmWrite, i->Pin.AvCipherV128Binary.dst); 2506 addHRegUse(u, HRmRead, i->Pin.AvCipherV128Binary.srcL); 2507 addHRegUse(u, HRmRead, i->Pin.AvCipherV128Binary.srcR); 2508 return; 2509 case Pin_AvHashV128Binary: 2510 addHRegUse(u, HRmWrite, i->Pin.AvHashV128Binary.dst); 2511 addHRegUse(u, HRmRead, i->Pin.AvHashV128Binary.src); 2512 addRegUsage_PPCRI(u, i->Pin.AvHashV128Binary.s_field); 2513 return; 2514 case Pin_AvBCDV128Trinary: 2515 addHRegUse(u, HRmWrite, i->Pin.AvBCDV128Trinary.dst); 2516 addHRegUse(u, HRmRead, i->Pin.AvBCDV128Trinary.src1); 2517 addHRegUse(u, HRmRead, i->Pin.AvBCDV128Trinary.src2); 2518 addRegUsage_PPCRI(u, i->Pin.AvBCDV128Trinary.ps); 2519 return; 2520 case Pin_Dfp64Unary: 2521 addHRegUse(u, HRmWrite, i->Pin.Dfp64Unary.dst); 2522 addHRegUse(u, HRmRead, i->Pin.Dfp64Unary.src); 2523 return; 2524 case Pin_Dfp64Binary: 2525 addHRegUse(u, HRmWrite, i->Pin.Dfp64Binary.dst); 2526 addHRegUse(u, HRmRead, i->Pin.Dfp64Binary.srcL); 2527 addHRegUse(u, HRmRead, i->Pin.Dfp64Binary.srcR); 2528 return; 2529 case Pin_DfpShift: 2530 addRegUsage_PPCRI(u, i->Pin.DfpShift.shift); 2531 addHRegUse(u, HRmWrite, i->Pin.DfpShift.src); 2532 addHRegUse(u, HRmWrite, i->Pin.DfpShift.dst); 2533 return; 2534 case Pin_Dfp128Unary: 2535 addHRegUse(u, HRmWrite, i->Pin.Dfp128Unary.dst_hi); 2536 addHRegUse(u, HRmWrite, i->Pin.Dfp128Unary.dst_lo); 2537 addHRegUse(u, HRmRead, i->Pin.Dfp128Unary.src_hi); 2538 addHRegUse(u, HRmRead, i->Pin.Dfp128Unary.src_lo); 2539 return; 2540 case Pin_Dfp128Binary: 2541 addHRegUse(u, HRmWrite, i->Pin.Dfp128Binary.dst_hi); 2542 addHRegUse(u, HRmWrite, i->Pin.Dfp128Binary.dst_lo); 2543 addHRegUse(u, HRmRead, i->Pin.Dfp128Binary.srcR_hi); 2544 addHRegUse(u, HRmRead, i->Pin.Dfp128Binary.srcR_lo); 2545 return; 2546 case Pin_DfpRound: 2547 addHRegUse(u, HRmWrite, i->Pin.DfpRound.dst); 2548 addHRegUse(u, HRmRead, i->Pin.DfpRound.src); 2549 return; 2550 case Pin_DfpRound128: 2551 addHRegUse(u, HRmWrite, i->Pin.DfpRound128.dst_hi); 2552 addHRegUse(u, HRmWrite, i->Pin.DfpRound128.dst_lo); 2553 addHRegUse(u, HRmRead, i->Pin.DfpRound128.src_hi); 2554 addHRegUse(u, HRmRead, i->Pin.DfpRound128.src_lo); 2555 return; 2556 case Pin_DfpQuantize: 2557 addRegUsage_PPCRI(u, i->Pin.DfpQuantize.rmc); 2558 addHRegUse(u, HRmWrite, i->Pin.DfpQuantize.dst); 2559 addHRegUse(u, HRmRead, i->Pin.DfpQuantize.srcL); 2560 addHRegUse(u, HRmRead, i->Pin.DfpQuantize.srcR); 2561 return; 2562 case Pin_DfpQuantize128: 2563 addHRegUse(u, HRmWrite, i->Pin.DfpQuantize128.dst_hi); 2564 addHRegUse(u, HRmWrite, i->Pin.DfpQuantize128.dst_lo); 2565 addHRegUse(u, HRmRead, i->Pin.DfpQuantize128.src_hi); 2566 addHRegUse(u, HRmRead, i->Pin.DfpQuantize128.src_lo); 2567 return; 2568 case Pin_DfpShift128: 2569 addRegUsage_PPCRI(u, i->Pin.DfpShift128.shift); 2570 addHRegUse(u, HRmWrite, i->Pin.DfpShift128.src_hi); 2571 addHRegUse(u, HRmWrite, i->Pin.DfpShift128.src_lo); 2572 addHRegUse(u, HRmWrite, i->Pin.DfpShift128.dst_hi); 2573 addHRegUse(u, HRmWrite, i->Pin.DfpShift128.dst_lo); 2574 return; 2575 case Pin_DfpD128toD64: 2576 addHRegUse(u, HRmWrite, i->Pin.DfpD128toD64.src_hi); 2577 addHRegUse(u, HRmWrite, i->Pin.DfpD128toD64.src_lo); 2578 addHRegUse(u, HRmWrite, i->Pin.DfpD128toD64.dst); 2579 return; 2580 case Pin_DfpI64StoD128: 2581 addHRegUse(u, HRmWrite, i->Pin.DfpI64StoD128.src); 2582 addHRegUse(u, HRmWrite, i->Pin.DfpI64StoD128.dst_hi); 2583 addHRegUse(u, HRmWrite, i->Pin.DfpI64StoD128.dst_lo); 2584 return; 2585 case Pin_ExtractExpD128: 2586 addHRegUse(u, HRmWrite, i->Pin.ExtractExpD128.dst); 2587 addHRegUse(u, HRmRead, i->Pin.ExtractExpD128.src_hi); 2588 addHRegUse(u, HRmRead, i->Pin.ExtractExpD128.src_lo); 2589 return; 2590 case Pin_InsertExpD128: 2591 addHRegUse(u, HRmWrite, i->Pin.InsertExpD128.dst_hi); 2592 addHRegUse(u, HRmWrite, i->Pin.InsertExpD128.dst_lo); 2593 addHRegUse(u, HRmRead, i->Pin.InsertExpD128.srcL); 2594 addHRegUse(u, HRmRead, i->Pin.InsertExpD128.srcR_hi); 2595 addHRegUse(u, HRmRead, i->Pin.InsertExpD128.srcR_lo); 2596 return; 2597 case Pin_Dfp64Cmp: 2598 addHRegUse(u, HRmWrite, i->Pin.Dfp64Cmp.dst); 2599 addHRegUse(u, HRmRead, i->Pin.Dfp64Cmp.srcL); 2600 addHRegUse(u, HRmRead, i->Pin.Dfp64Cmp.srcR); 2601 return; 2602 case Pin_Dfp128Cmp: 2603 addHRegUse(u, HRmWrite, i->Pin.Dfp128Cmp.dst); 2604 addHRegUse(u, HRmRead, i->Pin.Dfp128Cmp.srcL_hi); 2605 addHRegUse(u, HRmRead, i->Pin.Dfp128Cmp.srcL_lo); 2606 addHRegUse(u, HRmRead, i->Pin.Dfp128Cmp.srcR_hi); 2607 addHRegUse(u, HRmRead, i->Pin.Dfp128Cmp.srcR_lo); 2608 return; 2609 case Pin_EvCheck: 2610 /* We expect both amodes only to mention the GSP (r31), so this 2611 is in fact pointless, since GSP isn't allocatable, but 2612 anyway.. */ 2613 addRegUsage_PPCAMode(u, i->Pin.EvCheck.amCounter); 2614 addRegUsage_PPCAMode(u, i->Pin.EvCheck.amFailAddr); 2615 addHRegUse(u, HRmWrite, hregPPC_GPR30(mode64)); /* also unavail to RA */ 2616 return; 2617 case Pin_ProfInc: 2618 addHRegUse(u, HRmWrite, hregPPC_GPR29(mode64)); 2619 addHRegUse(u, HRmWrite, hregPPC_GPR30(mode64)); 2620 return; 2621 default: 2622 ppPPCInstr(i, mode64); 2623 vpanic("getRegUsage_PPCInstr"); 2624 } 2625 } 2626 2627 /* local helper */ 2628 static void mapReg( HRegRemap* m, HReg* r ) 2629 { 2630 *r = lookupHRegRemap(m, *r); 2631 } 2632 2633 void mapRegs_PPCInstr ( HRegRemap* m, PPCInstr* i, Bool mode64 ) 2634 { 2635 switch (i->tag) { 2636 case Pin_LI: 2637 mapReg(m, &i->Pin.LI.dst); 2638 return; 2639 case Pin_Alu: 2640 mapReg(m, &i->Pin.Alu.dst); 2641 mapReg(m, &i->Pin.Alu.srcL); 2642 mapRegs_PPCRH(m, i->Pin.Alu.srcR); 2643 return; 2644 case Pin_Shft: 2645 mapReg(m, &i->Pin.Shft.dst); 2646 mapReg(m, &i->Pin.Shft.srcL); 2647 mapRegs_PPCRH(m, i->Pin.Shft.srcR); 2648 return; 2649 case Pin_AddSubC: 2650 mapReg(m, &i->Pin.AddSubC.dst); 2651 mapReg(m, &i->Pin.AddSubC.srcL); 2652 mapReg(m, &i->Pin.AddSubC.srcR); 2653 return; 2654 case Pin_Cmp: 2655 mapReg(m, &i->Pin.Cmp.srcL); 2656 mapRegs_PPCRH(m, i->Pin.Cmp.srcR); 2657 return; 2658 case Pin_Unary: 2659 mapReg(m, &i->Pin.Unary.dst); 2660 mapReg(m, &i->Pin.Unary.src); 2661 return; 2662 case Pin_MulL: 2663 mapReg(m, &i->Pin.MulL.dst); 2664 mapReg(m, &i->Pin.MulL.srcL); 2665 mapReg(m, &i->Pin.MulL.srcR); 2666 return; 2667 case Pin_Div: 2668 mapReg(m, &i->Pin.Div.dst); 2669 mapReg(m, &i->Pin.Div.srcL); 2670 mapReg(m, &i->Pin.Div.srcR); 2671 return; 2672 case Pin_Call: 2673 return; 2674 case Pin_XDirect: 2675 mapRegs_PPCAMode(m, i->Pin.XDirect.amCIA); 2676 return; 2677 case Pin_XIndir: 2678 mapReg(m, &i->Pin.XIndir.dstGA); 2679 mapRegs_PPCAMode(m, i->Pin.XIndir.amCIA); 2680 return; 2681 case Pin_XAssisted: 2682 mapReg(m, &i->Pin.XAssisted.dstGA); 2683 mapRegs_PPCAMode(m, i->Pin.XAssisted.amCIA); 2684 return; 2685 case Pin_CMov: 2686 mapRegs_PPCRI(m, i->Pin.CMov.src); 2687 mapReg(m, &i->Pin.CMov.dst); 2688 return; 2689 case Pin_Load: 2690 mapRegs_PPCAMode(m, i->Pin.Load.src); 2691 mapReg(m, &i->Pin.Load.dst); 2692 return; 2693 case Pin_LoadL: 2694 mapReg(m, &i->Pin.LoadL.src); 2695 mapReg(m, &i->Pin.LoadL.dst); 2696 return; 2697 case Pin_Store: 2698 mapReg(m, &i->Pin.Store.src); 2699 mapRegs_PPCAMode(m, i->Pin.Store.dst); 2700 return; 2701 case Pin_StoreC: 2702 mapReg(m, &i->Pin.StoreC.src); 2703 mapReg(m, &i->Pin.StoreC.dst); 2704 return; 2705 case Pin_Set: 2706 mapReg(m, &i->Pin.Set.dst); 2707 return; 2708 case Pin_MfCR: 2709 mapReg(m, &i->Pin.MfCR.dst); 2710 return; 2711 case Pin_MFence: 2712 return; 2713 case Pin_FpUnary: 2714 mapReg(m, &i->Pin.FpUnary.dst); 2715 mapReg(m, &i->Pin.FpUnary.src); 2716 return; 2717 case Pin_FpBinary: 2718 mapReg(m, &i->Pin.FpBinary.dst); 2719 mapReg(m, &i->Pin.FpBinary.srcL); 2720 mapReg(m, &i->Pin.FpBinary.srcR); 2721 return; 2722 case Pin_FpMulAcc: 2723 mapReg(m, &i->Pin.FpMulAcc.dst); 2724 mapReg(m, &i->Pin.FpMulAcc.srcML); 2725 mapReg(m, &i->Pin.FpMulAcc.srcMR); 2726 mapReg(m, &i->Pin.FpMulAcc.srcAcc); 2727 return; 2728 case Pin_FpLdSt: 2729 mapReg(m, &i->Pin.FpLdSt.reg); 2730 mapRegs_PPCAMode(m, i->Pin.FpLdSt.addr); 2731 return; 2732 case Pin_FpSTFIW: 2733 mapReg(m, &i->Pin.FpSTFIW.addr); 2734 mapReg(m, &i->Pin.FpSTFIW.data); 2735 return; 2736 case Pin_FpRSP: 2737 mapReg(m, &i->Pin.FpRSP.dst); 2738 mapReg(m, &i->Pin.FpRSP.src); 2739 return; 2740 case Pin_FpCftI: 2741 mapReg(m, &i->Pin.FpCftI.dst); 2742 mapReg(m, &i->Pin.FpCftI.src); 2743 return; 2744 case Pin_FpCMov: 2745 mapReg(m, &i->Pin.FpCMov.dst); 2746 mapReg(m, &i->Pin.FpCMov.src); 2747 return; 2748 case Pin_FpLdFPSCR: 2749 mapReg(m, &i->Pin.FpLdFPSCR.src); 2750 return; 2751 case Pin_FpCmp: 2752 mapReg(m, &i->Pin.FpCmp.dst); 2753 mapReg(m, &i->Pin.FpCmp.srcL); 2754 mapReg(m, &i->Pin.FpCmp.srcR); 2755 return; 2756 case Pin_RdWrLR: 2757 mapReg(m, &i->Pin.RdWrLR.gpr); 2758 return; 2759 case Pin_AvLdSt: 2760 mapReg(m, &i->Pin.AvLdSt.reg); 2761 mapRegs_PPCAMode(m, i->Pin.AvLdSt.addr); 2762 return; 2763 case Pin_AvUnary: 2764 mapReg(m, &i->Pin.AvUnary.dst); 2765 mapReg(m, &i->Pin.AvUnary.src); 2766 return; 2767 case Pin_AvBinary: 2768 mapReg(m, &i->Pin.AvBinary.dst); 2769 mapReg(m, &i->Pin.AvBinary.srcL); 2770 mapReg(m, &i->Pin.AvBinary.srcR); 2771 return; 2772 case Pin_AvBin8x16: 2773 mapReg(m, &i->Pin.AvBin8x16.dst); 2774 mapReg(m, &i->Pin.AvBin8x16.srcL); 2775 mapReg(m, &i->Pin.AvBin8x16.srcR); 2776 return; 2777 case Pin_AvBin16x8: 2778 mapReg(m, &i->Pin.AvBin16x8.dst); 2779 mapReg(m, &i->Pin.AvBin16x8.srcL); 2780 mapReg(m, &i->Pin.AvBin16x8.srcR); 2781 return; 2782 case Pin_AvBin32x4: 2783 mapReg(m, &i->Pin.AvBin32x4.dst); 2784 mapReg(m, &i->Pin.AvBin32x4.srcL); 2785 mapReg(m, &i->Pin.AvBin32x4.srcR); 2786 return; 2787 case Pin_AvBin64x2: 2788 mapReg(m, &i->Pin.AvBin64x2.dst); 2789 mapReg(m, &i->Pin.AvBin64x2.srcL); 2790 mapReg(m, &i->Pin.AvBin64x2.srcR); 2791 return; 2792 case Pin_AvBin32Fx4: 2793 mapReg(m, &i->Pin.AvBin32Fx4.dst); 2794 mapReg(m, &i->Pin.AvBin32Fx4.srcL); 2795 mapReg(m, &i->Pin.AvBin32Fx4.srcR); 2796 return; 2797 case Pin_AvUn32Fx4: 2798 mapReg(m, &i->Pin.AvUn32Fx4.dst); 2799 mapReg(m, &i->Pin.AvUn32Fx4.src); 2800 return; 2801 case Pin_AvPerm: 2802 mapReg(m, &i->Pin.AvPerm.dst); 2803 mapReg(m, &i->Pin.AvPerm.srcL); 2804 mapReg(m, &i->Pin.AvPerm.srcR); 2805 mapReg(m, &i->Pin.AvPerm.ctl); 2806 return; 2807 case Pin_AvSel: 2808 mapReg(m, &i->Pin.AvSel.dst); 2809 mapReg(m, &i->Pin.AvSel.srcL); 2810 mapReg(m, &i->Pin.AvSel.srcR); 2811 mapReg(m, &i->Pin.AvSel.ctl); 2812 return; 2813 case Pin_AvSh: 2814 mapReg(m, &i->Pin.AvSh.dst); 2815 mapRegs_PPCAMode(m, i->Pin.AvSh.addr); 2816 return; 2817 case Pin_AvShlDbl: 2818 mapReg(m, &i->Pin.AvShlDbl.dst); 2819 mapReg(m, &i->Pin.AvShlDbl.srcL); 2820 mapReg(m, &i->Pin.AvShlDbl.srcR); 2821 return; 2822 case Pin_AvSplat: 2823 mapReg(m, &i->Pin.AvSplat.dst); 2824 mapRegs_PPCVI5s(m, i->Pin.AvSplat.src); 2825 return; 2826 case Pin_AvCMov: 2827 mapReg(m, &i->Pin.AvCMov.dst); 2828 mapReg(m, &i->Pin.AvCMov.src); 2829 return; 2830 case Pin_AvLdVSCR: 2831 mapReg(m, &i->Pin.AvLdVSCR.src); 2832 return; 2833 case Pin_AvCipherV128Unary: 2834 mapReg(m, &i->Pin.AvCipherV128Unary.dst); 2835 mapReg(m, &i->Pin.AvCipherV128Unary.src); 2836 return; 2837 case Pin_AvCipherV128Binary: 2838 mapReg(m, &i->Pin.AvCipherV128Binary.dst); 2839 mapReg(m, &i->Pin.AvCipherV128Binary.srcL); 2840 mapReg(m, &i->Pin.AvCipherV128Binary.srcR); 2841 return; 2842 case Pin_AvHashV128Binary: 2843 mapRegs_PPCRI(m, i->Pin.AvHashV128Binary.s_field); 2844 mapReg(m, &i->Pin.AvHashV128Binary.dst); 2845 mapReg(m, &i->Pin.AvHashV128Binary.src); 2846 return; 2847 case Pin_AvBCDV128Trinary: 2848 mapReg(m, &i->Pin.AvBCDV128Trinary.dst); 2849 mapReg(m, &i->Pin.AvBCDV128Trinary.src1); 2850 mapReg(m, &i->Pin.AvBCDV128Trinary.src2); 2851 mapRegs_PPCRI(m, i->Pin.AvBCDV128Trinary.ps); 2852 return; 2853 case Pin_Dfp64Unary: 2854 mapReg(m, &i->Pin.Dfp64Unary.dst); 2855 mapReg(m, &i->Pin.Dfp64Unary.src); 2856 return; 2857 case Pin_Dfp64Binary: 2858 mapReg(m, &i->Pin.Dfp64Binary.dst); 2859 mapReg(m, &i->Pin.Dfp64Binary.srcL); 2860 mapReg(m, &i->Pin.Dfp64Binary.srcR); 2861 return; 2862 case Pin_DfpShift: 2863 mapRegs_PPCRI(m, i->Pin.DfpShift.shift); 2864 mapReg(m, &i->Pin.DfpShift.src); 2865 mapReg(m, &i->Pin.DfpShift.dst); 2866 return; 2867 case Pin_Dfp128Unary: 2868 mapReg(m, &i->Pin.Dfp128Unary.dst_hi); 2869 mapReg(m, &i->Pin.Dfp128Unary.dst_lo); 2870 mapReg(m, &i->Pin.Dfp128Unary.src_hi); 2871 mapReg(m, &i->Pin.Dfp128Unary.src_lo); 2872 return; 2873 case Pin_Dfp128Binary: 2874 mapReg(m, &i->Pin.Dfp128Binary.dst_hi); 2875 mapReg(m, &i->Pin.Dfp128Binary.dst_lo); 2876 mapReg(m, &i->Pin.Dfp128Binary.srcR_hi); 2877 mapReg(m, &i->Pin.Dfp128Binary.srcR_lo); 2878 return; 2879 case Pin_DfpShift128: 2880 mapRegs_PPCRI(m, i->Pin.DfpShift128.shift); 2881 mapReg(m, &i->Pin.DfpShift128.src_hi); 2882 mapReg(m, &i->Pin.DfpShift128.src_lo); 2883 mapReg(m, &i->Pin.DfpShift128.dst_hi); 2884 mapReg(m, &i->Pin.DfpShift128.dst_lo); 2885 return; 2886 case Pin_DfpRound: 2887 mapReg(m, &i->Pin.DfpRound.dst); 2888 mapReg(m, &i->Pin.DfpRound.src); 2889 return; 2890 case Pin_DfpRound128: 2891 mapReg(m, &i->Pin.DfpRound128.dst_hi); 2892 mapReg(m, &i->Pin.DfpRound128.dst_lo); 2893 mapReg(m, &i->Pin.DfpRound128.src_hi); 2894 mapReg(m, &i->Pin.DfpRound128.src_lo); 2895 return; 2896 case Pin_DfpQuantize: 2897 mapRegs_PPCRI(m, i->Pin.DfpQuantize.rmc); 2898 mapReg(m, &i->Pin.DfpQuantize.dst); 2899 mapReg(m, &i->Pin.DfpQuantize.srcL); 2900 mapReg(m, &i->Pin.DfpQuantize.srcR); 2901 return; 2902 case Pin_DfpQuantize128: 2903 mapRegs_PPCRI(m, i->Pin.DfpQuantize128.rmc); 2904 mapReg(m, &i->Pin.DfpQuantize128.dst_hi); 2905 mapReg(m, &i->Pin.DfpQuantize128.dst_lo); 2906 mapReg(m, &i->Pin.DfpQuantize128.src_hi); 2907 mapReg(m, &i->Pin.DfpQuantize128.src_lo); 2908 return; 2909 case Pin_DfpD128toD64: 2910 mapReg(m, &i->Pin.DfpD128toD64.src_hi); 2911 mapReg(m, &i->Pin.DfpD128toD64.src_lo); 2912 mapReg(m, &i->Pin.DfpD128toD64.dst); 2913 return; 2914 case Pin_DfpI64StoD128: 2915 mapReg(m, &i->Pin.DfpI64StoD128.src); 2916 mapReg(m, &i->Pin.DfpI64StoD128.dst_hi); 2917 mapReg(m, &i->Pin.DfpI64StoD128.dst_lo); 2918 return; 2919 case Pin_ExtractExpD128: 2920 mapReg(m, &i->Pin.ExtractExpD128.dst); 2921 mapReg(m, &i->Pin.ExtractExpD128.src_hi); 2922 mapReg(m, &i->Pin.ExtractExpD128.src_lo); 2923 return; 2924 case Pin_InsertExpD128: 2925 mapReg(m, &i->Pin.InsertExpD128.dst_hi); 2926 mapReg(m, &i->Pin.InsertExpD128.dst_lo); 2927 mapReg(m, &i->Pin.InsertExpD128.srcL); 2928 mapReg(m, &i->Pin.InsertExpD128.srcR_hi); 2929 mapReg(m, &i->Pin.InsertExpD128.srcR_lo); 2930 return; 2931 case Pin_Dfp64Cmp: 2932 mapReg(m, &i->Pin.Dfp64Cmp.dst); 2933 mapReg(m, &i->Pin.Dfp64Cmp.srcL); 2934 mapReg(m, &i->Pin.Dfp64Cmp.srcR); 2935 return; 2936 case Pin_Dfp128Cmp: 2937 mapReg(m, &i->Pin.Dfp128Cmp.dst); 2938 mapReg(m, &i->Pin.Dfp128Cmp.srcL_hi); 2939 mapReg(m, &i->Pin.Dfp128Cmp.srcL_lo); 2940 mapReg(m, &i->Pin.Dfp128Cmp.srcR_hi); 2941 mapReg(m, &i->Pin.Dfp128Cmp.srcR_lo); 2942 return; 2943 case Pin_EvCheck: 2944 /* We expect both amodes only to mention the GSP (r31), so this 2945 is in fact pointless, since GSP isn't allocatable, but 2946 anyway.. */ 2947 mapRegs_PPCAMode(m, i->Pin.EvCheck.amCounter); 2948 mapRegs_PPCAMode(m, i->Pin.EvCheck.amFailAddr); 2949 return; 2950 case Pin_ProfInc: 2951 /* hardwires r29 and r30 -- nothing to modify. */ 2952 return; 2953 default: 2954 ppPPCInstr(i, mode64); 2955 vpanic("mapRegs_PPCInstr"); 2956 } 2957 } 2958 2959 /* Figure out if i represents a reg-reg move, and if so assign the 2960 source and destination to *src and *dst. If in doubt say No. Used 2961 by the register allocator to do move coalescing. 2962 */ 2963 Bool isMove_PPCInstr ( const PPCInstr* i, HReg* src, HReg* dst ) 2964 { 2965 /* Moves between integer regs */ 2966 if (i->tag == Pin_Alu) { 2967 // or Rd,Rs,Rs == mr Rd,Rs 2968 if (i->Pin.Alu.op != Palu_OR) 2969 return False; 2970 if (i->Pin.Alu.srcR->tag != Prh_Reg) 2971 return False; 2972 if (! sameHReg(i->Pin.Alu.srcR->Prh.Reg.reg, i->Pin.Alu.srcL)) 2973 return False; 2974 *src = i->Pin.Alu.srcL; 2975 *dst = i->Pin.Alu.dst; 2976 return True; 2977 } 2978 /* Moves between FP regs */ 2979 if (i->tag == Pin_FpUnary) { 2980 if (i->Pin.FpUnary.op != Pfp_MOV) 2981 return False; 2982 *src = i->Pin.FpUnary.src; 2983 *dst = i->Pin.FpUnary.dst; 2984 return True; 2985 } 2986 return False; 2987 } 2988 2989 2990 /* Generate ppc spill/reload instructions under the direction of the 2991 register allocator. Note it's critical these don't write the 2992 condition codes. */ 2993 2994 void genSpill_PPC ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2, 2995 HReg rreg, Int offsetB, Bool mode64 ) 2996 { 2997 PPCAMode* am; 2998 vassert(!hregIsVirtual(rreg)); 2999 *i1 = *i2 = NULL; 3000 am = PPCAMode_IR( offsetB, GuestStatePtr(mode64) ); 3001 switch (hregClass(rreg)) { 3002 case HRcInt64: 3003 vassert(mode64); 3004 *i1 = PPCInstr_Store( 8, am, rreg, mode64 ); 3005 return; 3006 case HRcInt32: 3007 vassert(!mode64); 3008 *i1 = PPCInstr_Store( 4, am, rreg, mode64 ); 3009 return; 3010 case HRcFlt64: 3011 *i1 = PPCInstr_FpLdSt ( False/*store*/, 8, rreg, am ); 3012 return; 3013 case HRcVec128: 3014 // XXX: GPR30 used as spill register to kludge AltiVec 3015 // AMode_IR 3016 *i1 = PPCInstr_AvLdSt ( False/*store*/, 16, rreg, am ); 3017 return; 3018 default: 3019 ppHRegClass(hregClass(rreg)); 3020 vpanic("genSpill_PPC: unimplemented regclass"); 3021 } 3022 } 3023 3024 void genReload_PPC ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2, 3025 HReg rreg, Int offsetB, Bool mode64 ) 3026 { 3027 PPCAMode* am; 3028 vassert(!hregIsVirtual(rreg)); 3029 *i1 = *i2 = NULL; 3030 am = PPCAMode_IR( offsetB, GuestStatePtr(mode64) ); 3031 switch (hregClass(rreg)) { 3032 case HRcInt64: 3033 vassert(mode64); 3034 *i1 = PPCInstr_Load( 8, rreg, am, mode64 ); 3035 return; 3036 case HRcInt32: 3037 vassert(!mode64); 3038 *i1 = PPCInstr_Load( 4, rreg, am, mode64 ); 3039 return; 3040 case HRcFlt64: 3041 *i1 = PPCInstr_FpLdSt ( True/*load*/, 8, rreg, am ); 3042 return; 3043 case HRcVec128: 3044 // XXX: GPR30 used as spill register to kludge AltiVec AMode_IR 3045 *i1 = PPCInstr_AvLdSt ( True/*load*/, 16, rreg, am ); 3046 return; 3047 default: 3048 ppHRegClass(hregClass(rreg)); 3049 vpanic("genReload_PPC: unimplemented regclass"); 3050 } 3051 } 3052 3053 3054 /* --------- The ppc assembler (bleh.) --------- */ 3055 3056 inline static UInt iregEnc ( HReg r, Bool mode64 ) 3057 { 3058 UInt n; 3059 vassert(hregClass(r) == (mode64 ? HRcInt64 : HRcInt32)); 3060 vassert(!hregIsVirtual(r)); 3061 n = hregEncoding(r); 3062 vassert(n <= 32); 3063 return n; 3064 } 3065 3066 inline static UInt fregEnc ( HReg fr ) 3067 { 3068 UInt n; 3069 vassert(hregClass(fr) == HRcFlt64); 3070 vassert(!hregIsVirtual(fr)); 3071 n = hregEncoding(fr); 3072 vassert(n <= 32); 3073 return n; 3074 } 3075 3076 inline static UInt vregEnc ( HReg v ) 3077 { 3078 UInt n; 3079 vassert(hregClass(v) == HRcVec128); 3080 vassert(!hregIsVirtual(v)); 3081 n = hregEncoding(v); 3082 vassert(n <= 32); 3083 return n; 3084 } 3085 3086 /* Emit an instruction ppc-endianly */ 3087 static UChar* emit32 ( UChar* p, UInt w32, VexEndness endness_host ) 3088 { 3089 if (endness_host == VexEndnessBE) { 3090 *p++ = toUChar((w32 >> 24) & 0x000000FF); 3091 *p++ = toUChar((w32 >> 16) & 0x000000FF); 3092 *p++ = toUChar((w32 >> 8) & 0x000000FF); 3093 *p++ = toUChar((w32) & 0x000000FF); 3094 } else { 3095 *p++ = toUChar((w32) & 0x000000FF); 3096 *p++ = toUChar((w32 >> 8) & 0x000000FF); 3097 *p++ = toUChar((w32 >> 16) & 0x000000FF); 3098 *p++ = toUChar((w32 >> 24) & 0x000000FF); 3099 } 3100 return p; 3101 } 3102 3103 /* Fetch an instruction ppc-endianly */ 3104 static UInt fetch32 ( UChar* p, VexEndness endness_host ) 3105 { 3106 UInt w32 = 0; 3107 if (endness_host == VexEndnessBE) { 3108 w32 |= ((0xFF & (UInt)p[0]) << 24); 3109 w32 |= ((0xFF & (UInt)p[1]) << 16); 3110 w32 |= ((0xFF & (UInt)p[2]) << 8); 3111 w32 |= ((0xFF & (UInt)p[3]) << 0); 3112 } else { 3113 w32 |= ((0xFF & (UInt)p[3]) << 24); 3114 w32 |= ((0xFF & (UInt)p[2]) << 16); 3115 w32 |= ((0xFF & (UInt)p[1]) << 8); 3116 w32 |= ((0xFF & (UInt)p[0]) << 0); 3117 } 3118 return w32; 3119 } 3120 3121 /* The following mkForm[...] functions refer to ppc instruction forms 3122 as per PPC32 p576 3123 */ 3124 3125 static UChar* mkFormD ( UChar* p, UInt opc1, 3126 UInt r1, UInt r2, UInt imm, VexEndness endness_host ) 3127 { 3128 UInt theInstr; 3129 vassert(opc1 < 0x40); 3130 vassert(r1 < 0x20); 3131 vassert(r2 < 0x20); 3132 imm = imm & 0xFFFF; 3133 theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) | (imm)); 3134 return emit32(p, theInstr, endness_host); 3135 } 3136 3137 static UChar* mkFormMD ( UChar* p, UInt opc1, UInt r1, UInt r2, 3138 UInt imm1, UInt imm2, UInt opc2, 3139 VexEndness endness_host ) 3140 { 3141 UInt theInstr; 3142 vassert(opc1 < 0x40); 3143 vassert(r1 < 0x20); 3144 vassert(r2 < 0x20); 3145 vassert(imm1 < 0x40); 3146 vassert(imm2 < 0x40); 3147 vassert(opc2 < 0x08); 3148 imm2 = ((imm2 & 0x1F) << 1) | (imm2 >> 5); 3149 theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) | 3150 ((imm1 & 0x1F)<<11) | (imm2<<5) | 3151 (opc2<<2) | ((imm1 >> 5)<<1)); 3152 return emit32(p, theInstr, endness_host); 3153 } 3154 3155 static UChar* mkFormX ( UChar* p, UInt opc1, UInt r1, UInt r2, 3156 UInt r3, UInt opc2, UInt b0, VexEndness endness_host ) 3157 { 3158 UInt theInstr; 3159 vassert(opc1 < 0x40); 3160 vassert(r1 < 0x20); 3161 vassert(r2 < 0x20); 3162 vassert(r3 < 0x20); 3163 vassert(opc2 < 0x400); 3164 vassert(b0 < 0x2); 3165 theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) | 3166 (r3<<11) | (opc2<<1) | (b0)); 3167 return emit32(p, theInstr, endness_host); 3168 } 3169 3170 static UChar* mkFormXO ( UChar* p, UInt opc1, UInt r1, UInt r2, 3171 UInt r3, UInt b10, UInt opc2, UInt b0, 3172 VexEndness endness_host ) 3173 { 3174 UInt theInstr; 3175 vassert(opc1 < 0x40); 3176 vassert(r1 < 0x20); 3177 vassert(r2 < 0x20); 3178 vassert(r3 < 0x20); 3179 vassert(b10 < 0x2); 3180 vassert(opc2 < 0x200); 3181 vassert(b0 < 0x2); 3182 theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) | 3183 (r3<<11) | (b10 << 10) | (opc2<<1) | (b0)); 3184 return emit32(p, theInstr, endness_host); 3185 } 3186 3187 static UChar* mkFormXL ( UChar* p, UInt opc1, UInt f1, UInt f2, 3188 UInt f3, UInt opc2, UInt b0, VexEndness endness_host ) 3189 { 3190 UInt theInstr; 3191 vassert(opc1 < 0x40); 3192 vassert(f1 < 0x20); 3193 vassert(f2 < 0x20); 3194 vassert(f3 < 0x20); 3195 vassert(opc2 < 0x400); 3196 vassert(b0 < 0x2); 3197 theInstr = ((opc1<<26) | (f1<<21) | (f2<<16) | 3198 (f3<<11) | (opc2<<1) | (b0)); 3199 return emit32(p, theInstr, endness_host); 3200 } 3201 3202 // Note: for split field ops, give mnemonic arg 3203 static UChar* mkFormXFX ( UChar* p, UInt r1, UInt f2, UInt opc2, 3204 VexEndness endness_host ) 3205 { 3206 UInt theInstr; 3207 vassert(r1 < 0x20); 3208 vassert(f2 < 0x20); 3209 vassert(opc2 < 0x400); 3210 switch (opc2) { 3211 case 144: // mtcrf 3212 vassert(f2 < 0x100); 3213 f2 = f2 << 1; 3214 break; 3215 case 339: // mfspr 3216 case 371: // mftb 3217 case 467: // mtspr 3218 vassert(f2 < 0x400); 3219 // re-arrange split field 3220 f2 = ((f2>>5) & 0x1F) | ((f2 & 0x1F)<<5); 3221 break; 3222 default: vpanic("mkFormXFX(ppch)"); 3223 } 3224 theInstr = ((31<<26) | (r1<<21) | (f2<<11) | (opc2<<1)); 3225 return emit32(p, theInstr, endness_host); 3226 } 3227 3228 // Only used by mtfsf 3229 static UChar* mkFormXFL ( UChar* p, UInt FM, UInt freg, UInt dfp_rm, 3230 VexEndness endness_host ) 3231 { 3232 UInt theInstr; 3233 vassert(FM < 0x100); 3234 vassert(freg < 0x20); 3235 theInstr = ((63<<26) | (FM<<17) | (dfp_rm<<16) | (freg<<11) | (711<<1)); 3236 return emit32(p, theInstr, endness_host); 3237 } 3238 3239 static UChar* mkFormXS ( UChar* p, UInt opc1, UInt r1, UInt r2, 3240 UInt imm, UInt opc2, UInt b0, 3241 VexEndness endness_host ) 3242 { 3243 UInt theInstr; 3244 vassert(opc1 < 0x40); 3245 vassert(r1 < 0x20); 3246 vassert(r2 < 0x20); 3247 vassert(imm < 0x40); 3248 vassert(opc2 < 0x400); 3249 vassert(b0 < 0x2); 3250 theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) | 3251 ((imm & 0x1F)<<11) | (opc2<<2) | ((imm>>5)<<1) | (b0)); 3252 return emit32(p, theInstr, endness_host); 3253 } 3254 3255 3256 #if 0 3257 // 'b' 3258 static UChar* mkFormI ( UChar* p, UInt LI, UInt AA, UInt LK, 3259 VexEndness endness_host ) 3260 { 3261 UInt theInstr; 3262 vassert(LI < 0x1000000); 3263 vassert(AA < 0x2); 3264 vassert(LK < 0x2); 3265 theInstr = ((18<<26) | (LI<<2) | (AA<<1) | (LK)); 3266 return emit32(p, theInstr, endness_host); 3267 } 3268 #endif 3269 3270 // 'bc' 3271 static UChar* mkFormB ( UChar* p, UInt BO, UInt BI, 3272 UInt BD, UInt AA, UInt LK, VexEndness endness_host ) 3273 { 3274 UInt theInstr; 3275 vassert(BO < 0x20); 3276 vassert(BI < 0x20); 3277 vassert(BD < 0x4000); 3278 vassert(AA < 0x2); 3279 vassert(LK < 0x2); 3280 theInstr = ((16<<26) | (BO<<21) | (BI<<16) | 3281 (BD<<2) | (AA<<1) | (LK)); 3282 return emit32(p, theInstr, endness_host); 3283 } 3284 3285 // rotates 3286 static UChar* mkFormM ( UChar* p, UInt opc1, UInt r1, UInt r2, 3287 UInt f3, UInt MB, UInt ME, UInt Rc, 3288 VexEndness endness_host ) 3289 { 3290 UInt theInstr; 3291 vassert(opc1 < 0x40); 3292 vassert(r1 < 0x20); 3293 vassert(r2 < 0x20); 3294 vassert(f3 < 0x20); 3295 vassert(MB < 0x20); 3296 vassert(ME < 0x20); 3297 vassert(Rc < 0x2); 3298 theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) | 3299 (f3<<11) | (MB<<6) | (ME<<1) | (Rc)); 3300 return emit32(p, theInstr, endness_host); 3301 } 3302 3303 static UChar* mkFormA ( UChar* p, UInt opc1, UInt r1, UInt r2, 3304 UInt r3, UInt r4, UInt opc2, UInt b0, 3305 VexEndness endness_host ) 3306 { 3307 UInt theInstr; 3308 vassert(opc1 < 0x40); 3309 vassert(r1 < 0x20); 3310 vassert(r2 < 0x20); 3311 vassert(r3 < 0x20); 3312 vassert(r4 < 0x20); 3313 vassert(opc2 < 0x20); 3314 vassert(b0 < 0x2 ); 3315 theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) | (r3<<11) | 3316 (r4<<6) | (opc2<<1) | (b0)); 3317 return emit32(p, theInstr, endness_host); 3318 } 3319 3320 static UChar* mkFormZ22 ( UChar* p, UInt opc1, UInt r1, UInt r2, 3321 UInt constant, UInt opc2, UInt b0, 3322 VexEndness endness_host) 3323 { 3324 UInt theInstr; 3325 vassert(opc1 < 0x40); 3326 vassert(r1 < 0x20); 3327 vassert(r2 < 0x20); 3328 vassert(constant < 0x40); /* 6 bit constant */ 3329 vassert(opc2 < 0x200); /* 9 bit field */ 3330 vassert(b0 < 0x2); 3331 theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) | 3332 (constant<<10) | (opc2<<1) | (b0)); 3333 return emit32(p, theInstr, endness_host); 3334 } 3335 3336 static UChar* mkFormZ23 ( UChar* p, UInt opc1, UInt r1, UInt r2, 3337 UInt r3, UInt rmc, UInt opc2, UInt b0, 3338 VexEndness endness_host) 3339 { 3340 UInt theInstr; 3341 vassert(opc1 < 0x40); 3342 vassert(r1 < 0x20); 3343 vassert(r2 < 0x20); 3344 vassert(r3 < 0x20); 3345 vassert(rmc < 0x4); 3346 vassert(opc2 < 0x100); 3347 vassert(b0 < 0x2); 3348 theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) | 3349 (r3<<11) | (rmc<<9) | (opc2<<1) | (b0)); 3350 return emit32(p, theInstr, endness_host); 3351 } 3352 3353 static UChar* doAMode_IR ( UChar* p, UInt opc1, UInt rSD, 3354 PPCAMode* am, Bool mode64, VexEndness endness_host ) 3355 { 3356 UInt rA, idx; 3357 vassert(am->tag == Pam_IR); 3358 vassert(am->Pam.IR.index < 0x10000); 3359 3360 rA = iregEnc(am->Pam.IR.base, mode64); 3361 idx = am->Pam.IR.index; 3362 3363 if (opc1 == 58 || opc1 == 62) { // ld/std: mode64 only 3364 vassert(mode64); 3365 /* stay sane with DS form: lowest 2 bits must be 00. This 3366 should be guaranteed to us by iselWordExpr_AMode. */ 3367 vassert(0 == (idx & 3)); 3368 } 3369 p = mkFormD(p, opc1, rSD, rA, idx, endness_host); 3370 return p; 3371 } 3372 3373 static UChar* doAMode_RR ( UChar* p, UInt opc1, UInt opc2, 3374 UInt rSD, PPCAMode* am, Bool mode64, 3375 VexEndness endness_host ) 3376 { 3377 UInt rA, rB; 3378 vassert(am->tag == Pam_RR); 3379 3380 rA = iregEnc(am->Pam.RR.base, mode64); 3381 rB = iregEnc(am->Pam.RR.index, mode64); 3382 3383 p = mkFormX(p, opc1, rSD, rA, rB, opc2, 0, endness_host); 3384 return p; 3385 } 3386 3387 3388 /* Load imm to r_dst */ 3389 static UChar* mkLoadImm ( UChar* p, UInt r_dst, ULong imm, Bool mode64, 3390 VexEndness endness_host ) 3391 { 3392 vassert(r_dst < 0x20); 3393 3394 if (!mode64) { 3395 /* In 32-bit mode, make sure the top 32 bits of imm are a sign 3396 extension of the bottom 32 bits, so that the range tests 3397 below work correctly. */ 3398 UInt u32 = (UInt)imm; 3399 Int s32 = (Int)u32; 3400 Long s64 = (Long)s32; 3401 imm = (ULong)s64; 3402 } 3403 3404 if (imm >= 0xFFFFFFFFFFFF8000ULL || imm < 0x8000) { 3405 // sign-extendable from 16 bits 3406 3407 // addi r_dst,0,imm => li r_dst,imm 3408 p = mkFormD(p, 14, r_dst, 0, imm & 0xFFFF, endness_host); 3409 } else { 3410 if (imm >= 0xFFFFFFFF80000000ULL || imm < 0x80000000ULL) { 3411 // sign-extendable from 32 bits 3412 3413 // addis r_dst,r0,(imm>>16) => lis r_dst, (imm>>16) 3414 p = mkFormD(p, 15, r_dst, 0, (imm>>16) & 0xFFFF, endness_host); 3415 // ori r_dst, r_dst, (imm & 0xFFFF) 3416 p = mkFormD(p, 24, r_dst, r_dst, imm & 0xFFFF, endness_host); 3417 } else { 3418 // full 64bit immediate load: 5 (five!) insns. 3419 vassert(mode64); 3420 3421 // load high word 3422 3423 // lis r_dst, (imm>>48) & 0xFFFF 3424 p = mkFormD(p, 15, r_dst, 0, (imm>>48) & 0xFFFF, endness_host); 3425 3426 // ori r_dst, r_dst, (imm>>32) & 0xFFFF 3427 if ((imm>>32) & 0xFFFF) 3428 p = mkFormD(p, 24, r_dst, r_dst, (imm>>32) & 0xFFFF, endness_host); 3429 3430 // shift r_dst low word to high word => rldicr 3431 p = mkFormMD(p, 30, r_dst, r_dst, 32, 31, 1, endness_host); 3432 3433 // load low word 3434 3435 // oris r_dst, r_dst, (imm>>16) & 0xFFFF 3436 if ((imm>>16) & 0xFFFF) 3437 p = mkFormD(p, 25, r_dst, r_dst, (imm>>16) & 0xFFFF, endness_host); 3438 3439 // ori r_dst, r_dst, (imm) & 0xFFFF 3440 if (imm & 0xFFFF) 3441 p = mkFormD(p, 24, r_dst, r_dst, imm & 0xFFFF, endness_host); 3442 } 3443 } 3444 return p; 3445 } 3446 3447 /* A simplified version of mkLoadImm that always generates 2 or 5 3448 instructions (32 or 64 bits respectively) even if it could generate 3449 fewer. This is needed for generating fixed sized patchable 3450 sequences. */ 3451 static UChar* mkLoadImm_EXACTLY2or5 ( UChar* p, 3452 UInt r_dst, ULong imm, Bool mode64, 3453 VexEndness endness_host ) 3454 { 3455 vassert(r_dst < 0x20); 3456 3457 if (!mode64) { 3458 /* In 32-bit mode, make sure the top 32 bits of imm are a sign 3459 extension of the bottom 32 bits. (Probably unnecessary.) */ 3460 UInt u32 = (UInt)imm; 3461 Int s32 = (Int)u32; 3462 Long s64 = (Long)s32; 3463 imm = (ULong)s64; 3464 } 3465 3466 if (!mode64) { 3467 // addis r_dst,r0,(imm>>16) => lis r_dst, (imm>>16) 3468 p = mkFormD(p, 15, r_dst, 0, (imm>>16) & 0xFFFF, endness_host); 3469 // ori r_dst, r_dst, (imm & 0xFFFF) 3470 p = mkFormD(p, 24, r_dst, r_dst, imm & 0xFFFF, endness_host); 3471 3472 } else { 3473 // full 64bit immediate load: 5 (five!) insns. 3474 3475 // load high word 3476 // lis r_dst, (imm>>48) & 0xFFFF 3477 p = mkFormD(p, 15, r_dst, 0, (imm>>48) & 0xFFFF, endness_host); 3478 3479 // ori r_dst, r_dst, (imm>>32) & 0xFFFF 3480 p = mkFormD(p, 24, r_dst, r_dst, (imm>>32) & 0xFFFF, endness_host); 3481 3482 // shift r_dst low word to high word => rldicr 3483 p = mkFormMD(p, 30, r_dst, r_dst, 32, 31, 1, endness_host); 3484 3485 // load low word 3486 // oris r_dst, r_dst, (imm>>16) & 0xFFFF 3487 p = mkFormD(p, 25, r_dst, r_dst, (imm>>16) & 0xFFFF, endness_host); 3488 3489 // ori r_dst, r_dst, (imm) & 0xFFFF 3490 p = mkFormD(p, 24, r_dst, r_dst, imm & 0xFFFF, endness_host); 3491 } 3492 return p; 3493 } 3494 3495 /* Checks whether the sequence of bytes at p was indeed created 3496 by mkLoadImm_EXACTLY2or5 with the given parameters. */ 3497 static Bool isLoadImm_EXACTLY2or5 ( UChar* p_to_check, 3498 UInt r_dst, ULong imm, Bool mode64, 3499 VexEndness endness_host ) 3500 { 3501 vassert(r_dst < 0x20); 3502 3503 if (!mode64) { 3504 /* In 32-bit mode, make sure the top 32 bits of imm are a sign 3505 extension of the bottom 32 bits. (Probably unnecessary.) */ 3506 UInt u32 = (UInt)imm; 3507 Int s32 = (Int)u32; 3508 Long s64 = (Long)s32; 3509 imm = (ULong)s64; 3510 } 3511 3512 if (!mode64) { 3513 UInt expect[2] = { 0, 0 }; 3514 UChar* p = (UChar*)&expect[0]; 3515 // addis r_dst,r0,(imm>>16) => lis r_dst, (imm>>16) 3516 p = mkFormD(p, 15, r_dst, 0, (imm>>16) & 0xFFFF, endness_host); 3517 // ori r_dst, r_dst, (imm & 0xFFFF) 3518 p = mkFormD(p, 24, r_dst, r_dst, imm & 0xFFFF, endness_host); 3519 vassert(p == (UChar*)&expect[2]); 3520 3521 return fetch32(p_to_check + 0, endness_host) == expect[0] 3522 && fetch32(p_to_check + 4, endness_host) == expect[1]; 3523 3524 } else { 3525 UInt expect[5] = { 0, 0, 0, 0, 0 }; 3526 UChar* p = (UChar*)&expect[0]; 3527 // full 64bit immediate load: 5 (five!) insns. 3528 3529 // load high word 3530 // lis r_dst, (imm>>48) & 0xFFFF 3531 p = mkFormD(p, 15, r_dst, 0, (imm>>48) & 0xFFFF, endness_host); 3532 3533 // ori r_dst, r_dst, (imm>>32) & 0xFFFF 3534 p = mkFormD(p, 24, r_dst, r_dst, (imm>>32) & 0xFFFF, endness_host); 3535 3536 // shift r_dst low word to high word => rldicr 3537 p = mkFormMD(p, 30, r_dst, r_dst, 32, 31, 1, endness_host); 3538 3539 // load low word 3540 // oris r_dst, r_dst, (imm>>16) & 0xFFFF 3541 p = mkFormD(p, 25, r_dst, r_dst, (imm>>16) & 0xFFFF, endness_host); 3542 3543 // ori r_dst, r_dst, (imm) & 0xFFFF 3544 p = mkFormD(p, 24, r_dst, r_dst, imm & 0xFFFF, endness_host); 3545 3546 vassert(p == (UChar*)&expect[5]); 3547 3548 return fetch32(p_to_check + 0, endness_host) == expect[0] 3549 && fetch32(p_to_check + 4, endness_host) == expect[1] 3550 && fetch32(p_to_check + 8, endness_host) == expect[2] 3551 && fetch32(p_to_check + 12, endness_host) == expect[3] 3552 && fetch32(p_to_check + 16, endness_host) == expect[4]; 3553 } 3554 } 3555 3556 3557 /* Generate a machine-word sized load or store. Simplified version of 3558 the Pin_Load and Pin_Store cases below. */ 3559 static UChar* do_load_or_store_machine_word ( 3560 UChar* p, Bool isLoad, 3561 UInt reg, PPCAMode* am, Bool mode64, VexEndness endness_host ) 3562 { 3563 if (isLoad) { 3564 UInt opc1, sz = mode64 ? 8 : 4; 3565 switch (am->tag) { 3566 case Pam_IR: 3567 if (mode64) { 3568 vassert(0 == (am->Pam.IR.index & 3)); 3569 } 3570 switch (sz) { 3571 case 4: opc1 = 32; vassert(!mode64); break; 3572 case 8: opc1 = 58; vassert(mode64); break; 3573 default: vassert(0); 3574 } 3575 p = doAMode_IR(p, opc1, reg, am, mode64, endness_host); 3576 break; 3577 case Pam_RR: 3578 /* we could handle this case, but we don't expect to ever 3579 need to. */ 3580 vassert(0); 3581 default: 3582 vassert(0); 3583 } 3584 } else /*store*/ { 3585 UInt opc1, sz = mode64 ? 8 : 4; 3586 switch (am->tag) { 3587 case Pam_IR: 3588 if (mode64) { 3589 vassert(0 == (am->Pam.IR.index & 3)); 3590 } 3591 switch (sz) { 3592 case 4: opc1 = 36; vassert(!mode64); break; 3593 case 8: opc1 = 62; vassert(mode64); break; 3594 default: vassert(0); 3595 } 3596 p = doAMode_IR(p, opc1, reg, am, mode64, endness_host); 3597 break; 3598 case Pam_RR: 3599 /* we could handle this case, but we don't expect to ever 3600 need to. */ 3601 vassert(0); 3602 default: 3603 vassert(0); 3604 } 3605 } 3606 return p; 3607 } 3608 3609 /* Generate a 32-bit sized load or store. Simplified version of 3610 do_load_or_store_machine_word above. */ 3611 static UChar* do_load_or_store_word32 ( 3612 UChar* p, Bool isLoad, 3613 UInt reg, PPCAMode* am, Bool mode64, VexEndness endness_host ) 3614 { 3615 if (isLoad) { 3616 UInt opc1; 3617 switch (am->tag) { 3618 case Pam_IR: 3619 if (mode64) { 3620 vassert(0 == (am->Pam.IR.index & 3)); 3621 } 3622 opc1 = 32; 3623 p = doAMode_IR(p, opc1, reg, am, mode64, endness_host); 3624 break; 3625 case Pam_RR: 3626 /* we could handle this case, but we don't expect to ever 3627 need to. */ 3628 vassert(0); 3629 default: 3630 vassert(0); 3631 } 3632 } else /*store*/ { 3633 UInt opc1; 3634 switch (am->tag) { 3635 case Pam_IR: 3636 if (mode64) { 3637 vassert(0 == (am->Pam.IR.index & 3)); 3638 } 3639 opc1 = 36; 3640 p = doAMode_IR(p, opc1, reg, am, mode64, endness_host); 3641 break; 3642 case Pam_RR: 3643 /* we could handle this case, but we don't expect to ever 3644 need to. */ 3645 vassert(0); 3646 default: 3647 vassert(0); 3648 } 3649 } 3650 return p; 3651 } 3652 3653 /* Move r_dst to r_src */ 3654 static UChar* mkMoveReg ( UChar* p, UInt r_dst, UInt r_src, 3655 VexEndness endness_host ) 3656 { 3657 vassert(r_dst < 0x20); 3658 vassert(r_src < 0x20); 3659 3660 if (r_dst != r_src) { 3661 /* or r_dst, r_src, r_src */ 3662 p = mkFormX(p, 31, r_src, r_dst, r_src, 444, 0, endness_host ); 3663 } 3664 return p; 3665 } 3666 3667 static UChar* mkFormVX ( UChar* p, UInt opc1, UInt r1, UInt r2, 3668 UInt r3, UInt opc2, VexEndness endness_host ) 3669 { 3670 UInt theInstr; 3671 vassert(opc1 < 0x40); 3672 vassert(r1 < 0x20); 3673 vassert(r2 < 0x20); 3674 vassert(r3 < 0x20); 3675 vassert(opc2 < 0x800); 3676 theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) | (r3<<11) | opc2); 3677 return emit32(p, theInstr, endness_host); 3678 } 3679 3680 static UChar* mkFormVXI ( UChar* p, UInt opc1, UInt r1, UInt r2, 3681 UInt r3, UInt opc2, VexEndness endness_host ) 3682 { 3683 UInt theInstr; 3684 vassert(opc1 < 0x40); 3685 vassert(r1 < 0x20); 3686 vassert(r2 < 0x20); 3687 vassert(r3 < 0x20); 3688 vassert(opc2 < 0x27); 3689 theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) | (r3<<11) | opc2<<1); 3690 return emit32(p, theInstr, endness_host); 3691 } 3692 3693 static UChar* mkFormVXR ( UChar* p, UInt opc1, UInt r1, UInt r2, 3694 UInt r3, UInt Rc, UInt opc2, 3695 VexEndness endness_host ) 3696 { 3697 UInt theInstr; 3698 vassert(opc1 < 0x40); 3699 vassert(r1 < 0x20); 3700 vassert(r2 < 0x20); 3701 vassert(r3 < 0x20); 3702 vassert(Rc < 0x2); 3703 vassert(opc2 < 0x400); 3704 theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) | 3705 (r3<<11) | (Rc<<10) | opc2); 3706 return emit32(p, theInstr, endness_host); 3707 } 3708 3709 static UChar* mkFormVA ( UChar* p, UInt opc1, UInt r1, UInt r2, 3710 UInt r3, UInt r4, UInt opc2, VexEndness endness_host ) 3711 { 3712 UInt theInstr; 3713 vassert(opc1 < 0x40); 3714 vassert(r1 < 0x20); 3715 vassert(r2 < 0x20); 3716 vassert(r3 < 0x20); 3717 vassert(r4 < 0x20); 3718 vassert(opc2 < 0x40); 3719 theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) | 3720 (r3<<11) | (r4<<6) | opc2); 3721 return emit32(p, theInstr, endness_host); 3722 } 3723 3724 3725 3726 /* Emit an instruction into buf and return the number of bytes used. 3727 Note that buf is not the insn's final place, and therefore it is 3728 imperative to emit position-independent code. If the emitted 3729 instruction was a profiler inc, set *is_profInc to True, else leave 3730 it unchanged. 3731 */ 3732 Int emit_PPCInstr ( /*MB_MOD*/Bool* is_profInc, 3733 UChar* buf, Int nbuf, const PPCInstr* i, 3734 Bool mode64, VexEndness endness_host, 3735 const void* disp_cp_chain_me_to_slowEP, 3736 const void* disp_cp_chain_me_to_fastEP, 3737 const void* disp_cp_xindir, 3738 const void* disp_cp_xassisted) 3739 { 3740 UChar* p = &buf[0]; 3741 vassert(nbuf >= 32); 3742 3743 if (0) { 3744 vex_printf("asm ");ppPPCInstr(i, mode64); vex_printf("\n"); 3745 } 3746 3747 switch (i->tag) { 3748 3749 case Pin_LI: 3750 p = mkLoadImm(p, iregEnc(i->Pin.LI.dst, mode64), 3751 i->Pin.LI.imm64, mode64, endness_host); 3752 goto done; 3753 3754 case Pin_Alu: { 3755 PPCRH* srcR = i->Pin.Alu.srcR; 3756 Bool immR = toBool(srcR->tag == Prh_Imm); 3757 UInt r_dst = iregEnc(i->Pin.Alu.dst, mode64); 3758 UInt r_srcL = iregEnc(i->Pin.Alu.srcL, mode64); 3759 UInt r_srcR = immR ? (-1)/*bogus*/ : 3760 iregEnc(srcR->Prh.Reg.reg, mode64); 3761 3762 switch (i->Pin.Alu.op) { 3763 case Palu_ADD: 3764 if (immR) { 3765 /* addi (PPC32 p350) */ 3766 vassert(srcR->Prh.Imm.syned); 3767 vassert(srcR->Prh.Imm.imm16 != 0x8000); 3768 p = mkFormD(p, 14, r_dst, r_srcL, srcR->Prh.Imm.imm16, endness_host); 3769 } else { 3770 /* add (PPC32 p347) */ 3771 p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 266, 0, endness_host); 3772 } 3773 break; 3774 3775 case Palu_SUB: 3776 if (immR) { 3777 /* addi (PPC32 p350), but with negated imm */ 3778 vassert(srcR->Prh.Imm.syned); 3779 vassert(srcR->Prh.Imm.imm16 != 0x8000); 3780 p = mkFormD(p, 14, r_dst, r_srcL, (- srcR->Prh.Imm.imm16), 3781 endness_host); 3782 } else { 3783 /* subf (PPC32 p537), with args the "wrong" way round */ 3784 p = mkFormXO(p, 31, r_dst, r_srcR, r_srcL, 0, 40, 0, endness_host); 3785 } 3786 break; 3787 3788 case Palu_AND: 3789 if (immR) { 3790 /* andi. (PPC32 p358) */ 3791 vassert(!srcR->Prh.Imm.syned); 3792 p = mkFormD(p, 28, r_srcL, r_dst, srcR->Prh.Imm.imm16, endness_host); 3793 } else { 3794 /* and (PPC32 p356) */ 3795 p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 28, 0, endness_host); 3796 } 3797 break; 3798 3799 case Palu_OR: 3800 if (immR) { 3801 /* ori (PPC32 p497) */ 3802 vassert(!srcR->Prh.Imm.syned); 3803 p = mkFormD(p, 24, r_srcL, r_dst, srcR->Prh.Imm.imm16, endness_host); 3804 } else { 3805 /* or (PPC32 p495) */ 3806 p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 444, 0, endness_host); 3807 } 3808 break; 3809 3810 case Palu_XOR: 3811 if (immR) { 3812 /* xori (PPC32 p550) */ 3813 vassert(!srcR->Prh.Imm.syned); 3814 p = mkFormD(p, 26, r_srcL, r_dst, srcR->Prh.Imm.imm16, endness_host); 3815 } else { 3816 /* xor (PPC32 p549) */ 3817 p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 316, 0, endness_host); 3818 } 3819 break; 3820 3821 default: 3822 goto bad; 3823 } 3824 goto done; 3825 } 3826 3827 case Pin_Shft: { 3828 PPCRH* srcR = i->Pin.Shft.srcR; 3829 Bool sz32 = i->Pin.Shft.sz32; 3830 Bool immR = toBool(srcR->tag == Prh_Imm); 3831 UInt r_dst = iregEnc(i->Pin.Shft.dst, mode64); 3832 UInt r_srcL = iregEnc(i->Pin.Shft.srcL, mode64); 3833 UInt r_srcR = immR ? (-1)/*bogus*/ : 3834 iregEnc(srcR->Prh.Reg.reg, mode64); 3835 if (!mode64) 3836 vassert(sz32); 3837 3838 switch (i->Pin.Shft.op) { 3839 case Pshft_SHL: 3840 if (sz32) { 3841 if (immR) { 3842 /* rd = rs << n, 1 <= n <= 31 3843 is 3844 rlwinm rd,rs,n,0,31-n (PPC32 p501) 3845 */ 3846 UInt n = srcR->Prh.Imm.imm16; 3847 vassert(!srcR->Prh.Imm.syned); 3848 vassert(n > 0 && n < 32); 3849 p = mkFormM(p, 21, r_srcL, r_dst, n, 0, 31-n, 0, endness_host); 3850 } else { 3851 /* slw (PPC32 p505) */ 3852 p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 24, 0, endness_host); 3853 } 3854 } else { 3855 if (immR) { 3856 /* rd = rs << n, 1 <= n <= 63 3857 is 3858 rldicr rd,rs,n,63-n (PPC64 p559) 3859 */ 3860 UInt n = srcR->Prh.Imm.imm16; 3861 vassert(!srcR->Prh.Imm.syned); 3862 vassert(n > 0 && n < 64); 3863 p = mkFormMD(p, 30, r_srcL, r_dst, n, 63-n, 1, endness_host); 3864 } else { 3865 /* sld (PPC64 p568) */ 3866 p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 27, 0, endness_host); 3867 } 3868 } 3869 break; 3870 3871 case Pshft_SHR: 3872 if (sz32) { 3873 if (immR) { 3874 /* rd = rs >>u n, 1 <= n <= 31 3875 is 3876 rlwinm rd,rs,32-n,n,31 (PPC32 p501) 3877 */ 3878 UInt n = srcR->Prh.Imm.imm16; 3879 vassert(!srcR->Prh.Imm.syned); 3880 vassert(n > 0 && n < 32); 3881 p = mkFormM(p, 21, r_srcL, r_dst, 32-n, n, 31, 0, endness_host); 3882 } else { 3883 /* srw (PPC32 p508) */ 3884 p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 536, 0, endness_host); 3885 } 3886 } else { 3887 if (immR) { 3888 /* rd = rs >>u n, 1 <= n <= 63 3889 is 3890 rldicl rd,rs,64-n,n (PPC64 p558) 3891 */ 3892 UInt n = srcR->Prh.Imm.imm16; 3893 vassert(!srcR->Prh.Imm.syned); 3894 vassert(n > 0 && n < 64); 3895 p = mkFormMD(p, 30, r_srcL, r_dst, 64-n, n, 0, endness_host); 3896 } else { 3897 /* srd (PPC64 p574) */ 3898 p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 539, 0, endness_host); 3899 } 3900 } 3901 break; 3902 3903 case Pshft_SAR: 3904 if (sz32) { 3905 if (immR) { 3906 /* srawi (PPC32 p507) */ 3907 UInt n = srcR->Prh.Imm.imm16; 3908 vassert(!srcR->Prh.Imm.syned); 3909 /* In 64-bit mode, we allow right shifts by zero bits 3910 as that is a handy way to sign extend the lower 32 3911 bits into the upper 32 bits. */ 3912 if (mode64) 3913 vassert(n >= 0 && n < 32); 3914 else 3915 vassert(n > 0 && n < 32); 3916 p = mkFormX(p, 31, r_srcL, r_dst, n, 824, 0, endness_host); 3917 } else { 3918 /* sraw (PPC32 p506) */ 3919 p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 792, 0, endness_host); 3920 } 3921 } else { 3922 if (immR) { 3923 /* sradi (PPC64 p571) */ 3924 UInt n = srcR->Prh.Imm.imm16; 3925 vassert(!srcR->Prh.Imm.syned); 3926 vassert(n > 0 && n < 64); 3927 p = mkFormXS(p, 31, r_srcL, r_dst, n, 413, 0, endness_host); 3928 } else { 3929 /* srad (PPC32 p570) */ 3930 p = mkFormX(p, 31, r_srcL, r_dst, r_srcR, 794, 0, endness_host); 3931 } 3932 } 3933 break; 3934 3935 default: 3936 goto bad; 3937 } 3938 goto done; 3939 } 3940 3941 case Pin_AddSubC: { 3942 Bool isAdd = i->Pin.AddSubC.isAdd; 3943 Bool setC = i->Pin.AddSubC.setC; 3944 UInt r_srcL = iregEnc(i->Pin.AddSubC.srcL, mode64); 3945 UInt r_srcR = iregEnc(i->Pin.AddSubC.srcR, mode64); 3946 UInt r_dst = iregEnc(i->Pin.AddSubC.dst, mode64); 3947 3948 if (isAdd) { 3949 if (setC) /* addc (PPC32 p348) */ 3950 p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 10, 0, endness_host); 3951 else /* adde (PPC32 p349) */ 3952 p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 138, 0, endness_host); 3953 } else { 3954 /* subfX, with args the "wrong" way round */ 3955 if (setC) /* subfc (PPC32 p538) */ 3956 p = mkFormXO(p, 31, r_dst, r_srcR, r_srcL, 0, 8, 0, endness_host); 3957 else /* subfe (PPC32 p539) */ 3958 p = mkFormXO(p, 31, r_dst, r_srcR, r_srcL, 0, 136, 0, endness_host); 3959 } 3960 goto done; 3961 } 3962 3963 case Pin_Cmp: { 3964 Bool syned = i->Pin.Cmp.syned; 3965 Bool sz32 = i->Pin.Cmp.sz32; 3966 UInt fld1 = i->Pin.Cmp.crfD << 2; 3967 UInt r_srcL = iregEnc(i->Pin.Cmp.srcL, mode64); 3968 UInt r_srcR, imm_srcR; 3969 PPCRH* srcR = i->Pin.Cmp.srcR; 3970 3971 if (!mode64) // cmp double word invalid for mode32 3972 vassert(sz32); 3973 else if (!sz32) // mode64 && cmp64: set L=1 3974 fld1 |= 1; 3975 3976 switch (srcR->tag) { 3977 case Prh_Imm: 3978 vassert(syned == srcR->Prh.Imm.syned); 3979 imm_srcR = srcR->Prh.Imm.imm16; 3980 if (syned) { // cmpw/di (signed) (PPC32 p368) 3981 vassert(imm_srcR != 0x8000); 3982 p = mkFormD(p, 11, fld1, r_srcL, imm_srcR, endness_host); 3983 } else { // cmplw/di (unsigned) (PPC32 p370) 3984 p = mkFormD(p, 10, fld1, r_srcL, imm_srcR, endness_host); 3985 } 3986 break; 3987 case Prh_Reg: 3988 r_srcR = iregEnc(srcR->Prh.Reg.reg, mode64); 3989 if (syned) // cmpwi (signed) (PPC32 p367) 3990 p = mkFormX(p, 31, fld1, r_srcL, r_srcR, 0, 0, endness_host); 3991 else // cmplwi (unsigned) (PPC32 p379) 3992 p = mkFormX(p, 31, fld1, r_srcL, r_srcR, 32, 0, endness_host); 3993 break; 3994 default: 3995 goto bad; 3996 } 3997 goto done; 3998 } 3999 4000 case Pin_Unary: { 4001 UInt r_dst = iregEnc(i->Pin.Unary.dst, mode64); 4002 UInt r_src = iregEnc(i->Pin.Unary.src, mode64); 4003 4004 switch (i->Pin.Unary.op) { 4005 case Pun_NOT: // nor r_dst,r_src,r_src 4006 p = mkFormX(p, 31, r_src, r_dst, r_src, 124, 0, endness_host); 4007 break; 4008 case Pun_NEG: // neg r_dst,r_src 4009 p = mkFormXO(p, 31, r_dst, r_src, 0, 0, 104, 0, endness_host); 4010 break; 4011 case Pun_CLZ32: // cntlzw r_dst, r_src 4012 p = mkFormX(p, 31, r_src, r_dst, 0, 26, 0, endness_host); 4013 break; 4014 case Pun_CLZ64: // cntlzd r_dst, r_src 4015 vassert(mode64); 4016 p = mkFormX(p, 31, r_src, r_dst, 0, 58, 0, endness_host); 4017 break; 4018 case Pun_EXTSW: // extsw r_dst, r_src 4019 vassert(mode64); 4020 p = mkFormX(p, 31, r_src, r_dst, 0, 986, 0, endness_host); 4021 break; 4022 default: goto bad; 4023 } 4024 goto done; 4025 } 4026 4027 case Pin_MulL: { 4028 Bool syned = i->Pin.MulL.syned; 4029 Bool sz32 = i->Pin.MulL.sz32; 4030 UInt r_dst = iregEnc(i->Pin.MulL.dst, mode64); 4031 UInt r_srcL = iregEnc(i->Pin.MulL.srcL, mode64); 4032 UInt r_srcR = iregEnc(i->Pin.MulL.srcR, mode64); 4033 4034 if (!mode64) 4035 vassert(sz32); 4036 4037 if (i->Pin.MulL.hi) { 4038 // mul hi words, must consider sign 4039 if (sz32) { 4040 if (syned) // mulhw r_dst,r_srcL,r_srcR 4041 p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 75, 0, 4042 endness_host); 4043 else // mulhwu r_dst,r_srcL,r_srcR 4044 p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 11, 0, 4045 endness_host); 4046 } else { 4047 if (syned) // mulhd r_dst,r_srcL,r_srcR 4048 p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 73, 0, 4049 endness_host); 4050 else // mulhdu r_dst,r_srcL,r_srcR 4051 p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 9, 0, endness_host); 4052 } 4053 } else { 4054 // mul low word, sign is irrelevant 4055 vassert(!i->Pin.MulL.syned); 4056 if (sz32) // mullw r_dst,r_srcL,r_srcR 4057 p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 235, 0, endness_host); 4058 else // mulld r_dst,r_srcL,r_srcR 4059 p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 233, 0, endness_host); 4060 } 4061 goto done; 4062 } 4063 4064 case Pin_Div: { 4065 Bool syned = i->Pin.Div.syned; 4066 Bool sz32 = i->Pin.Div.sz32; 4067 UInt r_dst = iregEnc(i->Pin.Div.dst, mode64); 4068 UInt r_srcL = iregEnc(i->Pin.Div.srcL, mode64); 4069 UInt r_srcR = iregEnc(i->Pin.Div.srcR, mode64); 4070 4071 if (!mode64) 4072 vassert(sz32); 4073 4074 if (i->Pin.Div.extended) { 4075 if (sz32) { 4076 if (syned) 4077 // divwe r_dst,r_srcL,r_srcR 4078 p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 427, 0, 4079 endness_host); 4080 else 4081 // divweu r_dst,r_srcL,r_srcR 4082 p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 395, 0, 4083 endness_host); 4084 } else { 4085 if (syned) 4086 // divde r_dst,r_srcL,r_srcR 4087 p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 425, 0, 4088 endness_host); 4089 else 4090 // divdeu r_dst,r_srcL,r_srcR 4091 p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 393, 0, 4092 endness_host); 4093 } 4094 } else if (sz32) { 4095 if (syned) // divw r_dst,r_srcL,r_srcR 4096 p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 491, 0, endness_host); 4097 else // divwu r_dst,r_srcL,r_srcR 4098 p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 459, 0, endness_host); 4099 } else { 4100 if (syned) // divd r_dst,r_srcL,r_srcR 4101 p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 489, 0, endness_host); 4102 else // divdu r_dst,r_srcL,r_srcR 4103 p = mkFormXO(p, 31, r_dst, r_srcL, r_srcR, 0, 457, 0, endness_host); 4104 } 4105 goto done; 4106 } 4107 4108 case Pin_Call: { 4109 if (i->Pin.Call.cond.test != Pct_ALWAYS 4110 && i->Pin.Call.rloc.pri != RLPri_None) { 4111 /* The call might not happen (it isn't unconditional) and it 4112 returns a result. In this case we will need to generate a 4113 control flow diamond to put 0x555..555 in the return 4114 register(s) in the case where the call doesn't happen. If 4115 this ever becomes necessary, maybe copy code from the ARM 4116 equivalent. Until that day, just give up. */ 4117 goto bad; 4118 } 4119 PPCCondCode cond = i->Pin.Call.cond; 4120 UInt r_dst = 10; 4121 /* As per detailed comment for Pin_Call in 4122 getRegUsage_PPCInstr above, %r10 is used as an address temp */ 4123 4124 /* jump over the following insns if condition does not hold */ 4125 UChar* ptmp = NULL; 4126 if (cond.test != Pct_ALWAYS) { 4127 /* jmp fwds if !condition */ 4128 /* don't know how many bytes to jump over yet... 4129 make space for a jump instruction and fill in later. */ 4130 ptmp = p; /* fill in this bit later */ 4131 p += 4; // p += 4 4132 } 4133 4134 /* load target to r_dst */ // p += 4|8|20 4135 p = mkLoadImm(p, r_dst, i->Pin.Call.target, mode64, endness_host); 4136 4137 /* mtspr 9,r_dst => move r_dst to count register */ 4138 p = mkFormXFX(p, r_dst, 9, 467, endness_host); // p += 4 4139 4140 /* bctrl => branch to count register (and save to lr) */ 4141 p = mkFormXL(p, 19, Pct_ALWAYS, 0, 0, 528, 1, endness_host); // p += 4 4142 4143 /* Fix up the conditional jump, if there was one. */ 4144 if (cond.test != Pct_ALWAYS) { 4145 Int delta = p - ptmp; 4146 vassert(delta >= 16 && delta <= 32); 4147 /* bc !ct,cf,delta */ 4148 mkFormB(ptmp, invertCondTest(cond.test), 4149 cond.flag, (delta>>2), 0, 0, endness_host); 4150 } 4151 goto done; 4152 } 4153 4154 case Pin_XDirect: { 4155 /* NB: what goes on here has to be very closely coordinated 4156 with the chainXDirect_PPC and unchainXDirect_PPC below. */ 4157 /* We're generating chain-me requests here, so we need to be 4158 sure this is actually allowed -- no-redir translations 4159 can't use chain-me's. Hence: */ 4160 vassert(disp_cp_chain_me_to_slowEP != NULL); 4161 vassert(disp_cp_chain_me_to_fastEP != NULL); 4162 4163 /* First off, if this is conditional, create a conditional jump 4164 over the rest of it. Or at least, leave a space for it that 4165 we will shortly fill in. */ 4166 UChar* ptmp = NULL; 4167 if (i->Pin.XDirect.cond.test != Pct_ALWAYS) { 4168 vassert(i->Pin.XDirect.cond.flag != Pcf_NONE); 4169 ptmp = p; 4170 p += 4; 4171 } else { 4172 vassert(i->Pin.XDirect.cond.flag == Pcf_NONE); 4173 } 4174 4175 /* Update the guest CIA. */ 4176 /* imm32/64 r30, dstGA */ 4177 if (!mode64) vassert(0 == (((ULong)i->Pin.XDirect.dstGA) >> 32)); 4178 p = mkLoadImm(p, /*r*/30, (ULong)i->Pin.XDirect.dstGA, mode64, 4179 endness_host); 4180 /* stw/std r30, amCIA */ 4181 p = do_load_or_store_machine_word( 4182 p, False/*!isLoad*/, 4183 /*r*/30, i->Pin.XDirect.amCIA, mode64, endness_host 4184 ); 4185 4186 /* --- FIRST PATCHABLE BYTE follows --- */ 4187 /* VG_(disp_cp_chain_me_to_{slowEP,fastEP}) (where we're calling 4188 to) backs up the return address, so as to find the address of 4189 the first patchable byte. So: don't change the number of 4190 instructions (32-bit: 4, 64-bit: 7) below. */ 4191 /* imm32/64-fixed r30, VG_(disp_cp_chain_me_to_{slowEP,fastEP} */ 4192 const void* disp_cp_chain_me 4193 = i->Pin.XDirect.toFastEP ? disp_cp_chain_me_to_fastEP 4194 : disp_cp_chain_me_to_slowEP; 4195 p = mkLoadImm_EXACTLY2or5( 4196 p, /*r*/30, (Addr)disp_cp_chain_me, mode64, endness_host); 4197 /* mtctr r30 */ 4198 p = mkFormXFX(p, /*r*/30, 9, 467, endness_host); 4199 /* bctrl */ 4200 p = mkFormXL(p, 19, Pct_ALWAYS, 0, 0, 528, 1, endness_host); 4201 /* --- END of PATCHABLE BYTES --- */ 4202 4203 /* Fix up the conditional jump, if there was one. */ 4204 if (i->Pin.XDirect.cond.test != Pct_ALWAYS) { 4205 Int delta = p - ptmp; 4206 vassert(delta >= 16 && delta <= 64 && 0 == (delta & 3)); 4207 /* bc !ct,cf,delta */ 4208 mkFormB(ptmp, invertCondTest(i->Pin.XDirect.cond.test), 4209 i->Pin.XDirect.cond.flag, (delta>>2), 0, 0, endness_host); 4210 } 4211 goto done; 4212 } 4213 4214 case Pin_XIndir: { 4215 /* We're generating transfers that could lead indirectly to a 4216 chain-me, so we need to be sure this is actually allowed -- 4217 no-redir translations are not allowed to reach normal 4218 translations without going through the scheduler. That means 4219 no XDirects or XIndirs out from no-redir translations. 4220 Hence: */ 4221 vassert(disp_cp_xindir != NULL); 4222 4223 /* First off, if this is conditional, create a conditional jump 4224 over the rest of it. Or at least, leave a space for it that 4225 we will shortly fill in. */ 4226 UChar* ptmp = NULL; 4227 if (i->Pin.XIndir.cond.test != Pct_ALWAYS) { 4228 vassert(i->Pin.XIndir.cond.flag != Pcf_NONE); 4229 ptmp = p; 4230 p += 4; 4231 } else { 4232 vassert(i->Pin.XIndir.cond.flag == Pcf_NONE); 4233 } 4234 4235 /* Update the guest CIA. */ 4236 /* stw/std r-dstGA, amCIA */ 4237 p = do_load_or_store_machine_word( 4238 p, False/*!isLoad*/, 4239 iregEnc(i->Pin.XIndir.dstGA, mode64), 4240 i->Pin.XIndir.amCIA, mode64, endness_host 4241 ); 4242 4243 /* imm32/64 r30, VG_(disp_cp_xindir) */ 4244 p = mkLoadImm(p, /*r*/30, (ULong)(Addr)disp_cp_xindir, mode64, 4245 endness_host); 4246 /* mtctr r30 */ 4247 p = mkFormXFX(p, /*r*/30, 9, 467, endness_host); 4248 /* bctr */ 4249 p = mkFormXL(p, 19, Pct_ALWAYS, 0, 0, 528, 0, endness_host); 4250 4251 /* Fix up the conditional jump, if there was one. */ 4252 if (i->Pin.XIndir.cond.test != Pct_ALWAYS) { 4253 Int delta = p - ptmp; 4254 vassert(delta >= 16 && delta <= 32 && 0 == (delta & 3)); 4255 /* bc !ct,cf,delta */ 4256 mkFormB(ptmp, invertCondTest(i->Pin.XIndir.cond.test), 4257 i->Pin.XIndir.cond.flag, (delta>>2), 0, 0, endness_host); 4258 } 4259 goto done; 4260 } 4261 4262 case Pin_XAssisted: { 4263 /* First off, if this is conditional, create a conditional jump 4264 over the rest of it. Or at least, leave a space for it that 4265 we will shortly fill in. */ 4266 UChar* ptmp = NULL; 4267 if (i->Pin.XAssisted.cond.test != Pct_ALWAYS) { 4268 vassert(i->Pin.XAssisted.cond.flag != Pcf_NONE); 4269 ptmp = p; 4270 p += 4; 4271 } else { 4272 vassert(i->Pin.XAssisted.cond.flag == Pcf_NONE); 4273 } 4274 4275 /* Update the guest CIA. */ 4276 /* stw/std r-dstGA, amCIA */ 4277 p = do_load_or_store_machine_word( 4278 p, False/*!isLoad*/, 4279 iregEnc(i->Pin.XIndir.dstGA, mode64), 4280 i->Pin.XIndir.amCIA, mode64, endness_host 4281 ); 4282 4283 /* imm32/64 r31, $magic_number */ 4284 UInt trcval = 0; 4285 switch (i->Pin.XAssisted.jk) { 4286 case Ijk_ClientReq: trcval = VEX_TRC_JMP_CLIENTREQ; break; 4287 case Ijk_Sys_syscall: trcval = VEX_TRC_JMP_SYS_SYSCALL; break; 4288 //case Ijk_Sys_int128: trcval = VEX_TRC_JMP_SYS_INT128; break; 4289 //case Ijk_Yield: trcval = VEX_TRC_JMP_YIELD; break; 4290 case Ijk_EmWarn: trcval = VEX_TRC_JMP_EMWARN; break; 4291 case Ijk_EmFail: trcval = VEX_TRC_JMP_EMFAIL; break; 4292 //case Ijk_MapFail: trcval = VEX_TRC_JMP_MAPFAIL; break; 4293 case Ijk_NoDecode: trcval = VEX_TRC_JMP_NODECODE; break; 4294 case Ijk_InvalICache: trcval = VEX_TRC_JMP_INVALICACHE; break; 4295 case Ijk_NoRedir: trcval = VEX_TRC_JMP_NOREDIR; break; 4296 case Ijk_SigTRAP: trcval = VEX_TRC_JMP_SIGTRAP; break; 4297 //case Ijk_SigSEGV: trcval = VEX_TRC_JMP_SIGSEGV; break; 4298 case Ijk_SigBUS: trcval = VEX_TRC_JMP_SIGBUS; break; 4299 case Ijk_Boring: trcval = VEX_TRC_JMP_BORING; break; 4300 /* We don't expect to see the following being assisted. */ 4301 //case Ijk_Ret: 4302 //case Ijk_Call: 4303 /* fallthrough */ 4304 default: 4305 ppIRJumpKind(i->Pin.XAssisted.jk); 4306 vpanic("emit_ARMInstr.Pin_XAssisted: unexpected jump kind"); 4307 } 4308 vassert(trcval != 0); 4309 p = mkLoadImm(p, /*r*/31, trcval, mode64, endness_host); 4310 4311 /* imm32/64 r30, VG_(disp_cp_xassisted) */ 4312 p = mkLoadImm(p, /*r*/30, 4313 (ULong)(Addr)disp_cp_xassisted, mode64, 4314 endness_host); 4315 /* mtctr r30 */ 4316 p = mkFormXFX(p, /*r*/30, 9, 467, endness_host); 4317 /* bctr */ 4318 p = mkFormXL(p, 19, Pct_ALWAYS, 0, 0, 528, 0, endness_host); 4319 4320 /* Fix up the conditional jump, if there was one. */ 4321 if (i->Pin.XAssisted.cond.test != Pct_ALWAYS) { 4322 Int delta = p - ptmp; 4323 vassert(delta >= 16 && delta <= 32 && 0 == (delta & 3)); 4324 /* bc !ct,cf,delta */ 4325 mkFormB(ptmp, invertCondTest(i->Pin.XAssisted.cond.test), 4326 i->Pin.XAssisted.cond.flag, (delta>>2), 0, 0, endness_host); 4327 } 4328 goto done; 4329 } 4330 4331 case Pin_CMov: { 4332 UInt r_dst, r_src; 4333 ULong imm_src; 4334 PPCCondCode cond; 4335 vassert(i->Pin.CMov.cond.test != Pct_ALWAYS); 4336 4337 r_dst = iregEnc(i->Pin.CMov.dst, mode64); 4338 cond = i->Pin.CMov.cond; 4339 4340 /* branch (if cond fails) over move instrs */ 4341 UChar* ptmp = NULL; 4342 if (cond.test != Pct_ALWAYS) { 4343 /* don't know how many bytes to jump over yet... 4344 make space for a jump instruction and fill in later. */ 4345 ptmp = p; /* fill in this bit later */ 4346 p += 4; 4347 } 4348 4349 // cond true: move src => dst 4350 switch (i->Pin.CMov.src->tag) { 4351 case Pri_Imm: 4352 imm_src = i->Pin.CMov.src->Pri.Imm; 4353 p = mkLoadImm(p, r_dst, imm_src, mode64, endness_host); // p += 4|8|20 4354 break; 4355 case Pri_Reg: 4356 r_src = iregEnc(i->Pin.CMov.src->Pri.Reg, mode64); 4357 p = mkMoveReg(p, r_dst, r_src, endness_host); // p += 4 4358 break; 4359 default: goto bad; 4360 } 4361 4362 /* Fix up the conditional jump, if there was one. */ 4363 if (cond.test != Pct_ALWAYS) { 4364 Int delta = p - ptmp; 4365 vassert(delta >= 8 && delta <= 24); 4366 /* bc !ct,cf,delta */ 4367 mkFormB(ptmp, invertCondTest(cond.test), 4368 cond.flag, (delta>>2), 0, 0, endness_host); 4369 } 4370 goto done; 4371 } 4372 4373 case Pin_Load: { 4374 PPCAMode* am_addr = i->Pin.Load.src; 4375 UInt r_dst = iregEnc(i->Pin.Load.dst, mode64); 4376 UInt opc1, opc2, sz = i->Pin.Load.sz; 4377 switch (am_addr->tag) { 4378 case Pam_IR: 4379 if (mode64 && (sz == 4 || sz == 8)) { 4380 /* should be guaranteed to us by iselWordExpr_AMode */ 4381 vassert(0 == (am_addr->Pam.IR.index & 3)); 4382 } 4383 switch(sz) { 4384 case 1: opc1 = 34; break; 4385 case 2: opc1 = 40; break; 4386 case 4: opc1 = 32; break; 4387 case 8: opc1 = 58; vassert(mode64); break; 4388 default: goto bad; 4389 } 4390 p = doAMode_IR(p, opc1, r_dst, am_addr, mode64, endness_host); 4391 goto done; 4392 case Pam_RR: 4393 switch(sz) { 4394 case 1: opc2 = 87; break; 4395 case 2: opc2 = 279; break; 4396 case 4: opc2 = 23; break; 4397 case 8: opc2 = 21; vassert(mode64); break; 4398 default: goto bad; 4399 } 4400 p = doAMode_RR(p, 31, opc2, r_dst, am_addr, mode64, endness_host); 4401 goto done; 4402 default: 4403 goto bad; 4404 } 4405 } 4406 4407 case Pin_LoadL: { 4408 if (i->Pin.LoadL.sz == 1) { 4409 p = mkFormX(p, 31, iregEnc(i->Pin.LoadL.dst, mode64), 4410 0, iregEnc(i->Pin.LoadL.src, mode64), 52, 0, endness_host); 4411 goto done; 4412 } 4413 if (i->Pin.LoadL.sz == 2) { 4414 p = mkFormX(p, 31, iregEnc(i->Pin.LoadL.dst, mode64), 4415 0, iregEnc(i->Pin.LoadL.src, mode64), 116, 0, endness_host); 4416 goto done; 4417 } 4418 if (i->Pin.LoadL.sz == 4) { 4419 p = mkFormX(p, 31, iregEnc(i->Pin.LoadL.dst, mode64), 4420 0, iregEnc(i->Pin.LoadL.src, mode64), 20, 0, endness_host); 4421 goto done; 4422 } 4423 if (i->Pin.LoadL.sz == 8 && mode64) { 4424 p = mkFormX(p, 31, iregEnc(i->Pin.LoadL.dst, mode64), 4425 0, iregEnc(i->Pin.LoadL.src, mode64), 84, 0, endness_host); 4426 goto done; 4427 } 4428 goto bad; 4429 } 4430 4431 case Pin_Set: { 4432 /* Make the destination register be 1 or 0, depending on whether 4433 the relevant condition holds. */ 4434 UInt r_dst = iregEnc(i->Pin.Set.dst, mode64); 4435 PPCCondCode cond = i->Pin.Set.cond; 4436 UInt rot_imm, r_tmp; 4437 4438 if (cond.test == Pct_ALWAYS) { 4439 // Just load 1 to dst => li dst,1 4440 p = mkFormD(p, 14, r_dst, 0, 1, endness_host); 4441 } else { 4442 vassert(cond.flag != Pcf_NONE); 4443 rot_imm = 1 + cond.flag; 4444 r_tmp = 0; // Not set in getAllocable, so no need to declare. 4445 4446 // r_tmp = CR => mfcr r_tmp 4447 p = mkFormX(p, 31, r_tmp, 0, 0, 19, 0, endness_host); 4448 4449 // r_dst = flag (rotate left and mask) 4450 // => rlwinm r_dst,r_tmp,rot_imm,31,31 4451 p = mkFormM(p, 21, r_tmp, r_dst, rot_imm, 31, 31, 0, endness_host); 4452 4453 if (cond.test == Pct_FALSE) { 4454 // flip bit => xori r_dst,r_dst,1 4455 p = mkFormD(p, 26, r_dst, r_dst, 1, endness_host); 4456 } 4457 } 4458 goto done; 4459 } 4460 4461 case Pin_MfCR: 4462 // mfcr dst 4463 p = mkFormX(p, 31, iregEnc(i->Pin.MfCR.dst, mode64), 0, 0, 19, 0, 4464 endness_host); 4465 goto done; 4466 4467 case Pin_MFence: { 4468 p = mkFormX(p, 31, 0, 0, 0, 598, 0, endness_host); // sync, PPC32 p616 4469 // CAB: Should this be isync? 4470 // p = mkFormXL(p, 19, 0, 0, 0, 150, 0); // isync, PPC32 p467 4471 goto done; 4472 } 4473 4474 case Pin_Store: { 4475 PPCAMode* am_addr = i->Pin.Store.dst; 4476 UInt r_src = iregEnc(i->Pin.Store.src, mode64); 4477 UInt opc1, opc2, sz = i->Pin.Store.sz; 4478 switch (i->Pin.Store.dst->tag) { 4479 case Pam_IR: 4480 if (mode64 && (sz == 4 || sz == 8)) { 4481 /* should be guaranteed to us by iselWordExpr_AMode */ 4482 vassert(0 == (am_addr->Pam.IR.index & 3)); 4483 } 4484 switch(sz) { 4485 case 1: opc1 = 38; break; 4486 case 2: opc1 = 44; break; 4487 case 4: opc1 = 36; break; 4488 case 8: vassert(mode64); 4489 opc1 = 62; break; 4490 default: 4491 goto bad; 4492 } 4493 p = doAMode_IR(p, opc1, r_src, am_addr, mode64, endness_host); 4494 goto done; 4495 case Pam_RR: 4496 switch(sz) { 4497 case 1: opc2 = 215; break; 4498 case 2: opc2 = 407; break; 4499 case 4: opc2 = 151; break; 4500 case 8: vassert(mode64); 4501 opc2 = 149; break; 4502 default: 4503 goto bad; 4504 } 4505 p = doAMode_RR(p, 31, opc2, r_src, am_addr, mode64, endness_host); 4506 goto done; 4507 default: 4508 goto bad; 4509 } 4510 goto done; 4511 } 4512 4513 case Pin_StoreC: { 4514 if (i->Pin.StoreC.sz == 1) { 4515 p = mkFormX(p, 31, iregEnc(i->Pin.StoreC.src, mode64), 4516 0, iregEnc(i->Pin.StoreC.dst, mode64), 694, 1, endness_host); 4517 goto done; 4518 } 4519 if (i->Pin.StoreC.sz == 2) { 4520 p = mkFormX(p, 31, iregEnc(i->Pin.StoreC.src, mode64), 4521 0, iregEnc(i->Pin.StoreC.dst, mode64), 726, 1, endness_host); 4522 goto done; 4523 } 4524 4525 if (i->Pin.StoreC.sz == 4) { 4526 p = mkFormX(p, 31, iregEnc(i->Pin.StoreC.src, mode64), 4527 0, iregEnc(i->Pin.StoreC.dst, mode64), 150, 1, endness_host); 4528 goto done; 4529 } 4530 if (i->Pin.StoreC.sz == 8 && mode64) { 4531 p = mkFormX(p, 31, iregEnc(i->Pin.StoreC.src, mode64), 4532 0, iregEnc(i->Pin.StoreC.dst, mode64), 214, 1, endness_host); 4533 goto done; 4534 } 4535 goto bad; 4536 } 4537 4538 case Pin_FpUnary: { 4539 UInt fr_dst = fregEnc(i->Pin.FpUnary.dst); 4540 UInt fr_src = fregEnc(i->Pin.FpUnary.src); 4541 switch (i->Pin.FpUnary.op) { 4542 case Pfp_RSQRTE: // frsqrtre, PPC32 p424 4543 p = mkFormA( p, 63, fr_dst, 0, fr_src, 0, 26, 0, endness_host ); 4544 break; 4545 case Pfp_RES: // fres, PPC32 p421 4546 p = mkFormA( p, 59, fr_dst, 0, fr_src, 0, 24, 0, endness_host ); 4547 break; 4548 case Pfp_SQRT: // fsqrt, PPC32 p427 4549 p = mkFormA( p, 63, fr_dst, 0, fr_src, 0, 22, 0, endness_host ); 4550 break; 4551 case Pfp_ABS: // fabs, PPC32 p399 4552 p = mkFormX(p, 63, fr_dst, 0, fr_src, 264, 0, endness_host); 4553 break; 4554 case Pfp_NEG: // fneg, PPC32 p416 4555 p = mkFormX(p, 63, fr_dst, 0, fr_src, 40, 0, endness_host); 4556 break; 4557 case Pfp_MOV: // fmr, PPC32 p410 4558 p = mkFormX(p, 63, fr_dst, 0, fr_src, 72, 0, endness_host); 4559 break; 4560 case Pfp_FRIM: // frim, PPC ISA 2.05 p137 4561 p = mkFormX(p, 63, fr_dst, 0, fr_src, 488, 0, endness_host); 4562 break; 4563 case Pfp_FRIP: // frip, PPC ISA 2.05 p137 4564 p = mkFormX(p, 63, fr_dst, 0, fr_src, 456, 0, endness_host); 4565 break; 4566 case Pfp_FRIN: // frin, PPC ISA 2.05 p137 4567 p = mkFormX(p, 63, fr_dst, 0, fr_src, 392, 0, endness_host); 4568 break; 4569 case Pfp_FRIZ: // friz, PPC ISA 2.05 p137 4570 p = mkFormX(p, 63, fr_dst, 0, fr_src, 424, 0, endness_host); 4571 break; 4572 default: 4573 goto bad; 4574 } 4575 goto done; 4576 } 4577 4578 case Pin_FpBinary: { 4579 UInt fr_dst = fregEnc(i->Pin.FpBinary.dst); 4580 UInt fr_srcL = fregEnc(i->Pin.FpBinary.srcL); 4581 UInt fr_srcR = fregEnc(i->Pin.FpBinary.srcR); 4582 switch (i->Pin.FpBinary.op) { 4583 case Pfp_ADDD: // fadd, PPC32 p400 4584 p = mkFormA( p, 63, fr_dst, fr_srcL, fr_srcR, 0, 21, 0, endness_host ); 4585 break; 4586 case Pfp_ADDS: // fadds, PPC32 p401 4587 p = mkFormA( p, 59, fr_dst, fr_srcL, fr_srcR, 0, 21, 0, endness_host ); 4588 break; 4589 case Pfp_SUBD: // fsub, PPC32 p429 4590 p = mkFormA( p, 63, fr_dst, fr_srcL, fr_srcR, 0, 20, 0, endness_host ); 4591 break; 4592 case Pfp_SUBS: // fsubs, PPC32 p430 4593 p = mkFormA( p, 59, fr_dst, fr_srcL, fr_srcR, 0, 20, 0, endness_host ); 4594 break; 4595 case Pfp_MULD: // fmul, PPC32 p413 4596 p = mkFormA( p, 63, fr_dst, fr_srcL, 0, fr_srcR, 25, 0, endness_host ); 4597 break; 4598 case Pfp_MULS: // fmuls, PPC32 p414 4599 p = mkFormA( p, 59, fr_dst, fr_srcL, 0, fr_srcR, 25, 0, endness_host ); 4600 break; 4601 case Pfp_DIVD: // fdiv, PPC32 p406 4602 p = mkFormA( p, 63, fr_dst, fr_srcL, fr_srcR, 0, 18, 0, endness_host ); 4603 break; 4604 case Pfp_DIVS: // fdivs, PPC32 p407 4605 p = mkFormA( p, 59, fr_dst, fr_srcL, fr_srcR, 0, 18, 0, endness_host ); 4606 break; 4607 default: 4608 goto bad; 4609 } 4610 goto done; 4611 } 4612 4613 case Pin_FpMulAcc: { 4614 UInt fr_dst = fregEnc(i->Pin.FpMulAcc.dst); 4615 UInt fr_srcML = fregEnc(i->Pin.FpMulAcc.srcML); 4616 UInt fr_srcMR = fregEnc(i->Pin.FpMulAcc.srcMR); 4617 UInt fr_srcAcc = fregEnc(i->Pin.FpMulAcc.srcAcc); 4618 switch (i->Pin.FpMulAcc.op) { 4619 case Pfp_MADDD: // fmadd, PPC32 p408 4620 p = mkFormA( p, 63, fr_dst, fr_srcML, fr_srcAcc, fr_srcMR, 29, 0, 4621 endness_host ); 4622 break; 4623 case Pfp_MADDS: // fmadds, PPC32 p409 4624 p = mkFormA( p, 59, fr_dst, fr_srcML, fr_srcAcc, fr_srcMR, 29, 0, 4625 endness_host ); 4626 break; 4627 case Pfp_MSUBD: // fmsub, PPC32 p411 4628 p = mkFormA( p, 63, fr_dst, fr_srcML, fr_srcAcc, fr_srcMR, 28, 0, 4629 endness_host ); 4630 break; 4631 case Pfp_MSUBS: // fmsubs, PPC32 p412 4632 p = mkFormA( p, 59, fr_dst, fr_srcML, fr_srcAcc, fr_srcMR, 28, 0, 4633 endness_host ); 4634 break; 4635 default: 4636 goto bad; 4637 } 4638 goto done; 4639 } 4640 4641 case Pin_FpLdSt: { 4642 PPCAMode* am_addr = i->Pin.FpLdSt.addr; 4643 UInt f_reg = fregEnc(i->Pin.FpLdSt.reg); 4644 Bool idxd = toBool(i->Pin.FpLdSt.addr->tag == Pam_RR); 4645 UChar sz = i->Pin.FpLdSt.sz; 4646 UInt opc; 4647 vassert(sz == 4 || sz == 8); 4648 4649 if (i->Pin.FpLdSt.isLoad) { // Load from memory 4650 if (idxd) { // lf[s|d]x, PPC32 p444|440 4651 opc = (sz == 4) ? 535 : 599; 4652 p = doAMode_RR(p, 31, opc, f_reg, am_addr, mode64, endness_host); 4653 } else { // lf[s|d], PPC32 p441|437 4654 opc = (sz == 4) ? 48 : 50; 4655 p = doAMode_IR(p, opc, f_reg, am_addr, mode64, endness_host); 4656 } 4657 } else { // Store to memory 4658 if (idxd) { // stf[s|d]x, PPC32 p521|516 4659 opc = (sz == 4) ? 663 : 727; 4660 p = doAMode_RR(p, 31, opc, f_reg, am_addr, mode64, endness_host); 4661 } else { // stf[s|d], PPC32 p518|513 4662 opc = (sz == 4) ? 52 : 54; 4663 p = doAMode_IR(p, opc, f_reg, am_addr, mode64, endness_host); 4664 } 4665 } 4666 goto done; 4667 } 4668 4669 case Pin_FpSTFIW: { 4670 UInt ir_addr = iregEnc(i->Pin.FpSTFIW.addr, mode64); 4671 UInt fr_data = fregEnc(i->Pin.FpSTFIW.data); 4672 // stfiwx (store fp64[lo32] as int32), PPC32 p517 4673 // Use rA==0, so that EA == rB == ir_addr 4674 p = mkFormX(p, 31, fr_data, 0/*rA=0*/, ir_addr, 983, 0, endness_host); 4675 goto done; 4676 } 4677 4678 case Pin_FpRSP: { 4679 UInt fr_dst = fregEnc(i->Pin.FpRSP.dst); 4680 UInt fr_src = fregEnc(i->Pin.FpRSP.src); 4681 // frsp, PPC32 p423 4682 p = mkFormX(p, 63, fr_dst, 0, fr_src, 12, 0, endness_host); 4683 goto done; 4684 } 4685 4686 case Pin_FpCftI: { 4687 UInt fr_dst = fregEnc(i->Pin.FpCftI.dst); 4688 UInt fr_src = fregEnc(i->Pin.FpCftI.src); 4689 if (i->Pin.FpCftI.fromI == False && i->Pin.FpCftI.int32 == True) { 4690 if (i->Pin.FpCftI.syned == True) { 4691 // fctiw (conv f64 to i32), PPC32 p404 4692 p = mkFormX(p, 63, fr_dst, 0, fr_src, 14, 0, endness_host); 4693 goto done; 4694 } else { 4695 // fctiwu (conv f64 to u32) 4696 p = mkFormX(p, 63, fr_dst, 0, fr_src, 142, 0, endness_host); 4697 goto done; 4698 } 4699 } 4700 if (i->Pin.FpCftI.fromI == False && i->Pin.FpCftI.int32 == False) { 4701 if (i->Pin.FpCftI.syned == True) { 4702 // fctid (conv f64 to i64), PPC64 p437 4703 p = mkFormX(p, 63, fr_dst, 0, fr_src, 814, 0, endness_host); 4704 goto done; 4705 } else { 4706 // fctidu (conv f64 to u64) 4707 p = mkFormX(p, 63, fr_dst, 0, fr_src, 942, 0, endness_host); 4708 goto done; 4709 } 4710 } 4711 if (i->Pin.FpCftI.fromI == True && i->Pin.FpCftI.int32 == False) { 4712 if (i->Pin.FpCftI.syned == True) { 4713 // fcfid (conv i64 to f64), PPC64 p434 4714 p = mkFormX(p, 63, fr_dst, 0, fr_src, 846, 0, endness_host); 4715 goto done; 4716 } else if (i->Pin.FpCftI.flt64 == True) { 4717 // fcfidu (conv u64 to f64) 4718 p = mkFormX(p, 63, fr_dst, 0, fr_src, 974, 0, endness_host); 4719 goto done; 4720 } else { 4721 // fcfidus (conv u64 to f32) 4722 p = mkFormX(p, 59, fr_dst, 0, fr_src, 974, 0, endness_host); 4723 goto done; 4724 } 4725 } 4726 goto bad; 4727 } 4728 4729 case Pin_FpCMov: { 4730 UInt fr_dst = fregEnc(i->Pin.FpCMov.dst); 4731 UInt fr_src = fregEnc(i->Pin.FpCMov.src); 4732 PPCCondCode cc = i->Pin.FpCMov.cond; 4733 4734 if (fr_dst == fr_src) goto done; 4735 4736 vassert(cc.test != Pct_ALWAYS); 4737 4738 /* jmp fwds if !condition */ 4739 if (cc.test != Pct_ALWAYS) { 4740 /* bc !ct,cf,n_bytes>>2 */ 4741 p = mkFormB(p, invertCondTest(cc.test), cc.flag, 8>>2, 0, 0, 4742 endness_host); 4743 } 4744 4745 // fmr, PPC32 p410 4746 p = mkFormX(p, 63, fr_dst, 0, fr_src, 72, 0, endness_host); 4747 goto done; 4748 } 4749 4750 case Pin_FpLdFPSCR: { 4751 UInt fr_src = fregEnc(i->Pin.FpLdFPSCR.src); 4752 p = mkFormXFL(p, 0xFF, fr_src, i->Pin.FpLdFPSCR.dfp_rm, endness_host); // mtfsf, PPC32 p480 4753 goto done; 4754 } 4755 4756 case Pin_FpCmp: { 4757 UChar crfD = 1; 4758 UInt r_dst = iregEnc(i->Pin.FpCmp.dst, mode64); 4759 UInt fr_srcL = fregEnc(i->Pin.FpCmp.srcL); 4760 UInt fr_srcR = fregEnc(i->Pin.FpCmp.srcR); 4761 vassert(crfD < 8); 4762 // fcmpo, PPC32 p402 4763 p = mkFormX(p, 63, crfD<<2, fr_srcL, fr_srcR, 32, 0, endness_host); 4764 4765 // mfcr (mv CR to r_dst), PPC32 p467 4766 p = mkFormX(p, 31, r_dst, 0, 0, 19, 0, endness_host); 4767 4768 // rlwinm r_dst,r_dst,8,28,31, PPC32 p501 4769 // => rotate field 1 to bottomw of word, masking out upper 28 4770 p = mkFormM(p, 21, r_dst, r_dst, 8, 28, 31, 0, endness_host); 4771 goto done; 4772 } 4773 4774 case Pin_RdWrLR: { 4775 UInt reg = iregEnc(i->Pin.RdWrLR.gpr, mode64); 4776 /* wrLR==True ? mtlr r4 : mflr r4 */ 4777 p = mkFormXFX(p, reg, 8, (i->Pin.RdWrLR.wrLR==True) ? 467 : 339, 4778 endness_host); 4779 goto done; 4780 } 4781 4782 4783 /* AltiVec */ 4784 case Pin_AvLdSt: { 4785 UInt opc2, v_reg, r_idx, r_base; 4786 UChar sz = i->Pin.AvLdSt.sz; 4787 Bool idxd = toBool(i->Pin.AvLdSt.addr->tag == Pam_RR); 4788 vassert(sz == 1 || sz == 2 || sz == 4 || sz == 16); 4789 4790 v_reg = vregEnc(i->Pin.AvLdSt.reg); 4791 r_base = iregEnc(i->Pin.AvLdSt.addr->Pam.RR.base, mode64); 4792 4793 // Only have AltiVec AMode_RR: kludge AMode_IR 4794 if (!idxd) { 4795 r_idx = 30; // XXX: Using r30 as temp 4796 p = mkLoadImm(p, r_idx, 4797 i->Pin.AvLdSt.addr->Pam.IR.index, mode64, endness_host); 4798 } else { 4799 r_idx = iregEnc(i->Pin.AvLdSt.addr->Pam.RR.index, mode64); 4800 } 4801 4802 if (i->Pin.FpLdSt.isLoad) { // Load from memory (1,2,4,16) 4803 opc2 = (sz==1) ? 7 : (sz==2) ? 39 : (sz==4) ? 71 : 103; 4804 p = mkFormX(p, 31, v_reg, r_idx, r_base, opc2, 0, endness_host); 4805 } else { // Store to memory (1,2,4,16) 4806 opc2 = (sz==1) ? 135 : (sz==2) ? 167 : (sz==4) ? 199 : 231; 4807 p = mkFormX(p, 31, v_reg, r_idx, r_base, opc2, 0, endness_host); 4808 } 4809 goto done; 4810 } 4811 4812 case Pin_AvUnary: { 4813 UInt v_dst = vregEnc(i->Pin.AvUnary.dst); 4814 UInt v_src = vregEnc(i->Pin.AvUnary.src); 4815 UInt opc2; 4816 switch (i->Pin.AvUnary.op) { 4817 case Pav_MOV: opc2 = 1156; break; // vor vD,vS,vS 4818 case Pav_NOT: opc2 = 1284; break; // vnor vD,vS,vS 4819 case Pav_UNPCKH8S: opc2 = 526; break; // vupkhsb 4820 case Pav_UNPCKH16S: opc2 = 590; break; // vupkhsh 4821 case Pav_UNPCKL8S: opc2 = 654; break; // vupklsb 4822 case Pav_UNPCKL16S: opc2 = 718; break; // vupklsh 4823 case Pav_UNPCKHPIX: opc2 = 846; break; // vupkhpx 4824 case Pav_UNPCKLPIX: opc2 = 974; break; // vupklpx 4825 4826 case Pav_ZEROCNTBYTE: opc2 = 1794; break; // vclzb 4827 case Pav_ZEROCNTHALF: opc2 = 1858; break; // vclzh 4828 case Pav_ZEROCNTWORD: opc2 = 1922; break; // vclzw 4829 case Pav_ZEROCNTDBL: opc2 = 1986; break; // vclzd 4830 case Pav_BITMTXXPOSE: opc2 = 1292; break; // vgbbd 4831 default: 4832 goto bad; 4833 } 4834 switch (i->Pin.AvUnary.op) { 4835 case Pav_MOV: 4836 case Pav_NOT: 4837 p = mkFormVX( p, 4, v_dst, v_src, v_src, opc2, endness_host ); 4838 break; 4839 default: 4840 p = mkFormVX( p, 4, v_dst, 0, v_src, opc2, endness_host ); 4841 break; 4842 } 4843 goto done; 4844 } 4845 4846 case Pin_AvBinary: { 4847 UInt v_dst = vregEnc(i->Pin.AvBinary.dst); 4848 UInt v_srcL = vregEnc(i->Pin.AvBinary.srcL); 4849 UInt v_srcR = vregEnc(i->Pin.AvBinary.srcR); 4850 UInt opc2; 4851 if (i->Pin.AvBinary.op == Pav_SHL) { 4852 p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, 1036, endness_host ); // vslo 4853 p = mkFormVX( p, 4, v_dst, v_dst, v_srcR, 452, endness_host ); // vsl 4854 goto done; 4855 } 4856 if (i->Pin.AvBinary.op == Pav_SHR) { 4857 p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, 1100, endness_host ); // vsro 4858 p = mkFormVX( p, 4, v_dst, v_dst, v_srcR, 708, endness_host ); // vsr 4859 goto done; 4860 } 4861 switch (i->Pin.AvBinary.op) { 4862 /* Bitwise */ 4863 case Pav_AND: opc2 = 1028; break; // vand 4864 case Pav_OR: opc2 = 1156; break; // vor 4865 case Pav_XOR: opc2 = 1220; break; // vxor 4866 default: 4867 goto bad; 4868 } 4869 p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, opc2, endness_host ); 4870 goto done; 4871 } 4872 4873 case Pin_AvBin8x16: { 4874 UInt v_dst = vregEnc(i->Pin.AvBin8x16.dst); 4875 UInt v_srcL = vregEnc(i->Pin.AvBin8x16.srcL); 4876 UInt v_srcR = vregEnc(i->Pin.AvBin8x16.srcR); 4877 UInt opc2; 4878 switch (i->Pin.AvBin8x16.op) { 4879 4880 case Pav_ADDU: opc2 = 0; break; // vaddubm 4881 case Pav_QADDU: opc2 = 512; break; // vaddubs 4882 case Pav_QADDS: opc2 = 768; break; // vaddsbs 4883 4884 case Pav_SUBU: opc2 = 1024; break; // vsububm 4885 case Pav_QSUBU: opc2 = 1536; break; // vsububs 4886 case Pav_QSUBS: opc2 = 1792; break; // vsubsbs 4887 4888 case Pav_OMULU: opc2 = 8; break; // vmuloub 4889 case Pav_OMULS: opc2 = 264; break; // vmulosb 4890 case Pav_EMULU: opc2 = 520; break; // vmuleub 4891 case Pav_EMULS: opc2 = 776; break; // vmulesb 4892 4893 case Pav_AVGU: opc2 = 1026; break; // vavgub 4894 case Pav_AVGS: opc2 = 1282; break; // vavgsb 4895 case Pav_MAXU: opc2 = 2; break; // vmaxub 4896 case Pav_MAXS: opc2 = 258; break; // vmaxsb 4897 case Pav_MINU: opc2 = 514; break; // vminub 4898 case Pav_MINS: opc2 = 770; break; // vminsb 4899 4900 case Pav_CMPEQU: opc2 = 6; break; // vcmpequb 4901 case Pav_CMPGTU: opc2 = 518; break; // vcmpgtub 4902 case Pav_CMPGTS: opc2 = 774; break; // vcmpgtsb 4903 4904 case Pav_SHL: opc2 = 260; break; // vslb 4905 case Pav_SHR: opc2 = 516; break; // vsrb 4906 case Pav_SAR: opc2 = 772; break; // vsrab 4907 case Pav_ROTL: opc2 = 4; break; // vrlb 4908 4909 case Pav_MRGHI: opc2 = 12; break; // vmrghb 4910 case Pav_MRGLO: opc2 = 268; break; // vmrglb 4911 4912 case Pav_POLYMULADD: opc2 = 1032; break; // vpmsumb 4913 4914 default: 4915 goto bad; 4916 } 4917 p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, opc2, endness_host ); 4918 goto done; 4919 } 4920 4921 case Pin_AvBin16x8: { 4922 UInt v_dst = vregEnc(i->Pin.AvBin16x8.dst); 4923 UInt v_srcL = vregEnc(i->Pin.AvBin16x8.srcL); 4924 UInt v_srcR = vregEnc(i->Pin.AvBin16x8.srcR); 4925 UInt opc2; 4926 switch (i->Pin.AvBin16x8.op) { 4927 4928 case Pav_ADDU: opc2 = 64; break; // vadduhm 4929 case Pav_QADDU: opc2 = 576; break; // vadduhs 4930 case Pav_QADDS: opc2 = 832; break; // vaddshs 4931 4932 case Pav_SUBU: opc2 = 1088; break; // vsubuhm 4933 case Pav_QSUBU: opc2 = 1600; break; // vsubuhs 4934 case Pav_QSUBS: opc2 = 1856; break; // vsubshs 4935 4936 case Pav_OMULU: opc2 = 72; break; // vmulouh 4937 case Pav_OMULS: opc2 = 328; break; // vmulosh 4938 case Pav_EMULU: opc2 = 584; break; // vmuleuh 4939 case Pav_EMULS: opc2 = 840; break; // vmulesh 4940 4941 case Pav_AVGU: opc2 = 1090; break; // vavguh 4942 case Pav_AVGS: opc2 = 1346; break; // vavgsh 4943 case Pav_MAXU: opc2 = 66; break; // vmaxuh 4944 case Pav_MAXS: opc2 = 322; break; // vmaxsh 4945 case Pav_MINS: opc2 = 834; break; // vminsh 4946 case Pav_MINU: opc2 = 578; break; // vminuh 4947 4948 case Pav_CMPEQU: opc2 = 70; break; // vcmpequh 4949 case Pav_CMPGTU: opc2 = 582; break; // vcmpgtuh 4950 case Pav_CMPGTS: opc2 = 838; break; // vcmpgtsh 4951 4952 case Pav_SHL: opc2 = 324; break; // vslh 4953 case Pav_SHR: opc2 = 580; break; // vsrh 4954 case Pav_SAR: opc2 = 836; break; // vsrah 4955 case Pav_ROTL: opc2 = 68; break; // vrlh 4956 4957 case Pav_PACKUU: opc2 = 14; break; // vpkuhum 4958 case Pav_QPACKUU: opc2 = 142; break; // vpkuhus 4959 case Pav_QPACKSU: opc2 = 270; break; // vpkshus 4960 case Pav_QPACKSS: opc2 = 398; break; // vpkshss 4961 case Pav_PACKPXL: opc2 = 782; break; // vpkpx 4962 4963 case Pav_MRGHI: opc2 = 76; break; // vmrghh 4964 case Pav_MRGLO: opc2 = 332; break; // vmrglh 4965 4966 case Pav_POLYMULADD: opc2 = 1224; break; // vpmsumh 4967 4968 default: 4969 goto bad; 4970 } 4971 p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, opc2, endness_host ); 4972 goto done; 4973 } 4974 4975 case Pin_AvBin32x4: { 4976 UInt v_dst = vregEnc(i->Pin.AvBin32x4.dst); 4977 UInt v_srcL = vregEnc(i->Pin.AvBin32x4.srcL); 4978 UInt v_srcR = vregEnc(i->Pin.AvBin32x4.srcR); 4979 UInt opc2; 4980 switch (i->Pin.AvBin32x4.op) { 4981 4982 case Pav_ADDU: opc2 = 128; break; // vadduwm 4983 case Pav_QADDU: opc2 = 640; break; // vadduws 4984 case Pav_QADDS: opc2 = 896; break; // vaddsws 4985 4986 case Pav_SUBU: opc2 = 1152; break; // vsubuwm 4987 case Pav_QSUBU: opc2 = 1664; break; // vsubuws 4988 case Pav_QSUBS: opc2 = 1920; break; // vsubsws 4989 4990 case Pav_MULU: opc2 = 137; break; // vmuluwm 4991 case Pav_OMULU: opc2 = 136; break; // vmulouw 4992 case Pav_OMULS: opc2 = 392; break; // vmulosw 4993 case Pav_EMULU: opc2 = 648; break; // vmuleuw 4994 case Pav_EMULS: opc2 = 904; break; // vmulesw 4995 4996 case Pav_AVGU: opc2 = 1154; break; // vavguw 4997 case Pav_AVGS: opc2 = 1410; break; // vavgsw 4998 4999 case Pav_MAXU: opc2 = 130; break; // vmaxuw 5000 case Pav_MAXS: opc2 = 386; break; // vmaxsw 5001 5002 case Pav_MINS: opc2 = 898; break; // vminsw 5003 case Pav_MINU: opc2 = 642; break; // vminuw 5004 5005 case Pav_CMPEQU: opc2 = 134; break; // vcmpequw 5006 case Pav_CMPGTS: opc2 = 902; break; // vcmpgtsw 5007 case Pav_CMPGTU: opc2 = 646; break; // vcmpgtuw 5008 5009 case Pav_SHL: opc2 = 388; break; // vslw 5010 case Pav_SHR: opc2 = 644; break; // vsrw 5011 case Pav_SAR: opc2 = 900; break; // vsraw 5012 case Pav_ROTL: opc2 = 132; break; // vrlw 5013 5014 case Pav_PACKUU: opc2 = 78; break; // vpkuwum 5015 case Pav_QPACKUU: opc2 = 206; break; // vpkuwus 5016 case Pav_QPACKSU: opc2 = 334; break; // vpkswus 5017 case Pav_QPACKSS: opc2 = 462; break; // vpkswss 5018 5019 case Pav_MRGHI: opc2 = 140; break; // vmrghw 5020 case Pav_MRGLO: opc2 = 396; break; // vmrglw 5021 5022 case Pav_CATODD: opc2 = 1676; break; // vmrgow 5023 case Pav_CATEVEN: opc2 = 1932; break; // vmrgew 5024 5025 case Pav_POLYMULADD: opc2 = 1160; break; // vpmsumw 5026 5027 default: 5028 goto bad; 5029 } 5030 p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, opc2, endness_host ); 5031 goto done; 5032 } 5033 5034 case Pin_AvBin64x2: { 5035 UInt v_dst = vregEnc(i->Pin.AvBin64x2.dst); 5036 UInt v_srcL = vregEnc(i->Pin.AvBin64x2.srcL); 5037 UInt v_srcR = vregEnc(i->Pin.AvBin64x2.srcR); 5038 UInt opc2; 5039 switch (i->Pin.AvBin64x2.op) { 5040 case Pav_ADDU: opc2 = 192; break; // vaddudm vector double add 5041 case Pav_SUBU: opc2 = 1216; break; // vsubudm vector double add 5042 case Pav_MAXU: opc2 = 194; break; // vmaxud vector double max 5043 case Pav_MAXS: opc2 = 450; break; // vmaxsd vector double max 5044 case Pav_MINU: opc2 = 706; break; // vminud vector double min 5045 case Pav_MINS: opc2 = 962; break; // vminsd vector double min 5046 case Pav_CMPEQU: opc2 = 199; break; // vcmpequd vector double compare 5047 case Pav_CMPGTU: opc2 = 711; break; // vcmpgtud vector double compare 5048 case Pav_CMPGTS: opc2 = 967; break; // vcmpgtsd vector double compare 5049 case Pav_SHL: opc2 = 1476; break; // vsld 5050 case Pav_SHR: opc2 = 1732; break; // vsrd 5051 case Pav_SAR: opc2 = 964; break; // vsrad 5052 case Pav_ROTL: opc2 = 196; break; // vrld 5053 case Pav_PACKUU: opc2 = 1102; break; // vpkudum 5054 case Pav_QPACKUU: opc2 = 1230; break; // vpkudus, vpksdus (emulated) 5055 case Pav_QPACKSS: opc2 = 1486; break; // vpksdsm 5056 case Pav_MRGHI: opc2 = 1614; break; // vmrghw 5057 case Pav_MRGLO: opc2 = 1742; break; // vmrglw 5058 case Pav_POLYMULADD: opc2 = 1096; break; // vpmsumd 5059 default: 5060 goto bad; 5061 } 5062 p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, opc2, endness_host ); 5063 goto done; 5064 } 5065 case Pin_AvCipherV128Unary: { 5066 UInt v_dst = vregEnc(i->Pin.AvCipherV128Unary.dst); 5067 UInt v_src = vregEnc(i->Pin.AvCipherV128Unary.src); 5068 UInt opc2; 5069 switch (i->Pin.AvCipherV128Unary.op) { 5070 case Pav_CIPHERSUBV128: opc2 = 1480; break; // vsbox 5071 default: 5072 goto bad; 5073 } 5074 p = mkFormVX( p, 4, v_dst, v_src, 0, opc2, endness_host ); 5075 goto done; 5076 } 5077 case Pin_AvCipherV128Binary: { 5078 UInt v_dst = vregEnc(i->Pin.AvCipherV128Binary.dst); 5079 UInt v_srcL = vregEnc(i->Pin.AvCipherV128Binary.srcL); 5080 UInt v_srcR = vregEnc(i->Pin.AvCipherV128Binary.srcR); 5081 UInt opc2; 5082 switch (i->Pin.AvCipherV128Binary.op) { 5083 case Pav_CIPHERV128: opc2 = 1288; break; // vcipher 5084 case Pav_CIPHERLV128: opc2 = 1289; break; // vcipherlast 5085 case Pav_NCIPHERV128: opc2 = 1352; break; // vncipher 5086 case Pav_NCIPHERLV128: opc2 = 1353; break; // vncipherlast 5087 default: 5088 goto bad; 5089 } 5090 p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, opc2, endness_host ); 5091 goto done; 5092 } 5093 case Pin_AvHashV128Binary: { 5094 UInt v_dst = vregEnc(i->Pin.AvHashV128Binary.dst); 5095 UInt v_src = vregEnc(i->Pin.AvHashV128Binary.src); 5096 PPCRI* s_field = i->Pin.AvHashV128Binary.s_field; 5097 UInt opc2; 5098 switch (i->Pin.AvHashV128Binary.op) { 5099 case Pav_SHA256: opc2 = 1666; break; // vshasigmaw 5100 case Pav_SHA512: opc2 = 1730; break; // vshasigmad 5101 default: 5102 goto bad; 5103 } 5104 p = mkFormVX( p, 4, v_dst, v_src, s_field->Pri.Imm, opc2, endness_host ); 5105 goto done; 5106 } 5107 case Pin_AvBCDV128Trinary: { 5108 UInt v_dst = vregEnc(i->Pin.AvBCDV128Trinary.dst); 5109 UInt v_src1 = vregEnc(i->Pin.AvBCDV128Trinary.src1); 5110 UInt v_src2 = vregEnc(i->Pin.AvBCDV128Trinary.src2); 5111 PPCRI* ps = i->Pin.AvBCDV128Trinary.ps; 5112 UInt opc2; 5113 switch (i->Pin.AvBCDV128Trinary.op) { 5114 case Pav_BCDAdd: opc2 = 1; break; // bcdadd 5115 case Pav_BCDSub: opc2 = 65; break; // bcdsub 5116 default: 5117 goto bad; 5118 } 5119 p = mkFormVXR( p, 4, v_dst, v_src1, v_src2, 5120 0x1, (ps->Pri.Imm << 9) | opc2, endness_host ); 5121 goto done; 5122 } 5123 case Pin_AvBin32Fx4: { 5124 UInt v_dst = vregEnc(i->Pin.AvBin32Fx4.dst); 5125 UInt v_srcL = vregEnc(i->Pin.AvBin32Fx4.srcL); 5126 UInt v_srcR = vregEnc(i->Pin.AvBin32Fx4.srcR); 5127 switch (i->Pin.AvBin32Fx4.op) { 5128 5129 case Pavfp_ADDF: 5130 p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, 10, endness_host ); // vaddfp 5131 break; 5132 case Pavfp_SUBF: 5133 p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, 74, endness_host ); // vsubfp 5134 break; 5135 case Pavfp_MAXF: 5136 p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, 1034, endness_host ); // vmaxfp 5137 break; 5138 case Pavfp_MINF: 5139 p = mkFormVX( p, 4, v_dst, v_srcL, v_srcR, 1098, endness_host ); // vminfp 5140 break; 5141 5142 case Pavfp_MULF: { 5143 /* Make a vmulfp from a vmaddfp: 5144 load -0.0 (0x8000_0000) to each 32-bit word of vB 5145 this makes the add a noop. 5146 */ 5147 UInt vB = 29; // XXX: Using v29 for temp do not change 5148 // without also changing 5149 // getRegUsage_PPCInstr 5150 UInt konst = 0x1F; 5151 5152 // Better way to load -0.0 (0x80000000) ? 5153 // vspltisw vB,0x1F (0x1F => each word of vB) 5154 p = mkFormVX( p, 4, vB, konst, 0, 908, endness_host ); 5155 5156 // vslw vB,vB,vB (each word of vB = (0x1F << 0x1F) = 0x80000000 5157 p = mkFormVX( p, 4, vB, vB, vB, 388, endness_host ); 5158 5159 // Finally, do the multiply: 5160 p = mkFormVA( p, 4, v_dst, v_srcL, vB, v_srcR, 46, endness_host ); 5161 break; 5162 } 5163 case Pavfp_CMPEQF: // vcmpeqfp 5164 p = mkFormVXR( p, 4, v_dst, v_srcL, v_srcR, 0, 198, endness_host); 5165 break; 5166 case Pavfp_CMPGTF: // vcmpgtfp 5167 p = mkFormVXR( p, 4, v_dst, v_srcL, v_srcR, 0, 710, endness_host ); 5168 break; 5169 case Pavfp_CMPGEF: // vcmpgefp 5170 p = mkFormVXR( p, 4, v_dst, v_srcL, v_srcR, 0, 454, endness_host ); 5171 break; 5172 5173 default: 5174 goto bad; 5175 } 5176 goto done; 5177 } 5178 5179 case Pin_AvUn32Fx4: { 5180 UInt v_dst = vregEnc(i->Pin.AvUn32Fx4.dst); 5181 UInt v_src = vregEnc(i->Pin.AvUn32Fx4.src); 5182 UInt opc2; 5183 switch (i->Pin.AvUn32Fx4.op) { 5184 case Pavfp_RCPF: opc2 = 266; break; // vrefp 5185 case Pavfp_RSQRTF: opc2 = 330; break; // vrsqrtefp 5186 case Pavfp_CVTU2F: opc2 = 778; break; // vcfux 5187 case Pavfp_CVTS2F: opc2 = 842; break; // vcfsx 5188 case Pavfp_QCVTF2U: opc2 = 906; break; // vctuxs 5189 case Pavfp_QCVTF2S: opc2 = 970; break; // vctsxs 5190 case Pavfp_ROUNDM: opc2 = 714; break; // vrfim 5191 case Pavfp_ROUNDP: opc2 = 650; break; // vrfip 5192 case Pavfp_ROUNDN: opc2 = 522; break; // vrfin 5193 case Pavfp_ROUNDZ: opc2 = 586; break; // vrfiz 5194 default: 5195 goto bad; 5196 } 5197 p = mkFormVX( p, 4, v_dst, 0, v_src, opc2, endness_host ); 5198 goto done; 5199 } 5200 5201 case Pin_AvPerm: { // vperm 5202 UInt v_dst = vregEnc(i->Pin.AvPerm.dst); 5203 UInt v_srcL = vregEnc(i->Pin.AvPerm.srcL); 5204 UInt v_srcR = vregEnc(i->Pin.AvPerm.srcR); 5205 UInt v_ctl = vregEnc(i->Pin.AvPerm.ctl); 5206 p = mkFormVA( p, 4, v_dst, v_srcL, v_srcR, v_ctl, 43, endness_host ); 5207 goto done; 5208 } 5209 5210 case Pin_AvSel: { // vsel 5211 UInt v_ctl = vregEnc(i->Pin.AvSel.ctl); 5212 UInt v_dst = vregEnc(i->Pin.AvSel.dst); 5213 UInt v_srcL = vregEnc(i->Pin.AvSel.srcL); 5214 UInt v_srcR = vregEnc(i->Pin.AvSel.srcR); 5215 p = mkFormVA( p, 4, v_dst, v_srcL, v_srcR, v_ctl, 42, endness_host ); 5216 goto done; 5217 } 5218 5219 case Pin_AvSh: { // vsl or vsr 5220 UInt v_dst = vregEnc(i->Pin.AvSh.dst); 5221 Bool idxd = toBool(i->Pin.AvSh.addr->tag == Pam_RR); 5222 UInt r_idx, r_base; 5223 5224 r_base = iregEnc(i->Pin.AvSh.addr->Pam.RR.base, mode64); 5225 5226 if (!idxd) { 5227 r_idx = 30; // XXX: Using r30 as temp 5228 p = mkLoadImm(p, r_idx, 5229 i->Pin.AvSh.addr->Pam.IR.index, mode64, endness_host); 5230 } else { 5231 r_idx = iregEnc(i->Pin.AvSh.addr->Pam.RR.index, mode64); 5232 } 5233 5234 if (i->Pin.AvSh.shLeft) 5235 //vsl VRT,RA,RB 5236 p = mkFormVXI( p, 31, v_dst, r_idx, r_base, 6, endness_host ); 5237 else 5238 //vsr VRT,RA,RB 5239 p = mkFormVXI( p, 31, v_dst, r_idx, r_base, 38, endness_host ); 5240 goto done; 5241 } 5242 5243 case Pin_AvShlDbl: { // vsldoi 5244 UInt shift = i->Pin.AvShlDbl.shift; 5245 UInt v_dst = vregEnc(i->Pin.AvShlDbl.dst); 5246 UInt v_srcL = vregEnc(i->Pin.AvShlDbl.srcL); 5247 UInt v_srcR = vregEnc(i->Pin.AvShlDbl.srcR); 5248 vassert(shift <= 0xF); 5249 p = mkFormVA( p, 4, v_dst, v_srcL, v_srcR, shift, 44, endness_host ); 5250 goto done; 5251 } 5252 5253 case Pin_AvSplat: { // vsplt(is)(b,h,w) 5254 UInt v_dst = vregEnc(i->Pin.AvShlDbl.dst); 5255 UChar sz = i->Pin.AvSplat.sz; 5256 UInt v_src, opc2; 5257 vassert(sz == 8 || sz == 16 || sz == 32); 5258 5259 if (i->Pin.AvSplat.src->tag == Pvi_Imm) { 5260 Char simm5; 5261 opc2 = (sz == 8) ? 780 : (sz == 16) ? 844 : 908; // 8,16,32 5262 /* expects 5-bit-signed-imm */ 5263 simm5 = i->Pin.AvSplat.src->Pvi.Imm5s; 5264 vassert(simm5 >= -16 && simm5 <= 15); 5265 simm5 = simm5 & 0x1F; 5266 p = mkFormVX( p, 4, v_dst, (UInt)simm5, 0, opc2, endness_host ); 5267 } 5268 else { // Pri_Reg 5269 UInt lowest_lane; 5270 opc2 = (sz == 8) ? 524 : (sz == 16) ? 588 : 652; // 8,16,32 5271 vassert(hregClass(i->Pin.AvSplat.src->Pvi.Reg) == HRcVec128); 5272 v_src = vregEnc(i->Pin.AvSplat.src->Pvi.Reg); 5273 lowest_lane = (128/sz)-1; 5274 p = mkFormVX( p, 4, v_dst, lowest_lane, v_src, opc2, endness_host ); 5275 } 5276 goto done; 5277 } 5278 5279 case Pin_AvCMov: { 5280 UInt v_dst = vregEnc(i->Pin.AvCMov.dst); 5281 UInt v_src = vregEnc(i->Pin.AvCMov.src); 5282 PPCCondCode cc = i->Pin.AvCMov.cond; 5283 5284 if (v_dst == v_src) goto done; 5285 5286 vassert(cc.test != Pct_ALWAYS); 5287 5288 /* jmp fwds 2 insns if !condition */ 5289 if (cc.test != Pct_ALWAYS) { 5290 /* bc !ct,cf,n_bytes>>2 */ 5291 p = mkFormB(p, invertCondTest(cc.test), cc.flag, 8>>2, 0, 0, 5292 endness_host); 5293 } 5294 /* vmr */ 5295 p = mkFormVX( p, 4, v_dst, v_src, v_src, 1156, endness_host ); 5296 goto done; 5297 } 5298 5299 case Pin_AvLdVSCR: { // mtvscr 5300 UInt v_src = vregEnc(i->Pin.AvLdVSCR.src); 5301 p = mkFormVX( p, 4, 0, 0, v_src, 1604, endness_host ); 5302 goto done; 5303 } 5304 5305 case Pin_Dfp64Unary: { 5306 UInt fr_dst = fregEnc( i->Pin.FpUnary.dst ); 5307 UInt fr_src = fregEnc( i->Pin.FpUnary.src ); 5308 5309 switch (i->Pin.Dfp64Unary.op) { 5310 case Pfp_MOV: // fmr, PPC32 p410 5311 p = mkFormX( p, 63, fr_dst, 0, fr_src, 72, 0, endness_host ); 5312 break; 5313 case Pfp_DCTDP: // D32 to D64 5314 p = mkFormX( p, 59, fr_dst, 0, fr_src, 258, 0, endness_host ); 5315 break; 5316 case Pfp_DRSP: // D64 to D32 5317 p = mkFormX( p, 59, fr_dst, 0, fr_src, 770, 0, endness_host ); 5318 break; 5319 case Pfp_DCFFIX: // I64 to D64 conversion 5320 /* ONLY WORKS ON POWER7 */ 5321 p = mkFormX( p, 59, fr_dst, 0, fr_src, 802, 0, endness_host ); 5322 break; 5323 case Pfp_DCTFIX: // D64 to I64 conversion 5324 p = mkFormX( p, 59, fr_dst, 0, fr_src, 290, 0, endness_host ); 5325 break; 5326 case Pfp_DXEX: // Extract exponent 5327 p = mkFormX( p, 59, fr_dst, 0, fr_src, 354, 0, endness_host ); 5328 break; 5329 default: 5330 goto bad; 5331 } 5332 goto done; 5333 } 5334 5335 case Pin_Dfp64Binary: { 5336 UInt fr_dst = fregEnc( i->Pin.Dfp64Binary.dst ); 5337 UInt fr_srcL = fregEnc( i->Pin.Dfp64Binary.srcL ); 5338 UInt fr_srcR = fregEnc( i->Pin.Dfp64Binary.srcR ); 5339 switch (i->Pin.Dfp64Binary.op) { 5340 case Pfp_DFPADD: /* dadd, dfp add, use default RM from reg ignore mode 5341 * from the Iop instruction. */ 5342 p = mkFormX( p, 59, fr_dst, fr_srcL, fr_srcR, 2, 0, endness_host ); 5343 break; 5344 case Pfp_DFPSUB: /* dsub, dfp subtract, use default RM from reg ignore 5345 * mode from the Iop instruction. */ 5346 p = mkFormX( p, 59, fr_dst, fr_srcL, fr_srcR, 514, 0, endness_host ); 5347 break; 5348 case Pfp_DFPMUL: /* dmul, dfp multipy, use default RM from reg ignore 5349 * mode from the Iop instruction. */ 5350 p = mkFormX( p, 59, fr_dst, fr_srcL, fr_srcR, 34, 0, endness_host ); 5351 break; 5352 case Pfp_DFPDIV: /* ddiv, dfp divide, use default RM from reg ignore 5353 * mode from the Iop instruction. */ 5354 p = mkFormX( p, 59, fr_dst, fr_srcL, fr_srcR, 546, 0, endness_host ); 5355 break; 5356 case Pfp_DIEX: /* diex, insert exponent */ 5357 p = mkFormX( p, 59, fr_dst, fr_srcL, fr_srcR, 866, 0, endness_host ); 5358 break; 5359 default: 5360 goto bad; 5361 } 5362 goto done; 5363 } 5364 5365 case Pin_DfpShift: { 5366 UInt fr_src = fregEnc(i->Pin.DfpShift.src); 5367 UInt fr_dst = fregEnc(i->Pin.DfpShift.dst); 5368 UInt shift; 5369 5370 shift = i->Pin.DfpShift.shift->Pri.Imm; 5371 5372 switch (i->Pin.DfpShift.op) { 5373 case Pfp_DSCLI: /* dscli, DFP shift left by fr_srcR */ 5374 p = mkFormZ22( p, 59, fr_dst, fr_src, shift, 66, 0, endness_host ); 5375 break; 5376 case Pfp_DSCRI: /* dscri, DFP shift right by fr_srcR */ 5377 p = mkFormZ22( p, 59, fr_dst, fr_src, shift, 98, 0, endness_host ); 5378 break; 5379 default: 5380 vex_printf("ERROR: emit_PPCInstr default case\n"); 5381 goto bad; 5382 } 5383 goto done; 5384 } 5385 5386 case Pin_ExtractExpD128: { 5387 UInt fr_dst = fregEnc(i->Pin.ExtractExpD128.dst); 5388 UInt fr_srcHi = fregEnc(i->Pin.ExtractExpD128.src_hi); 5389 UInt fr_srcLo = fregEnc(i->Pin.ExtractExpD128.src_lo); 5390 5391 switch (i->Pin.ExtractExpD128.op) { 5392 case Pfp_DXEXQ: 5393 /* Setup the upper and lower registers of the source operand 5394 * register pair. 5395 */ 5396 p = mkFormX( p, 63, 12, 0, fr_srcHi, 72, 0, endness_host ); 5397 p = mkFormX( p, 63, 13, 0, fr_srcLo, 72, 0, endness_host ); 5398 p = mkFormX( p, 63, 10, 0, 12, 354, 0, endness_host ); 5399 5400 /* The instruction will put the 64-bit result in 5401 * register 10. 5402 */ 5403 p = mkFormX(p, 63, fr_dst, 0, 10, 72, 0, endness_host); 5404 break; 5405 default: 5406 vex_printf("Error: emit_PPCInstr case Pin_DfpExtractExp, case inst Default\n"); 5407 goto bad; 5408 } 5409 goto done; 5410 } 5411 case Pin_Dfp128Unary: { 5412 UInt fr_dstHi = fregEnc(i->Pin.Dfp128Unary.dst_hi); 5413 UInt fr_dstLo = fregEnc(i->Pin.Dfp128Unary.dst_lo); 5414 UInt fr_srcLo = fregEnc(i->Pin.Dfp128Unary.src_lo); 5415 5416 /* Do instruction with 128-bit source operands in registers (10,11) 5417 * and (12,13). 5418 */ 5419 switch (i->Pin.Dfp128Unary.op) { 5420 case Pfp_DCTQPQ: // D64 to D128, srcLo holds 64 bit operand 5421 p = mkFormX( p, 63, 12, 0, fr_srcLo, 72, 0, endness_host ); 5422 5423 p = mkFormX( p, 63, 10, 0, 12, 258, 0, endness_host ); 5424 5425 /* The instruction will put the 128-bit result in 5426 * registers (10,11). Note, the operand in the instruction only 5427 * reference the first of the two registers in the pair. 5428 */ 5429 p = mkFormX(p, 63, fr_dstHi, 0, 10, 72, 0, endness_host); 5430 p = mkFormX(p, 63, fr_dstLo, 0, 11, 72, 0, endness_host); 5431 break; 5432 default: 5433 vex_printf("Error: emit_PPCInstr case Pin_Dfp128Unary, case inst Default\ 5434 \n"); 5435 goto bad; 5436 } 5437 goto done; 5438 } 5439 5440 case Pin_Dfp128Binary: { 5441 /* dst is used to supply the left source operand and return 5442 * the result. 5443 */ 5444 UInt fr_dstHi = fregEnc( i->Pin.Dfp128Binary.dst_hi ); 5445 UInt fr_dstLo = fregEnc( i->Pin.Dfp128Binary.dst_lo ); 5446 UInt fr_srcRHi = fregEnc( i->Pin.Dfp128Binary.srcR_hi ); 5447 UInt fr_srcRLo = fregEnc( i->Pin.Dfp128Binary.srcR_lo ); 5448 5449 /* Setup the upper and lower registers of the source operand 5450 * register pair. 5451 */ 5452 p = mkFormX( p, 63, 10, 0, fr_dstHi, 72, 0, endness_host ); 5453 p = mkFormX( p, 63, 11, 0, fr_dstLo, 72, 0, endness_host ); 5454 p = mkFormX( p, 63, 12, 0, fr_srcRHi, 72, 0, endness_host ); 5455 p = mkFormX( p, 63, 13, 0, fr_srcRLo, 72, 0, endness_host ); 5456 5457 /* Do instruction with 128-bit source operands in registers (10,11) 5458 * and (12,13). 5459 */ 5460 switch (i->Pin.Dfp128Binary.op) { 5461 case Pfp_DFPADDQ: 5462 p = mkFormX( p, 63, 10, 10, 12, 2, 0, endness_host ); 5463 break; 5464 case Pfp_DFPSUBQ: 5465 p = mkFormX( p, 63, 10, 10, 12, 514, 0, endness_host ); 5466 break; 5467 case Pfp_DFPMULQ: 5468 p = mkFormX( p, 63, 10, 10, 12, 34, 0, endness_host ); 5469 break; 5470 case Pfp_DFPDIVQ: 5471 p = mkFormX( p, 63, 10, 10, 12, 546, 0, endness_host ); 5472 break; 5473 default: 5474 goto bad; 5475 } 5476 5477 /* The instruction will put the 128-bit result in 5478 * registers (10,11). Note, the operand in the instruction only 5479 * reference the first of the two registers in the pair. 5480 */ 5481 p = mkFormX(p, 63, fr_dstHi, 0, 10, 72, 0, endness_host); 5482 p = mkFormX(p, 63, fr_dstLo, 0, 11, 72, 0, endness_host); 5483 goto done; 5484 } 5485 5486 case Pin_DfpShift128: { 5487 UInt fr_src_hi = fregEnc(i->Pin.DfpShift128.src_hi); 5488 UInt fr_src_lo = fregEnc(i->Pin.DfpShift128.src_lo); 5489 UInt fr_dst_hi = fregEnc(i->Pin.DfpShift128.dst_hi); 5490 UInt fr_dst_lo = fregEnc(i->Pin.DfpShift128.dst_lo); 5491 UInt shift; 5492 5493 shift = i->Pin.DfpShift128.shift->Pri.Imm; 5494 5495 /* setup source operand in register 12, 13 pair */ 5496 p = mkFormX(p, 63, 12, 0, fr_src_hi, 72, 0, endness_host); 5497 p = mkFormX(p, 63, 13, 0, fr_src_lo, 72, 0, endness_host); 5498 5499 /* execute instruction putting result in register 10, 11 pair */ 5500 switch (i->Pin.DfpShift128.op) { 5501 case Pfp_DSCLIQ: /* dscliq, DFP shift left, fr_srcR is the integer 5502 * shift amount. 5503 */ 5504 p = mkFormZ22( p, 63, 10, 12, shift, 66, 0, endness_host ); 5505 break; 5506 case Pfp_DSCRIQ: /* dscriq, DFP shift right, fr_srcR is the integer 5507 * shift amount. 5508 */ 5509 p = mkFormZ22( p, 63, 10, 12, shift, 98, 0, endness_host ); 5510 break; 5511 default: 5512 vex_printf("ERROR: emit_PPCInstr quad default case %d \n", 5513 (Int)i->Pin.DfpShift128.op); 5514 goto bad; 5515 } 5516 5517 /* The instruction put the 128-bit result in registers (10,11). 5518 * Note, the operand in the instruction only reference the first of 5519 * the two registers in the pair. 5520 */ 5521 p = mkFormX(p, 63, fr_dst_hi, 0, 10, 72, 0, endness_host); 5522 p = mkFormX(p, 63, fr_dst_lo, 0, 11, 72, 0, endness_host); 5523 goto done; 5524 } 5525 5526 case Pin_DfpRound: { 5527 UInt fr_dst = fregEnc(i->Pin.DfpRound.dst); 5528 UInt fr_src = fregEnc(i->Pin.DfpRound.src); 5529 UInt r_rmc, r, rmc; 5530 5531 r_rmc = i->Pin.DfpRound.r_rmc->Pri.Imm; 5532 r = (r_rmc & 0x8) >> 3; 5533 rmc = r_rmc & 0x3; 5534 5535 // drintx 5536 p = mkFormZ23(p, 59, fr_dst, r, fr_src, rmc, 99, 0, endness_host); 5537 goto done; 5538 } 5539 5540 case Pin_DfpRound128: { 5541 UInt fr_dstHi = fregEnc(i->Pin.DfpRound128.dst_hi); 5542 UInt fr_dstLo = fregEnc(i->Pin.DfpRound128.dst_lo); 5543 UInt fr_srcHi = fregEnc(i->Pin.DfpRound128.src_hi); 5544 UInt fr_srcLo = fregEnc(i->Pin.DfpRound128.src_lo); 5545 UInt r_rmc, r, rmc; 5546 5547 r_rmc = i->Pin.DfpRound128.r_rmc->Pri.Imm; 5548 r = (r_rmc & 0x8) >> 3; 5549 rmc = r_rmc & 0x3; 5550 5551 /* Setup the upper and lower registers of the source operand 5552 * register pair. 5553 */ 5554 p = mkFormX(p, 63, 12, 0, fr_srcHi, 72, 0, endness_host); 5555 p = mkFormX(p, 63, 13, 0, fr_srcLo, 72, 0, endness_host); 5556 5557 /* Do drintx instruction with 128-bit source operands in 5558 * registers (12,13). 5559 */ 5560 p = mkFormZ23(p, 63, 10, r, 12, rmc, 99, 0, endness_host); 5561 5562 /* The instruction will put the 128-bit result in 5563 * registers (10,11). Note, the operand in the instruction only 5564 * reference the first of the two registers in the pair. 5565 */ 5566 p = mkFormX(p, 63, fr_dstHi, 0, 10, 72, 0, endness_host); 5567 p = mkFormX(p, 63, fr_dstLo, 0, 11, 72, 0, endness_host); 5568 goto done; 5569 } 5570 5571 case Pin_DfpQuantize: { 5572 UInt fr_dst = fregEnc(i->Pin.DfpQuantize.dst); 5573 UInt fr_srcL = fregEnc(i->Pin.DfpQuantize.srcL); 5574 UInt fr_srcR = fregEnc(i->Pin.DfpQuantize.srcR); 5575 UInt rmc; 5576 5577 rmc = i->Pin.DfpQuantize.rmc->Pri.Imm; 5578 5579 switch (i->Pin.DfpQuantize.op) { 5580 case Pfp_DQUA: 5581 p = mkFormZ23(p, 59, fr_dst, fr_srcL, fr_srcR, rmc, 3, 0, endness_host); 5582 break; 5583 case Pfp_RRDTR: 5584 p = mkFormZ23(p, 59, fr_dst, fr_srcL, fr_srcR, rmc, 35, 0, endness_host); 5585 break; 5586 default: 5587 break; 5588 } 5589 goto done; 5590 } 5591 5592 case Pin_DfpQuantize128: { 5593 UInt fr_dst_hi = fregEnc(i->Pin.DfpQuantize128.dst_hi); 5594 UInt fr_dst_lo = fregEnc(i->Pin.DfpQuantize128.dst_lo); 5595 UInt fr_src_hi = fregEnc(i->Pin.DfpQuantize128.src_hi); 5596 UInt fr_src_lo = fregEnc(i->Pin.DfpQuantize128.src_lo); 5597 UInt rmc; 5598 5599 rmc = i->Pin.DfpQuantize128.rmc->Pri.Imm; 5600 /* Setup the upper and lower registers of the source operand 5601 * register pairs. Note, left source operand passed in via the 5602 * dst register pair. 5603 */ 5604 p = mkFormX(p, 63, 10, 0, fr_dst_hi, 72, 0, endness_host); 5605 p = mkFormX(p, 63, 11, 0, fr_dst_lo, 72, 0, endness_host); 5606 p = mkFormX(p, 63, 12, 0, fr_src_hi, 72, 0, endness_host); 5607 p = mkFormX(p, 63, 13, 0, fr_src_lo, 72, 0, endness_host); 5608 5609 /* Do dquaq instruction with 128-bit source operands in 5610 * registers (12,13). 5611 */ 5612 switch (i->Pin.DfpQuantize128.op) { 5613 case Pfp_DQUAQ: 5614 p = mkFormZ23(p, 63, 10, 10, 12, rmc, 3, 0, endness_host); 5615 break; 5616 case Pfp_DRRNDQ: 5617 p = mkFormZ23(p, 63, 10, 10, 12, rmc, 35, 0, endness_host); 5618 break; 5619 default: 5620 vpanic("Pin_DfpQuantize128: default case, couldn't find inst to issue \n"); 5621 break; 5622 } 5623 5624 /* The instruction will put the 128-bit result in 5625 * registers (10,11). Note, the operand in the instruction only 5626 * reference the first of the two registers in the pair. 5627 */ 5628 p = mkFormX(p, 63, fr_dst_hi, 0, 10, 72, 0, endness_host); 5629 p = mkFormX(p, 63, fr_dst_lo, 0, 11, 72, 0, endness_host); 5630 goto done; 5631 } 5632 5633 case Pin_DfpD128toD64: { 5634 UInt fr_dst = fregEnc( i->Pin.DfpD128toD64.dst ); 5635 UInt fr_srcHi = fregEnc( i->Pin.DfpD128toD64.src_hi ); 5636 UInt fr_srcLo = fregEnc( i->Pin.DfpD128toD64.src_lo ); 5637 5638 /* Setup the upper and lower registers of the source operand 5639 * register pair. 5640 */ 5641 p = mkFormX( p, 63, 10, 0, fr_dst, 72, 0, endness_host ); 5642 p = mkFormX( p, 63, 12, 0, fr_srcHi, 72, 0, endness_host ); 5643 p = mkFormX( p, 63, 13, 0, fr_srcLo, 72, 0, endness_host ); 5644 5645 /* Do instruction with 128-bit source operands in registers (10,11) */ 5646 switch (i->Pin.Dfp128Binary.op) { 5647 case Pfp_DRDPQ: 5648 p = mkFormX( p, 63, 10, 0, 12, 770, 0, endness_host ); 5649 break; 5650 case Pfp_DCTFIXQ: 5651 p = mkFormX( p, 63, 10, 0, 12, 290, 0, endness_host ); 5652 break; 5653 default: 5654 goto bad; 5655 } 5656 5657 /* The instruction will put the 64-bit result in registers 10. */ 5658 p = mkFormX(p, 63, fr_dst, 0, 10, 72, 0, endness_host); 5659 goto done; 5660 } 5661 5662 case Pin_DfpI64StoD128: { 5663 UInt fr_dstHi = fregEnc( i->Pin.DfpI64StoD128.dst_hi ); 5664 UInt fr_dstLo = fregEnc( i->Pin.DfpI64StoD128.dst_lo ); 5665 UInt fr_src = fregEnc( i->Pin.DfpI64StoD128.src ); 5666 5667 switch (i->Pin.Dfp128Binary.op) { 5668 case Pfp_DCFFIXQ: 5669 p = mkFormX( p, 63, 10, 11, fr_src, 802, 0, endness_host ); 5670 break; 5671 default: 5672 goto bad; 5673 } 5674 5675 /* The instruction will put the 64-bit result in registers 10, 11. */ 5676 p = mkFormX(p, 63, fr_dstHi, 0, 10, 72, 0, endness_host); 5677 p = mkFormX(p, 63, fr_dstLo, 0, 11, 72, 0, endness_host); 5678 goto done; 5679 } 5680 5681 case Pin_InsertExpD128: { 5682 UInt fr_dstHi = fregEnc(i->Pin.InsertExpD128.dst_hi); 5683 UInt fr_dstLo = fregEnc(i->Pin.InsertExpD128.dst_lo); 5684 UInt fr_srcL = fregEnc(i->Pin.InsertExpD128.srcL); 5685 UInt fr_srcRHi = fregEnc(i->Pin.InsertExpD128.srcR_hi); 5686 UInt fr_srcRLo = fregEnc(i->Pin.InsertExpD128.srcR_lo); 5687 5688 /* The left operand is a single F64 value, the right is an F128 5689 * register pair. 5690 */ 5691 p = mkFormX(p, 63, 10, 0, fr_srcL, 72, 0, endness_host); 5692 p = mkFormX(p, 63, 12, 0, fr_srcRHi, 72, 0, endness_host); 5693 p = mkFormX(p, 63, 13, 0, fr_srcRLo, 72, 0, endness_host); 5694 p = mkFormX(p, 63, 10, 10, 12, 866, 0, endness_host ); 5695 5696 /* The instruction will put the 128-bit result into 5697 * registers (10,11). Note, the operand in the instruction only 5698 * reference the first of the two registers in the pair. 5699 */ 5700 p = mkFormX(p, 63, fr_dstHi, 0, 10, 72, 0, endness_host); 5701 p = mkFormX(p, 63, fr_dstLo, 0, 11, 72, 0, endness_host); 5702 goto done; 5703 } 5704 5705 case Pin_Dfp64Cmp:{ 5706 UChar crfD = 1; 5707 UInt r_dst = iregEnc(i->Pin.Dfp64Cmp.dst, mode64); 5708 UInt fr_srcL = fregEnc(i->Pin.Dfp64Cmp.srcL); 5709 UInt fr_srcR = fregEnc(i->Pin.Dfp64Cmp.srcR); 5710 vassert(crfD < 8); 5711 // dcmpo, dcmpu 5712 p = mkFormX(p, 59, crfD<<2, fr_srcL, fr_srcR, 130, 0, endness_host); 5713 5714 // mfcr (mv CR to r_dst) 5715 p = mkFormX(p, 31, r_dst, 0, 0, 19, 0, endness_host); 5716 5717 // rlwinm r_dst,r_dst,8,28,31 5718 // => rotate field 1 to bottomw of word, masking out upper 28 5719 p = mkFormM(p, 21, r_dst, r_dst, 8, 28, 31, 0, endness_host); 5720 goto done; 5721 } 5722 5723 case Pin_Dfp128Cmp: { 5724 UChar crfD = 1; 5725 UInt r_dst = iregEnc(i->Pin.Dfp128Cmp.dst, mode64); 5726 UInt fr_srcL_hi = fregEnc(i->Pin.Dfp128Cmp.srcL_hi); 5727 UInt fr_srcL_lo = fregEnc(i->Pin.Dfp128Cmp.srcL_lo); 5728 UInt fr_srcR_hi = fregEnc(i->Pin.Dfp128Cmp.srcR_hi); 5729 UInt fr_srcR_lo = fregEnc(i->Pin.Dfp128Cmp.srcR_lo); 5730 vassert(crfD < 8); 5731 // dcmpoq, dcmpuq 5732 /* Setup the upper and lower registers of the source operand 5733 * register pair. 5734 */ 5735 p = mkFormX(p, 63, 10, 0, fr_srcL_hi, 72, 0, endness_host); 5736 p = mkFormX(p, 63, 11, 0, fr_srcL_lo, 72, 0, endness_host); 5737 p = mkFormX(p, 63, 12, 0, fr_srcR_hi, 72, 0, endness_host); 5738 p = mkFormX(p, 63, 13, 0, fr_srcR_lo, 72, 0, endness_host); 5739 5740 p = mkFormX(p, 63, crfD<<2, 10, 12, 130, 0, endness_host); 5741 5742 // mfcr (mv CR to r_dst) 5743 p = mkFormX(p, 31, r_dst, 0, 0, 19, 0, endness_host); 5744 5745 // rlwinm r_dst,r_dst,8,28,31 5746 // => rotate field 1 to bottomw of word, masking out upper 28 5747 p = mkFormM(p, 21, r_dst, r_dst, 8, 28, 31, 0, endness_host); 5748 goto done; 5749 } 5750 5751 case Pin_EvCheck: { 5752 /* This requires a 32-bit dec/test in both 32- and 64-bit 5753 modes. */ 5754 /* We generate: 5755 lwz r30, amCounter 5756 addic. r30, r30, -1 5757 stw r30, amCounter 5758 bge nofail 5759 lwz/ld r30, amFailAddr 5760 mtctr r30 5761 bctr 5762 nofail: 5763 */ 5764 UChar* p0 = p; 5765 /* lwz r30, amCounter */ 5766 p = do_load_or_store_word32(p, True/*isLoad*/, /*r*/30, 5767 i->Pin.EvCheck.amCounter, mode64, 5768 endness_host); 5769 /* addic. r30,r30,-1 */ 5770 p = emit32(p, 0x37DEFFFF, endness_host); 5771 /* stw r30, amCounter */ 5772 p = do_load_or_store_word32(p, False/*!isLoad*/, /*r*/30, 5773 i->Pin.EvCheck.amCounter, mode64, 5774 endness_host); 5775 /* bge nofail */ 5776 p = emit32(p, 0x40800010, endness_host); 5777 /* lwz/ld r30, amFailAddr */ 5778 p = do_load_or_store_machine_word(p, True/*isLoad*/, /*r*/30, 5779 i->Pin.EvCheck.amFailAddr, mode64, 5780 endness_host); 5781 /* mtctr r30 */ 5782 p = mkFormXFX(p, /*r*/30, 9, 467, endness_host); 5783 /* bctr */ 5784 p = mkFormXL(p, 19, Pct_ALWAYS, 0, 0, 528, 0, endness_host); 5785 /* nofail: */ 5786 5787 /* Crosscheck */ 5788 vassert(evCheckSzB_PPC() == (UChar*)p - (UChar*)p0); 5789 goto done; 5790 } 5791 5792 case Pin_ProfInc: { 5793 /* We generate: 5794 (ctrP is unknown now, so use 0x65556555(65556555) in the 5795 expectation that a later call to LibVEX_patchProfCtr 5796 will be used to fill in the immediate fields once the 5797 right value is known.) 5798 32-bit: 5799 imm32-exactly r30, 0x65556555 5800 lwz r29, 4(r30) 5801 addic. r29, r29, 1 5802 stw r29, 4(r30) 5803 lwz r29, 0(r30) 5804 addze r29, r29 5805 stw r29, 0(r30) 5806 64-bit: 5807 imm64-exactly r30, 0x6555655565556555 5808 ld r29, 0(r30) 5809 addi r29, r29, 1 5810 std r29, 0(r30) 5811 */ 5812 if (mode64) { 5813 p = mkLoadImm_EXACTLY2or5( 5814 p, /*r*/30, 0x6555655565556555ULL, True/*mode64*/, endness_host); 5815 p = emit32(p, 0xEBBE0000, endness_host); 5816 p = emit32(p, 0x3BBD0001, endness_host); 5817 p = emit32(p, 0xFBBE0000, endness_host); 5818 } else { 5819 p = mkLoadImm_EXACTLY2or5( 5820 p, /*r*/30, 0x65556555ULL, False/*!mode64*/, endness_host); 5821 p = emit32(p, 0x83BE0004, endness_host); 5822 p = emit32(p, 0x37BD0001, endness_host); 5823 p = emit32(p, 0x93BE0004, endness_host); 5824 p = emit32(p, 0x83BE0000, endness_host); 5825 p = emit32(p, 0x7FBD0194, endness_host); 5826 p = emit32(p, 0x93BE0000, endness_host); 5827 } 5828 /* Tell the caller .. */ 5829 vassert(!(*is_profInc)); 5830 *is_profInc = True; 5831 goto done; 5832 } 5833 5834 default: 5835 goto bad; 5836 } 5837 5838 bad: 5839 vex_printf("\n=> "); 5840 ppPPCInstr(i, mode64); 5841 vpanic("emit_PPCInstr"); 5842 /*NOTREACHED*/ 5843 5844 done: 5845 vassert(p - &buf[0] <= 64); 5846 return p - &buf[0]; 5847 } 5848 5849 5850 /* How big is an event check? See case for Pin_EvCheck in 5851 emit_PPCInstr just above. That crosschecks what this returns, so 5852 we can tell if we're inconsistent. */ 5853 Int evCheckSzB_PPC (void) 5854 { 5855 return 28; 5856 } 5857 5858 5859 /* NB: what goes on here has to be very closely coordinated with the 5860 emitInstr case for XDirect, above. */ 5861 VexInvalRange chainXDirect_PPC ( VexEndness endness_host, 5862 void* place_to_chain, 5863 const void* disp_cp_chain_me_EXPECTED, 5864 const void* place_to_jump_to, 5865 Bool mode64 ) 5866 { 5867 if (mode64) { 5868 vassert((endness_host == VexEndnessBE) || 5869 (endness_host == VexEndnessLE)); 5870 } else { 5871 vassert(endness_host == VexEndnessBE); 5872 } 5873 5874 /* What we're expecting to see is: 5875 imm32/64-fixed r30, disp_cp_chain_me_to_EXPECTED 5876 mtctr r30 5877 bctrl 5878 viz 5879 <8 or 20 bytes generated by mkLoadImm_EXACTLY2or5> 5880 7F C9 03 A6 5881 4E 80 04 21 5882 */ 5883 UChar* p = (UChar*)place_to_chain; 5884 vassert(0 == (3 & (HWord)p)); 5885 vassert(isLoadImm_EXACTLY2or5(p, /*r*/30, 5886 (Addr)disp_cp_chain_me_EXPECTED, 5887 mode64, endness_host)); 5888 vassert(fetch32(p + (mode64 ? 20 : 8) + 0, endness_host) == 0x7FC903A6); 5889 vassert(fetch32(p + (mode64 ? 20 : 8) + 4, endness_host) == 0x4E800421); 5890 /* And what we want to change it to is: 5891 imm32/64-fixed r30, place_to_jump_to 5892 mtctr r30 5893 bctr 5894 viz 5895 <8 or 20 bytes generated by mkLoadImm_EXACTLY2or5> 5896 7F C9 03 A6 5897 4E 80 04 20 5898 The replacement has the same length as the original. 5899 */ 5900 p = mkLoadImm_EXACTLY2or5(p, /*r*/30, 5901 (Addr)place_to_jump_to, mode64, 5902 endness_host); 5903 p = emit32(p, 0x7FC903A6, endness_host); 5904 p = emit32(p, 0x4E800420, endness_host); 5905 5906 Int len = p - (UChar*)place_to_chain; 5907 vassert(len == (mode64 ? 28 : 16)); /* stay sane */ 5908 VexInvalRange vir = {(HWord)place_to_chain, len}; 5909 return vir; 5910 } 5911 5912 5913 /* NB: what goes on here has to be very closely coordinated with the 5914 emitInstr case for XDirect, above. */ 5915 VexInvalRange unchainXDirect_PPC ( VexEndness endness_host, 5916 void* place_to_unchain, 5917 const void* place_to_jump_to_EXPECTED, 5918 const void* disp_cp_chain_me, 5919 Bool mode64 ) 5920 { 5921 if (mode64) { 5922 vassert((endness_host == VexEndnessBE) || 5923 (endness_host == VexEndnessLE)); 5924 } else { 5925 vassert(endness_host == VexEndnessBE); 5926 } 5927 5928 /* What we're expecting to see is: 5929 imm32/64-fixed r30, place_to_jump_to_EXPECTED 5930 mtctr r30 5931 bctr 5932 viz 5933 <8 or 20 bytes generated by mkLoadImm_EXACTLY2or5> 5934 7F C9 03 A6 5935 4E 80 04 20 5936 */ 5937 UChar* p = (UChar*)place_to_unchain; 5938 vassert(0 == (3 & (HWord)p)); 5939 vassert(isLoadImm_EXACTLY2or5(p, /*r*/30, 5940 (Addr)place_to_jump_to_EXPECTED, 5941 mode64, endness_host)); 5942 vassert(fetch32(p + (mode64 ? 20 : 8) + 0, endness_host) == 0x7FC903A6); 5943 vassert(fetch32(p + (mode64 ? 20 : 8) + 4, endness_host) == 0x4E800420); 5944 /* And what we want to change it to is: 5945 imm32/64-fixed r30, disp_cp_chain_me 5946 mtctr r30 5947 bctrl 5948 viz 5949 <8 or 20 bytes generated by mkLoadImm_EXACTLY2or5> 5950 7F C9 03 A6 5951 4E 80 04 21 5952 The replacement has the same length as the original. 5953 */ 5954 p = mkLoadImm_EXACTLY2or5(p, /*r*/30, 5955 (Addr)disp_cp_chain_me, mode64, 5956 endness_host); 5957 p = emit32(p, 0x7FC903A6, endness_host); 5958 p = emit32(p, 0x4E800421, endness_host); 5959 5960 Int len = p - (UChar*)place_to_unchain; 5961 vassert(len == (mode64 ? 28 : 16)); /* stay sane */ 5962 VexInvalRange vir = {(HWord)place_to_unchain, len}; 5963 return vir; 5964 } 5965 5966 5967 /* Patch the counter address into a profile inc point, as previously 5968 created by the Pin_ProfInc case for emit_PPCInstr. */ 5969 VexInvalRange patchProfInc_PPC ( VexEndness endness_host, 5970 void* place_to_patch, 5971 const ULong* location_of_counter, 5972 Bool mode64 ) 5973 { 5974 if (mode64) { 5975 vassert((endness_host == VexEndnessBE) || 5976 (endness_host == VexEndnessLE)); 5977 } else { 5978 vassert(endness_host == VexEndnessBE); 5979 } 5980 5981 UChar* p = (UChar*)place_to_patch; 5982 vassert(0 == (3 & (HWord)p)); 5983 5984 Int len = 0; 5985 if (mode64) { 5986 vassert(isLoadImm_EXACTLY2or5(p, /*r*/30, 5987 0x6555655565556555ULL, True/*mode64*/, 5988 endness_host)); 5989 vassert(fetch32(p + 20, endness_host) == 0xEBBE0000); 5990 vassert(fetch32(p + 24, endness_host) == 0x3BBD0001); 5991 vassert(fetch32(p + 28, endness_host) == 0xFBBE0000); 5992 p = mkLoadImm_EXACTLY2or5(p, /*r*/30, 5993 (Addr)location_of_counter, 5994 True/*mode64*/, endness_host); 5995 len = p - (UChar*)place_to_patch; 5996 vassert(len == 20); 5997 } else { 5998 vassert(isLoadImm_EXACTLY2or5(p, /*r*/30, 5999 0x65556555ULL, False/*!mode64*/, 6000 endness_host)); 6001 vassert(fetch32(p + 8, endness_host) == 0x83BE0004); 6002 vassert(fetch32(p + 12, endness_host) == 0x37BD0001); 6003 vassert(fetch32(p + 16, endness_host) == 0x93BE0004); 6004 vassert(fetch32(p + 20, endness_host) == 0x83BE0000); 6005 vassert(fetch32(p + 24, endness_host) == 0x7FBD0194); 6006 vassert(fetch32(p + 28, endness_host) == 0x93BE0000); 6007 p = mkLoadImm_EXACTLY2or5(p, /*r*/30, 6008 (Addr)location_of_counter, 6009 False/*!mode64*/, endness_host); 6010 len = p - (UChar*)place_to_patch; 6011 vassert(len == 8); 6012 } 6013 VexInvalRange vir = {(HWord)place_to_patch, len}; 6014 return vir; 6015 } 6016 6017 6018 /*---------------------------------------------------------------*/ 6019 /*--- end host_ppc_defs.c ---*/ 6020 /*---------------------------------------------------------------*/ 6021