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