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