1 2 /*---------------------------------------------------------------*/ 3 /*--- begin ir_defs.c ---*/ 4 /*---------------------------------------------------------------*/ 5 6 /* 7 This file is part of Valgrind, a dynamic binary instrumentation 8 framework. 9 10 Copyright (C) 2004-2010 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_ir.h" 38 #include "libvex.h" 39 40 #include "main_util.h" 41 42 43 /*---------------------------------------------------------------*/ 44 /*--- Printing the IR ---*/ 45 /*---------------------------------------------------------------*/ 46 47 void ppIRType ( IRType ty ) 48 { 49 switch (ty) { 50 case Ity_INVALID: vex_printf("Ity_INVALID"); break; 51 case Ity_I1: vex_printf( "I1"); break; 52 case Ity_I8: vex_printf( "I8"); break; 53 case Ity_I16: vex_printf( "I16"); break; 54 case Ity_I32: vex_printf( "I32"); break; 55 case Ity_I64: vex_printf( "I64"); break; 56 case Ity_I128: vex_printf( "I128"); break; 57 case Ity_F32: vex_printf( "F32"); break; 58 case Ity_F64: vex_printf( "F64"); break; 59 case Ity_V128: vex_printf( "V128"); break; 60 default: vex_printf("ty = 0x%x\n", (Int)ty); 61 vpanic("ppIRType"); 62 } 63 } 64 65 void ppIRConst ( IRConst* con ) 66 { 67 union { ULong i64; Double f64; } u; 68 vassert(sizeof(ULong) == sizeof(Double)); 69 switch (con->tag) { 70 case Ico_U1: vex_printf( "%d:I1", con->Ico.U1 ? 1 : 0); break; 71 case Ico_U8: vex_printf( "0x%x:I8", (UInt)(con->Ico.U8)); break; 72 case Ico_U16: vex_printf( "0x%x:I16", (UInt)(con->Ico.U16)); break; 73 case Ico_U32: vex_printf( "0x%x:I32", (UInt)(con->Ico.U32)); break; 74 case Ico_U64: vex_printf( "0x%llx:I64", (ULong)(con->Ico.U64)); break; 75 case Ico_F64: u.f64 = con->Ico.F64; 76 vex_printf( "F64{0x%llx}", u.i64); 77 break; 78 case Ico_F64i: vex_printf( "F64i{0x%llx}", con->Ico.F64i); break; 79 case Ico_V128: vex_printf( "V128{0x%04x}", (UInt)(con->Ico.V128)); break; 80 default: vpanic("ppIRConst"); 81 } 82 } 83 84 void ppIRCallee ( IRCallee* ce ) 85 { 86 vex_printf("%s", ce->name); 87 if (ce->regparms > 0) 88 vex_printf("[rp=%d]", ce->regparms); 89 if (ce->mcx_mask > 0) 90 vex_printf("[mcx=0x%x]", ce->mcx_mask); 91 vex_printf("{%p}", (void*)ce->addr); 92 } 93 94 void ppIRRegArray ( IRRegArray* arr ) 95 { 96 vex_printf("(%d:%dx", arr->base, arr->nElems); 97 ppIRType(arr->elemTy); 98 vex_printf(")"); 99 } 100 101 void ppIRTemp ( IRTemp tmp ) 102 { 103 if (tmp == IRTemp_INVALID) 104 vex_printf("IRTemp_INVALID"); 105 else 106 vex_printf( "t%d", (Int)tmp); 107 } 108 109 void ppIROp ( IROp op ) 110 { 111 HChar* str = NULL; 112 IROp base; 113 switch (op) { 114 case Iop_Add8 ... Iop_Add64: 115 str = "Add"; base = Iop_Add8; break; 116 case Iop_Sub8 ... Iop_Sub64: 117 str = "Sub"; base = Iop_Sub8; break; 118 case Iop_Mul8 ... Iop_Mul64: 119 str = "Mul"; base = Iop_Mul8; break; 120 case Iop_Or8 ... Iop_Or64: 121 str = "Or"; base = Iop_Or8; break; 122 case Iop_And8 ... Iop_And64: 123 str = "And"; base = Iop_And8; break; 124 case Iop_Xor8 ... Iop_Xor64: 125 str = "Xor"; base = Iop_Xor8; break; 126 case Iop_Shl8 ... Iop_Shl64: 127 str = "Shl"; base = Iop_Shl8; break; 128 case Iop_Shr8 ... Iop_Shr64: 129 str = "Shr"; base = Iop_Shr8; break; 130 case Iop_Sar8 ... Iop_Sar64: 131 str = "Sar"; base = Iop_Sar8; break; 132 case Iop_CmpEQ8 ... Iop_CmpEQ64: 133 str = "CmpEQ"; base = Iop_CmpEQ8; break; 134 case Iop_CmpNE8 ... Iop_CmpNE64: 135 str = "CmpNE"; base = Iop_CmpNE8; break; 136 case Iop_CasCmpEQ8 ... Iop_CasCmpEQ64: 137 str = "CasCmpEQ"; base = Iop_CasCmpEQ8; break; 138 case Iop_CasCmpNE8 ... Iop_CasCmpNE64: 139 str = "CasCmpNE"; base = Iop_CasCmpNE8; break; 140 case Iop_Not8 ... Iop_Not64: 141 str = "Not"; base = Iop_Not8; break; 142 /* other cases must explicitly "return;" */ 143 case Iop_8Uto16: vex_printf("8Uto16"); return; 144 case Iop_8Uto32: vex_printf("8Uto32"); return; 145 case Iop_16Uto32: vex_printf("16Uto32"); return; 146 case Iop_8Sto16: vex_printf("8Sto16"); return; 147 case Iop_8Sto32: vex_printf("8Sto32"); return; 148 case Iop_16Sto32: vex_printf("16Sto32"); return; 149 case Iop_32Sto64: vex_printf("32Sto64"); return; 150 case Iop_32Uto64: vex_printf("32Uto64"); return; 151 case Iop_32to8: vex_printf("32to8"); return; 152 case Iop_16Uto64: vex_printf("16Uto64"); return; 153 case Iop_16Sto64: vex_printf("16Sto64"); return; 154 case Iop_8Uto64: vex_printf("8Uto64"); return; 155 case Iop_8Sto64: vex_printf("8Sto64"); return; 156 case Iop_64to16: vex_printf("64to16"); return; 157 case Iop_64to8: vex_printf("64to8"); return; 158 159 case Iop_Not1: vex_printf("Not1"); return; 160 case Iop_32to1: vex_printf("32to1"); return; 161 case Iop_64to1: vex_printf("64to1"); return; 162 case Iop_1Uto8: vex_printf("1Uto8"); return; 163 case Iop_1Uto32: vex_printf("1Uto32"); return; 164 case Iop_1Uto64: vex_printf("1Uto64"); return; 165 case Iop_1Sto8: vex_printf("1Sto8"); return; 166 case Iop_1Sto16: vex_printf("1Sto16"); return; 167 case Iop_1Sto32: vex_printf("1Sto32"); return; 168 case Iop_1Sto64: vex_printf("1Sto64"); return; 169 170 case Iop_MullS8: vex_printf("MullS8"); return; 171 case Iop_MullS16: vex_printf("MullS16"); return; 172 case Iop_MullS32: vex_printf("MullS32"); return; 173 case Iop_MullS64: vex_printf("MullS64"); return; 174 case Iop_MullU8: vex_printf("MullU8"); return; 175 case Iop_MullU16: vex_printf("MullU16"); return; 176 case Iop_MullU32: vex_printf("MullU32"); return; 177 case Iop_MullU64: vex_printf("MullU64"); return; 178 179 case Iop_Clz64: vex_printf("Clz64"); return; 180 case Iop_Clz32: vex_printf("Clz32"); return; 181 case Iop_Ctz64: vex_printf("Ctz64"); return; 182 case Iop_Ctz32: vex_printf("Ctz32"); return; 183 184 case Iop_CmpLT32S: vex_printf("CmpLT32S"); return; 185 case Iop_CmpLE32S: vex_printf("CmpLE32S"); return; 186 case Iop_CmpLT32U: vex_printf("CmpLT32U"); return; 187 case Iop_CmpLE32U: vex_printf("CmpLE32U"); return; 188 189 case Iop_CmpLT64S: vex_printf("CmpLT64S"); return; 190 case Iop_CmpLE64S: vex_printf("CmpLE64S"); return; 191 case Iop_CmpLT64U: vex_printf("CmpLT64U"); return; 192 case Iop_CmpLE64U: vex_printf("CmpLE64U"); return; 193 194 case Iop_CmpNEZ8: vex_printf("CmpNEZ8"); return; 195 case Iop_CmpNEZ16: vex_printf("CmpNEZ16"); return; 196 case Iop_CmpNEZ32: vex_printf("CmpNEZ32"); return; 197 case Iop_CmpNEZ64: vex_printf("CmpNEZ64"); return; 198 199 case Iop_CmpwNEZ32: vex_printf("CmpwNEZ32"); return; 200 case Iop_CmpwNEZ64: vex_printf("CmpwNEZ64"); return; 201 202 case Iop_Left8: vex_printf("Left8"); return; 203 case Iop_Left16: vex_printf("Left16"); return; 204 case Iop_Left32: vex_printf("Left32"); return; 205 case Iop_Left64: vex_printf("Left64"); return; 206 case Iop_Max32U: vex_printf("Max32U"); return; 207 208 case Iop_CmpORD32U: vex_printf("CmpORD32U"); return; 209 case Iop_CmpORD32S: vex_printf("CmpORD32S"); return; 210 211 case Iop_CmpORD64U: vex_printf("CmpORD64U"); return; 212 case Iop_CmpORD64S: vex_printf("CmpORD64S"); return; 213 214 case Iop_DivU32: vex_printf("DivU32"); return; 215 case Iop_DivS32: vex_printf("DivS32"); return; 216 case Iop_DivU64: vex_printf("DivU64"); return; 217 case Iop_DivS64: vex_printf("DivS64"); return; 218 219 case Iop_DivModU64to32: vex_printf("DivModU64to32"); return; 220 case Iop_DivModS64to32: vex_printf("DivModS64to32"); return; 221 222 case Iop_DivModU128to64: vex_printf("DivModU128to64"); return; 223 case Iop_DivModS128to64: vex_printf("DivModS128to64"); return; 224 225 case Iop_16HIto8: vex_printf("16HIto8"); return; 226 case Iop_16to8: vex_printf("16to8"); return; 227 case Iop_8HLto16: vex_printf("8HLto16"); return; 228 229 case Iop_32HIto16: vex_printf("32HIto16"); return; 230 case Iop_32to16: vex_printf("32to16"); return; 231 case Iop_16HLto32: vex_printf("16HLto32"); return; 232 233 case Iop_64HIto32: vex_printf("64HIto32"); return; 234 case Iop_64to32: vex_printf("64to32"); return; 235 case Iop_32HLto64: vex_printf("32HLto64"); return; 236 237 case Iop_128HIto64: vex_printf("128HIto64"); return; 238 case Iop_128to64: vex_printf("128to64"); return; 239 case Iop_64HLto128: vex_printf("64HLto128"); return; 240 241 case Iop_AddF64: vex_printf("AddF64"); return; 242 case Iop_SubF64: vex_printf("SubF64"); return; 243 case Iop_MulF64: vex_printf("MulF64"); return; 244 case Iop_DivF64: vex_printf("DivF64"); return; 245 case Iop_AddF64r32: vex_printf("AddF64r32"); return; 246 case Iop_SubF64r32: vex_printf("SubF64r32"); return; 247 case Iop_MulF64r32: vex_printf("MulF64r32"); return; 248 case Iop_DivF64r32: vex_printf("DivF64r32"); return; 249 case Iop_AddF32: vex_printf("AddF32"); return; 250 case Iop_SubF32: vex_printf("SubF32"); return; 251 case Iop_MulF32: vex_printf("MulF32"); return; 252 case Iop_DivF32: vex_printf("DivF32"); return; 253 254 case Iop_ScaleF64: vex_printf("ScaleF64"); return; 255 case Iop_AtanF64: vex_printf("AtanF64"); return; 256 case Iop_Yl2xF64: vex_printf("Yl2xF64"); return; 257 case Iop_Yl2xp1F64: vex_printf("Yl2xp1F64"); return; 258 case Iop_PRemF64: vex_printf("PRemF64"); return; 259 case Iop_PRemC3210F64: vex_printf("PRemC3210F64"); return; 260 case Iop_PRem1F64: vex_printf("PRem1F64"); return; 261 case Iop_PRem1C3210F64: vex_printf("PRem1C3210F64"); return; 262 case Iop_NegF64: vex_printf("NegF64"); return; 263 case Iop_AbsF64: vex_printf("AbsF64"); return; 264 case Iop_NegF32: vex_printf("NegF32"); return; 265 case Iop_AbsF32: vex_printf("AbsF32"); return; 266 case Iop_SqrtF64: vex_printf("SqrtF64"); return; 267 case Iop_SqrtF32: vex_printf("SqrtF32"); return; 268 case Iop_SinF64: vex_printf("SinF64"); return; 269 case Iop_CosF64: vex_printf("CosF64"); return; 270 case Iop_TanF64: vex_printf("TanF64"); return; 271 case Iop_2xm1F64: vex_printf("2xm1F64"); return; 272 273 case Iop_MAddF64: vex_printf("MAddF64"); return; 274 case Iop_MSubF64: vex_printf("MSubF64"); return; 275 case Iop_MAddF64r32: vex_printf("MAddF64r32"); return; 276 case Iop_MSubF64r32: vex_printf("MSubF64r32"); return; 277 278 case Iop_Est5FRSqrt: vex_printf("Est5FRSqrt"); return; 279 case Iop_RoundF64toF64_NEAREST: vex_printf("RoundF64toF64_NEAREST"); return; 280 case Iop_RoundF64toF64_NegINF: vex_printf("RoundF64toF64_NegINF"); return; 281 case Iop_RoundF64toF64_PosINF: vex_printf("RoundF64toF64_PosINF"); return; 282 case Iop_RoundF64toF64_ZERO: vex_printf("RoundF64toF64_ZERO"); return; 283 284 case Iop_TruncF64asF32: vex_printf("TruncF64asF32"); return; 285 case Iop_CalcFPRF: vex_printf("CalcFPRF"); return; 286 287 case Iop_Add16x2: vex_printf("Add16x2"); return; 288 case Iop_Sub16x2: vex_printf("Sub16x2"); return; 289 case Iop_QAdd16Sx2: vex_printf("QAdd16Sx2"); return; 290 case Iop_QAdd16Ux2: vex_printf("QAdd16Ux2"); return; 291 case Iop_QSub16Sx2: vex_printf("QSub16Sx2"); return; 292 case Iop_QSub16Ux2: vex_printf("QSub16Ux2"); return; 293 case Iop_HAdd16Ux2: vex_printf("HAdd16Ux2"); return; 294 case Iop_HAdd16Sx2: vex_printf("HAdd16Sx2"); return; 295 case Iop_HSub16Ux2: vex_printf("HSub16Ux2"); return; 296 case Iop_HSub16Sx2: vex_printf("HSub16Sx2"); return; 297 298 case Iop_Add8x4: vex_printf("Add8x4"); return; 299 case Iop_Sub8x4: vex_printf("Sub8x4"); return; 300 case Iop_QAdd8Sx4: vex_printf("QAdd8Sx4"); return; 301 case Iop_QAdd8Ux4: vex_printf("QAdd8Ux4"); return; 302 case Iop_QSub8Sx4: vex_printf("QSub8Sx4"); return; 303 case Iop_QSub8Ux4: vex_printf("QSub8Ux4"); return; 304 case Iop_HAdd8Ux4: vex_printf("HAdd8Ux4"); return; 305 case Iop_HAdd8Sx4: vex_printf("HAdd8Sx4"); return; 306 case Iop_HSub8Ux4: vex_printf("HSub8Ux4"); return; 307 case Iop_HSub8Sx4: vex_printf("HSub8Sx4"); return; 308 case Iop_Sad8Ux4: vex_printf("Sad8Ux4"); return; 309 310 case Iop_CmpNEZ16x2: vex_printf("CmpNEZ16x2"); return; 311 case Iop_CmpNEZ8x4: vex_printf("CmpNEZ8x4"); return; 312 313 case Iop_CmpF64: vex_printf("CmpF64"); return; 314 315 case Iop_F64toI16S: vex_printf("F64toI16S"); return; 316 case Iop_F64toI32S: vex_printf("F64toI32S"); return; 317 case Iop_F64toI64S: vex_printf("F64toI64S"); return; 318 319 case Iop_F64toI32U: vex_printf("F64toI32U"); return; 320 321 case Iop_I16StoF64: vex_printf("I16StoF64"); return; 322 case Iop_I32StoF64: vex_printf("I32StoF64"); return; 323 case Iop_I64StoF64: vex_printf("I64StoF64"); return; 324 325 case Iop_I32UtoF64: vex_printf("I32UtoF64"); return; 326 327 case Iop_F32toF64: vex_printf("F32toF64"); return; 328 case Iop_F64toF32: vex_printf("F64toF32"); return; 329 330 case Iop_RoundF64toInt: vex_printf("RoundF64toInt"); return; 331 case Iop_RoundF32toInt: vex_printf("RoundF32toInt"); return; 332 case Iop_RoundF64toF32: vex_printf("RoundF64toF32"); return; 333 334 case Iop_ReinterpF64asI64: vex_printf("ReinterpF64asI64"); return; 335 case Iop_ReinterpI64asF64: vex_printf("ReinterpI64asF64"); return; 336 case Iop_ReinterpF32asI32: vex_printf("ReinterpF32asI32"); return; 337 case Iop_ReinterpI32asF32: vex_printf("ReinterpI32asF32"); return; 338 339 case Iop_I32UtoFx4: vex_printf("I32UtoFx4"); return; 340 case Iop_I32StoFx4: vex_printf("I32StoFx4"); return; 341 342 case Iop_F32toF16x4: vex_printf("F32toF16x4"); return; 343 case Iop_F16toF32x4: vex_printf("F16toF32x4"); return; 344 345 case Iop_Rsqrte32Fx4: vex_printf("VRsqrte32Fx4"); return; 346 case Iop_Rsqrte32x4: vex_printf("VRsqrte32x4"); return; 347 case Iop_Rsqrte32Fx2: vex_printf("VRsqrte32Fx2"); return; 348 case Iop_Rsqrte32x2: vex_printf("VRsqrte32x2"); return; 349 350 case Iop_QFtoI32Ux4_RZ: vex_printf("QFtoI32Ux4_RZ"); return; 351 case Iop_QFtoI32Sx4_RZ: vex_printf("QFtoI32Sx4_RZ"); return; 352 353 case Iop_FtoI32Ux4_RZ: vex_printf("FtoI32Ux4_RZ"); return; 354 case Iop_FtoI32Sx4_RZ: vex_printf("FtoI32Sx4_RZ"); return; 355 356 case Iop_I32UtoFx2: vex_printf("I32UtoFx2"); return; 357 case Iop_I32StoFx2: vex_printf("I32StoFx2"); return; 358 359 case Iop_FtoI32Ux2_RZ: vex_printf("FtoI32Ux2_RZ"); return; 360 case Iop_FtoI32Sx2_RZ: vex_printf("FtoI32Sx2_RZ"); return; 361 362 case Iop_RoundF32x4_RM: vex_printf("RoundF32x4_RM"); return; 363 case Iop_RoundF32x4_RP: vex_printf("RoundF32x4_RP"); return; 364 case Iop_RoundF32x4_RN: vex_printf("RoundF32x4_RN"); return; 365 case Iop_RoundF32x4_RZ: vex_printf("RoundF32x4_RZ"); return; 366 367 case Iop_Abs8x8: vex_printf("Abs8x8"); return; 368 case Iop_Abs16x4: vex_printf("Abs16x4"); return; 369 case Iop_Abs32x2: vex_printf("Abs32x2"); return; 370 case Iop_Add8x8: vex_printf("Add8x8"); return; 371 case Iop_Add16x4: vex_printf("Add16x4"); return; 372 case Iop_Add32x2: vex_printf("Add32x2"); return; 373 case Iop_QAdd8Ux8: vex_printf("QAdd8Ux8"); return; 374 case Iop_QAdd16Ux4: vex_printf("QAdd16Ux4"); return; 375 case Iop_QAdd32Ux2: vex_printf("QAdd32Ux2"); return; 376 case Iop_QAdd64Ux1: vex_printf("QAdd64Ux1"); return; 377 case Iop_QAdd8Sx8: vex_printf("QAdd8Sx8"); return; 378 case Iop_QAdd16Sx4: vex_printf("QAdd16Sx4"); return; 379 case Iop_QAdd32Sx2: vex_printf("QAdd32Sx2"); return; 380 case Iop_QAdd64Sx1: vex_printf("QAdd64Sx1"); return; 381 case Iop_PwAdd8x8: vex_printf("PwAdd8x8"); return; 382 case Iop_PwAdd16x4: vex_printf("PwAdd16x4"); return; 383 case Iop_PwAdd32x2: vex_printf("PwAdd32x2"); return; 384 case Iop_PwAdd32Fx2: vex_printf("PwAdd32Fx2"); return; 385 case Iop_PwAddL8Ux8: vex_printf("PwAddL8Ux8"); return; 386 case Iop_PwAddL16Ux4: vex_printf("PwAddL16Ux4"); return; 387 case Iop_PwAddL32Ux2: vex_printf("PwAddL32Ux2"); return; 388 case Iop_PwAddL8Sx8: vex_printf("PwAddL8Sx8"); return; 389 case Iop_PwAddL16Sx4: vex_printf("PwAddL16Sx4"); return; 390 case Iop_PwAddL32Sx2: vex_printf("PwAddL32Sx2"); return; 391 case Iop_Sub8x8: vex_printf("Sub8x8"); return; 392 case Iop_Sub16x4: vex_printf("Sub16x4"); return; 393 case Iop_Sub32x2: vex_printf("Sub32x2"); return; 394 case Iop_QSub8Ux8: vex_printf("QSub8Ux8"); return; 395 case Iop_QSub16Ux4: vex_printf("QSub16Ux4"); return; 396 case Iop_QSub32Ux2: vex_printf("QSub32Ux2"); return; 397 case Iop_QSub64Ux1: vex_printf("QSub64Ux1"); return; 398 case Iop_QSub8Sx8: vex_printf("QSub8Sx8"); return; 399 case Iop_QSub16Sx4: vex_printf("QSub16Sx4"); return; 400 case Iop_QSub32Sx2: vex_printf("QSub32Sx2"); return; 401 case Iop_QSub64Sx1: vex_printf("QSub64Sx1"); return; 402 case Iop_Mul8x8: vex_printf("Mul8x8"); return; 403 case Iop_Mul16x4: vex_printf("Mul16x4"); return; 404 case Iop_Mul32x2: vex_printf("Mul32x2"); return; 405 case Iop_Mul32Fx2: vex_printf("Mul32Fx2"); return; 406 case Iop_PolynomialMul8x8: vex_printf("PolynomialMul8x8"); return; 407 case Iop_MulHi16Ux4: vex_printf("MulHi16Ux4"); return; 408 case Iop_MulHi16Sx4: vex_printf("MulHi16Sx4"); return; 409 case Iop_QDMulHi16Sx4: vex_printf("QDMulHi16Sx4"); return; 410 case Iop_QDMulHi32Sx2: vex_printf("QDMulHi32Sx2"); return; 411 case Iop_QRDMulHi16Sx4: vex_printf("QRDMulHi16Sx4"); return; 412 case Iop_QRDMulHi32Sx2: vex_printf("QRDMulHi32Sx2"); return; 413 case Iop_QDMulLong16Sx4: vex_printf("QDMulLong16Sx4"); return; 414 case Iop_QDMulLong32Sx2: vex_printf("QDMulLong32Sx2"); return; 415 case Iop_Avg8Ux8: vex_printf("Avg8Ux8"); return; 416 case Iop_Avg16Ux4: vex_printf("Avg16Ux4"); return; 417 case Iop_Max8Sx8: vex_printf("Max8Sx8"); return; 418 case Iop_Max16Sx4: vex_printf("Max16Sx4"); return; 419 case Iop_Max32Sx2: vex_printf("Max32Sx2"); return; 420 case Iop_Max8Ux8: vex_printf("Max8Ux8"); return; 421 case Iop_Max16Ux4: vex_printf("Max16Ux4"); return; 422 case Iop_Max32Ux2: vex_printf("Max32Ux2"); return; 423 case Iop_Min8Sx8: vex_printf("Min8Sx8"); return; 424 case Iop_Min16Sx4: vex_printf("Min16Sx4"); return; 425 case Iop_Min32Sx2: vex_printf("Min32Sx2"); return; 426 case Iop_Min8Ux8: vex_printf("Min8Ux8"); return; 427 case Iop_Min16Ux4: vex_printf("Min16Ux4"); return; 428 case Iop_Min32Ux2: vex_printf("Min32Ux2"); return; 429 case Iop_PwMax8Sx8: vex_printf("PwMax8Sx8"); return; 430 case Iop_PwMax16Sx4: vex_printf("PwMax16Sx4"); return; 431 case Iop_PwMax32Sx2: vex_printf("PwMax32Sx2"); return; 432 case Iop_PwMax8Ux8: vex_printf("PwMax8Ux8"); return; 433 case Iop_PwMax16Ux4: vex_printf("PwMax16Ux4"); return; 434 case Iop_PwMax32Ux2: vex_printf("PwMax32Ux2"); return; 435 case Iop_PwMin8Sx8: vex_printf("PwMin8Sx8"); return; 436 case Iop_PwMin16Sx4: vex_printf("PwMin16Sx4"); return; 437 case Iop_PwMin32Sx2: vex_printf("PwMin32Sx2"); return; 438 case Iop_PwMin8Ux8: vex_printf("PwMin8Ux8"); return; 439 case Iop_PwMin16Ux4: vex_printf("PwMin16Ux4"); return; 440 case Iop_PwMin32Ux2: vex_printf("PwMin32Ux2"); return; 441 case Iop_CmpEQ8x8: vex_printf("CmpEQ8x8"); return; 442 case Iop_CmpEQ16x4: vex_printf("CmpEQ16x4"); return; 443 case Iop_CmpEQ32x2: vex_printf("CmpEQ32x2"); return; 444 case Iop_CmpGT8Ux8: vex_printf("CmpGT8Ux8"); return; 445 case Iop_CmpGT16Ux4: vex_printf("CmpGT16Ux4"); return; 446 case Iop_CmpGT32Ux2: vex_printf("CmpGT32Ux2"); return; 447 case Iop_CmpGT8Sx8: vex_printf("CmpGT8Sx8"); return; 448 case Iop_CmpGT16Sx4: vex_printf("CmpGT16Sx4"); return; 449 case Iop_CmpGT32Sx2: vex_printf("CmpGT32Sx2"); return; 450 case Iop_Cnt8x8: vex_printf("Cnt8x8"); return; 451 case Iop_Clz8Sx8: vex_printf("Clz8Sx8"); return; 452 case Iop_Clz16Sx4: vex_printf("Clz16Sx4"); return; 453 case Iop_Clz32Sx2: vex_printf("Clz32Sx2"); return; 454 case Iop_Cls8Sx8: vex_printf("Cls8Sx8"); return; 455 case Iop_Cls16Sx4: vex_printf("Cls16Sx4"); return; 456 case Iop_Cls32Sx2: vex_printf("Cls32Sx2"); return; 457 case Iop_ShlN8x8: vex_printf("ShlN8x8"); return; 458 case Iop_ShlN16x4: vex_printf("ShlN16x4"); return; 459 case Iop_ShlN32x2: vex_printf("ShlN32x2"); return; 460 case Iop_ShrN8x8: vex_printf("ShrN8x8"); return; 461 case Iop_ShrN16x4: vex_printf("ShrN16x4"); return; 462 case Iop_ShrN32x2: vex_printf("ShrN32x2"); return; 463 case Iop_SarN8x8: vex_printf("SarN8x8"); return; 464 case Iop_SarN16x4: vex_printf("SarN16x4"); return; 465 case Iop_SarN32x2: vex_printf("SarN32x2"); return; 466 case Iop_QNarrow16Ux4: vex_printf("QNarrow16Ux4"); return; 467 case Iop_QNarrow16Sx4: vex_printf("QNarrow16Sx4"); return; 468 case Iop_QNarrow32Sx2: vex_printf("QNarrow32Sx2"); return; 469 case Iop_InterleaveHI8x8: vex_printf("InterleaveHI8x8"); return; 470 case Iop_InterleaveHI16x4: vex_printf("InterleaveHI16x4"); return; 471 case Iop_InterleaveHI32x2: vex_printf("InterleaveHI32x2"); return; 472 case Iop_InterleaveLO8x8: vex_printf("InterleaveLO8x8"); return; 473 case Iop_InterleaveLO16x4: vex_printf("InterleaveLO16x4"); return; 474 case Iop_InterleaveLO32x2: vex_printf("InterleaveLO32x2"); return; 475 case Iop_CatOddLanes8x8: vex_printf("CatOddLanes8x8"); return; 476 case Iop_CatOddLanes16x4: vex_printf("CatOddLanes16x4"); return; 477 case Iop_CatEvenLanes8x8: vex_printf("CatEvenLanes8x8"); return; 478 case Iop_CatEvenLanes16x4: vex_printf("CatEvenLanes16x4"); return; 479 case Iop_InterleaveOddLanes8x8: vex_printf("InterleaveOddLanes8x8"); return; 480 case Iop_InterleaveOddLanes16x4: vex_printf("InterleaveOddLanes16x4"); return; 481 case Iop_InterleaveEvenLanes8x8: vex_printf("InterleaveEvenLanes8x8"); return; 482 case Iop_InterleaveEvenLanes16x4: vex_printf("InterleaveEvenLanes16x4"); return; 483 case Iop_Shl8x8: vex_printf("Shl8x8"); return; 484 case Iop_Shl16x4: vex_printf("Shl16x4"); return; 485 case Iop_Shl32x2: vex_printf("Shl32x2"); return; 486 case Iop_Shr8x8: vex_printf("Shr8x8"); return; 487 case Iop_Shr16x4: vex_printf("Shr16x4"); return; 488 case Iop_Shr32x2: vex_printf("Shr32x2"); return; 489 case Iop_QShl8x8: vex_printf("QShl8x8"); return; 490 case Iop_QShl16x4: vex_printf("QShl16x4"); return; 491 case Iop_QShl32x2: vex_printf("QShl32x2"); return; 492 case Iop_QShl64x1: vex_printf("QShl64x1"); return; 493 case Iop_QSal8x8: vex_printf("QSal8x8"); return; 494 case Iop_QSal16x4: vex_printf("QSal16x4"); return; 495 case Iop_QSal32x2: vex_printf("QSal32x2"); return; 496 case Iop_QSal64x1: vex_printf("QSal64x1"); return; 497 case Iop_QShlN8x8: vex_printf("QShlN8x8"); return; 498 case Iop_QShlN16x4: vex_printf("QShlN16x4"); return; 499 case Iop_QShlN32x2: vex_printf("QShlN32x2"); return; 500 case Iop_QShlN64x1: vex_printf("QShlN64x1"); return; 501 case Iop_QShlN8Sx8: vex_printf("QShlN8Sx8"); return; 502 case Iop_QShlN16Sx4: vex_printf("QShlN16Sx4"); return; 503 case Iop_QShlN32Sx2: vex_printf("QShlN32Sx2"); return; 504 case Iop_QShlN64Sx1: vex_printf("QShlN64Sx1"); return; 505 case Iop_QSalN8x8: vex_printf("QSalN8x8"); return; 506 case Iop_QSalN16x4: vex_printf("QSalN16x4"); return; 507 case Iop_QSalN32x2: vex_printf("QSalN32x2"); return; 508 case Iop_QSalN64x1: vex_printf("QSalN64x1"); return; 509 case Iop_Sar8x8: vex_printf("Sar8x8"); return; 510 case Iop_Sar16x4: vex_printf("Sar16x4"); return; 511 case Iop_Sar32x2: vex_printf("Sar32x2"); return; 512 case Iop_Sal8x8: vex_printf("Sal8x8"); return; 513 case Iop_Sal16x4: vex_printf("Sal16x4"); return; 514 case Iop_Sal32x2: vex_printf("Sal32x2"); return; 515 case Iop_Sal64x1: vex_printf("Sal64x1"); return; 516 case Iop_Perm8x8: vex_printf("Perm8x8"); return; 517 case Iop_Reverse16_8x8: vex_printf("Reverse16_8x8"); return; 518 case Iop_Reverse32_8x8: vex_printf("Reverse32_8x8"); return; 519 case Iop_Reverse32_16x4: vex_printf("Reverse32_16x4"); return; 520 case Iop_Reverse64_8x8: vex_printf("Reverse64_8x8"); return; 521 case Iop_Reverse64_16x4: vex_printf("Reverse64_16x4"); return; 522 case Iop_Reverse64_32x2: vex_printf("Reverse64_32x2"); return; 523 case Iop_Abs32Fx2: vex_printf("Abs32Fx2"); return; 524 525 case Iop_CmpNEZ32x2: vex_printf("CmpNEZ32x2"); return; 526 case Iop_CmpNEZ16x4: vex_printf("CmpNEZ16x4"); return; 527 case Iop_CmpNEZ8x8: vex_printf("CmpNEZ8x8"); return; 528 529 case Iop_Add32Fx4: vex_printf("Add32Fx4"); return; 530 case Iop_Add32Fx2: vex_printf("Add32Fx2"); return; 531 case Iop_Add32F0x4: vex_printf("Add32F0x4"); return; 532 case Iop_Add64Fx2: vex_printf("Add64Fx2"); return; 533 case Iop_Add64F0x2: vex_printf("Add64F0x2"); return; 534 535 case Iop_Div32Fx4: vex_printf("Div32Fx4"); return; 536 case Iop_Div32F0x4: vex_printf("Div32F0x4"); return; 537 case Iop_Div64Fx2: vex_printf("Div64Fx2"); return; 538 case Iop_Div64F0x2: vex_printf("Div64F0x2"); return; 539 540 case Iop_Max32Fx4: vex_printf("Max32Fx4"); return; 541 case Iop_Max32Fx2: vex_printf("Max32Fx2"); return; 542 case Iop_PwMax32Fx4: vex_printf("PwMax32Fx4"); return; 543 case Iop_PwMax32Fx2: vex_printf("PwMax32Fx2"); return; 544 case Iop_Max32F0x4: vex_printf("Max32F0x4"); return; 545 case Iop_Max64Fx2: vex_printf("Max64Fx2"); return; 546 case Iop_Max64F0x2: vex_printf("Max64F0x2"); return; 547 548 case Iop_Min32Fx4: vex_printf("Min32Fx4"); return; 549 case Iop_Min32Fx2: vex_printf("Min32Fx2"); return; 550 case Iop_PwMin32Fx4: vex_printf("PwMin32Fx4"); return; 551 case Iop_PwMin32Fx2: vex_printf("PwMin32Fx2"); return; 552 case Iop_Min32F0x4: vex_printf("Min32F0x4"); return; 553 case Iop_Min64Fx2: vex_printf("Min64Fx2"); return; 554 case Iop_Min64F0x2: vex_printf("Min64F0x2"); return; 555 556 case Iop_Mul32Fx4: vex_printf("Mul32Fx4"); return; 557 case Iop_Mul32F0x4: vex_printf("Mul32F0x4"); return; 558 case Iop_Mul64Fx2: vex_printf("Mul64Fx2"); return; 559 case Iop_Mul64F0x2: vex_printf("Mul64F0x2"); return; 560 561 case Iop_Recip32x2: vex_printf("Recip32x2"); return; 562 case Iop_Recip32Fx2: vex_printf("Recip32Fx2"); return; 563 case Iop_Recip32Fx4: vex_printf("Recip32Fx4"); return; 564 case Iop_Recip32x4: vex_printf("Recip32x4"); return; 565 case Iop_Recip32F0x4: vex_printf("Recip32F0x4"); return; 566 case Iop_Recip64Fx2: vex_printf("Recip64Fx2"); return; 567 case Iop_Recip64F0x2: vex_printf("Recip64F0x2"); return; 568 case Iop_Recps32Fx2: vex_printf("VRecps32Fx2"); return; 569 case Iop_Recps32Fx4: vex_printf("VRecps32Fx4"); return; 570 case Iop_Abs32Fx4: vex_printf("Abs32Fx4"); return; 571 case Iop_Rsqrts32Fx4: vex_printf("VRsqrts32Fx4"); return; 572 case Iop_Rsqrts32Fx2: vex_printf("VRsqrts32Fx2"); return; 573 574 case Iop_RSqrt32Fx4: vex_printf("RSqrt32Fx4"); return; 575 case Iop_RSqrt32F0x4: vex_printf("RSqrt32F0x4"); return; 576 case Iop_RSqrt64Fx2: vex_printf("RSqrt64Fx2"); return; 577 case Iop_RSqrt64F0x2: vex_printf("RSqrt64F0x2"); return; 578 579 case Iop_Sqrt32Fx4: vex_printf("Sqrt32Fx4"); return; 580 case Iop_Sqrt32F0x4: vex_printf("Sqrt32F0x4"); return; 581 case Iop_Sqrt64Fx2: vex_printf("Sqrt64Fx2"); return; 582 case Iop_Sqrt64F0x2: vex_printf("Sqrt64F0x2"); return; 583 584 case Iop_Sub32Fx4: vex_printf("Sub32Fx4"); return; 585 case Iop_Sub32Fx2: vex_printf("Sub32Fx2"); return; 586 case Iop_Sub32F0x4: vex_printf("Sub32F0x4"); return; 587 case Iop_Sub64Fx2: vex_printf("Sub64Fx2"); return; 588 case Iop_Sub64F0x2: vex_printf("Sub64F0x2"); return; 589 590 case Iop_CmpEQ32Fx4: vex_printf("CmpEQ32Fx4"); return; 591 case Iop_CmpLT32Fx4: vex_printf("CmpLT32Fx4"); return; 592 case Iop_CmpLE32Fx4: vex_printf("CmpLE32Fx4"); return; 593 case Iop_CmpGT32Fx4: vex_printf("CmpGT32Fx4"); return; 594 case Iop_CmpGE32Fx4: vex_printf("CmpGE32Fx4"); return; 595 case Iop_CmpUN32Fx4: vex_printf("CmpUN32Fx4"); return; 596 case Iop_CmpEQ64Fx2: vex_printf("CmpEQ64Fx2"); return; 597 case Iop_CmpLT64Fx2: vex_printf("CmpLT64Fx2"); return; 598 case Iop_CmpLE64Fx2: vex_printf("CmpLE64Fx2"); return; 599 case Iop_CmpUN64Fx2: vex_printf("CmpUN64Fx2"); return; 600 case Iop_CmpGT32Fx2: vex_printf("CmpGT32Fx2"); return; 601 case Iop_CmpEQ32Fx2: vex_printf("CmpEQ32Fx2"); return; 602 case Iop_CmpGE32Fx2: vex_printf("CmpGE32Fx2"); return; 603 604 case Iop_CmpEQ32F0x4: vex_printf("CmpEQ32F0x4"); return; 605 case Iop_CmpLT32F0x4: vex_printf("CmpLT32F0x4"); return; 606 case Iop_CmpLE32F0x4: vex_printf("CmpLE32F0x4"); return; 607 case Iop_CmpUN32F0x4: vex_printf("CmpUN32F0x4"); return; 608 case Iop_CmpEQ64F0x2: vex_printf("CmpEQ64F0x2"); return; 609 case Iop_CmpLT64F0x2: vex_printf("CmpLT64F0x2"); return; 610 case Iop_CmpLE64F0x2: vex_printf("CmpLE64F0x2"); return; 611 case Iop_CmpUN64F0x2: vex_printf("CmpUN64F0x2"); return; 612 613 case Iop_Neg32Fx4: vex_printf("Neg32Fx4"); return; 614 case Iop_Neg32Fx2: vex_printf("Neg32Fx2"); return; 615 616 case Iop_V128to64: vex_printf("V128to64"); return; 617 case Iop_V128HIto64: vex_printf("V128HIto64"); return; 618 case Iop_64HLtoV128: vex_printf("64HLtoV128"); return; 619 620 case Iop_64UtoV128: vex_printf("64UtoV128"); return; 621 case Iop_SetV128lo64: vex_printf("SetV128lo64"); return; 622 623 case Iop_32UtoV128: vex_printf("32UtoV128"); return; 624 case Iop_V128to32: vex_printf("V128to32"); return; 625 case Iop_SetV128lo32: vex_printf("SetV128lo32"); return; 626 627 case Iop_Dup8x16: vex_printf("Dup8x16"); return; 628 case Iop_Dup16x8: vex_printf("Dup16x8"); return; 629 case Iop_Dup32x4: vex_printf("Dup32x4"); return; 630 case Iop_Dup8x8: vex_printf("Dup8x8"); return; 631 case Iop_Dup16x4: vex_printf("Dup16x4"); return; 632 case Iop_Dup32x2: vex_printf("Dup32x2"); return; 633 634 case Iop_NotV128: vex_printf("NotV128"); return; 635 case Iop_AndV128: vex_printf("AndV128"); return; 636 case Iop_OrV128: vex_printf("OrV128"); return; 637 case Iop_XorV128: vex_printf("XorV128"); return; 638 639 case Iop_CmpNEZ8x16: vex_printf("CmpNEZ8x16"); return; 640 case Iop_CmpNEZ16x8: vex_printf("CmpNEZ16x8"); return; 641 case Iop_CmpNEZ32x4: vex_printf("CmpNEZ32x4"); return; 642 case Iop_CmpNEZ64x2: vex_printf("CmpNEZ64x2"); return; 643 644 case Iop_Abs8x16: vex_printf("Abs8x16"); return; 645 case Iop_Abs16x8: vex_printf("Abs16x8"); return; 646 case Iop_Abs32x4: vex_printf("Abs32x4"); return; 647 648 case Iop_Add8x16: vex_printf("Add8x16"); return; 649 case Iop_Add16x8: vex_printf("Add16x8"); return; 650 case Iop_Add32x4: vex_printf("Add32x4"); return; 651 case Iop_Add64x2: vex_printf("Add64x2"); return; 652 case Iop_QAdd8Ux16: vex_printf("QAdd8Ux16"); return; 653 case Iop_QAdd16Ux8: vex_printf("QAdd16Ux8"); return; 654 case Iop_QAdd32Ux4: vex_printf("QAdd32Ux4"); return; 655 case Iop_QAdd8Sx16: vex_printf("QAdd8Sx16"); return; 656 case Iop_QAdd16Sx8: vex_printf("QAdd16Sx8"); return; 657 case Iop_QAdd32Sx4: vex_printf("QAdd32Sx4"); return; 658 case Iop_QAdd64Ux2: vex_printf("QAdd64Ux2"); return; 659 case Iop_QAdd64Sx2: vex_printf("QAdd64Sx2"); return; 660 case Iop_PwAdd8x16: vex_printf("PwAdd8x16"); return; 661 case Iop_PwAdd16x8: vex_printf("PwAdd16x8"); return; 662 case Iop_PwAdd32x4: vex_printf("PwAdd32x4"); return; 663 case Iop_PwAddL8Ux16: vex_printf("PwAddL8Ux16"); return; 664 case Iop_PwAddL16Ux8: vex_printf("PwAddL16Ux8"); return; 665 case Iop_PwAddL32Ux4: vex_printf("PwAddL32Ux4"); return; 666 case Iop_PwAddL8Sx16: vex_printf("PwAddL8Sx16"); return; 667 case Iop_PwAddL16Sx8: vex_printf("PwAddL16Sx8"); return; 668 case Iop_PwAddL32Sx4: vex_printf("PwAddL32Sx4"); return; 669 670 case Iop_Sub8x16: vex_printf("Sub8x16"); return; 671 case Iop_Sub16x8: vex_printf("Sub16x8"); return; 672 case Iop_Sub32x4: vex_printf("Sub32x4"); return; 673 case Iop_Sub64x2: vex_printf("Sub64x2"); return; 674 case Iop_QSub8Ux16: vex_printf("QSub8Ux16"); return; 675 case Iop_QSub16Ux8: vex_printf("QSub16Ux8"); return; 676 case Iop_QSub32Ux4: vex_printf("QSub32Ux4"); return; 677 case Iop_QSub8Sx16: vex_printf("QSub8Sx16"); return; 678 case Iop_QSub16Sx8: vex_printf("QSub16Sx8"); return; 679 case Iop_QSub32Sx4: vex_printf("QSub32Sx4"); return; 680 case Iop_QSub64Ux2: vex_printf("QSub64Ux2"); return; 681 case Iop_QSub64Sx2: vex_printf("QSub64Sx2"); return; 682 683 case Iop_Mul8x16: vex_printf("Mul8x16"); return; 684 case Iop_Mul16x8: vex_printf("Mul16x8"); return; 685 case Iop_Mul32x4: vex_printf("Mul32x4"); return; 686 case Iop_Mull8Ux8: vex_printf("Mull8Ux8"); return; 687 case Iop_Mull8Sx8: vex_printf("Mull8Sx8"); return; 688 case Iop_Mull16Ux4: vex_printf("Mull16Ux4"); return; 689 case Iop_Mull16Sx4: vex_printf("Mull16Sx4"); return; 690 case Iop_Mull32Ux2: vex_printf("Mull32Ux2"); return; 691 case Iop_Mull32Sx2: vex_printf("Mull32Sx2"); return; 692 case Iop_PolynomialMul8x16: vex_printf("PolynomialMul8x16"); return; 693 case Iop_PolynomialMull8x8: vex_printf("PolynomialMull8x8"); return; 694 case Iop_MulHi16Ux8: vex_printf("MulHi16Ux8"); return; 695 case Iop_MulHi32Ux4: vex_printf("MulHi32Ux4"); return; 696 case Iop_MulHi16Sx8: vex_printf("MulHi16Sx8"); return; 697 case Iop_MulHi32Sx4: vex_printf("MulHi32Sx4"); return; 698 case Iop_QDMulHi16Sx8: vex_printf("QDMulHi16Sx8"); return; 699 case Iop_QDMulHi32Sx4: vex_printf("QDMulHi32Sx4"); return; 700 case Iop_QRDMulHi16Sx8: vex_printf("QRDMulHi16Sx8"); return; 701 case Iop_QRDMulHi32Sx4: vex_printf("QRDMulHi32Sx4"); return; 702 703 case Iop_MullEven8Ux16: vex_printf("MullEven8Ux16"); return; 704 case Iop_MullEven16Ux8: vex_printf("MullEven16Ux8"); return; 705 case Iop_MullEven8Sx16: vex_printf("MullEven8Sx16"); return; 706 case Iop_MullEven16Sx8: vex_printf("MullEven16Sx8"); return; 707 708 case Iop_Avg8Ux16: vex_printf("Avg8Ux16"); return; 709 case Iop_Avg16Ux8: vex_printf("Avg16Ux8"); return; 710 case Iop_Avg32Ux4: vex_printf("Avg32Ux4"); return; 711 case Iop_Avg8Sx16: vex_printf("Avg8Sx16"); return; 712 case Iop_Avg16Sx8: vex_printf("Avg16Sx8"); return; 713 case Iop_Avg32Sx4: vex_printf("Avg32Sx4"); return; 714 715 case Iop_Max8Sx16: vex_printf("Max8Sx16"); return; 716 case Iop_Max16Sx8: vex_printf("Max16Sx8"); return; 717 case Iop_Max32Sx4: vex_printf("Max32Sx4"); return; 718 case Iop_Max8Ux16: vex_printf("Max8Ux16"); return; 719 case Iop_Max16Ux8: vex_printf("Max16Ux8"); return; 720 case Iop_Max32Ux4: vex_printf("Max32Ux4"); return; 721 722 case Iop_Min8Sx16: vex_printf("Min8Sx16"); return; 723 case Iop_Min16Sx8: vex_printf("Min16Sx8"); return; 724 case Iop_Min32Sx4: vex_printf("Min32Sx4"); return; 725 case Iop_Min8Ux16: vex_printf("Min8Ux16"); return; 726 case Iop_Min16Ux8: vex_printf("Min16Ux8"); return; 727 case Iop_Min32Ux4: vex_printf("Min32Ux4"); return; 728 729 case Iop_CmpEQ8x16: vex_printf("CmpEQ8x16"); return; 730 case Iop_CmpEQ16x8: vex_printf("CmpEQ16x8"); return; 731 case Iop_CmpEQ32x4: vex_printf("CmpEQ32x4"); return; 732 case Iop_CmpGT8Sx16: vex_printf("CmpGT8Sx16"); return; 733 case Iop_CmpGT16Sx8: vex_printf("CmpGT16Sx8"); return; 734 case Iop_CmpGT32Sx4: vex_printf("CmpGT32Sx4"); return; 735 case Iop_CmpGT64Sx2: vex_printf("CmpGT64Sx2"); return; 736 case Iop_CmpGT8Ux16: vex_printf("CmpGT8Ux16"); return; 737 case Iop_CmpGT16Ux8: vex_printf("CmpGT16Ux8"); return; 738 case Iop_CmpGT32Ux4: vex_printf("CmpGT32Ux4"); return; 739 740 case Iop_Cnt8x16: vex_printf("Cnt8x16"); return; 741 case Iop_Clz8Sx16: vex_printf("Clz8Sx16"); return; 742 case Iop_Clz16Sx8: vex_printf("Clz16Sx8"); return; 743 case Iop_Clz32Sx4: vex_printf("Clz32Sx4"); return; 744 case Iop_Cls8Sx16: vex_printf("Cls8Sx16"); return; 745 case Iop_Cls16Sx8: vex_printf("Cls16Sx8"); return; 746 case Iop_Cls32Sx4: vex_printf("Cls32Sx4"); return; 747 748 case Iop_ShlV128: vex_printf("ShlV128"); return; 749 case Iop_ShrV128: vex_printf("ShrV128"); return; 750 751 case Iop_ShlN8x16: vex_printf("ShlN8x16"); return; 752 case Iop_ShlN16x8: vex_printf("ShlN16x8"); return; 753 case Iop_ShlN32x4: vex_printf("ShlN32x4"); return; 754 case Iop_ShlN64x2: vex_printf("ShlN64x2"); return; 755 case Iop_ShrN8x16: vex_printf("ShrN8x16"); return; 756 case Iop_ShrN16x8: vex_printf("ShrN16x8"); return; 757 case Iop_ShrN32x4: vex_printf("ShrN32x4"); return; 758 case Iop_ShrN64x2: vex_printf("ShrN64x2"); return; 759 case Iop_SarN8x16: vex_printf("SarN8x16"); return; 760 case Iop_SarN16x8: vex_printf("SarN16x8"); return; 761 case Iop_SarN32x4: vex_printf("SarN32x4"); return; 762 case Iop_SarN64x2: vex_printf("SarN64x2"); return; 763 764 case Iop_Shl8x16: vex_printf("Shl8x16"); return; 765 case Iop_Shl16x8: vex_printf("Shl16x8"); return; 766 case Iop_Shl32x4: vex_printf("Shl32x4"); return; 767 case Iop_Shl64x2: vex_printf("Shl64x2"); return; 768 case Iop_QSal8x16: vex_printf("QSal8x16"); return; 769 case Iop_QSal16x8: vex_printf("QSal16x8"); return; 770 case Iop_QSal32x4: vex_printf("QSal32x4"); return; 771 case Iop_QSal64x2: vex_printf("QSal64x2"); return; 772 case Iop_QShl8x16: vex_printf("QShl8x16"); return; 773 case Iop_QShl16x8: vex_printf("QShl16x8"); return; 774 case Iop_QShl32x4: vex_printf("QShl32x4"); return; 775 case Iop_QShl64x2: vex_printf("QShl64x2"); return; 776 case Iop_QSalN8x16: vex_printf("QSalN8x16"); return; 777 case Iop_QSalN16x8: vex_printf("QSalN16x8"); return; 778 case Iop_QSalN32x4: vex_printf("QSalN32x4"); return; 779 case Iop_QSalN64x2: vex_printf("QSalN64x2"); return; 780 case Iop_QShlN8x16: vex_printf("QShlN8x16"); return; 781 case Iop_QShlN16x8: vex_printf("QShlN16x8"); return; 782 case Iop_QShlN32x4: vex_printf("QShlN32x4"); return; 783 case Iop_QShlN64x2: vex_printf("QShlN64x2"); return; 784 case Iop_QShlN8Sx16: vex_printf("QShlN8Sx16"); return; 785 case Iop_QShlN16Sx8: vex_printf("QShlN16Sx8"); return; 786 case Iop_QShlN32Sx4: vex_printf("QShlN32Sx4"); return; 787 case Iop_QShlN64Sx2: vex_printf("QShlN64Sx2"); return; 788 case Iop_Shr8x16: vex_printf("Shr8x16"); return; 789 case Iop_Shr16x8: vex_printf("Shr16x8"); return; 790 case Iop_Shr32x4: vex_printf("Shr32x4"); return; 791 case Iop_Shr64x2: vex_printf("Shr64x2"); return; 792 case Iop_Sar8x16: vex_printf("Sar8x16"); return; 793 case Iop_Sar16x8: vex_printf("Sar16x8"); return; 794 case Iop_Sar32x4: vex_printf("Sar32x4"); return; 795 case Iop_Sar64x2: vex_printf("Sar64x2"); return; 796 case Iop_Sal8x16: vex_printf("Sal8x16"); return; 797 case Iop_Sal16x8: vex_printf("Sal16x8"); return; 798 case Iop_Sal32x4: vex_printf("Sal32x4"); return; 799 case Iop_Sal64x2: vex_printf("Sal64x2"); return; 800 case Iop_Rol8x16: vex_printf("Rol8x16"); return; 801 case Iop_Rol16x8: vex_printf("Rol16x8"); return; 802 case Iop_Rol32x4: vex_printf("Rol32x4"); return; 803 804 case Iop_Narrow16x8: vex_printf("Narrow16x8"); return; 805 case Iop_Narrow32x4: vex_printf("Narrow32x4"); return; 806 case Iop_QNarrow16Ux8: vex_printf("QNarrow16Ux8"); return; 807 case Iop_QNarrow32Ux4: vex_printf("QNarrow32Ux4"); return; 808 case Iop_QNarrow16Sx8: vex_printf("QNarrow16Sx8"); return; 809 case Iop_QNarrow32Sx4: vex_printf("QNarrow32Sx4"); return; 810 case Iop_Shorten16x8: vex_printf("Shorten16x8"); return; 811 case Iop_Shorten32x4: vex_printf("Shorten32x4"); return; 812 case Iop_Shorten64x2: vex_printf("Shorten64x2"); return; 813 case Iop_QShortenU16Ux8: vex_printf("QShortenU16Ux8"); return; 814 case Iop_QShortenU32Ux4: vex_printf("QShortenU32Ux4"); return; 815 case Iop_QShortenU64Ux2: vex_printf("QShortenU64Ux2"); return; 816 case Iop_QShortenS16Sx8: vex_printf("QShortenS16Sx8"); return; 817 case Iop_QShortenS32Sx4: vex_printf("QShortenS32Sx4"); return; 818 case Iop_QShortenS64Sx2: vex_printf("QShortenS64Sx2"); return; 819 case Iop_QShortenU16Sx8: vex_printf("QShortenU16Sx8"); return; 820 case Iop_QShortenU32Sx4: vex_printf("QShortenU32Sx4"); return; 821 case Iop_QShortenU64Sx2: vex_printf("QShortenU64Sx2"); return; 822 case Iop_Longen8Ux8: vex_printf("Longen8Ux8"); return; 823 case Iop_Longen16Ux4: vex_printf("Longen16Ux4"); return; 824 case Iop_Longen32Ux2: vex_printf("Longen32Ux2"); return; 825 case Iop_Longen8Sx8: vex_printf("Longen8Sx8"); return; 826 case Iop_Longen16Sx4: vex_printf("Longen16Sx4"); return; 827 case Iop_Longen32Sx2: vex_printf("Longen32Sx2"); return; 828 829 case Iop_InterleaveHI8x16: vex_printf("InterleaveHI8x16"); return; 830 case Iop_InterleaveHI16x8: vex_printf("InterleaveHI16x8"); return; 831 case Iop_InterleaveHI32x4: vex_printf("InterleaveHI32x4"); return; 832 case Iop_InterleaveHI64x2: vex_printf("InterleaveHI64x2"); return; 833 case Iop_InterleaveLO8x16: vex_printf("InterleaveLO8x16"); return; 834 case Iop_InterleaveLO16x8: vex_printf("InterleaveLO16x8"); return; 835 case Iop_InterleaveLO32x4: vex_printf("InterleaveLO32x4"); return; 836 case Iop_InterleaveLO64x2: vex_printf("InterleaveLO64x2"); return; 837 838 case Iop_CatOddLanes8x16: vex_printf("CatOddLanes8x16"); return; 839 case Iop_CatOddLanes16x8: vex_printf("CatOddLanes16x8"); return; 840 case Iop_CatOddLanes32x4: vex_printf("CatOddLanes32x4"); return; 841 case Iop_CatEvenLanes8x16: vex_printf("CatEvenLanes8x16"); return; 842 case Iop_CatEvenLanes16x8: vex_printf("CatEvenLanes16x8"); return; 843 case Iop_CatEvenLanes32x4: vex_printf("CatEvenLanes32x4"); return; 844 845 case Iop_InterleaveOddLanes8x16: vex_printf("InterleaveOddLanes8x16"); return; 846 case Iop_InterleaveOddLanes16x8: vex_printf("InterleaveOddLanes16x8"); return; 847 case Iop_InterleaveOddLanes32x4: vex_printf("InterleaveOddLanes32x4"); return; 848 case Iop_InterleaveEvenLanes8x16: vex_printf("InterleaveEvenLanes8x16"); return; 849 case Iop_InterleaveEvenLanes16x8: vex_printf("InterleaveEvenLanes16x8"); return; 850 case Iop_InterleaveEvenLanes32x4: vex_printf("InterleaveEvenLanes32x4"); return; 851 852 case Iop_GetElem8x16: vex_printf("GetElem8x16"); return; 853 case Iop_GetElem16x8: vex_printf("GetElem16x8"); return; 854 case Iop_GetElem32x4: vex_printf("GetElem32x4"); return; 855 case Iop_GetElem64x2: vex_printf("GetElem64x2"); return; 856 857 case Iop_GetElem8x8: vex_printf("GetElem8x8"); return; 858 case Iop_GetElem16x4: vex_printf("GetElem16x4"); return; 859 case Iop_GetElem32x2: vex_printf("GetElem32x2"); return; 860 case Iop_SetElem8x8: vex_printf("SetElem8x8"); return; 861 case Iop_SetElem16x4: vex_printf("SetElem16x4"); return; 862 case Iop_SetElem32x2: vex_printf("SetElem32x2"); return; 863 864 case Iop_Extract64: vex_printf("Extract64"); return; 865 case Iop_ExtractV128: vex_printf("ExtractV128"); return; 866 867 case Iop_Perm8x16: vex_printf("Perm8x16"); return; 868 case Iop_Reverse16_8x16: vex_printf("Reverse16_8x16"); return; 869 case Iop_Reverse32_8x16: vex_printf("Reverse32_8x16"); return; 870 case Iop_Reverse32_16x8: vex_printf("Reverse32_16x8"); return; 871 case Iop_Reverse64_8x16: vex_printf("Reverse64_8x16"); return; 872 case Iop_Reverse64_16x8: vex_printf("Reverse64_16x8"); return; 873 case Iop_Reverse64_32x4: vex_printf("Reverse64_32x4"); return; 874 875 case Iop_F32ToFixed32Ux4_RZ: vex_printf("F32ToFixed32Ux4_RZ"); return; 876 case Iop_F32ToFixed32Sx4_RZ: vex_printf("F32ToFixed32Sx4_RZ"); return; 877 case Iop_Fixed32UToF32x4_RN: vex_printf("Fixed32UToF32x4_RN"); return; 878 case Iop_Fixed32SToF32x4_RN: vex_printf("Fixed32SToF32x4_RN"); return; 879 case Iop_F32ToFixed32Ux2_RZ: vex_printf("F32ToFixed32Ux2_RZ"); return; 880 case Iop_F32ToFixed32Sx2_RZ: vex_printf("F32ToFixed32Sx2_RZ"); return; 881 case Iop_Fixed32UToF32x2_RN: vex_printf("Fixed32UToF32x2_RN"); return; 882 case Iop_Fixed32SToF32x2_RN: vex_printf("Fixed32SToF32x2_RN"); return; 883 884 default: vpanic("ppIROp(1)"); 885 } 886 887 vassert(str); 888 switch (op - base) { 889 case 0: vex_printf("%s",str); vex_printf("8"); break; 890 case 1: vex_printf("%s",str); vex_printf("16"); break; 891 case 2: vex_printf("%s",str); vex_printf("32"); break; 892 case 3: vex_printf("%s",str); vex_printf("64"); break; 893 default: vpanic("ppIROp(2)"); 894 } 895 } 896 897 void ppIRExpr ( IRExpr* e ) 898 { 899 Int i; 900 switch (e->tag) { 901 case Iex_Binder: 902 vex_printf("BIND-%d", e->Iex.Binder.binder); 903 break; 904 case Iex_Get: 905 vex_printf( "GET:" ); 906 ppIRType(e->Iex.Get.ty); 907 vex_printf("(%d)", e->Iex.Get.offset); 908 break; 909 case Iex_GetI: 910 vex_printf( "GETI" ); 911 ppIRRegArray(e->Iex.GetI.descr); 912 vex_printf("["); 913 ppIRExpr(e->Iex.GetI.ix); 914 vex_printf(",%d]", e->Iex.GetI.bias); 915 break; 916 case Iex_RdTmp: 917 ppIRTemp(e->Iex.RdTmp.tmp); 918 break; 919 case Iex_Qop: 920 ppIROp(e->Iex.Qop.op); 921 vex_printf( "(" ); 922 ppIRExpr(e->Iex.Qop.arg1); 923 vex_printf( "," ); 924 ppIRExpr(e->Iex.Qop.arg2); 925 vex_printf( "," ); 926 ppIRExpr(e->Iex.Qop.arg3); 927 vex_printf( "," ); 928 ppIRExpr(e->Iex.Qop.arg4); 929 vex_printf( ")" ); 930 break; 931 case Iex_Triop: 932 ppIROp(e->Iex.Triop.op); 933 vex_printf( "(" ); 934 ppIRExpr(e->Iex.Triop.arg1); 935 vex_printf( "," ); 936 ppIRExpr(e->Iex.Triop.arg2); 937 vex_printf( "," ); 938 ppIRExpr(e->Iex.Triop.arg3); 939 vex_printf( ")" ); 940 break; 941 case Iex_Binop: 942 ppIROp(e->Iex.Binop.op); 943 vex_printf( "(" ); 944 ppIRExpr(e->Iex.Binop.arg1); 945 vex_printf( "," ); 946 ppIRExpr(e->Iex.Binop.arg2); 947 vex_printf( ")" ); 948 break; 949 case Iex_Unop: 950 ppIROp(e->Iex.Unop.op); 951 vex_printf( "(" ); 952 ppIRExpr(e->Iex.Unop.arg); 953 vex_printf( ")" ); 954 break; 955 case Iex_Load: 956 vex_printf( "LD%s:", e->Iex.Load.end==Iend_LE ? "le" : "be" ); 957 ppIRType(e->Iex.Load.ty); 958 vex_printf( "(" ); 959 ppIRExpr(e->Iex.Load.addr); 960 vex_printf( ")" ); 961 break; 962 case Iex_Const: 963 ppIRConst(e->Iex.Const.con); 964 break; 965 case Iex_CCall: 966 ppIRCallee(e->Iex.CCall.cee); 967 vex_printf("("); 968 for (i = 0; e->Iex.CCall.args[i] != NULL; i++) { 969 ppIRExpr(e->Iex.CCall.args[i]); 970 if (e->Iex.CCall.args[i+1] != NULL) 971 vex_printf(","); 972 } 973 vex_printf("):"); 974 ppIRType(e->Iex.CCall.retty); 975 break; 976 case Iex_Mux0X: 977 vex_printf("Mux0X("); 978 ppIRExpr(e->Iex.Mux0X.cond); 979 vex_printf(","); 980 ppIRExpr(e->Iex.Mux0X.expr0); 981 vex_printf(","); 982 ppIRExpr(e->Iex.Mux0X.exprX); 983 vex_printf(")"); 984 break; 985 default: 986 vpanic("ppIRExpr"); 987 } 988 } 989 990 void ppIREffect ( IREffect fx ) 991 { 992 switch (fx) { 993 case Ifx_None: vex_printf("noFX"); return; 994 case Ifx_Read: vex_printf("RdFX"); return; 995 case Ifx_Write: vex_printf("WrFX"); return; 996 case Ifx_Modify: vex_printf("MoFX"); return; 997 default: vpanic("ppIREffect"); 998 } 999 } 1000 1001 void ppIRDirty ( IRDirty* d ) 1002 { 1003 Int i; 1004 if (d->tmp != IRTemp_INVALID) { 1005 ppIRTemp(d->tmp); 1006 vex_printf(" = "); 1007 } 1008 vex_printf("DIRTY "); 1009 ppIRExpr(d->guard); 1010 if (d->needsBBP) 1011 vex_printf(" NeedsBBP"); 1012 if (d->mFx != Ifx_None) { 1013 vex_printf(" "); 1014 ppIREffect(d->mFx); 1015 vex_printf("-mem("); 1016 ppIRExpr(d->mAddr); 1017 vex_printf(",%d)", d->mSize); 1018 } 1019 for (i = 0; i < d->nFxState; i++) { 1020 vex_printf(" "); 1021 ppIREffect(d->fxState[i].fx); 1022 vex_printf("-gst(%d,%d)", d->fxState[i].offset, d->fxState[i].size); 1023 } 1024 vex_printf(" ::: "); 1025 ppIRCallee(d->cee); 1026 vex_printf("("); 1027 for (i = 0; d->args[i] != NULL; i++) { 1028 ppIRExpr(d->args[i]); 1029 if (d->args[i+1] != NULL) { 1030 vex_printf(","); 1031 } 1032 } 1033 vex_printf(")"); 1034 } 1035 1036 void ppIRCAS ( IRCAS* cas ) 1037 { 1038 /* Print even structurally invalid constructions, as an aid to 1039 debugging. */ 1040 if (cas->oldHi != IRTemp_INVALID) { 1041 ppIRTemp(cas->oldHi); 1042 vex_printf(","); 1043 } 1044 ppIRTemp(cas->oldLo); 1045 vex_printf(" = CAS%s(", cas->end==Iend_LE ? "le" : "be" ); 1046 ppIRExpr(cas->addr); 1047 vex_printf("::"); 1048 if (cas->expdHi) { 1049 ppIRExpr(cas->expdHi); 1050 vex_printf(","); 1051 } 1052 ppIRExpr(cas->expdLo); 1053 vex_printf("->"); 1054 if (cas->dataHi) { 1055 ppIRExpr(cas->dataHi); 1056 vex_printf(","); 1057 } 1058 ppIRExpr(cas->dataLo); 1059 vex_printf(")"); 1060 } 1061 1062 void ppIRJumpKind ( IRJumpKind kind ) 1063 { 1064 switch (kind) { 1065 case Ijk_Boring: vex_printf("Boring"); break; 1066 case Ijk_Call: vex_printf("Call"); break; 1067 case Ijk_Ret: vex_printf("Return"); break; 1068 case Ijk_ClientReq: vex_printf("ClientReq"); break; 1069 case Ijk_Yield: vex_printf("Yield"); break; 1070 case Ijk_YieldNoRedir: vex_printf("YieldNoRedir"); break; 1071 case Ijk_EmWarn: vex_printf("EmWarn"); break; 1072 case Ijk_EmFail: vex_printf("EmFail"); break; 1073 case Ijk_NoDecode: vex_printf("NoDecode"); break; 1074 case Ijk_MapFail: vex_printf("MapFail"); break; 1075 case Ijk_TInval: vex_printf("Invalidate"); break; 1076 case Ijk_NoRedir: vex_printf("NoRedir"); break; 1077 case Ijk_SigTRAP: vex_printf("SigTRAP"); break; 1078 case Ijk_SigSEGV: vex_printf("SigSEGV"); break; 1079 case Ijk_SigBUS: vex_printf("SigBUS"); break; 1080 case Ijk_Sys_syscall: vex_printf("Sys_syscall"); break; 1081 case Ijk_Sys_int32: vex_printf("Sys_int32"); break; 1082 case Ijk_Sys_int128: vex_printf("Sys_int128"); break; 1083 case Ijk_Sys_int129: vex_printf("Sys_int129"); break; 1084 case Ijk_Sys_int130: vex_printf("Sys_int130"); break; 1085 case Ijk_Sys_sysenter: vex_printf("Sys_sysenter"); break; 1086 default: vpanic("ppIRJumpKind"); 1087 } 1088 } 1089 1090 void ppIRMBusEvent ( IRMBusEvent event ) 1091 { 1092 switch (event) { 1093 case Imbe_Fence: vex_printf("Fence"); break; 1094 default: vpanic("ppIRMBusEvent"); 1095 } 1096 } 1097 1098 void ppIRStmt ( IRStmt* s ) 1099 { 1100 if (!s) { 1101 vex_printf("!!! IRStmt* which is NULL !!!"); 1102 return; 1103 } 1104 switch (s->tag) { 1105 case Ist_NoOp: 1106 vex_printf("IR-NoOp"); 1107 break; 1108 case Ist_IMark: 1109 vex_printf( "------ IMark(0x%llx, %d) ------", 1110 s->Ist.IMark.addr, s->Ist.IMark.len); 1111 break; 1112 case Ist_AbiHint: 1113 vex_printf("====== AbiHint("); 1114 ppIRExpr(s->Ist.AbiHint.base); 1115 vex_printf(", %d, ", s->Ist.AbiHint.len); 1116 ppIRExpr(s->Ist.AbiHint.nia); 1117 vex_printf(") ======"); 1118 break; 1119 case Ist_Put: 1120 vex_printf( "PUT(%d) = ", s->Ist.Put.offset); 1121 ppIRExpr(s->Ist.Put.data); 1122 break; 1123 case Ist_PutI: 1124 vex_printf( "PUTI" ); 1125 ppIRRegArray(s->Ist.PutI.descr); 1126 vex_printf("["); 1127 ppIRExpr(s->Ist.PutI.ix); 1128 vex_printf(",%d] = ", s->Ist.PutI.bias); 1129 ppIRExpr(s->Ist.PutI.data); 1130 break; 1131 case Ist_WrTmp: 1132 ppIRTemp(s->Ist.WrTmp.tmp); 1133 vex_printf( " = " ); 1134 ppIRExpr(s->Ist.WrTmp.data); 1135 break; 1136 case Ist_Store: 1137 vex_printf( "ST%s(", s->Ist.Store.end==Iend_LE ? "le" : "be" ); 1138 ppIRExpr(s->Ist.Store.addr); 1139 vex_printf( ") = "); 1140 ppIRExpr(s->Ist.Store.data); 1141 break; 1142 case Ist_CAS: 1143 ppIRCAS(s->Ist.CAS.details); 1144 break; 1145 case Ist_LLSC: 1146 if (s->Ist.LLSC.storedata == NULL) { 1147 ppIRTemp(s->Ist.LLSC.result); 1148 vex_printf(" = LD%s-Linked(", 1149 s->Ist.LLSC.end==Iend_LE ? "le" : "be"); 1150 ppIRExpr(s->Ist.LLSC.addr); 1151 vex_printf(")"); 1152 } else { 1153 ppIRTemp(s->Ist.LLSC.result); 1154 vex_printf(" = ( ST%s-Cond(", 1155 s->Ist.LLSC.end==Iend_LE ? "le" : "be"); 1156 ppIRExpr(s->Ist.LLSC.addr); 1157 vex_printf(") = "); 1158 ppIRExpr(s->Ist.LLSC.storedata); 1159 vex_printf(" )"); 1160 } 1161 break; 1162 case Ist_Dirty: 1163 ppIRDirty(s->Ist.Dirty.details); 1164 break; 1165 case Ist_MBE: 1166 vex_printf("IR-"); 1167 ppIRMBusEvent(s->Ist.MBE.event); 1168 break; 1169 case Ist_Exit: 1170 vex_printf( "if (" ); 1171 ppIRExpr(s->Ist.Exit.guard); 1172 vex_printf( ") goto {"); 1173 ppIRJumpKind(s->Ist.Exit.jk); 1174 vex_printf("} "); 1175 ppIRConst(s->Ist.Exit.dst); 1176 break; 1177 default: 1178 vpanic("ppIRStmt"); 1179 } 1180 } 1181 1182 void ppIRTypeEnv ( IRTypeEnv* env ) { 1183 UInt i; 1184 for (i = 0; i < env->types_used; i++) { 1185 if (i % 8 == 0) 1186 vex_printf( " "); 1187 ppIRTemp(i); 1188 vex_printf( ":"); 1189 ppIRType(env->types[i]); 1190 if (i % 8 == 7) 1191 vex_printf( "\n"); 1192 else 1193 vex_printf( " "); 1194 } 1195 if (env->types_used > 0 && env->types_used % 8 != 7) 1196 vex_printf( "\n"); 1197 } 1198 1199 void ppIRSB ( IRSB* bb ) 1200 { 1201 Int i; 1202 vex_printf("IRSB {\n"); 1203 ppIRTypeEnv(bb->tyenv); 1204 vex_printf("\n"); 1205 for (i = 0; i < bb->stmts_used; i++) { 1206 vex_printf( " "); 1207 ppIRStmt(bb->stmts[i]); 1208 vex_printf( "\n"); 1209 } 1210 vex_printf( " goto {"); 1211 ppIRJumpKind(bb->jumpkind); 1212 vex_printf( "} "); 1213 ppIRExpr( bb->next ); 1214 vex_printf( "\n}\n"); 1215 } 1216 1217 1218 /*---------------------------------------------------------------*/ 1219 /*--- Constructors ---*/ 1220 /*---------------------------------------------------------------*/ 1221 1222 1223 /* Constructors -- IRConst */ 1224 1225 IRConst* IRConst_U1 ( Bool bit ) 1226 { 1227 IRConst* c = LibVEX_Alloc(sizeof(IRConst)); 1228 c->tag = Ico_U1; 1229 c->Ico.U1 = bit; 1230 /* call me paranoid; I don't care :-) */ 1231 vassert(bit == False || bit == True); 1232 return c; 1233 } 1234 IRConst* IRConst_U8 ( UChar u8 ) 1235 { 1236 IRConst* c = LibVEX_Alloc(sizeof(IRConst)); 1237 c->tag = Ico_U8; 1238 c->Ico.U8 = u8; 1239 return c; 1240 } 1241 IRConst* IRConst_U16 ( UShort u16 ) 1242 { 1243 IRConst* c = LibVEX_Alloc(sizeof(IRConst)); 1244 c->tag = Ico_U16; 1245 c->Ico.U16 = u16; 1246 return c; 1247 } 1248 IRConst* IRConst_U32 ( UInt u32 ) 1249 { 1250 IRConst* c = LibVEX_Alloc(sizeof(IRConst)); 1251 c->tag = Ico_U32; 1252 c->Ico.U32 = u32; 1253 return c; 1254 } 1255 IRConst* IRConst_U64 ( ULong u64 ) 1256 { 1257 IRConst* c = LibVEX_Alloc(sizeof(IRConst)); 1258 c->tag = Ico_U64; 1259 c->Ico.U64 = u64; 1260 return c; 1261 } 1262 IRConst* IRConst_F64 ( Double f64 ) 1263 { 1264 IRConst* c = LibVEX_Alloc(sizeof(IRConst)); 1265 c->tag = Ico_F64; 1266 c->Ico.F64 = f64; 1267 return c; 1268 } 1269 IRConst* IRConst_F64i ( ULong f64i ) 1270 { 1271 IRConst* c = LibVEX_Alloc(sizeof(IRConst)); 1272 c->tag = Ico_F64i; 1273 c->Ico.F64i = f64i; 1274 return c; 1275 } 1276 IRConst* IRConst_V128 ( UShort con ) 1277 { 1278 IRConst* c = LibVEX_Alloc(sizeof(IRConst)); 1279 c->tag = Ico_V128; 1280 c->Ico.V128 = con; 1281 return c; 1282 } 1283 1284 /* Constructors -- IRCallee */ 1285 1286 IRCallee* mkIRCallee ( Int regparms, HChar* name, void* addr ) 1287 { 1288 IRCallee* ce = LibVEX_Alloc(sizeof(IRCallee)); 1289 ce->regparms = regparms; 1290 ce->name = name; 1291 ce->addr = addr; 1292 ce->mcx_mask = 0; 1293 vassert(regparms >= 0 && regparms <= 3); 1294 vassert(name != NULL); 1295 vassert(addr != 0); 1296 return ce; 1297 } 1298 1299 1300 /* Constructors -- IRRegArray */ 1301 1302 IRRegArray* mkIRRegArray ( Int base, IRType elemTy, Int nElems ) 1303 { 1304 IRRegArray* arr = LibVEX_Alloc(sizeof(IRRegArray)); 1305 arr->base = base; 1306 arr->elemTy = elemTy; 1307 arr->nElems = nElems; 1308 vassert(!(arr->base < 0 || arr->base > 10000 /* somewhat arbitrary */)); 1309 vassert(!(arr->elemTy == Ity_I1)); 1310 vassert(!(arr->nElems <= 0 || arr->nElems > 500 /* somewhat arbitrary */)); 1311 return arr; 1312 } 1313 1314 1315 /* Constructors -- IRExpr */ 1316 1317 IRExpr* IRExpr_Binder ( Int binder ) { 1318 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr)); 1319 e->tag = Iex_Binder; 1320 e->Iex.Binder.binder = binder; 1321 return e; 1322 } 1323 IRExpr* IRExpr_Get ( Int off, IRType ty ) { 1324 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr)); 1325 e->tag = Iex_Get; 1326 e->Iex.Get.offset = off; 1327 e->Iex.Get.ty = ty; 1328 return e; 1329 } 1330 IRExpr* IRExpr_GetI ( IRRegArray* descr, IRExpr* ix, Int bias ) { 1331 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr)); 1332 e->tag = Iex_GetI; 1333 e->Iex.GetI.descr = descr; 1334 e->Iex.GetI.ix = ix; 1335 e->Iex.GetI.bias = bias; 1336 return e; 1337 } 1338 IRExpr* IRExpr_RdTmp ( IRTemp tmp ) { 1339 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr)); 1340 e->tag = Iex_RdTmp; 1341 e->Iex.RdTmp.tmp = tmp; 1342 return e; 1343 } 1344 IRExpr* IRExpr_Qop ( IROp op, IRExpr* arg1, IRExpr* arg2, 1345 IRExpr* arg3, IRExpr* arg4 ) { 1346 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr)); 1347 e->tag = Iex_Qop; 1348 e->Iex.Qop.op = op; 1349 e->Iex.Qop.arg1 = arg1; 1350 e->Iex.Qop.arg2 = arg2; 1351 e->Iex.Qop.arg3 = arg3; 1352 e->Iex.Qop.arg4 = arg4; 1353 return e; 1354 } 1355 IRExpr* IRExpr_Triop ( IROp op, IRExpr* arg1, 1356 IRExpr* arg2, IRExpr* arg3 ) { 1357 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr)); 1358 e->tag = Iex_Triop; 1359 e->Iex.Triop.op = op; 1360 e->Iex.Triop.arg1 = arg1; 1361 e->Iex.Triop.arg2 = arg2; 1362 e->Iex.Triop.arg3 = arg3; 1363 return e; 1364 } 1365 IRExpr* IRExpr_Binop ( IROp op, IRExpr* arg1, IRExpr* arg2 ) { 1366 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr)); 1367 e->tag = Iex_Binop; 1368 e->Iex.Binop.op = op; 1369 e->Iex.Binop.arg1 = arg1; 1370 e->Iex.Binop.arg2 = arg2; 1371 return e; 1372 } 1373 IRExpr* IRExpr_Unop ( IROp op, IRExpr* arg ) { 1374 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr)); 1375 e->tag = Iex_Unop; 1376 e->Iex.Unop.op = op; 1377 e->Iex.Unop.arg = arg; 1378 return e; 1379 } 1380 IRExpr* IRExpr_Load ( IREndness end, IRType ty, IRExpr* addr ) { 1381 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr)); 1382 e->tag = Iex_Load; 1383 e->Iex.Load.end = end; 1384 e->Iex.Load.ty = ty; 1385 e->Iex.Load.addr = addr; 1386 vassert(end == Iend_LE || end == Iend_BE); 1387 return e; 1388 } 1389 IRExpr* IRExpr_Const ( IRConst* con ) { 1390 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr)); 1391 e->tag = Iex_Const; 1392 e->Iex.Const.con = con; 1393 return e; 1394 } 1395 IRExpr* IRExpr_CCall ( IRCallee* cee, IRType retty, IRExpr** args ) { 1396 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr)); 1397 e->tag = Iex_CCall; 1398 e->Iex.CCall.cee = cee; 1399 e->Iex.CCall.retty = retty; 1400 e->Iex.CCall.args = args; 1401 return e; 1402 } 1403 IRExpr* IRExpr_Mux0X ( IRExpr* cond, IRExpr* expr0, IRExpr* exprX ) { 1404 IRExpr* e = LibVEX_Alloc(sizeof(IRExpr)); 1405 e->tag = Iex_Mux0X; 1406 e->Iex.Mux0X.cond = cond; 1407 e->Iex.Mux0X.expr0 = expr0; 1408 e->Iex.Mux0X.exprX = exprX; 1409 return e; 1410 } 1411 1412 1413 /* Constructors for NULL-terminated IRExpr expression vectors, 1414 suitable for use as arg lists in clean/dirty helper calls. */ 1415 1416 IRExpr** mkIRExprVec_0 ( void ) { 1417 IRExpr** vec = LibVEX_Alloc(1 * sizeof(IRExpr*)); 1418 vec[0] = NULL; 1419 return vec; 1420 } 1421 IRExpr** mkIRExprVec_1 ( IRExpr* arg1 ) { 1422 IRExpr** vec = LibVEX_Alloc(2 * sizeof(IRExpr*)); 1423 vec[0] = arg1; 1424 vec[1] = NULL; 1425 return vec; 1426 } 1427 IRExpr** mkIRExprVec_2 ( IRExpr* arg1, IRExpr* arg2 ) { 1428 IRExpr** vec = LibVEX_Alloc(3 * sizeof(IRExpr*)); 1429 vec[0] = arg1; 1430 vec[1] = arg2; 1431 vec[2] = NULL; 1432 return vec; 1433 } 1434 IRExpr** mkIRExprVec_3 ( IRExpr* arg1, IRExpr* arg2, IRExpr* arg3 ) { 1435 IRExpr** vec = LibVEX_Alloc(4 * sizeof(IRExpr*)); 1436 vec[0] = arg1; 1437 vec[1] = arg2; 1438 vec[2] = arg3; 1439 vec[3] = NULL; 1440 return vec; 1441 } 1442 IRExpr** mkIRExprVec_4 ( IRExpr* arg1, IRExpr* arg2, IRExpr* arg3, 1443 IRExpr* arg4 ) { 1444 IRExpr** vec = LibVEX_Alloc(5 * sizeof(IRExpr*)); 1445 vec[0] = arg1; 1446 vec[1] = arg2; 1447 vec[2] = arg3; 1448 vec[3] = arg4; 1449 vec[4] = NULL; 1450 return vec; 1451 } 1452 IRExpr** mkIRExprVec_5 ( IRExpr* arg1, IRExpr* arg2, IRExpr* arg3, 1453 IRExpr* arg4, IRExpr* arg5 ) { 1454 IRExpr** vec = LibVEX_Alloc(6 * sizeof(IRExpr*)); 1455 vec[0] = arg1; 1456 vec[1] = arg2; 1457 vec[2] = arg3; 1458 vec[3] = arg4; 1459 vec[4] = arg5; 1460 vec[5] = NULL; 1461 return vec; 1462 } 1463 IRExpr** mkIRExprVec_6 ( IRExpr* arg1, IRExpr* arg2, IRExpr* arg3, 1464 IRExpr* arg4, IRExpr* arg5, IRExpr* arg6 ) { 1465 IRExpr** vec = LibVEX_Alloc(7 * sizeof(IRExpr*)); 1466 vec[0] = arg1; 1467 vec[1] = arg2; 1468 vec[2] = arg3; 1469 vec[3] = arg4; 1470 vec[4] = arg5; 1471 vec[5] = arg6; 1472 vec[6] = NULL; 1473 return vec; 1474 } 1475 IRExpr** mkIRExprVec_7 ( IRExpr* arg1, IRExpr* arg2, IRExpr* arg3, 1476 IRExpr* arg4, IRExpr* arg5, IRExpr* arg6, 1477 IRExpr* arg7 ) { 1478 IRExpr** vec = LibVEX_Alloc(8 * sizeof(IRExpr*)); 1479 vec[0] = arg1; 1480 vec[1] = arg2; 1481 vec[2] = arg3; 1482 vec[3] = arg4; 1483 vec[4] = arg5; 1484 vec[5] = arg6; 1485 vec[6] = arg7; 1486 vec[7] = NULL; 1487 return vec; 1488 } 1489 IRExpr** mkIRExprVec_8 ( IRExpr* arg1, IRExpr* arg2, IRExpr* arg3, 1490 IRExpr* arg4, IRExpr* arg5, IRExpr* arg6, 1491 IRExpr* arg7, IRExpr* arg8 ) { 1492 IRExpr** vec = LibVEX_Alloc(9 * sizeof(IRExpr*)); 1493 vec[0] = arg1; 1494 vec[1] = arg2; 1495 vec[2] = arg3; 1496 vec[3] = arg4; 1497 vec[4] = arg5; 1498 vec[5] = arg6; 1499 vec[6] = arg7; 1500 vec[7] = arg8; 1501 vec[8] = NULL; 1502 return vec; 1503 } 1504 1505 1506 /* Constructors -- IRDirty */ 1507 1508 IRDirty* emptyIRDirty ( void ) { 1509 IRDirty* d = LibVEX_Alloc(sizeof(IRDirty)); 1510 d->cee = NULL; 1511 d->guard = NULL; 1512 d->args = NULL; 1513 d->tmp = IRTemp_INVALID; 1514 d->mFx = Ifx_None; 1515 d->mAddr = NULL; 1516 d->mSize = 0; 1517 d->needsBBP = False; 1518 d->nFxState = 0; 1519 return d; 1520 } 1521 1522 1523 /* Constructors -- IRCAS */ 1524 1525 IRCAS* mkIRCAS ( IRTemp oldHi, IRTemp oldLo, 1526 IREndness end, IRExpr* addr, 1527 IRExpr* expdHi, IRExpr* expdLo, 1528 IRExpr* dataHi, IRExpr* dataLo ) { 1529 IRCAS* cas = LibVEX_Alloc(sizeof(IRCAS)); 1530 cas->oldHi = oldHi; 1531 cas->oldLo = oldLo; 1532 cas->end = end; 1533 cas->addr = addr; 1534 cas->expdHi = expdHi; 1535 cas->expdLo = expdLo; 1536 cas->dataHi = dataHi; 1537 cas->dataLo = dataLo; 1538 return cas; 1539 } 1540 1541 1542 /* Constructors -- IRStmt */ 1543 1544 IRStmt* IRStmt_NoOp ( void ) 1545 { 1546 /* Just use a single static closure. */ 1547 static IRStmt static_closure; 1548 static_closure.tag = Ist_NoOp; 1549 return &static_closure; 1550 } 1551 IRStmt* IRStmt_IMark ( Addr64 addr, Int len ) { 1552 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt)); 1553 s->tag = Ist_IMark; 1554 s->Ist.IMark.addr = addr; 1555 s->Ist.IMark.len = len; 1556 return s; 1557 } 1558 IRStmt* IRStmt_AbiHint ( IRExpr* base, Int len, IRExpr* nia ) { 1559 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt)); 1560 s->tag = Ist_AbiHint; 1561 s->Ist.AbiHint.base = base; 1562 s->Ist.AbiHint.len = len; 1563 s->Ist.AbiHint.nia = nia; 1564 return s; 1565 } 1566 IRStmt* IRStmt_Put ( Int off, IRExpr* data ) { 1567 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt)); 1568 s->tag = Ist_Put; 1569 s->Ist.Put.offset = off; 1570 s->Ist.Put.data = data; 1571 return s; 1572 } 1573 IRStmt* IRStmt_PutI ( IRRegArray* descr, IRExpr* ix, 1574 Int bias, IRExpr* data ) { 1575 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt)); 1576 s->tag = Ist_PutI; 1577 s->Ist.PutI.descr = descr; 1578 s->Ist.PutI.ix = ix; 1579 s->Ist.PutI.bias = bias; 1580 s->Ist.PutI.data = data; 1581 return s; 1582 } 1583 IRStmt* IRStmt_WrTmp ( IRTemp tmp, IRExpr* data ) { 1584 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt)); 1585 s->tag = Ist_WrTmp; 1586 s->Ist.WrTmp.tmp = tmp; 1587 s->Ist.WrTmp.data = data; 1588 return s; 1589 } 1590 IRStmt* IRStmt_Store ( IREndness end, IRExpr* addr, IRExpr* data ) { 1591 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt)); 1592 s->tag = Ist_Store; 1593 s->Ist.Store.end = end; 1594 s->Ist.Store.addr = addr; 1595 s->Ist.Store.data = data; 1596 vassert(end == Iend_LE || end == Iend_BE); 1597 return s; 1598 } 1599 IRStmt* IRStmt_CAS ( IRCAS* cas ) { 1600 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt)); 1601 s->tag = Ist_CAS; 1602 s->Ist.CAS.details = cas; 1603 return s; 1604 } 1605 IRStmt* IRStmt_LLSC ( IREndness end, 1606 IRTemp result, IRExpr* addr, IRExpr* storedata ) { 1607 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt)); 1608 s->tag = Ist_LLSC; 1609 s->Ist.LLSC.end = end; 1610 s->Ist.LLSC.result = result; 1611 s->Ist.LLSC.addr = addr; 1612 s->Ist.LLSC.storedata = storedata; 1613 return s; 1614 } 1615 IRStmt* IRStmt_Dirty ( IRDirty* d ) 1616 { 1617 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt)); 1618 s->tag = Ist_Dirty; 1619 s->Ist.Dirty.details = d; 1620 return s; 1621 } 1622 IRStmt* IRStmt_MBE ( IRMBusEvent event ) 1623 { 1624 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt)); 1625 s->tag = Ist_MBE; 1626 s->Ist.MBE.event = event; 1627 return s; 1628 } 1629 IRStmt* IRStmt_Exit ( IRExpr* guard, IRJumpKind jk, IRConst* dst ) { 1630 IRStmt* s = LibVEX_Alloc(sizeof(IRStmt)); 1631 s->tag = Ist_Exit; 1632 s->Ist.Exit.guard = guard; 1633 s->Ist.Exit.jk = jk; 1634 s->Ist.Exit.dst = dst; 1635 return s; 1636 } 1637 1638 1639 /* Constructors -- IRTypeEnv */ 1640 1641 IRTypeEnv* emptyIRTypeEnv ( void ) 1642 { 1643 IRTypeEnv* env = LibVEX_Alloc(sizeof(IRTypeEnv)); 1644 env->types = LibVEX_Alloc(8 * sizeof(IRType)); 1645 env->types_size = 8; 1646 env->types_used = 0; 1647 return env; 1648 } 1649 1650 1651 /* Constructors -- IRSB */ 1652 1653 IRSB* emptyIRSB ( void ) 1654 { 1655 IRSB* bb = LibVEX_Alloc(sizeof(IRSB)); 1656 bb->tyenv = emptyIRTypeEnv(); 1657 bb->stmts_used = 0; 1658 bb->stmts_size = 8; 1659 bb->stmts = LibVEX_Alloc(bb->stmts_size * sizeof(IRStmt*)); 1660 bb->next = NULL; 1661 bb->jumpkind = Ijk_Boring; 1662 return bb; 1663 } 1664 1665 1666 /*---------------------------------------------------------------*/ 1667 /*--- (Deep) copy constructors. These make complete copies ---*/ 1668 /*--- the original, which can be modified without affecting ---*/ 1669 /*--- the original. ---*/ 1670 /*---------------------------------------------------------------*/ 1671 1672 /* Copying IR Expr vectors (for call args). */ 1673 1674 /* Shallow copy of an IRExpr vector */ 1675 1676 IRExpr** shallowCopyIRExprVec ( IRExpr** vec ) 1677 { 1678 Int i; 1679 IRExpr** newvec; 1680 for (i = 0; vec[i]; i++) 1681 ; 1682 newvec = LibVEX_Alloc((i+1)*sizeof(IRExpr*)); 1683 for (i = 0; vec[i]; i++) 1684 newvec[i] = vec[i]; 1685 newvec[i] = NULL; 1686 return newvec; 1687 } 1688 1689 /* Deep copy of an IRExpr vector */ 1690 1691 IRExpr** deepCopyIRExprVec ( IRExpr** vec ) 1692 { 1693 Int i; 1694 IRExpr** newvec = shallowCopyIRExprVec( vec ); 1695 for (i = 0; newvec[i]; i++) 1696 newvec[i] = deepCopyIRExpr(newvec[i]); 1697 return newvec; 1698 } 1699 1700 /* Deep copy constructors for all heap-allocated IR types follow. */ 1701 1702 IRConst* deepCopyIRConst ( IRConst* c ) 1703 { 1704 switch (c->tag) { 1705 case Ico_U1: return IRConst_U1(c->Ico.U1); 1706 case Ico_U8: return IRConst_U8(c->Ico.U8); 1707 case Ico_U16: return IRConst_U16(c->Ico.U16); 1708 case Ico_U32: return IRConst_U32(c->Ico.U32); 1709 case Ico_U64: return IRConst_U64(c->Ico.U64); 1710 case Ico_F64: return IRConst_F64(c->Ico.F64); 1711 case Ico_F64i: return IRConst_F64i(c->Ico.F64i); 1712 case Ico_V128: return IRConst_V128(c->Ico.V128); 1713 default: vpanic("deepCopyIRConst"); 1714 } 1715 } 1716 1717 IRCallee* deepCopyIRCallee ( IRCallee* ce ) 1718 { 1719 IRCallee* ce2 = mkIRCallee(ce->regparms, ce->name, ce->addr); 1720 ce2->mcx_mask = ce->mcx_mask; 1721 return ce2; 1722 } 1723 1724 IRRegArray* deepCopyIRRegArray ( IRRegArray* d ) 1725 { 1726 return mkIRRegArray(d->base, d->elemTy, d->nElems); 1727 } 1728 1729 IRExpr* deepCopyIRExpr ( IRExpr* e ) 1730 { 1731 switch (e->tag) { 1732 case Iex_Get: 1733 return IRExpr_Get(e->Iex.Get.offset, e->Iex.Get.ty); 1734 case Iex_GetI: 1735 return IRExpr_GetI(deepCopyIRRegArray(e->Iex.GetI.descr), 1736 deepCopyIRExpr(e->Iex.GetI.ix), 1737 e->Iex.GetI.bias); 1738 case Iex_RdTmp: 1739 return IRExpr_RdTmp(e->Iex.RdTmp.tmp); 1740 case Iex_Qop: 1741 return IRExpr_Qop(e->Iex.Qop.op, 1742 deepCopyIRExpr(e->Iex.Qop.arg1), 1743 deepCopyIRExpr(e->Iex.Qop.arg2), 1744 deepCopyIRExpr(e->Iex.Qop.arg3), 1745 deepCopyIRExpr(e->Iex.Qop.arg4)); 1746 case Iex_Triop: 1747 return IRExpr_Triop(e->Iex.Triop.op, 1748 deepCopyIRExpr(e->Iex.Triop.arg1), 1749 deepCopyIRExpr(e->Iex.Triop.arg2), 1750 deepCopyIRExpr(e->Iex.Triop.arg3)); 1751 case Iex_Binop: 1752 return IRExpr_Binop(e->Iex.Binop.op, 1753 deepCopyIRExpr(e->Iex.Binop.arg1), 1754 deepCopyIRExpr(e->Iex.Binop.arg2)); 1755 case Iex_Unop: 1756 return IRExpr_Unop(e->Iex.Unop.op, 1757 deepCopyIRExpr(e->Iex.Unop.arg)); 1758 case Iex_Load: 1759 return IRExpr_Load(e->Iex.Load.end, 1760 e->Iex.Load.ty, 1761 deepCopyIRExpr(e->Iex.Load.addr)); 1762 case Iex_Const: 1763 return IRExpr_Const(deepCopyIRConst(e->Iex.Const.con)); 1764 case Iex_CCall: 1765 return IRExpr_CCall(deepCopyIRCallee(e->Iex.CCall.cee), 1766 e->Iex.CCall.retty, 1767 deepCopyIRExprVec(e->Iex.CCall.args)); 1768 1769 case Iex_Mux0X: 1770 return IRExpr_Mux0X(deepCopyIRExpr(e->Iex.Mux0X.cond), 1771 deepCopyIRExpr(e->Iex.Mux0X.expr0), 1772 deepCopyIRExpr(e->Iex.Mux0X.exprX)); 1773 default: 1774 vpanic("deepCopyIRExpr"); 1775 } 1776 } 1777 1778 IRDirty* deepCopyIRDirty ( IRDirty* d ) 1779 { 1780 Int i; 1781 IRDirty* d2 = emptyIRDirty(); 1782 d2->cee = deepCopyIRCallee(d->cee); 1783 d2->guard = deepCopyIRExpr(d->guard); 1784 d2->args = deepCopyIRExprVec(d->args); 1785 d2->tmp = d->tmp; 1786 d2->mFx = d->mFx; 1787 d2->mAddr = d->mAddr==NULL ? NULL : deepCopyIRExpr(d->mAddr); 1788 d2->mSize = d->mSize; 1789 d2->needsBBP = d->needsBBP; 1790 d2->nFxState = d->nFxState; 1791 for (i = 0; i < d2->nFxState; i++) 1792 d2->fxState[i] = d->fxState[i]; 1793 return d2; 1794 } 1795 1796 IRCAS* deepCopyIRCAS ( IRCAS* cas ) 1797 { 1798 return mkIRCAS( cas->oldHi, cas->oldLo, cas->end, 1799 deepCopyIRExpr(cas->addr), 1800 cas->expdHi==NULL ? NULL : deepCopyIRExpr(cas->expdHi), 1801 deepCopyIRExpr(cas->expdLo), 1802 cas->dataHi==NULL ? NULL : deepCopyIRExpr(cas->dataHi), 1803 deepCopyIRExpr(cas->dataLo) ); 1804 } 1805 1806 IRStmt* deepCopyIRStmt ( IRStmt* s ) 1807 { 1808 switch (s->tag) { 1809 case Ist_NoOp: 1810 return IRStmt_NoOp(); 1811 case Ist_AbiHint: 1812 return IRStmt_AbiHint(deepCopyIRExpr(s->Ist.AbiHint.base), 1813 s->Ist.AbiHint.len, 1814 deepCopyIRExpr(s->Ist.AbiHint.nia)); 1815 case Ist_IMark: 1816 return IRStmt_IMark(s->Ist.IMark.addr, s->Ist.IMark.len); 1817 case Ist_Put: 1818 return IRStmt_Put(s->Ist.Put.offset, 1819 deepCopyIRExpr(s->Ist.Put.data)); 1820 case Ist_PutI: 1821 return IRStmt_PutI(deepCopyIRRegArray(s->Ist.PutI.descr), 1822 deepCopyIRExpr(s->Ist.PutI.ix), 1823 s->Ist.PutI.bias, 1824 deepCopyIRExpr(s->Ist.PutI.data)); 1825 case Ist_WrTmp: 1826 return IRStmt_WrTmp(s->Ist.WrTmp.tmp, 1827 deepCopyIRExpr(s->Ist.WrTmp.data)); 1828 case Ist_Store: 1829 return IRStmt_Store(s->Ist.Store.end, 1830 deepCopyIRExpr(s->Ist.Store.addr), 1831 deepCopyIRExpr(s->Ist.Store.data)); 1832 case Ist_CAS: 1833 return IRStmt_CAS(deepCopyIRCAS(s->Ist.CAS.details)); 1834 case Ist_LLSC: 1835 return IRStmt_LLSC(s->Ist.LLSC.end, 1836 s->Ist.LLSC.result, 1837 deepCopyIRExpr(s->Ist.LLSC.addr), 1838 s->Ist.LLSC.storedata 1839 ? deepCopyIRExpr(s->Ist.LLSC.storedata) 1840 : NULL); 1841 case Ist_Dirty: 1842 return IRStmt_Dirty(deepCopyIRDirty(s->Ist.Dirty.details)); 1843 case Ist_MBE: 1844 return IRStmt_MBE(s->Ist.MBE.event); 1845 case Ist_Exit: 1846 return IRStmt_Exit(deepCopyIRExpr(s->Ist.Exit.guard), 1847 s->Ist.Exit.jk, 1848 deepCopyIRConst(s->Ist.Exit.dst)); 1849 default: 1850 vpanic("deepCopyIRStmt"); 1851 } 1852 } 1853 1854 IRTypeEnv* deepCopyIRTypeEnv ( IRTypeEnv* src ) 1855 { 1856 Int i; 1857 IRTypeEnv* dst = LibVEX_Alloc(sizeof(IRTypeEnv)); 1858 dst->types_size = src->types_size; 1859 dst->types_used = src->types_used; 1860 dst->types = LibVEX_Alloc(dst->types_size * sizeof(IRType)); 1861 for (i = 0; i < src->types_used; i++) 1862 dst->types[i] = src->types[i]; 1863 return dst; 1864 } 1865 1866 IRSB* deepCopyIRSB ( IRSB* bb ) 1867 { 1868 Int i; 1869 IRStmt** sts2; 1870 IRSB* bb2 = deepCopyIRSBExceptStmts(bb); 1871 bb2->stmts_used = bb2->stmts_size = bb->stmts_used; 1872 sts2 = LibVEX_Alloc(bb2->stmts_used * sizeof(IRStmt*)); 1873 for (i = 0; i < bb2->stmts_used; i++) 1874 sts2[i] = deepCopyIRStmt(bb->stmts[i]); 1875 bb2->stmts = sts2; 1876 return bb2; 1877 } 1878 1879 IRSB* deepCopyIRSBExceptStmts ( IRSB* bb ) 1880 { 1881 IRSB* bb2 = emptyIRSB(); 1882 bb2->tyenv = deepCopyIRTypeEnv(bb->tyenv); 1883 bb2->next = deepCopyIRExpr(bb->next); 1884 bb2->jumpkind = bb->jumpkind; 1885 return bb2; 1886 } 1887 1888 1889 /*---------------------------------------------------------------*/ 1890 /*--- Primop types ---*/ 1891 /*---------------------------------------------------------------*/ 1892 1893 static 1894 void typeOfPrimop ( IROp op, 1895 /*OUTs*/ 1896 IRType* t_dst, 1897 IRType* t_arg1, IRType* t_arg2, 1898 IRType* t_arg3, IRType* t_arg4 ) 1899 { 1900 # define UNARY(_ta1,_td) \ 1901 *t_dst = (_td); *t_arg1 = (_ta1); break 1902 # define BINARY(_ta1,_ta2,_td) \ 1903 *t_dst = (_td); *t_arg1 = (_ta1); *t_arg2 = (_ta2); break 1904 # define TERNARY(_ta1,_ta2,_ta3,_td) \ 1905 *t_dst = (_td); *t_arg1 = (_ta1); \ 1906 *t_arg2 = (_ta2); *t_arg3 = (_ta3); break 1907 # define QUATERNARY(_ta1,_ta2,_ta3,_ta4,_td) \ 1908 *t_dst = (_td); *t_arg1 = (_ta1); \ 1909 *t_arg2 = (_ta2); *t_arg3 = (_ta3); \ 1910 *t_arg4 = (_ta4); break 1911 # define COMPARISON(_ta) \ 1912 *t_dst = Ity_I1; *t_arg1 = *t_arg2 = (_ta); break; 1913 # define UNARY_COMPARISON(_ta) \ 1914 *t_dst = Ity_I1; *t_arg1 = (_ta); break; 1915 1916 /* Rounding mode values are always Ity_I32, encoded as per 1917 IRRoundingMode */ 1918 const IRType ity_RMode = Ity_I32; 1919 1920 *t_dst = Ity_INVALID; 1921 *t_arg1 = Ity_INVALID; 1922 *t_arg2 = Ity_INVALID; 1923 *t_arg3 = Ity_INVALID; 1924 *t_arg4 = Ity_INVALID; 1925 switch (op) { 1926 case Iop_Add8: case Iop_Sub8: case Iop_Mul8: 1927 case Iop_Or8: case Iop_And8: case Iop_Xor8: 1928 BINARY(Ity_I8,Ity_I8, Ity_I8); 1929 1930 case Iop_Add16: case Iop_Sub16: case Iop_Mul16: 1931 case Iop_Or16: case Iop_And16: case Iop_Xor16: 1932 BINARY(Ity_I16,Ity_I16, Ity_I16); 1933 1934 case Iop_CmpORD32U: 1935 case Iop_CmpORD32S: 1936 case Iop_Add32: case Iop_Sub32: case Iop_Mul32: 1937 case Iop_Or32: case Iop_And32: case Iop_Xor32: 1938 case Iop_Max32U: 1939 case Iop_Add16x2: case Iop_Sub16x2: 1940 case Iop_QAdd16Sx2: case Iop_QAdd16Ux2: 1941 case Iop_QSub16Sx2: case Iop_QSub16Ux2: 1942 case Iop_HAdd16Ux2: case Iop_HAdd16Sx2: 1943 case Iop_HSub16Ux2: case Iop_HSub16Sx2: 1944 case Iop_Add8x4: case Iop_Sub8x4: 1945 case Iop_QAdd8Sx4: case Iop_QAdd8Ux4: 1946 case Iop_QSub8Sx4: case Iop_QSub8Ux4: 1947 case Iop_HAdd8Ux4: case Iop_HAdd8Sx4: 1948 case Iop_HSub8Ux4: case Iop_HSub8Sx4: 1949 case Iop_Sad8Ux4: 1950 BINARY(Ity_I32,Ity_I32, Ity_I32); 1951 1952 case Iop_Add64: case Iop_Sub64: case Iop_Mul64: 1953 case Iop_Or64: case Iop_And64: case Iop_Xor64: 1954 case Iop_CmpORD64U: 1955 case Iop_CmpORD64S: 1956 case Iop_Avg8Ux8: case Iop_Avg16Ux4: 1957 case Iop_Add8x8: case Iop_Add16x4: case Iop_Add32x2: 1958 case Iop_Add32Fx2: case Iop_Sub32Fx2: 1959 case Iop_CmpEQ8x8: case Iop_CmpEQ16x4: case Iop_CmpEQ32x2: 1960 case Iop_CmpGT8Sx8: case Iop_CmpGT16Sx4: case Iop_CmpGT32Sx2: 1961 case Iop_CmpGT8Ux8: case Iop_CmpGT16Ux4: case Iop_CmpGT32Ux2: 1962 case Iop_CmpGT32Fx2: case Iop_CmpEQ32Fx2: case Iop_CmpGE32Fx2: 1963 case Iop_InterleaveHI8x8: case Iop_InterleaveLO8x8: 1964 case Iop_InterleaveHI16x4: case Iop_InterleaveLO16x4: 1965 case Iop_InterleaveHI32x2: case Iop_InterleaveLO32x2: 1966 case Iop_CatOddLanes8x8: case Iop_CatEvenLanes8x8: 1967 case Iop_CatOddLanes16x4: case Iop_CatEvenLanes16x4: 1968 case Iop_InterleaveOddLanes8x8: case Iop_InterleaveEvenLanes8x8: 1969 case Iop_InterleaveOddLanes16x4: case Iop_InterleaveEvenLanes16x4: 1970 case Iop_Perm8x8: 1971 case Iop_Max8Ux8: case Iop_Max16Ux4: case Iop_Max32Ux2: 1972 case Iop_Max8Sx8: case Iop_Max16Sx4: case Iop_Max32Sx2: 1973 case Iop_Max32Fx2: case Iop_Min32Fx2: 1974 case Iop_PwMax32Fx2: case Iop_PwMin32Fx2: 1975 case Iop_Min8Ux8: case Iop_Min16Ux4: case Iop_Min32Ux2: 1976 case Iop_Min8Sx8: case Iop_Min16Sx4: case Iop_Min32Sx2: 1977 case Iop_PwMax8Ux8: case Iop_PwMax16Ux4: case Iop_PwMax32Ux2: 1978 case Iop_PwMax8Sx8: case Iop_PwMax16Sx4: case Iop_PwMax32Sx2: 1979 case Iop_PwMin8Ux8: case Iop_PwMin16Ux4: case Iop_PwMin32Ux2: 1980 case Iop_PwMin8Sx8: case Iop_PwMin16Sx4: case Iop_PwMin32Sx2: 1981 case Iop_Mul8x8: case Iop_Mul16x4: case Iop_Mul32x2: 1982 case Iop_Mul32Fx2: 1983 case Iop_PolynomialMul8x8: 1984 case Iop_MulHi16Sx4: case Iop_MulHi16Ux4: 1985 case Iop_QDMulHi16Sx4: case Iop_QDMulHi32Sx2: 1986 case Iop_QRDMulHi16Sx4: case Iop_QRDMulHi32Sx2: 1987 case Iop_QAdd8Sx8: case Iop_QAdd16Sx4: 1988 case Iop_QAdd32Sx2: case Iop_QAdd64Sx1: 1989 case Iop_QAdd8Ux8: case Iop_QAdd16Ux4: 1990 case Iop_QAdd32Ux2: case Iop_QAdd64Ux1: 1991 case Iop_PwAdd8x8: case Iop_PwAdd16x4: case Iop_PwAdd32x2: 1992 case Iop_PwAdd32Fx2: 1993 case Iop_QNarrow32Sx2: 1994 case Iop_QNarrow16Sx4: case Iop_QNarrow16Ux4: 1995 case Iop_Sub8x8: case Iop_Sub16x4: case Iop_Sub32x2: 1996 case Iop_QSub8Sx8: case Iop_QSub16Sx4: 1997 case Iop_QSub32Sx2: case Iop_QSub64Sx1: 1998 case Iop_QSub8Ux8: case Iop_QSub16Ux4: 1999 case Iop_QSub32Ux2: case Iop_QSub64Ux1: 2000 case Iop_Shl8x8: case Iop_Shl16x4: case Iop_Shl32x2: 2001 case Iop_Shr8x8: case Iop_Shr16x4: case Iop_Shr32x2: 2002 case Iop_Sar8x8: case Iop_Sar16x4: case Iop_Sar32x2: 2003 case Iop_Sal8x8: case Iop_Sal16x4: case Iop_Sal32x2: case Iop_Sal64x1: 2004 case Iop_QShl8x8: case Iop_QShl16x4: case Iop_QShl32x2: case Iop_QShl64x1: 2005 case Iop_QSal8x8: case Iop_QSal16x4: case Iop_QSal32x2: case Iop_QSal64x1: 2006 case Iop_Recps32Fx2: 2007 case Iop_Rsqrts32Fx2: 2008 BINARY(Ity_I64,Ity_I64, Ity_I64); 2009 2010 case Iop_ShlN32x2: case Iop_ShlN16x4: case Iop_ShlN8x8: 2011 case Iop_ShrN32x2: case Iop_ShrN16x4: case Iop_ShrN8x8: 2012 case Iop_SarN32x2: case Iop_SarN16x4: case Iop_SarN8x8: 2013 case Iop_QShlN8x8: case Iop_QShlN16x4: 2014 case Iop_QShlN32x2: case Iop_QShlN64x1: 2015 case Iop_QShlN8Sx8: case Iop_QShlN16Sx4: 2016 case Iop_QShlN32Sx2: case Iop_QShlN64Sx1: 2017 case Iop_QSalN8x8: case Iop_QSalN16x4: 2018 case Iop_QSalN32x2: case Iop_QSalN64x1: 2019 BINARY(Ity_I64,Ity_I8, Ity_I64); 2020 2021 case Iop_Shl8: case Iop_Shr8: case Iop_Sar8: 2022 BINARY(Ity_I8,Ity_I8, Ity_I8); 2023 case Iop_Shl16: case Iop_Shr16: case Iop_Sar16: 2024 BINARY(Ity_I16,Ity_I8, Ity_I16); 2025 case Iop_Shl32: case Iop_Shr32: case Iop_Sar32: 2026 BINARY(Ity_I32,Ity_I8, Ity_I32); 2027 case Iop_Shl64: case Iop_Shr64: case Iop_Sar64: 2028 BINARY(Ity_I64,Ity_I8, Ity_I64); 2029 2030 case Iop_Not8: 2031 UNARY(Ity_I8, Ity_I8); 2032 case Iop_Not16: 2033 UNARY(Ity_I16, Ity_I16); 2034 case Iop_Not32: 2035 case Iop_CmpNEZ16x2: case Iop_CmpNEZ8x4: 2036 UNARY(Ity_I32, Ity_I32); 2037 2038 case Iop_Not64: 2039 case Iop_CmpNEZ32x2: case Iop_CmpNEZ16x4: case Iop_CmpNEZ8x8: 2040 case Iop_Cnt8x8: 2041 case Iop_Clz8Sx8: case Iop_Clz16Sx4: case Iop_Clz32Sx2: 2042 case Iop_Cls8Sx8: case Iop_Cls16Sx4: case Iop_Cls32Sx2: 2043 case Iop_PwAddL8Ux8: case Iop_PwAddL16Ux4: case Iop_PwAddL32Ux2: 2044 case Iop_PwAddL8Sx8: case Iop_PwAddL16Sx4: case Iop_PwAddL32Sx2: 2045 case Iop_Reverse64_8x8: case Iop_Reverse64_16x4: case Iop_Reverse64_32x2: 2046 case Iop_Reverse32_8x8: case Iop_Reverse32_16x4: 2047 case Iop_Reverse16_8x8: 2048 case Iop_FtoI32Sx2_RZ: case Iop_FtoI32Ux2_RZ: 2049 case Iop_I32StoFx2: case Iop_I32UtoFx2: 2050 case Iop_Recip32x2: case Iop_Recip32Fx2: 2051 case Iop_Abs32Fx2: 2052 case Iop_Rsqrte32Fx2: 2053 case Iop_Rsqrte32x2: 2054 case Iop_Neg32Fx2: 2055 case Iop_Abs8x8: case Iop_Abs16x4: case Iop_Abs32x2: 2056 UNARY(Ity_I64, Ity_I64); 2057 2058 case Iop_CmpEQ8: case Iop_CmpNE8: 2059 case Iop_CasCmpEQ8: case Iop_CasCmpNE8: 2060 COMPARISON(Ity_I8); 2061 case Iop_CmpEQ16: case Iop_CmpNE16: 2062 case Iop_CasCmpEQ16: case Iop_CasCmpNE16: 2063 COMPARISON(Ity_I16); 2064 case Iop_CmpEQ32: case Iop_CmpNE32: 2065 case Iop_CasCmpEQ32: case Iop_CasCmpNE32: 2066 case Iop_CmpLT32S: case Iop_CmpLE32S: 2067 case Iop_CmpLT32U: case Iop_CmpLE32U: 2068 COMPARISON(Ity_I32); 2069 case Iop_CmpEQ64: case Iop_CmpNE64: 2070 case Iop_CasCmpEQ64: case Iop_CasCmpNE64: 2071 case Iop_CmpLT64S: case Iop_CmpLE64S: 2072 case Iop_CmpLT64U: case Iop_CmpLE64U: 2073 COMPARISON(Ity_I64); 2074 2075 case Iop_CmpNEZ8: UNARY_COMPARISON(Ity_I8); 2076 case Iop_CmpNEZ16: UNARY_COMPARISON(Ity_I16); 2077 case Iop_CmpNEZ32: UNARY_COMPARISON(Ity_I32); 2078 case Iop_CmpNEZ64: UNARY_COMPARISON(Ity_I64); 2079 2080 case Iop_Left8: UNARY(Ity_I8, Ity_I8); 2081 case Iop_Left16: UNARY(Ity_I16,Ity_I16); 2082 case Iop_CmpwNEZ32: case Iop_Left32: UNARY(Ity_I32,Ity_I32); 2083 case Iop_CmpwNEZ64: case Iop_Left64: UNARY(Ity_I64,Ity_I64); 2084 2085 case Iop_MullU8: case Iop_MullS8: 2086 BINARY(Ity_I8,Ity_I8, Ity_I16); 2087 case Iop_MullU16: case Iop_MullS16: 2088 BINARY(Ity_I16,Ity_I16, Ity_I32); 2089 case Iop_MullU32: case Iop_MullS32: 2090 BINARY(Ity_I32,Ity_I32, Ity_I64); 2091 case Iop_MullU64: case Iop_MullS64: 2092 BINARY(Ity_I64,Ity_I64, Ity_I128); 2093 2094 case Iop_Clz32: case Iop_Ctz32: 2095 UNARY(Ity_I32, Ity_I32); 2096 2097 case Iop_Clz64: case Iop_Ctz64: 2098 UNARY(Ity_I64, Ity_I64); 2099 2100 case Iop_DivU32: case Iop_DivS32: 2101 BINARY(Ity_I32,Ity_I32, Ity_I32); 2102 2103 case Iop_DivU64: case Iop_DivS64: 2104 BINARY(Ity_I64,Ity_I64, Ity_I64); 2105 2106 case Iop_DivModU64to32: case Iop_DivModS64to32: 2107 BINARY(Ity_I64,Ity_I32, Ity_I64); 2108 2109 case Iop_DivModU128to64: case Iop_DivModS128to64: 2110 BINARY(Ity_I128,Ity_I64, Ity_I128); 2111 2112 case Iop_16HIto8: case Iop_16to8: 2113 UNARY(Ity_I16, Ity_I8); 2114 case Iop_8HLto16: 2115 BINARY(Ity_I8,Ity_I8, Ity_I16); 2116 2117 case Iop_32HIto16: case Iop_32to16: 2118 UNARY(Ity_I32, Ity_I16); 2119 case Iop_16HLto32: 2120 BINARY(Ity_I16,Ity_I16, Ity_I32); 2121 2122 case Iop_64HIto32: case Iop_64to32: 2123 UNARY(Ity_I64, Ity_I32); 2124 case Iop_32HLto64: 2125 BINARY(Ity_I32,Ity_I32, Ity_I64); 2126 2127 case Iop_128HIto64: case Iop_128to64: 2128 UNARY(Ity_I128, Ity_I64); 2129 case Iop_64HLto128: 2130 BINARY(Ity_I64,Ity_I64, Ity_I128); 2131 2132 case Iop_Not1: UNARY(Ity_I1, Ity_I1); 2133 case Iop_1Uto8: UNARY(Ity_I1, Ity_I8); 2134 case Iop_1Sto8: UNARY(Ity_I1, Ity_I8); 2135 case Iop_1Sto16: UNARY(Ity_I1, Ity_I16); 2136 case Iop_1Uto32: case Iop_1Sto32: UNARY(Ity_I1, Ity_I32); 2137 case Iop_1Sto64: case Iop_1Uto64: UNARY(Ity_I1, Ity_I64); 2138 case Iop_32to1: UNARY(Ity_I32, Ity_I1); 2139 case Iop_64to1: UNARY(Ity_I64, Ity_I1); 2140 2141 case Iop_8Uto32: case Iop_8Sto32: 2142 UNARY(Ity_I8, Ity_I32); 2143 2144 case Iop_8Uto16: case Iop_8Sto16: 2145 UNARY(Ity_I8, Ity_I16); 2146 2147 case Iop_16Uto32: case Iop_16Sto32: 2148 UNARY(Ity_I16, Ity_I32); 2149 2150 case Iop_32Sto64: case Iop_32Uto64: 2151 UNARY(Ity_I32, Ity_I64); 2152 2153 case Iop_8Uto64: case Iop_8Sto64: 2154 UNARY(Ity_I8, Ity_I64); 2155 2156 case Iop_16Uto64: case Iop_16Sto64: 2157 UNARY(Ity_I16, Ity_I64); 2158 case Iop_64to16: 2159 UNARY(Ity_I64, Ity_I16); 2160 2161 case Iop_32to8: UNARY(Ity_I32, Ity_I8); 2162 case Iop_64to8: UNARY(Ity_I64, Ity_I8); 2163 2164 case Iop_AddF64: case Iop_SubF64: 2165 case Iop_MulF64: case Iop_DivF64: 2166 case Iop_AddF64r32: case Iop_SubF64r32: 2167 case Iop_MulF64r32: case Iop_DivF64r32: 2168 TERNARY(ity_RMode,Ity_F64,Ity_F64, Ity_F64); 2169 2170 case Iop_AddF32: case Iop_SubF32: 2171 case Iop_MulF32: case Iop_DivF32: 2172 TERNARY(ity_RMode,Ity_F32,Ity_F32, Ity_F32); 2173 2174 case Iop_NegF64: case Iop_AbsF64: 2175 UNARY(Ity_F64, Ity_F64); 2176 2177 case Iop_NegF32: case Iop_AbsF32: 2178 UNARY(Ity_F32, Ity_F32); 2179 2180 case Iop_SqrtF64: 2181 case Iop_SqrtF64r32: 2182 BINARY(ity_RMode,Ity_F64, Ity_F64); 2183 2184 case Iop_SqrtF32: 2185 case Iop_RoundF32toInt: 2186 BINARY(ity_RMode,Ity_F32, Ity_F32); 2187 2188 case Iop_CmpF64: 2189 BINARY(Ity_F64,Ity_F64, Ity_I32); 2190 2191 case Iop_F64toI16S: BINARY(ity_RMode,Ity_F64, Ity_I16); 2192 case Iop_F64toI32S: BINARY(ity_RMode,Ity_F64, Ity_I32); 2193 case Iop_F64toI64S: BINARY(ity_RMode,Ity_F64, Ity_I64); 2194 2195 case Iop_F64toI32U: BINARY(ity_RMode,Ity_F64, Ity_I32); 2196 2197 case Iop_I16StoF64: UNARY(Ity_I16, Ity_F64); 2198 case Iop_I32StoF64: UNARY(Ity_I32, Ity_F64); 2199 case Iop_I64StoF64: BINARY(ity_RMode,Ity_I64, Ity_F64); 2200 2201 case Iop_I32UtoF64: UNARY(Ity_I32, Ity_F64); 2202 2203 case Iop_F32toF64: UNARY(Ity_F32, Ity_F64); 2204 case Iop_F64toF32: BINARY(ity_RMode,Ity_F64, Ity_F32); 2205 2206 case Iop_ReinterpI64asF64: UNARY(Ity_I64, Ity_F64); 2207 case Iop_ReinterpF64asI64: UNARY(Ity_F64, Ity_I64); 2208 case Iop_ReinterpI32asF32: UNARY(Ity_I32, Ity_F32); 2209 case Iop_ReinterpF32asI32: UNARY(Ity_F32, Ity_I32); 2210 2211 case Iop_AtanF64: case Iop_Yl2xF64: case Iop_Yl2xp1F64: 2212 case Iop_ScaleF64: case Iop_PRemF64: case Iop_PRem1F64: 2213 TERNARY(ity_RMode,Ity_F64,Ity_F64, Ity_F64); 2214 2215 case Iop_PRemC3210F64: case Iop_PRem1C3210F64: 2216 TERNARY(ity_RMode,Ity_F64,Ity_F64, Ity_I32); 2217 2218 case Iop_SinF64: case Iop_CosF64: case Iop_TanF64: 2219 case Iop_2xm1F64: 2220 case Iop_RoundF64toInt: BINARY(ity_RMode,Ity_F64, Ity_F64); 2221 2222 case Iop_MAddF64: case Iop_MSubF64: 2223 case Iop_MAddF64r32: case Iop_MSubF64r32: 2224 QUATERNARY(ity_RMode,Ity_F64,Ity_F64,Ity_F64, Ity_F64); 2225 2226 case Iop_Est5FRSqrt: 2227 case Iop_RoundF64toF64_NEAREST: case Iop_RoundF64toF64_NegINF: 2228 case Iop_RoundF64toF64_PosINF: case Iop_RoundF64toF64_ZERO: 2229 UNARY(Ity_F64, Ity_F64); 2230 case Iop_RoundF64toF32: 2231 BINARY(ity_RMode,Ity_F64, Ity_F64); 2232 case Iop_CalcFPRF: 2233 UNARY(Ity_F64, Ity_I32); 2234 case Iop_TruncF64asF32: 2235 UNARY(Ity_F64, Ity_F32); 2236 2237 case Iop_I32UtoFx4: 2238 case Iop_I32StoFx4: 2239 case Iop_QFtoI32Ux4_RZ: 2240 case Iop_QFtoI32Sx4_RZ: 2241 case Iop_FtoI32Ux4_RZ: 2242 case Iop_FtoI32Sx4_RZ: 2243 case Iop_RoundF32x4_RM: 2244 case Iop_RoundF32x4_RP: 2245 case Iop_RoundF32x4_RN: 2246 case Iop_RoundF32x4_RZ: 2247 case Iop_Abs32Fx4: 2248 case Iop_Rsqrte32Fx4: 2249 case Iop_Rsqrte32x4: 2250 UNARY(Ity_V128, Ity_V128); 2251 2252 case Iop_64HLtoV128: BINARY(Ity_I64,Ity_I64, Ity_V128); 2253 case Iop_V128to64: case Iop_V128HIto64: 2254 case Iop_Shorten16x8: case Iop_Shorten32x4: case Iop_Shorten64x2: 2255 case Iop_QShortenU16Ux8: case Iop_QShortenU32Ux4: case Iop_QShortenU64Ux2: 2256 case Iop_QShortenS16Sx8: case Iop_QShortenS32Sx4: case Iop_QShortenS64Sx2: 2257 case Iop_QShortenU16Sx8: case Iop_QShortenU32Sx4: case Iop_QShortenU64Sx2: 2258 case Iop_F32toF16x4: 2259 UNARY(Ity_V128, Ity_I64); 2260 2261 case Iop_Longen8Ux8: case Iop_Longen16Ux4: case Iop_Longen32Ux2: 2262 case Iop_Longen8Sx8: case Iop_Longen16Sx4: case Iop_Longen32Sx2: 2263 case Iop_F16toF32x4: 2264 UNARY(Ity_I64, Ity_V128); 2265 2266 case Iop_V128to32: UNARY(Ity_V128, Ity_I32); 2267 case Iop_32UtoV128: UNARY(Ity_I32, Ity_V128); 2268 case Iop_64UtoV128: UNARY(Ity_I64, Ity_V128); 2269 case Iop_SetV128lo32: BINARY(Ity_V128,Ity_I32, Ity_V128); 2270 case Iop_SetV128lo64: BINARY(Ity_V128,Ity_I64, Ity_V128); 2271 2272 case Iop_Dup8x16: UNARY(Ity_I8, Ity_V128); 2273 case Iop_Dup16x8: UNARY(Ity_I16, Ity_V128); 2274 case Iop_Dup32x4: UNARY(Ity_I32, Ity_V128); 2275 case Iop_Dup8x8: UNARY(Ity_I8, Ity_I64); 2276 case Iop_Dup16x4: UNARY(Ity_I16, Ity_I64); 2277 case Iop_Dup32x2: UNARY(Ity_I32, Ity_I64); 2278 2279 case Iop_CmpEQ32Fx4: case Iop_CmpLT32Fx4: 2280 case Iop_CmpEQ64Fx2: case Iop_CmpLT64Fx2: 2281 case Iop_CmpLE32Fx4: case Iop_CmpUN32Fx4: 2282 case Iop_CmpLE64Fx2: case Iop_CmpUN64Fx2: 2283 case Iop_CmpGT32Fx4: case Iop_CmpGE32Fx4: 2284 case Iop_CmpEQ32F0x4: case Iop_CmpLT32F0x4: 2285 case Iop_CmpEQ64F0x2: case Iop_CmpLT64F0x2: 2286 case Iop_CmpLE32F0x4: case Iop_CmpUN32F0x4: 2287 case Iop_CmpLE64F0x2: case Iop_CmpUN64F0x2: 2288 case Iop_Add32Fx4: case Iop_Add32F0x4: 2289 case Iop_Add64Fx2: case Iop_Add64F0x2: 2290 case Iop_Div32Fx4: case Iop_Div32F0x4: 2291 case Iop_Div64Fx2: case Iop_Div64F0x2: 2292 case Iop_Max32Fx4: case Iop_Max32F0x4: 2293 case Iop_PwMax32Fx4: case Iop_PwMin32Fx4: 2294 case Iop_Max64Fx2: case Iop_Max64F0x2: 2295 case Iop_Min32Fx4: case Iop_Min32F0x4: 2296 case Iop_Min64Fx2: case Iop_Min64F0x2: 2297 case Iop_Mul32Fx4: case Iop_Mul32F0x4: 2298 case Iop_Mul64Fx2: case Iop_Mul64F0x2: 2299 case Iop_Sub32Fx4: case Iop_Sub32F0x4: 2300 case Iop_Sub64Fx2: case Iop_Sub64F0x2: 2301 case Iop_AndV128: case Iop_OrV128: case Iop_XorV128: 2302 case Iop_Add8x16: case Iop_Add16x8: 2303 case Iop_Add32x4: case Iop_Add64x2: 2304 case Iop_QAdd8Ux16: case Iop_QAdd16Ux8: 2305 case Iop_QAdd32Ux4: //case Iop_QAdd64Ux2: 2306 case Iop_QAdd8Sx16: case Iop_QAdd16Sx8: 2307 case Iop_QAdd32Sx4: case Iop_QAdd64Sx2: 2308 case Iop_PwAdd8x16: case Iop_PwAdd16x8: case Iop_PwAdd32x4: 2309 case Iop_Sub8x16: case Iop_Sub16x8: 2310 case Iop_Sub32x4: case Iop_Sub64x2: 2311 case Iop_QSub8Ux16: case Iop_QSub16Ux8: 2312 case Iop_QSub32Ux4: //case Iop_QSub64Ux2: 2313 case Iop_QSub8Sx16: case Iop_QSub16Sx8: 2314 case Iop_QSub32Sx4: case Iop_QSub64Sx2: 2315 case Iop_Mul8x16: case Iop_Mul16x8: case Iop_Mul32x4: 2316 case Iop_PolynomialMul8x16: 2317 case Iop_MulHi16Ux8: case Iop_MulHi32Ux4: 2318 case Iop_MulHi16Sx8: case Iop_MulHi32Sx4: 2319 case Iop_QDMulHi16Sx8: case Iop_QDMulHi32Sx4: 2320 case Iop_QRDMulHi16Sx8: case Iop_QRDMulHi32Sx4: 2321 case Iop_MullEven8Ux16: case Iop_MullEven16Ux8: 2322 case Iop_MullEven8Sx16: case Iop_MullEven16Sx8: 2323 case Iop_Avg8Ux16: case Iop_Avg16Ux8: case Iop_Avg32Ux4: 2324 case Iop_Avg8Sx16: case Iop_Avg16Sx8: case Iop_Avg32Sx4: 2325 case Iop_Max8Sx16: case Iop_Max16Sx8: case Iop_Max32Sx4: 2326 case Iop_Max8Ux16: case Iop_Max16Ux8: case Iop_Max32Ux4: 2327 case Iop_Min8Sx16: case Iop_Min16Sx8: case Iop_Min32Sx4: 2328 case Iop_Min8Ux16: case Iop_Min16Ux8: case Iop_Min32Ux4: 2329 case Iop_CmpEQ8x16: case Iop_CmpEQ16x8: case Iop_CmpEQ32x4: 2330 case Iop_CmpGT8Sx16: case Iop_CmpGT16Sx8: case Iop_CmpGT32Sx4: 2331 case Iop_CmpGT64Sx2: 2332 case Iop_CmpGT8Ux16: case Iop_CmpGT16Ux8: case Iop_CmpGT32Ux4: 2333 case Iop_Shl8x16: case Iop_Shl16x8: case Iop_Shl32x4: case Iop_Shl64x2: 2334 case Iop_QShl8x16: case Iop_QShl16x8: case Iop_QShl32x4: case Iop_QShl64x2: 2335 case Iop_QSal8x16: case Iop_QSal16x8: case Iop_QSal32x4: case Iop_QSal64x2: 2336 case Iop_Shr8x16: case Iop_Shr16x8: case Iop_Shr32x4: case Iop_Shr64x2: 2337 case Iop_Sar8x16: case Iop_Sar16x8: case Iop_Sar32x4: case Iop_Sar64x2: 2338 case Iop_Sal8x16: case Iop_Sal16x8: case Iop_Sal32x4: case Iop_Sal64x2: 2339 case Iop_Rol8x16: case Iop_Rol16x8: case Iop_Rol32x4: 2340 case Iop_QNarrow16Ux8: case Iop_QNarrow32Ux4: 2341 case Iop_QNarrow16Sx8: case Iop_QNarrow32Sx4: 2342 case Iop_Narrow16x8: case Iop_Narrow32x4: 2343 case Iop_InterleaveHI8x16: case Iop_InterleaveHI16x8: 2344 case Iop_InterleaveHI32x4: case Iop_InterleaveHI64x2: 2345 case Iop_InterleaveLO8x16: case Iop_InterleaveLO16x8: 2346 case Iop_InterleaveLO32x4: case Iop_InterleaveLO64x2: 2347 case Iop_CatOddLanes8x16: case Iop_CatEvenLanes8x16: 2348 case Iop_CatOddLanes16x8: case Iop_CatEvenLanes16x8: 2349 case Iop_CatOddLanes32x4: case Iop_CatEvenLanes32x4: 2350 case Iop_InterleaveOddLanes8x16: case Iop_InterleaveEvenLanes8x16: 2351 case Iop_InterleaveOddLanes16x8: case Iop_InterleaveEvenLanes16x8: 2352 case Iop_InterleaveOddLanes32x4: case Iop_InterleaveEvenLanes32x4: 2353 case Iop_Perm8x16: 2354 case Iop_Recps32Fx4: 2355 case Iop_Rsqrts32Fx4: 2356 BINARY(Ity_V128,Ity_V128, Ity_V128); 2357 2358 case Iop_PolynomialMull8x8: 2359 case Iop_Mull8Ux8: case Iop_Mull8Sx8: 2360 case Iop_Mull16Ux4: case Iop_Mull16Sx4: 2361 case Iop_Mull32Ux2: case Iop_Mull32Sx2: 2362 BINARY(Ity_I64, Ity_I64, Ity_V128); 2363 2364 case Iop_NotV128: 2365 case Iop_Recip32Fx4: case Iop_Recip32F0x4: 2366 case Iop_Recip32x4: 2367 case Iop_Recip64Fx2: case Iop_Recip64F0x2: 2368 case Iop_RSqrt32Fx4: case Iop_RSqrt32F0x4: 2369 case Iop_RSqrt64Fx2: case Iop_RSqrt64F0x2: 2370 case Iop_Sqrt32Fx4: case Iop_Sqrt32F0x4: 2371 case Iop_Sqrt64Fx2: case Iop_Sqrt64F0x2: 2372 case Iop_CmpNEZ8x16: case Iop_CmpNEZ16x8: 2373 case Iop_CmpNEZ32x4: case Iop_CmpNEZ64x2: 2374 case Iop_Cnt8x16: 2375 case Iop_Clz8Sx16: case Iop_Clz16Sx8: case Iop_Clz32Sx4: 2376 case Iop_Cls8Sx16: case Iop_Cls16Sx8: case Iop_Cls32Sx4: 2377 case Iop_PwAddL8Ux16: case Iop_PwAddL16Ux8: case Iop_PwAddL32Ux4: 2378 case Iop_PwAddL8Sx16: case Iop_PwAddL16Sx8: case Iop_PwAddL32Sx4: 2379 case Iop_Reverse64_8x16: case Iop_Reverse64_16x8: case Iop_Reverse64_32x4: 2380 case Iop_Reverse32_8x16: case Iop_Reverse32_16x8: 2381 case Iop_Reverse16_8x16: 2382 case Iop_Neg32Fx4: 2383 case Iop_Abs8x16: case Iop_Abs16x8: case Iop_Abs32x4: 2384 UNARY(Ity_V128, Ity_V128); 2385 2386 case Iop_ShlV128: case Iop_ShrV128: 2387 case Iop_ShlN8x16: case Iop_ShlN16x8: 2388 case Iop_ShlN32x4: case Iop_ShlN64x2: 2389 case Iop_ShrN8x16: case Iop_ShrN16x8: 2390 case Iop_ShrN32x4: case Iop_ShrN64x2: 2391 case Iop_SarN8x16: case Iop_SarN16x8: 2392 case Iop_SarN32x4: case Iop_SarN64x2: 2393 case Iop_QShlN8x16: case Iop_QShlN16x8: 2394 case Iop_QShlN32x4: case Iop_QShlN64x2: 2395 case Iop_QShlN8Sx16: case Iop_QShlN16Sx8: 2396 case Iop_QShlN32Sx4: case Iop_QShlN64Sx2: 2397 case Iop_QSalN8x16: case Iop_QSalN16x8: 2398 case Iop_QSalN32x4: case Iop_QSalN64x2: 2399 BINARY(Ity_V128,Ity_I8, Ity_V128); 2400 2401 case Iop_F32ToFixed32Ux4_RZ: 2402 case Iop_F32ToFixed32Sx4_RZ: 2403 case Iop_Fixed32UToF32x4_RN: 2404 case Iop_Fixed32SToF32x4_RN: 2405 BINARY(Ity_V128, Ity_I8, Ity_V128); 2406 2407 case Iop_F32ToFixed32Ux2_RZ: 2408 case Iop_F32ToFixed32Sx2_RZ: 2409 case Iop_Fixed32UToF32x2_RN: 2410 case Iop_Fixed32SToF32x2_RN: 2411 BINARY(Ity_I64, Ity_I8, Ity_I64); 2412 2413 case Iop_GetElem8x16: 2414 BINARY(Ity_V128, Ity_I8, Ity_I8); 2415 case Iop_GetElem16x8: 2416 BINARY(Ity_V128, Ity_I8, Ity_I16); 2417 case Iop_GetElem32x4: 2418 BINARY(Ity_V128, Ity_I8, Ity_I32); 2419 case Iop_GetElem64x2: 2420 BINARY(Ity_V128, Ity_I8, Ity_I64); 2421 case Iop_GetElem8x8: 2422 BINARY(Ity_I64, Ity_I8, Ity_I8); 2423 case Iop_GetElem16x4: 2424 BINARY(Ity_I64, Ity_I8, Ity_I16); 2425 case Iop_GetElem32x2: 2426 BINARY(Ity_I64, Ity_I8, Ity_I32); 2427 case Iop_SetElem8x8: 2428 TERNARY(Ity_I64, Ity_I8, Ity_I8, Ity_I64); 2429 case Iop_SetElem16x4: 2430 TERNARY(Ity_I64, Ity_I8, Ity_I16, Ity_I64); 2431 case Iop_SetElem32x2: 2432 TERNARY(Ity_I64, Ity_I8, Ity_I32, Ity_I64); 2433 2434 case Iop_Extract64: 2435 TERNARY(Ity_I64, Ity_I64, Ity_I8, Ity_I64); 2436 case Iop_ExtractV128: 2437 TERNARY(Ity_V128, Ity_V128, Ity_I8, Ity_V128); 2438 2439 case Iop_QDMulLong16Sx4: case Iop_QDMulLong32Sx2: 2440 BINARY(Ity_I64, Ity_I64, Ity_V128); 2441 2442 default: 2443 ppIROp(op); 2444 vpanic("typeOfPrimop"); 2445 } 2446 # undef UNARY 2447 # undef BINARY 2448 # undef TERNARY 2449 # undef COMPARISON 2450 # undef UNARY_COMPARISON 2451 } 2452 2453 2454 /*---------------------------------------------------------------*/ 2455 /*--- Helper functions for the IR -- IR Basic Blocks ---*/ 2456 /*---------------------------------------------------------------*/ 2457 2458 void addStmtToIRSB ( IRSB* bb, IRStmt* st ) 2459 { 2460 Int i; 2461 if (bb->stmts_used == bb->stmts_size) { 2462 IRStmt** stmts2 = LibVEX_Alloc(2 * bb->stmts_size * sizeof(IRStmt*)); 2463 for (i = 0; i < bb->stmts_size; i++) 2464 stmts2[i] = bb->stmts[i]; 2465 bb->stmts = stmts2; 2466 bb->stmts_size *= 2; 2467 } 2468 vassert(bb->stmts_used < bb->stmts_size); 2469 bb->stmts[bb->stmts_used] = st; 2470 bb->stmts_used++; 2471 } 2472 2473 2474 /*---------------------------------------------------------------*/ 2475 /*--- Helper functions for the IR -- IR Type Environments ---*/ 2476 /*---------------------------------------------------------------*/ 2477 2478 /* Allocate a new IRTemp, given its type. */ 2479 2480 IRTemp newIRTemp ( IRTypeEnv* env, IRType ty ) 2481 { 2482 vassert(env); 2483 vassert(env->types_used >= 0); 2484 vassert(env->types_size >= 0); 2485 vassert(env->types_used <= env->types_size); 2486 if (env->types_used < env->types_size) { 2487 env->types[env->types_used] = ty; 2488 return env->types_used++; 2489 } else { 2490 Int i; 2491 Int new_size = env->types_size==0 ? 8 : 2*env->types_size; 2492 IRType* new_types 2493 = LibVEX_Alloc(new_size * sizeof(IRType)); 2494 for (i = 0; i < env->types_used; i++) 2495 new_types[i] = env->types[i]; 2496 env->types = new_types; 2497 env->types_size = new_size; 2498 return newIRTemp(env, ty); 2499 } 2500 } 2501 2502 2503 /*---------------------------------------------------------------*/ 2504 /*--- Helper functions for the IR -- finding types of exprs ---*/ 2505 /*---------------------------------------------------------------*/ 2506 2507 inline 2508 IRType typeOfIRTemp ( IRTypeEnv* env, IRTemp tmp ) 2509 { 2510 vassert(tmp >= 0); 2511 vassert(tmp < env->types_used); 2512 return env->types[tmp]; 2513 } 2514 2515 2516 IRType typeOfIRConst ( IRConst* con ) 2517 { 2518 switch (con->tag) { 2519 case Ico_U1: return Ity_I1; 2520 case Ico_U8: return Ity_I8; 2521 case Ico_U16: return Ity_I16; 2522 case Ico_U32: return Ity_I32; 2523 case Ico_U64: return Ity_I64; 2524 case Ico_F64: return Ity_F64; 2525 case Ico_F64i: return Ity_F64; 2526 case Ico_V128: return Ity_V128; 2527 default: vpanic("typeOfIRConst"); 2528 } 2529 } 2530 2531 IRType typeOfIRExpr ( IRTypeEnv* tyenv, IRExpr* e ) 2532 { 2533 IRType t_dst, t_arg1, t_arg2, t_arg3, t_arg4; 2534 start: 2535 switch (e->tag) { 2536 case Iex_Load: 2537 return e->Iex.Load.ty; 2538 case Iex_Get: 2539 return e->Iex.Get.ty; 2540 case Iex_GetI: 2541 return e->Iex.GetI.descr->elemTy; 2542 case Iex_RdTmp: 2543 return typeOfIRTemp(tyenv, e->Iex.RdTmp.tmp); 2544 case Iex_Const: 2545 return typeOfIRConst(e->Iex.Const.con); 2546 case Iex_Qop: 2547 typeOfPrimop(e->Iex.Qop.op, 2548 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4); 2549 return t_dst; 2550 case Iex_Triop: 2551 typeOfPrimop(e->Iex.Triop.op, 2552 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4); 2553 return t_dst; 2554 case Iex_Binop: 2555 typeOfPrimop(e->Iex.Binop.op, 2556 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4); 2557 return t_dst; 2558 case Iex_Unop: 2559 typeOfPrimop(e->Iex.Unop.op, 2560 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4); 2561 return t_dst; 2562 case Iex_CCall: 2563 return e->Iex.CCall.retty; 2564 case Iex_Mux0X: 2565 e = e->Iex.Mux0X.expr0; 2566 goto start; 2567 /* return typeOfIRExpr(tyenv, e->Iex.Mux0X.expr0); */ 2568 case Iex_Binder: 2569 vpanic("typeOfIRExpr: Binder is not a valid expression"); 2570 default: 2571 ppIRExpr(e); 2572 vpanic("typeOfIRExpr"); 2573 } 2574 } 2575 2576 /* Is this any value actually in the enumeration 'IRType' ? */ 2577 Bool isPlausibleIRType ( IRType ty ) 2578 { 2579 switch (ty) { 2580 case Ity_INVALID: case Ity_I1: 2581 case Ity_I8: case Ity_I16: case Ity_I32: 2582 case Ity_I64: case Ity_I128: 2583 case Ity_F32: case Ity_F64: 2584 case Ity_V128: 2585 return True; 2586 default: 2587 return False; 2588 } 2589 } 2590 2591 2592 /*---------------------------------------------------------------*/ 2593 /*--- Sanity checking -- FLATNESS ---*/ 2594 /*---------------------------------------------------------------*/ 2595 2596 /* Check that the canonical flatness constraints hold on an 2597 IRStmt. The only place where any expression is allowed to be 2598 non-atomic is the RHS of IRStmt_Tmp. */ 2599 2600 /* Relies on: 2601 inline static Bool isAtom ( IRExpr* e ) { 2602 return e->tag == Iex_RdTmp || e->tag == Iex_Const; 2603 } 2604 */ 2605 2606 Bool isFlatIRStmt ( IRStmt* st ) 2607 { 2608 Int i; 2609 IRExpr* e; 2610 IRDirty* di; 2611 IRCAS* cas; 2612 2613 switch (st->tag) { 2614 case Ist_AbiHint: 2615 return isIRAtom(st->Ist.AbiHint.base) 2616 && isIRAtom(st->Ist.AbiHint.nia); 2617 case Ist_Put: 2618 return isIRAtom(st->Ist.Put.data); 2619 case Ist_PutI: 2620 return toBool( isIRAtom(st->Ist.PutI.ix) 2621 && isIRAtom(st->Ist.PutI.data) ); 2622 case Ist_WrTmp: 2623 /* This is the only interesting case. The RHS can be any 2624 expression, *but* all its subexpressions *must* be 2625 atoms. */ 2626 e = st->Ist.WrTmp.data; 2627 switch (e->tag) { 2628 case Iex_Binder: return True; 2629 case Iex_Get: return True; 2630 case Iex_GetI: return isIRAtom(e->Iex.GetI.ix); 2631 case Iex_RdTmp: return True; 2632 case Iex_Qop: return toBool( 2633 isIRAtom(e->Iex.Qop.arg1) 2634 && isIRAtom(e->Iex.Qop.arg2) 2635 && isIRAtom(e->Iex.Qop.arg3) 2636 && isIRAtom(e->Iex.Qop.arg4)); 2637 case Iex_Triop: return toBool( 2638 isIRAtom(e->Iex.Triop.arg1) 2639 && isIRAtom(e->Iex.Triop.arg2) 2640 && isIRAtom(e->Iex.Triop.arg3)); 2641 case Iex_Binop: return toBool( 2642 isIRAtom(e->Iex.Binop.arg1) 2643 && isIRAtom(e->Iex.Binop.arg2)); 2644 case Iex_Unop: return isIRAtom(e->Iex.Unop.arg); 2645 case Iex_Load: return isIRAtom(e->Iex.Load.addr); 2646 case Iex_Const: return True; 2647 case Iex_CCall: for (i = 0; e->Iex.CCall.args[i]; i++) 2648 if (!isIRAtom(e->Iex.CCall.args[i])) 2649 return False; 2650 return True; 2651 case Iex_Mux0X: return toBool ( 2652 isIRAtom(e->Iex.Mux0X.cond) 2653 && isIRAtom(e->Iex.Mux0X.expr0) 2654 && isIRAtom(e->Iex.Mux0X.exprX)); 2655 default: vpanic("isFlatIRStmt(e)"); 2656 } 2657 /*notreached*/ 2658 vassert(0); 2659 case Ist_Store: 2660 return toBool( isIRAtom(st->Ist.Store.addr) 2661 && isIRAtom(st->Ist.Store.data) ); 2662 case Ist_CAS: 2663 cas = st->Ist.CAS.details; 2664 return toBool( isIRAtom(cas->addr) 2665 && (cas->expdHi ? isIRAtom(cas->expdHi) : True) 2666 && isIRAtom(cas->expdLo) 2667 && (cas->dataHi ? isIRAtom(cas->dataHi) : True) 2668 && isIRAtom(cas->dataLo) ); 2669 case Ist_LLSC: 2670 return toBool( isIRAtom(st->Ist.LLSC.addr) 2671 && (st->Ist.LLSC.storedata 2672 ? isIRAtom(st->Ist.LLSC.storedata) : True) ); 2673 case Ist_Dirty: 2674 di = st->Ist.Dirty.details; 2675 if (!isIRAtom(di->guard)) 2676 return False; 2677 for (i = 0; di->args[i]; i++) 2678 if (!isIRAtom(di->args[i])) 2679 return False; 2680 if (di->mAddr && !isIRAtom(di->mAddr)) 2681 return False; 2682 return True; 2683 case Ist_NoOp: 2684 case Ist_IMark: 2685 case Ist_MBE: 2686 return True; 2687 case Ist_Exit: 2688 return isIRAtom(st->Ist.Exit.guard); 2689 default: 2690 vpanic("isFlatIRStmt(st)"); 2691 } 2692 } 2693 2694 2695 /*---------------------------------------------------------------*/ 2696 /*--- Sanity checking ---*/ 2697 /*---------------------------------------------------------------*/ 2698 2699 /* Checks: 2700 2701 Everything is type-consistent. No ill-typed anything. 2702 The target address at the end of the BB is a 32- or 64- 2703 bit expression, depending on the guest's word size. 2704 2705 Each temp is assigned only once, before its uses. 2706 */ 2707 2708 static inline Int countArgs ( IRExpr** args ) 2709 { 2710 Int i; 2711 for (i = 0; args[i]; i++) 2712 ; 2713 return i; 2714 } 2715 2716 static 2717 __attribute((noreturn)) 2718 void sanityCheckFail ( IRSB* bb, IRStmt* stmt, HChar* what ) 2719 { 2720 vex_printf("\nIR SANITY CHECK FAILURE\n\n"); 2721 ppIRSB(bb); 2722 if (stmt) { 2723 vex_printf("\nIN STATEMENT:\n\n"); 2724 ppIRStmt(stmt); 2725 } 2726 vex_printf("\n\nERROR = %s\n\n", what ); 2727 vpanic("sanityCheckFail: exiting due to bad IR"); 2728 } 2729 2730 static Bool saneIRRegArray ( IRRegArray* arr ) 2731 { 2732 if (arr->base < 0 || arr->base > 10000 /* somewhat arbitrary */) 2733 return False; 2734 if (arr->elemTy == Ity_I1) 2735 return False; 2736 if (arr->nElems <= 0 || arr->nElems > 500 /* somewhat arbitrary */) 2737 return False; 2738 return True; 2739 } 2740 2741 static Bool saneIRCallee ( IRCallee* cee ) 2742 { 2743 if (cee->name == NULL) 2744 return False; 2745 if (cee->addr == 0) 2746 return False; 2747 if (cee->regparms < 0 || cee->regparms > 3) 2748 return False; 2749 return True; 2750 } 2751 2752 static Bool saneIRConst ( IRConst* con ) 2753 { 2754 switch (con->tag) { 2755 case Ico_U1: 2756 return toBool( con->Ico.U1 == True || con->Ico.U1 == False ); 2757 default: 2758 /* Is there anything we can meaningfully check? I don't 2759 think so. */ 2760 return True; 2761 } 2762 } 2763 2764 /* Traverse a Stmt/Expr, inspecting IRTemp uses. Report any out of 2765 range ones. Report any which are read and for which the current 2766 def_count is zero. */ 2767 2768 static 2769 void useBeforeDef_Temp ( IRSB* bb, IRStmt* stmt, IRTemp tmp, Int* def_counts ) 2770 { 2771 if (tmp < 0 || tmp >= bb->tyenv->types_used) 2772 sanityCheckFail(bb,stmt, "out of range Temp in IRExpr"); 2773 if (def_counts[tmp] < 1) 2774 sanityCheckFail(bb,stmt, "IRTemp use before def in IRExpr"); 2775 } 2776 2777 static 2778 void useBeforeDef_Expr ( IRSB* bb, IRStmt* stmt, IRExpr* expr, Int* def_counts ) 2779 { 2780 Int i; 2781 switch (expr->tag) { 2782 case Iex_Get: 2783 break; 2784 case Iex_GetI: 2785 useBeforeDef_Expr(bb,stmt,expr->Iex.GetI.ix,def_counts); 2786 break; 2787 case Iex_RdTmp: 2788 useBeforeDef_Temp(bb,stmt,expr->Iex.RdTmp.tmp,def_counts); 2789 break; 2790 case Iex_Qop: 2791 useBeforeDef_Expr(bb,stmt,expr->Iex.Qop.arg1,def_counts); 2792 useBeforeDef_Expr(bb,stmt,expr->Iex.Qop.arg2,def_counts); 2793 useBeforeDef_Expr(bb,stmt,expr->Iex.Qop.arg3,def_counts); 2794 useBeforeDef_Expr(bb,stmt,expr->Iex.Qop.arg4,def_counts); 2795 break; 2796 case Iex_Triop: 2797 useBeforeDef_Expr(bb,stmt,expr->Iex.Triop.arg1,def_counts); 2798 useBeforeDef_Expr(bb,stmt,expr->Iex.Triop.arg2,def_counts); 2799 useBeforeDef_Expr(bb,stmt,expr->Iex.Triop.arg3,def_counts); 2800 break; 2801 case Iex_Binop: 2802 useBeforeDef_Expr(bb,stmt,expr->Iex.Binop.arg1,def_counts); 2803 useBeforeDef_Expr(bb,stmt,expr->Iex.Binop.arg2,def_counts); 2804 break; 2805 case Iex_Unop: 2806 useBeforeDef_Expr(bb,stmt,expr->Iex.Unop.arg,def_counts); 2807 break; 2808 case Iex_Load: 2809 useBeforeDef_Expr(bb,stmt,expr->Iex.Load.addr,def_counts); 2810 break; 2811 case Iex_Const: 2812 break; 2813 case Iex_CCall: 2814 for (i = 0; expr->Iex.CCall.args[i]; i++) 2815 useBeforeDef_Expr(bb,stmt,expr->Iex.CCall.args[i],def_counts); 2816 break; 2817 case Iex_Mux0X: 2818 useBeforeDef_Expr(bb,stmt,expr->Iex.Mux0X.cond,def_counts); 2819 useBeforeDef_Expr(bb,stmt,expr->Iex.Mux0X.expr0,def_counts); 2820 useBeforeDef_Expr(bb,stmt,expr->Iex.Mux0X.exprX,def_counts); 2821 break; 2822 default: 2823 vpanic("useBeforeDef_Expr"); 2824 } 2825 } 2826 2827 static 2828 void useBeforeDef_Stmt ( IRSB* bb, IRStmt* stmt, Int* def_counts ) 2829 { 2830 Int i; 2831 IRDirty* d; 2832 IRCAS* cas; 2833 switch (stmt->tag) { 2834 case Ist_IMark: 2835 break; 2836 case Ist_AbiHint: 2837 useBeforeDef_Expr(bb,stmt,stmt->Ist.AbiHint.base,def_counts); 2838 useBeforeDef_Expr(bb,stmt,stmt->Ist.AbiHint.nia,def_counts); 2839 break; 2840 case Ist_Put: 2841 useBeforeDef_Expr(bb,stmt,stmt->Ist.Put.data,def_counts); 2842 break; 2843 case Ist_PutI: 2844 useBeforeDef_Expr(bb,stmt,stmt->Ist.PutI.ix,def_counts); 2845 useBeforeDef_Expr(bb,stmt,stmt->Ist.PutI.data,def_counts); 2846 break; 2847 case Ist_WrTmp: 2848 useBeforeDef_Expr(bb,stmt,stmt->Ist.WrTmp.data,def_counts); 2849 break; 2850 case Ist_Store: 2851 useBeforeDef_Expr(bb,stmt,stmt->Ist.Store.addr,def_counts); 2852 useBeforeDef_Expr(bb,stmt,stmt->Ist.Store.data,def_counts); 2853 break; 2854 case Ist_CAS: 2855 cas = stmt->Ist.CAS.details; 2856 useBeforeDef_Expr(bb,stmt,cas->addr,def_counts); 2857 if (cas->expdHi) 2858 useBeforeDef_Expr(bb,stmt,cas->expdHi,def_counts); 2859 useBeforeDef_Expr(bb,stmt,cas->expdLo,def_counts); 2860 if (cas->dataHi) 2861 useBeforeDef_Expr(bb,stmt,cas->dataHi,def_counts); 2862 useBeforeDef_Expr(bb,stmt,cas->dataLo,def_counts); 2863 break; 2864 case Ist_LLSC: 2865 useBeforeDef_Expr(bb,stmt,stmt->Ist.LLSC.addr,def_counts); 2866 if (stmt->Ist.LLSC.storedata != NULL) 2867 useBeforeDef_Expr(bb,stmt,stmt->Ist.LLSC.storedata,def_counts); 2868 break; 2869 case Ist_Dirty: 2870 d = stmt->Ist.Dirty.details; 2871 for (i = 0; d->args[i] != NULL; i++) 2872 useBeforeDef_Expr(bb,stmt,d->args[i],def_counts); 2873 if (d->mFx != Ifx_None) 2874 useBeforeDef_Expr(bb,stmt,d->mAddr,def_counts); 2875 break; 2876 case Ist_NoOp: 2877 case Ist_MBE: 2878 break; 2879 case Ist_Exit: 2880 useBeforeDef_Expr(bb,stmt,stmt->Ist.Exit.guard,def_counts); 2881 break; 2882 default: 2883 vpanic("useBeforeDef_Stmt"); 2884 } 2885 } 2886 2887 static 2888 void tcExpr ( IRSB* bb, IRStmt* stmt, IRExpr* expr, IRType gWordTy ) 2889 { 2890 Int i; 2891 IRType t_dst, t_arg1, t_arg2, t_arg3, t_arg4; 2892 IRTypeEnv* tyenv = bb->tyenv; 2893 switch (expr->tag) { 2894 case Iex_Get: 2895 case Iex_RdTmp: 2896 break; 2897 case Iex_GetI: 2898 tcExpr(bb,stmt, expr->Iex.GetI.ix, gWordTy ); 2899 if (typeOfIRExpr(tyenv,expr->Iex.GetI.ix) != Ity_I32) 2900 sanityCheckFail(bb,stmt,"IRExpr.GetI.ix: not :: Ity_I32"); 2901 if (!saneIRRegArray(expr->Iex.GetI.descr)) 2902 sanityCheckFail(bb,stmt,"IRExpr.GetI.descr: invalid descr"); 2903 break; 2904 case Iex_Qop: { 2905 IRType ttarg1, ttarg2, ttarg3, ttarg4; 2906 tcExpr(bb,stmt, expr->Iex.Qop.arg1, gWordTy ); 2907 tcExpr(bb,stmt, expr->Iex.Qop.arg2, gWordTy ); 2908 tcExpr(bb,stmt, expr->Iex.Qop.arg3, gWordTy ); 2909 tcExpr(bb,stmt, expr->Iex.Qop.arg4, gWordTy ); 2910 typeOfPrimop(expr->Iex.Qop.op, 2911 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4); 2912 if (t_arg1 == Ity_INVALID || t_arg2 == Ity_INVALID 2913 || t_arg3 == Ity_INVALID || t_arg4 == Ity_INVALID) { 2914 vex_printf(" op name: " ); 2915 ppIROp(expr->Iex.Qop.op); 2916 vex_printf("\n"); 2917 sanityCheckFail(bb,stmt, 2918 "Iex.Qop: wrong arity op\n" 2919 "... name of op precedes BB printout\n"); 2920 } 2921 ttarg1 = typeOfIRExpr(tyenv, expr->Iex.Qop.arg1); 2922 ttarg2 = typeOfIRExpr(tyenv, expr->Iex.Qop.arg2); 2923 ttarg3 = typeOfIRExpr(tyenv, expr->Iex.Qop.arg3); 2924 ttarg4 = typeOfIRExpr(tyenv, expr->Iex.Qop.arg4); 2925 if (t_arg1 != ttarg1 || t_arg2 != ttarg2 2926 || t_arg3 != ttarg3 || t_arg4 != ttarg4) { 2927 vex_printf(" op name: "); 2928 ppIROp(expr->Iex.Qop.op); 2929 vex_printf("\n"); 2930 vex_printf(" op type is ("); 2931 ppIRType(t_arg1); 2932 vex_printf(","); 2933 ppIRType(t_arg2); 2934 vex_printf(","); 2935 ppIRType(t_arg3); 2936 vex_printf(","); 2937 ppIRType(t_arg4); 2938 vex_printf(") -> "); 2939 ppIRType (t_dst); 2940 vex_printf("\narg tys are ("); 2941 ppIRType(ttarg1); 2942 vex_printf(","); 2943 ppIRType(ttarg2); 2944 vex_printf(","); 2945 ppIRType(ttarg3); 2946 vex_printf(","); 2947 ppIRType(ttarg4); 2948 vex_printf(")\n"); 2949 sanityCheckFail(bb,stmt, 2950 "Iex.Qop: arg tys don't match op tys\n" 2951 "... additional details precede BB printout\n"); 2952 } 2953 break; 2954 } 2955 case Iex_Triop: { 2956 IRType ttarg1, ttarg2, ttarg3; 2957 tcExpr(bb,stmt, expr->Iex.Triop.arg1, gWordTy ); 2958 tcExpr(bb,stmt, expr->Iex.Triop.arg2, gWordTy ); 2959 tcExpr(bb,stmt, expr->Iex.Triop.arg3, gWordTy ); 2960 typeOfPrimop(expr->Iex.Triop.op, 2961 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4); 2962 if (t_arg1 == Ity_INVALID || t_arg2 == Ity_INVALID 2963 || t_arg3 == Ity_INVALID || t_arg4 != Ity_INVALID) { 2964 vex_printf(" op name: " ); 2965 ppIROp(expr->Iex.Triop.op); 2966 vex_printf("\n"); 2967 sanityCheckFail(bb,stmt, 2968 "Iex.Triop: wrong arity op\n" 2969 "... name of op precedes BB printout\n"); 2970 } 2971 ttarg1 = typeOfIRExpr(tyenv, expr->Iex.Triop.arg1); 2972 ttarg2 = typeOfIRExpr(tyenv, expr->Iex.Triop.arg2); 2973 ttarg3 = typeOfIRExpr(tyenv, expr->Iex.Triop.arg3); 2974 if (t_arg1 != ttarg1 || t_arg2 != ttarg2 || t_arg3 != ttarg3) { 2975 vex_printf(" op name: "); 2976 ppIROp(expr->Iex.Triop.op); 2977 vex_printf("\n"); 2978 vex_printf(" op type is ("); 2979 ppIRType(t_arg1); 2980 vex_printf(","); 2981 ppIRType(t_arg2); 2982 vex_printf(","); 2983 ppIRType(t_arg3); 2984 vex_printf(") -> "); 2985 ppIRType (t_dst); 2986 vex_printf("\narg tys are ("); 2987 ppIRType(ttarg1); 2988 vex_printf(","); 2989 ppIRType(ttarg2); 2990 vex_printf(","); 2991 ppIRType(ttarg3); 2992 vex_printf(")\n"); 2993 sanityCheckFail(bb,stmt, 2994 "Iex.Triop: arg tys don't match op tys\n" 2995 "... additional details precede BB printout\n"); 2996 } 2997 break; 2998 } 2999 case Iex_Binop: { 3000 IRType ttarg1, ttarg2; 3001 tcExpr(bb,stmt, expr->Iex.Binop.arg1, gWordTy ); 3002 tcExpr(bb,stmt, expr->Iex.Binop.arg2, gWordTy ); 3003 typeOfPrimop(expr->Iex.Binop.op, 3004 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4); 3005 if (t_arg1 == Ity_INVALID || t_arg2 == Ity_INVALID 3006 || t_arg3 != Ity_INVALID || t_arg4 != Ity_INVALID) { 3007 vex_printf(" op name: " ); 3008 ppIROp(expr->Iex.Binop.op); 3009 vex_printf("\n"); 3010 sanityCheckFail(bb,stmt, 3011 "Iex.Binop: wrong arity op\n" 3012 "... name of op precedes BB printout\n"); 3013 } 3014 ttarg1 = typeOfIRExpr(tyenv, expr->Iex.Binop.arg1); 3015 ttarg2 = typeOfIRExpr(tyenv, expr->Iex.Binop.arg2); 3016 if (t_arg1 != ttarg1 || t_arg2 != ttarg2) { 3017 vex_printf(" op name: "); 3018 ppIROp(expr->Iex.Binop.op); 3019 vex_printf("\n"); 3020 vex_printf(" op type is ("); 3021 ppIRType(t_arg1); 3022 vex_printf(","); 3023 ppIRType(t_arg2); 3024 vex_printf(") -> "); 3025 ppIRType (t_dst); 3026 vex_printf("\narg tys are ("); 3027 ppIRType(ttarg1); 3028 vex_printf(","); 3029 ppIRType(ttarg2); 3030 vex_printf(")\n"); 3031 sanityCheckFail(bb,stmt, 3032 "Iex.Binop: arg tys don't match op tys\n" 3033 "... additional details precede BB printout\n"); 3034 } 3035 break; 3036 } 3037 case Iex_Unop: 3038 tcExpr(bb,stmt, expr->Iex.Unop.arg, gWordTy ); 3039 typeOfPrimop(expr->Iex.Binop.op, 3040 &t_dst, &t_arg1, &t_arg2, &t_arg3, &t_arg4); 3041 if (t_arg1 == Ity_INVALID || t_arg2 != Ity_INVALID 3042 || t_arg3 != Ity_INVALID || t_arg4 != Ity_INVALID) 3043 sanityCheckFail(bb,stmt,"Iex.Unop: wrong arity op"); 3044 if (t_arg1 != typeOfIRExpr(tyenv, expr->Iex.Unop.arg)) 3045 sanityCheckFail(bb,stmt,"Iex.Unop: arg ty doesn't match op ty"); 3046 break; 3047 case Iex_Load: 3048 tcExpr(bb,stmt, expr->Iex.Load.addr, gWordTy); 3049 if (typeOfIRExpr(tyenv, expr->Iex.Load.addr) != gWordTy) 3050 sanityCheckFail(bb,stmt,"Iex.Load.addr: not :: guest word type"); 3051 if (expr->Iex.Load.end != Iend_LE && expr->Iex.Load.end != Iend_BE) 3052 sanityCheckFail(bb,stmt,"Iex.Load.end: bogus endianness"); 3053 break; 3054 case Iex_CCall: 3055 if (!saneIRCallee(expr->Iex.CCall.cee)) 3056 sanityCheckFail(bb,stmt,"Iex.CCall.cee: bad IRCallee"); 3057 if (expr->Iex.CCall.cee->regparms > countArgs(expr->Iex.CCall.args)) 3058 sanityCheckFail(bb,stmt,"Iex.CCall.cee: #regparms > #args"); 3059 for (i = 0; expr->Iex.CCall.args[i]; i++) { 3060 if (i >= 32) 3061 sanityCheckFail(bb,stmt,"Iex.CCall: > 32 args"); 3062 tcExpr(bb,stmt, expr->Iex.CCall.args[i], gWordTy); 3063 } 3064 if (expr->Iex.CCall.retty == Ity_I1) 3065 sanityCheckFail(bb,stmt,"Iex.CCall.retty: cannot return :: Ity_I1"); 3066 for (i = 0; expr->Iex.CCall.args[i]; i++) 3067 if (typeOfIRExpr(tyenv, expr->Iex.CCall.args[i]) == Ity_I1) 3068 sanityCheckFail(bb,stmt,"Iex.CCall.arg: arg :: Ity_I1"); 3069 break; 3070 case Iex_Const: 3071 if (!saneIRConst(expr->Iex.Const.con)) 3072 sanityCheckFail(bb,stmt,"Iex.Const.con: invalid const"); 3073 break; 3074 case Iex_Mux0X: 3075 tcExpr(bb,stmt, expr->Iex.Mux0X.cond, gWordTy); 3076 tcExpr(bb,stmt, expr->Iex.Mux0X.expr0, gWordTy); 3077 tcExpr(bb,stmt, expr->Iex.Mux0X.exprX, gWordTy); 3078 if (typeOfIRExpr(tyenv, expr->Iex.Mux0X.cond) != Ity_I8) 3079 sanityCheckFail(bb,stmt,"Iex.Mux0X.cond: cond :: Ity_I8"); 3080 if (typeOfIRExpr(tyenv, expr->Iex.Mux0X.expr0) 3081 != typeOfIRExpr(tyenv, expr->Iex.Mux0X.exprX)) 3082 sanityCheckFail(bb,stmt,"Iex.Mux0X: expr0/exprX mismatch"); 3083 break; 3084 default: 3085 vpanic("tcExpr"); 3086 } 3087 } 3088 3089 3090 static 3091 void tcStmt ( IRSB* bb, IRStmt* stmt, IRType gWordTy ) 3092 { 3093 Int i; 3094 IRDirty* d; 3095 IRCAS* cas; 3096 IRType tyExpd, tyData; 3097 IRTypeEnv* tyenv = bb->tyenv; 3098 switch (stmt->tag) { 3099 case Ist_IMark: 3100 /* Somewhat heuristic, but rule out totally implausible 3101 instruction sizes. */ 3102 if (stmt->Ist.IMark.len < 0 || stmt->Ist.IMark.len > 20) 3103 sanityCheckFail(bb,stmt,"IRStmt.IMark.len: implausible"); 3104 break; 3105 case Ist_AbiHint: 3106 if (typeOfIRExpr(tyenv, stmt->Ist.AbiHint.base) != gWordTy) 3107 sanityCheckFail(bb,stmt,"IRStmt.AbiHint.base: " 3108 "not :: guest word type"); 3109 if (typeOfIRExpr(tyenv, stmt->Ist.AbiHint.nia) != gWordTy) 3110 sanityCheckFail(bb,stmt,"IRStmt.AbiHint.nia: " 3111 "not :: guest word type"); 3112 break; 3113 case Ist_Put: 3114 tcExpr( bb, stmt, stmt->Ist.Put.data, gWordTy ); 3115 if (typeOfIRExpr(tyenv,stmt->Ist.Put.data) == Ity_I1) 3116 sanityCheckFail(bb,stmt,"IRStmt.Put.data: cannot Put :: Ity_I1"); 3117 break; 3118 case Ist_PutI: 3119 tcExpr( bb, stmt, stmt->Ist.PutI.data, gWordTy ); 3120 tcExpr( bb, stmt, stmt->Ist.PutI.ix, gWordTy ); 3121 if (typeOfIRExpr(tyenv,stmt->Ist.PutI.data) == Ity_I1) 3122 sanityCheckFail(bb,stmt,"IRStmt.PutI.data: cannot PutI :: Ity_I1"); 3123 if (typeOfIRExpr(tyenv,stmt->Ist.PutI.data) 3124 != stmt->Ist.PutI.descr->elemTy) 3125 sanityCheckFail(bb,stmt,"IRStmt.PutI.data: data ty != elem ty"); 3126 if (typeOfIRExpr(tyenv,stmt->Ist.PutI.ix) != Ity_I32) 3127 sanityCheckFail(bb,stmt,"IRStmt.PutI.ix: not :: Ity_I32"); 3128 if (!saneIRRegArray(stmt->Ist.PutI.descr)) 3129 sanityCheckFail(bb,stmt,"IRStmt.PutI.descr: invalid descr"); 3130 break; 3131 case Ist_WrTmp: 3132 tcExpr( bb, stmt, stmt->Ist.WrTmp.data, gWordTy ); 3133 if (typeOfIRTemp(tyenv, stmt->Ist.WrTmp.tmp) 3134 != typeOfIRExpr(tyenv, stmt->Ist.WrTmp.data)) 3135 sanityCheckFail(bb,stmt,"IRStmt.Put.Tmp: tmp and expr do not match"); 3136 break; 3137 case Ist_Store: 3138 tcExpr( bb, stmt, stmt->Ist.Store.addr, gWordTy ); 3139 tcExpr( bb, stmt, stmt->Ist.Store.data, gWordTy ); 3140 if (typeOfIRExpr(tyenv, stmt->Ist.Store.addr) != gWordTy) 3141 sanityCheckFail(bb,stmt,"IRStmt.Store.addr: not :: guest word type"); 3142 if (typeOfIRExpr(tyenv, stmt->Ist.Store.data) == Ity_I1) 3143 sanityCheckFail(bb,stmt,"IRStmt.Store.data: cannot Store :: Ity_I1"); 3144 if (stmt->Ist.Store.end != Iend_LE && stmt->Ist.Store.end != Iend_BE) 3145 sanityCheckFail(bb,stmt,"Ist.Store.end: bogus endianness"); 3146 break; 3147 case Ist_CAS: 3148 cas = stmt->Ist.CAS.details; 3149 /* make sure it's definitely either a CAS or a DCAS */ 3150 if (cas->oldHi == IRTemp_INVALID 3151 && cas->expdHi == NULL && cas->dataHi == NULL) { 3152 /* fine; it's a single cas */ 3153 } 3154 else 3155 if (cas->oldHi != IRTemp_INVALID 3156 && cas->expdHi != NULL && cas->dataHi != NULL) { 3157 /* fine; it's a double cas */ 3158 } 3159 else { 3160 /* it's some el-mutanto hybrid */ 3161 goto bad_cas; 3162 } 3163 /* check the address type */ 3164 tcExpr( bb, stmt, cas->addr, gWordTy ); 3165 if (typeOfIRExpr(tyenv, cas->addr) != gWordTy) goto bad_cas; 3166 /* check types on the {old,expd,data}Lo components agree */ 3167 tyExpd = typeOfIRExpr(tyenv, cas->expdLo); 3168 tyData = typeOfIRExpr(tyenv, cas->dataLo); 3169 if (tyExpd != tyData) goto bad_cas; 3170 if (tyExpd != typeOfIRTemp(tyenv, cas->oldLo)) 3171 goto bad_cas; 3172 /* check the base element type is sane */ 3173 if (tyExpd == Ity_I8 || tyExpd == Ity_I16 || tyExpd == Ity_I32 3174 || (gWordTy == Ity_I64 && tyExpd == Ity_I64)) { 3175 /* fine */ 3176 } else { 3177 goto bad_cas; 3178 } 3179 /* If it's a DCAS, check types on the {old,expd,data}Hi 3180 components too */ 3181 if (cas->oldHi != IRTemp_INVALID) { 3182 tyExpd = typeOfIRExpr(tyenv, cas->expdHi); 3183 tyData = typeOfIRExpr(tyenv, cas->dataHi); 3184 if (tyExpd != tyData) goto bad_cas; 3185 if (tyExpd != typeOfIRTemp(tyenv, cas->oldHi)) 3186 goto bad_cas; 3187 /* and finally check that oldLo and oldHi have the same 3188 type. This forces equivalence amongst all 6 types. */ 3189 if (typeOfIRTemp(tyenv, cas->oldHi) 3190 != typeOfIRTemp(tyenv, cas->oldLo)) 3191 goto bad_cas; 3192 } 3193 break; 3194 bad_cas: 3195 sanityCheckFail(bb,stmt,"IRStmt.CAS: ill-formed"); 3196 break; 3197 case Ist_LLSC: { 3198 IRType tyRes; 3199 if (typeOfIRExpr(tyenv, stmt->Ist.LLSC.addr) != gWordTy) 3200 sanityCheckFail(bb,stmt,"IRStmt.LLSC.addr: not :: guest word type"); 3201 if (stmt->Ist.LLSC.end != Iend_LE && stmt->Ist.LLSC.end != Iend_BE) 3202 sanityCheckFail(bb,stmt,"Ist.LLSC.end: bogus endianness"); 3203 tyRes = typeOfIRTemp(tyenv, stmt->Ist.LLSC.result); 3204 if (stmt->Ist.LLSC.storedata == NULL) { 3205 /* it's a LL */ 3206 if (tyRes != Ity_I64 && tyRes != Ity_I32 && tyRes != Ity_I8) 3207 sanityCheckFail(bb,stmt,"Ist.LLSC(LL).result :: bogus"); 3208 } else { 3209 /* it's a SC */ 3210 if (tyRes != Ity_I1) 3211 sanityCheckFail(bb,stmt,"Ist.LLSC(SC).result: not :: Ity_I1"); 3212 tyData = typeOfIRExpr(tyenv, stmt->Ist.LLSC.storedata); 3213 if (tyData != Ity_I64 && tyData != Ity_I32 && tyData != Ity_I8) 3214 sanityCheckFail(bb,stmt, 3215 "Ist.LLSC(SC).result :: storedata bogus"); 3216 } 3217 break; 3218 } 3219 case Ist_Dirty: 3220 /* Mostly check for various kinds of ill-formed dirty calls. */ 3221 d = stmt->Ist.Dirty.details; 3222 if (d->cee == NULL) goto bad_dirty; 3223 if (!saneIRCallee(d->cee)) goto bad_dirty; 3224 if (d->cee->regparms > countArgs(d->args)) goto bad_dirty; 3225 if (d->mFx == Ifx_None) { 3226 if (d->mAddr != NULL || d->mSize != 0) 3227 goto bad_dirty; 3228 } else { 3229 if (d->mAddr == NULL || d->mSize == 0) 3230 goto bad_dirty; 3231 } 3232 if (d->nFxState < 0 || d->nFxState > VEX_N_FXSTATE) 3233 goto bad_dirty; 3234 if (d->nFxState == 0 && d->needsBBP) 3235 goto bad_dirty; 3236 for (i = 0; i < d->nFxState; i++) { 3237 if (d->fxState[i].fx == Ifx_None) goto bad_dirty; 3238 if (d->fxState[i].size <= 0) goto bad_dirty; 3239 } 3240 /* check types, minimally */ 3241 if (d->guard == NULL) goto bad_dirty; 3242 tcExpr( bb, stmt, d->guard, gWordTy ); 3243 if (typeOfIRExpr(tyenv, d->guard) != Ity_I1) 3244 sanityCheckFail(bb,stmt,"IRStmt.Dirty.guard not :: Ity_I1"); 3245 if (d->tmp != IRTemp_INVALID 3246 && typeOfIRTemp(tyenv, d->tmp) == Ity_I1) 3247 sanityCheckFail(bb,stmt,"IRStmt.Dirty.dst :: Ity_I1"); 3248 for (i = 0; d->args[i] != NULL; i++) { 3249 if (i >= 32) 3250 sanityCheckFail(bb,stmt,"IRStmt.Dirty: > 32 args"); 3251 if (typeOfIRExpr(tyenv, d->args[i]) == Ity_I1) 3252 sanityCheckFail(bb,stmt,"IRStmt.Dirty.arg[i] :: Ity_I1"); 3253 } 3254 break; 3255 bad_dirty: 3256 sanityCheckFail(bb,stmt,"IRStmt.Dirty: ill-formed"); 3257 break; 3258 case Ist_NoOp: 3259 break; 3260 case Ist_MBE: 3261 switch (stmt->Ist.MBE.event) { 3262 case Imbe_Fence: 3263 break; 3264 default: sanityCheckFail(bb,stmt,"IRStmt.MBE.event: unknown"); 3265 break; 3266 } 3267 break; 3268 case Ist_Exit: 3269 tcExpr( bb, stmt, stmt->Ist.Exit.guard, gWordTy ); 3270 if (typeOfIRExpr(tyenv,stmt->Ist.Exit.guard) != Ity_I1) 3271 sanityCheckFail(bb,stmt,"IRStmt.Exit.guard: not :: Ity_I1"); 3272 if (!saneIRConst(stmt->Ist.Exit.dst)) 3273 sanityCheckFail(bb,stmt,"IRStmt.Exit.dst: bad dst"); 3274 if (typeOfIRConst(stmt->Ist.Exit.dst) != gWordTy) 3275 sanityCheckFail(bb,stmt,"IRStmt.Exit.dst: not :: guest word type"); 3276 break; 3277 default: 3278 vpanic("tcStmt"); 3279 } 3280 } 3281 3282 void sanityCheckIRSB ( IRSB* bb, HChar* caller, 3283 Bool require_flat, IRType guest_word_size ) 3284 { 3285 Int i; 3286 IRStmt* stmt; 3287 Int n_temps = bb->tyenv->types_used; 3288 Int* def_counts = LibVEX_Alloc(n_temps * sizeof(Int)); 3289 3290 if (0) 3291 vex_printf("sanityCheck: %s\n", caller); 3292 3293 vassert(guest_word_size == Ity_I32 3294 || guest_word_size == Ity_I64); 3295 3296 if (bb->stmts_used < 0 || bb->stmts_size < 8 3297 || bb->stmts_used > bb->stmts_size) 3298 /* this BB is so strange we can't even print it */ 3299 vpanic("sanityCheckIRSB: stmts array limits wierd"); 3300 3301 /* Ensure each temp has a plausible type. */ 3302 for (i = 0; i < n_temps; i++) { 3303 IRType ty = typeOfIRTemp(bb->tyenv,(IRTemp)i); 3304 if (!isPlausibleIRType(ty)) { 3305 vex_printf("Temp t%d declared with implausible type 0x%x\n", 3306 i, (UInt)ty); 3307 sanityCheckFail(bb,NULL,"Temp declared with implausible type"); 3308 } 3309 } 3310 3311 /* Check for flatness, if required. */ 3312 if (require_flat) { 3313 for (i = 0; i < bb->stmts_used; i++) { 3314 stmt = bb->stmts[i]; 3315 if (!stmt) 3316 sanityCheckFail(bb, stmt, "IRStmt: is NULL"); 3317 if (!isFlatIRStmt(stmt)) 3318 sanityCheckFail(bb, stmt, "IRStmt: is not flat"); 3319 } 3320 if (!isIRAtom(bb->next)) 3321 sanityCheckFail(bb, NULL, "bb->next is not an atom"); 3322 } 3323 3324 /* Count the defs of each temp. Only one def is allowed. 3325 Also, check that each used temp has already been defd. */ 3326 3327 for (i = 0; i < n_temps; i++) 3328 def_counts[i] = 0; 3329 3330 for (i = 0; i < bb->stmts_used; i++) { 3331 IRDirty* d; 3332 IRCAS* cas; 3333 stmt = bb->stmts[i]; 3334 /* Check any temps used by this statement. */ 3335 useBeforeDef_Stmt(bb,stmt,def_counts); 3336 3337 /* Now make note of any temps defd by this statement. */ 3338 switch (stmt->tag) { 3339 case Ist_WrTmp: 3340 if (stmt->Ist.WrTmp.tmp < 0 || stmt->Ist.WrTmp.tmp >= n_temps) 3341 sanityCheckFail(bb, stmt, 3342 "IRStmt.Tmp: destination tmp is out of range"); 3343 def_counts[stmt->Ist.WrTmp.tmp]++; 3344 if (def_counts[stmt->Ist.WrTmp.tmp] > 1) 3345 sanityCheckFail(bb, stmt, 3346 "IRStmt.Tmp: destination tmp is assigned more than once"); 3347 break; 3348 case Ist_Store: 3349 break; 3350 case Ist_Dirty: 3351 if (stmt->Ist.Dirty.details->tmp != IRTemp_INVALID) { 3352 d = stmt->Ist.Dirty.details; 3353 if (d->tmp < 0 || d->tmp >= n_temps) 3354 sanityCheckFail(bb, stmt, 3355 "IRStmt.Dirty: destination tmp is out of range"); 3356 def_counts[d->tmp]++; 3357 if (def_counts[d->tmp] > 1) 3358 sanityCheckFail(bb, stmt, 3359 "IRStmt.Dirty: destination tmp is assigned more than once"); 3360 } 3361 break; 3362 case Ist_CAS: 3363 cas = stmt->Ist.CAS.details; 3364 if (cas->oldHi != IRTemp_INVALID) { 3365 if (cas->oldHi < 0 || cas->oldHi >= n_temps) 3366 sanityCheckFail(bb, stmt, 3367 "IRStmt.CAS: destination tmpHi is out of range"); 3368 def_counts[cas->oldHi]++; 3369 if (def_counts[cas->oldHi] > 1) 3370 sanityCheckFail(bb, stmt, 3371 "IRStmt.CAS: destination tmpHi is assigned more than once"); 3372 } 3373 if (cas->oldLo < 0 || cas->oldLo >= n_temps) 3374 sanityCheckFail(bb, stmt, 3375 "IRStmt.CAS: destination tmpLo is out of range"); 3376 def_counts[cas->oldLo]++; 3377 if (def_counts[cas->oldLo] > 1) 3378 sanityCheckFail(bb, stmt, 3379 "IRStmt.CAS: destination tmpLo is assigned more than once"); 3380 break; 3381 case Ist_LLSC: 3382 if (stmt->Ist.LLSC.result < 0 || stmt->Ist.LLSC.result >= n_temps) 3383 sanityCheckFail(bb, stmt, 3384 "IRStmt.LLSC: destination tmp is out of range"); 3385 def_counts[stmt->Ist.LLSC.result]++; 3386 if (def_counts[stmt->Ist.LLSC.result] > 1) 3387 sanityCheckFail(bb, stmt, 3388 "IRStmt.LLSC: destination tmp is assigned more than once"); 3389 break; 3390 default: 3391 /* explicitly handle the rest, so as to keep gcc quiet */ 3392 break; 3393 } 3394 } 3395 3396 /* Typecheck everything. */ 3397 for (i = 0; i < bb->stmts_used; i++) 3398 if (bb->stmts[i]) 3399 tcStmt( bb, bb->stmts[i], guest_word_size ); 3400 if (typeOfIRExpr(bb->tyenv,bb->next) != guest_word_size) 3401 sanityCheckFail(bb, NULL, "bb->next field has wrong type"); 3402 } 3403 3404 /*---------------------------------------------------------------*/ 3405 /*--- Misc helper functions ---*/ 3406 /*---------------------------------------------------------------*/ 3407 3408 Bool eqIRConst ( IRConst* c1, IRConst* c2 ) 3409 { 3410 if (c1->tag != c2->tag) 3411 return False; 3412 3413 switch (c1->tag) { 3414 case Ico_U1: return toBool( (1 & c1->Ico.U1) == (1 & c2->Ico.U1) ); 3415 case Ico_U8: return toBool( c1->Ico.U8 == c2->Ico.U8 ); 3416 case Ico_U16: return toBool( c1->Ico.U16 == c2->Ico.U16 ); 3417 case Ico_U32: return toBool( c1->Ico.U32 == c2->Ico.U32 ); 3418 case Ico_U64: return toBool( c1->Ico.U64 == c2->Ico.U64 ); 3419 case Ico_F64: return toBool( c1->Ico.F64 == c2->Ico.F64 ); 3420 case Ico_F64i: return toBool( c1->Ico.F64i == c2->Ico.F64i ); 3421 case Ico_V128: return toBool( c1->Ico.V128 == c2->Ico.V128 ); 3422 default: vpanic("eqIRConst"); 3423 } 3424 } 3425 3426 Bool eqIRRegArray ( IRRegArray* descr1, IRRegArray* descr2 ) 3427 { 3428 return toBool( descr1->base == descr2->base 3429 && descr1->elemTy == descr2->elemTy 3430 && descr1->nElems == descr2->nElems ); 3431 } 3432 3433 Int sizeofIRType ( IRType ty ) 3434 { 3435 switch (ty) { 3436 case Ity_I8: return 1; 3437 case Ity_I16: return 2; 3438 case Ity_I32: return 4; 3439 case Ity_I64: return 8; 3440 case Ity_I128: return 16; 3441 case Ity_F32: return 4; 3442 case Ity_F64: return 8; 3443 case Ity_V128: return 16; 3444 default: vex_printf("\n"); ppIRType(ty); vex_printf("\n"); 3445 vpanic("sizeofIRType"); 3446 } 3447 } 3448 3449 IRExpr* mkIRExpr_HWord ( HWord hw ) 3450 { 3451 vassert(sizeof(void*) == sizeof(HWord)); 3452 if (sizeof(HWord) == 4) 3453 return IRExpr_Const(IRConst_U32((UInt)hw)); 3454 if (sizeof(HWord) == 8) 3455 return IRExpr_Const(IRConst_U64((ULong)hw)); 3456 vpanic("mkIRExpr_HWord"); 3457 } 3458 3459 IRDirty* unsafeIRDirty_0_N ( Int regparms, HChar* name, void* addr, 3460 IRExpr** args ) 3461 { 3462 IRDirty* d = emptyIRDirty(); 3463 d->cee = mkIRCallee ( regparms, name, addr ); 3464 d->guard = IRExpr_Const(IRConst_U1(True)); 3465 d->args = args; 3466 return d; 3467 } 3468 3469 IRDirty* unsafeIRDirty_1_N ( IRTemp dst, 3470 Int regparms, HChar* name, void* addr, 3471 IRExpr** args ) 3472 { 3473 IRDirty* d = emptyIRDirty(); 3474 d->cee = mkIRCallee ( regparms, name, addr ); 3475 d->guard = IRExpr_Const(IRConst_U1(True)); 3476 d->args = args; 3477 d->tmp = dst; 3478 return d; 3479 } 3480 3481 IRExpr* mkIRExprCCall ( IRType retty, 3482 Int regparms, HChar* name, void* addr, 3483 IRExpr** args ) 3484 { 3485 return IRExpr_CCall ( mkIRCallee ( regparms, name, addr ), 3486 retty, args ); 3487 } 3488 3489 Bool eqIRAtom ( IRExpr* a1, IRExpr* a2 ) 3490 { 3491 vassert(isIRAtom(a1)); 3492 vassert(isIRAtom(a2)); 3493 if (a1->tag == Iex_RdTmp && a2->tag == Iex_RdTmp) 3494 return toBool(a1->Iex.RdTmp.tmp == a2->Iex.RdTmp.tmp); 3495 if (a1->tag == Iex_Const && a2->tag == Iex_Const) 3496 return eqIRConst(a1->Iex.Const.con, a2->Iex.Const.con); 3497 return False; 3498 } 3499 3500 /*---------------------------------------------------------------*/ 3501 /*--- end ir_defs.c ---*/ 3502 /*---------------------------------------------------------------*/ 3503