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