Newer
Older
case NN_movmskpd: // Extract Packed Double-Precision Floating-Point Sign Mask
return false;
break;
case NN_movntdq: // Store Double Quadword Using Non-Temporal Hint
case NN_movnti: // Store Doubleword Using Non-Temporal Hint
case NN_movntpd: // Store Packed Double-Precision Floating-Point Values Using Non-Temporal Hint
case NN_movq2dq: // Move Quadword from MMX to XMM Register
case NN_movsd: // Move Scalar Double-Precision Floating-Point Values
case NN_movupd: // Move Unaligned Packed Double-Precision Floating-Point Values
return this->BuildMoveRTL(SMP_NULL_OPERATOR);
break;
case NN_mulpd: // Multiply Packed Double-Precision Floating-Point Values
case NN_mulsd: // Multiply Scalar Double-Precision Floating-Point Values
case NN_orpd: // Bitwise Logical OR of Double-Precision Floating-Point Values
return this->BuildBinaryRTL(SMP_BINARY_FLOATING_ARITHMETIC);
break;
case NN_paddq: // Add Packed Quadword Integers
return this->BuildBinaryRTL(SMP_ADD);
case NN_pause: // Spin Loop Hint
NopRT->SetParentInst(this);
NopRT->SetOperator(SMP_NULL_OPERATOR);
this->RTL.push_back(NopRT);
NopRT = NULL;
return true;
case NN_pmuludq: // Multiply Packed Unsigned Doubleword Integers
return this->BuildBinaryRTL(SMP_U_MULTIPLY);
case NN_pshufd: // Shuffle Packed Doublewords
case NN_pshufhw: // Shuffle Packed High Words
case NN_pshuflw: // Shuffle Packed Low Words
return this->BuildBinaryRTL(SMP_SHUFFLE);
break;
case NN_pslldq: // Shift Double Quadword Left Logical
return this->BuildBinaryRTL(SMP_U_LEFT_SHIFT);
break;
case NN_psrldq: // Shift Double Quadword Right Logical
return this->BuildBinaryRTL(SMP_U_RIGHT_SHIFT);
break;
case NN_psubq: // Subtract Packed Quadword Integers
return this->BuildBinaryRTL(SMP_SUBTRACT);
break;
case NN_punpckhqdq: // Unpack High Data
case NN_punpcklqdq: // Unpack Low Data
return this->BuildBinaryRTL(SMP_INTERLEAVE);
break;
case NN_shufpd: // Shuffle Packed Double-Precision Floating-Point Values
return this->BuildBinaryRTL(SMP_SHUFFLE);
break;
case NN_sqrtpd: // Compute Square Roots of Packed Double-Precision Floating-Point Values
case NN_sqrtsd: // Compute Square Rootof Scalar Double-Precision Floating-Point Value
return this->BuildUnary2OpndRTL(SMP_UNARY_FLOATING_ARITHMETIC);
break;
case NN_subpd: // Subtract Packed Double-Precision Floating-Point Values
case NN_subsd: // Subtract Scalar Double-Precision Floating-Point Values
return this->BuildBinaryRTL(SMP_BINARY_FLOATING_ARITHMETIC);
break;
case NN_ucomisd: // Unordered Compare Scalar Ordered Double-Precision Floating-Point Values and Set EFLAGS
return false;
break;
case NN_unpckhpd: // Unpack and Interleave High Packed Double-Precision Floating-Point Values
case NN_unpcklpd: // Unpack and Interleave Low Packed Double-Precision Floating-Point Values
return this->BuildBinaryRTL(SMP_INTERLEAVE);
break;
case NN_xorpd: // Bitwise Logical OR of Double-Precision Floating-Point Values
return this->BuildBinaryRTL(SMP_BINARY_FLOATING_ARITHMETIC);
// AMD syscall/sysret instructions
case NN_syscall: // Low latency system call
case NN_sysret: // Return from system call
// AMD64 instructions
case NN_swapgs: // Exchange GS base with KernelGSBase MSR
// New Pentium instructions (SSE3)
case NN_movddup: // Move One Double-FP and Duplicate
case NN_movshdup: // Move Packed Single-FP High and Duplicate
case NN_movsldup: // Move Packed Single-FP Low and Duplicate
return false;
break;
// Missing AMD64 instructions
case NN_movsxd: // Move with Sign-Extend Doubleword
case NN_cmpxchg16b: // Compare and Exchange 16 Bytes
return false;
break;
// SSE3 instructions
case NN_addsubpd: // Add /Sub packed DP FP numbers
case NN_addsubps: // Add /Sub packed SP FP numbers
case NN_haddpd: // Add horizontally packed DP FP numbers
case NN_haddps: // Add horizontally packed SP FP numbers
case NN_hsubpd: // Sub horizontally packed DP FP numbers
case NN_hsubps: // Sub horizontally packed SP FP numbers
case NN_monitor: // Set up a linear address range to be monitored by hardware
case NN_mwait: // Wait until write-back store performed within the range specified by the MONITOR instruction
return false;
break;
case NN_fisttp: // Store ST in intXX (chop) and pop
return this->BuildBinaryRTL(SMP_CONVERT_FP_TO_INT);
break;
case NN_lddqu: // Load unaligned integer 128-bit
return this->BuildMoveRTL(SMP_NULL_OPERATOR);
break;
// SSSE3 instructions
case NN_psignb: // Packed SIGN Byte
case NN_psignw: // Packed SIGN Word
case NN_psignd: // Packed SIGN Doubleword
case NN_pshufb: // Packed Shuffle Bytes
return this->BuildBinaryRTL(SMP_SHUFFLE);
break;
case NN_pmulhrsw: // Packed Multiply High with Round and Scale
return this->BuildBinaryRTL(SMP_BINARY_FLOATING_ARITHMETIC);
break;
case NN_pmaddubsw: // Multiply and Add Packed Signed and Unsigned Bytes
return this->BuildBinaryRTL(SMP_MULTIPLY_AND_ADD);
break;
case NN_phsubsw: // Packed Horizontal Subtract and Saturate
return this->BuildBinaryRTL(SMP_SUBTRACT);
break;
case NN_phaddsw: // Packed Horizontal Add and Saturate
return this->BuildBinaryRTL(SMP_ADD);
break;
case NN_phaddw: // Packed Horizontal Add Word
case NN_phaddd: // Packed Horizontal Add Doubleword
return this->BuildBinaryRTL(SMP_ADD);
break;
case NN_phsubw: // Packed Horizontal Subtract Word
case NN_phsubd: // Packed Horizontal Subtract Doubleword
return this->BuildBinaryRTL(SMP_SUBTRACT);
case NN_palignr: // Packed Align Right
return this->BuildPackShiftRTL(SMP_CONCATENATE, SMP_REVERSE_SHIFT_U);
break;
case NN_pabsb: // Packed Absolute Value Byte
case NN_pabsw: // Packed Absolute Value Word
case NN_pabsd: // Packed Absolute Value Doubleword
return this->BuildUnary2OpndRTL(SMP_ABSOLUTE_VALUE);
// VMX instructions
case NN_vmcall: // Call to VM Monitor
case NN_vmclear: // Clear Virtual Machine Control Structure
case NN_vmlaunch: // Launch Virtual Machine
case NN_vmresume: // Resume Virtual Machine
case NN_vmptrld: // Load Pointer to Virtual Machine Control Structure
case NN_vmptrst: // Store Pointer to Virtual Machine Control Structure
case NN_vmread: // Read Field from Virtual Machine Control Structure
case NN_vmwrite: // Write Field from Virtual Machine Control Structure
case NN_vmxoff: // Leave VMX Operation
case NN_vmxon: // Enter VMX Operation
return false;
break;
14193
14194
14195
14196
14197
14198
14199
14200
14201
14202
14203
14204
14205
14206
14207
14208
14209
14210
14211
14212
14213
14214
14215
14216
14217
14218
14219
14220
14221
14222
14223
14224
14225
14226
14227
14228
14229
14230
14231
14232
14233
14234
14235
14236
14237
14238
14239
14240
#if 599 < IDA_SDK_VERSION
case NN_ud2: // Undefined Instruction
return false;
break;
// Added with x86-64
case NN_rdtscp: // Read Time-Stamp Counter and Processor ID
return false;
break;
// Geode LX 3DNow! extensions
case NN_pfrcpv: // Reciprocal Approximation for a Pair of 32-bit Floats
case NN_pfrsqrtv: // Reciprocal Square Root Approximation for a Pair of 32-bit Floats
return false;
break;
// SSE2 pseudoinstructions
case NN_cmpeqpd: // Packed Double-FP Compare EQ
case NN_cmpltpd: // Packed Double-FP Compare LT
case NN_cmplepd: // Packed Double-FP Compare LE
case NN_cmpunordpd: // Packed Double-FP Compare UNORD
case NN_cmpneqpd: // Packed Double-FP Compare NOT EQ
case NN_cmpnltpd: // Packed Double-FP Compare NOT LT
case NN_cmpnlepd: // Packed Double-FP Compare NOT LE
case NN_cmpordpd: // Packed Double-FP Compare ORDERED
case NN_cmpeqsd: // Scalar Double-FP Compare EQ
case NN_cmpltsd: // Scalar Double-FP Compare LT
case NN_cmplesd: // Scalar Double-FP Compare LE
case NN_cmpunordsd: // Scalar Double-FP Compare UNORD
case NN_cmpneqsd: // Scalar Double-FP Compare NOT EQ
case NN_cmpnltsd: // Scalar Double-FP Compare NOT LT
case NN_cmpnlesd: // Scalar Double-FP Compare NOT LE
case NN_cmpordsd: // Scalar Double-FP Compare ORDERED
return false;
break;
// SSSE4.1 instructions
case NN_blendpd: // Blend Packed Double Precision Floating-Point Values
case NN_blendps: // Blend Packed Single Precision Floating-Point Values
case NN_blendvpd: // Variable Blend Packed Double Precision Floating-Point Values
case NN_blendvps: // Variable Blend Packed Single Precision Floating-Point Values
case NN_dppd: // Dot Product of Packed Double Precision Floating-Point Values
case NN_dpps: // Dot Product of Packed Single Precision Floating-Point Values
return false;
break;
case NN_extractps: // Extract Packed Single Precision Floating-Point Value
case NN_insertps: // Insert Packed Single Precision Floating-Point Value
case NN_movntdqa: // Load Double Quadword Non-Temporal Aligned Hint
case NN_mpsadbw: // Compute Multiple Packed Sums of Absolute Difference
case NN_packusdw: // Pack with Unsigned Saturation
case NN_pblendvb: // Variable Blend Packed Bytes
case NN_pblendw: // Blend Packed Words
case NN_pcmpeqq: // Compare Packed Qword Data for Equal
return false;
break;
case NN_pextrb: // Extract Byte
case NN_pextrd: // Extract Dword
case NN_pextrq: // Extract Qword
return this->BuildBinaryPlusImmedRTL(SMP_EXTRACT_ZERO_EXTEND, SMP_CREATE_MASK);
14260
14261
14262
14263
14264
14265
14266
14267
14268
14269
14270
14271
14272
14273
14274
14275
14276
14277
14278
14279
14280
14281
14282
14283
14284
14285
14286
14287
14288
14289
14290
14291
14292
14293
14294
14295
14296
14297
14298
14299
14300
14301
14302
14303
14304
14305
14306
14307
14308
14309
14310
14311
14312
14313
14314
14315
14316
14317
14318
14319
14320
14321
14322
14323
14324
14325
14326
14327
14328
14329
14330
14331
14332
14333
14334
case NN_phminposuw: // Packed Horizontal Word Minimum
return false;
break;
case NN_pinsrb: // Insert Byte
case NN_pinsrd: // Insert Dword
case NN_pinsrq: // Insert Qword
return this->BuildBinaryPlusImmedRTL(SMP_BITWISE_AND, SMP_CREATE_MASK);
break;
case NN_pmaxsb: // Maximum of Packed Signed Byte Integers
case NN_pmaxsd: // Maximum of Packed Signed Dword Integers
case NN_pmaxud: // Maximum of Packed Unsigned Dword Integers
case NN_pmaxuw: // Maximum of Packed Word Integers
case NN_pminsb: // Minimum of Packed Signed Byte Integers
case NN_pminsd: // Minimum of Packed Signed Dword Integers
case NN_pminud: // Minimum of Packed Unsigned Dword Integers
case NN_pminuw: // Minimum of Packed Word Integers
case NN_pmovsxbw: // Packed Move with Sign Extend
case NN_pmovsxbd: // Packed Move with Sign Extend
case NN_pmovsxbq: // Packed Move with Sign Extend
case NN_pmovsxwd: // Packed Move with Sign Extend
case NN_pmovsxwq: // Packed Move with Sign Extend
case NN_pmovsxdq: // Packed Move with Sign Extend
case NN_pmovzxbw: // Packed Move with Zero Extend
case NN_pmovzxbd: // Packed Move with Zero Extend
case NN_pmovzxbq: // Packed Move with Zero Extend
case NN_pmovzxwd: // Packed Move with Zero Extend
case NN_pmovzxwq: // Packed Move with Zero Extend
case NN_pmovzxdq: // Packed Move with Zero Extend
case NN_pmuldq: // Multiply Packed Signed Dword Integers
case NN_pmulld: // Multiply Packed Signed Dword Integers and Store Low Result
return false;
break;
case NN_ptest: // Logical Compare
return this->BuildFlagsDestBinaryRTL(SMP_U_COMPARE);
case NN_roundpd: // Round Packed Double Precision Floating-Point Values
case NN_roundps: // Round Packed Single Precision Floating-Point Values
case NN_roundsd: // Round Scalar Double Precision Floating-Point Values
case NN_roundss: // Round Scalar Single Precision Floating-Point Values
return false;
break;
// SSSE4.2 instructions
case NN_crc32: // Accumulate CRC32 Value
return false;
break;
case NN_pcmpestri: // Packed Compare Explicit Length Strings, Return Index
case NN_pcmpestrm: // Packed Compare Explicit Length Strings, Return Mask
case NN_pcmpistri: // Packed Compare Implicit Length Strings, Return Index
case NN_pcmpistrm: // Packed Compare Implicit Length Strings, Return Mask
return BuildBinaryIgnoreImmedRTL(SMP_GENERAL_COMPARE);
break;
case NN_pcmpgtq: // Compare Packed Data for Greater Than
case NN_popcnt: // Return the Count of Number of Bits Set to 1
return false;
break;
// AMD SSE4a instructions
case NN_extrq: // Extract Field From Register
case NN_insertq: // Insert Field
case NN_movntsd: // Move Non-Temporal Scalar Double-Precision Floating-Point
case NN_movntss: // Move Non-Temporal Scalar Single-Precision Floating-Point
case NN_lzcnt: // Leading Zero Count
return false;
break;
// xsave/xrstor instructions
case NN_xgetbv: // Get Value of Extended Control Register
return this->BuildOptType8RTL();
14337
14338
14339
14340
14341
14342
14343
14344
14345
14346
14347
14348
14349
14350
14351
14352
14353
14354
14355
14356
14357
14358
14359
14360
14361
14362
14363
14364
14365
14366
14367
14368
14369
14370
14371
14372
14373
14374
14375
14376
14377
14378
14379
14380
14381
14382
14383
case NN_xrstor: // Restore Processor Extended States
case NN_xsave: // Save Processor Extended States
case NN_xsetbv: // Set Value of Extended Control Register
return false;
break;
// Intel Safer Mode Extensions (SMX)
case NN_getsec: // Safer Mode Extensions (SMX) Instruction
return false;
break;
// AMD-V Virtualization ISA Extension
case NN_clgi: // Clear Global Interrupt Flag
case NN_invlpga: // Invalidate TLB Entry in a Specified ASID
case NN_skinit: // Secure Init and Jump with Attestation
case NN_stgi: // Set Global Interrupt Flag
case NN_vmexit: // Stop Executing Guest, Begin Executing Host
case NN_vmload: // Load State from VMCB
case NN_vmmcall: // Call VMM
case NN_vmrun: // Run Virtual Machine
case NN_vmsave: // Save State to VMCB
return false;
break;
// VMX+ instructions
case NN_invept: // Invalidate Translations Derived from EPT
case NN_invvpid: // Invalidate Translations Based on VPID
return false;
break;
// Intel Atom instructions
case NN_movbe: // Move Data After Swapping Bytes
return false;
break;
// Intel AES instructions
case NN_aesenc: // Perform One Round of an AES Encryption Flow
case NN_aesenclast: // Perform the Last Round of an AES Encryption Flow
case NN_aesdec: // Perform One Round of an AES Decryption Flow
case NN_aesdeclast: // Perform the Last Round of an AES Decryption Flow
case NN_aesimc: // Perform the AES InvMixColumn Transformation
case NN_aeskeygenassist: // AES Round Key Generation Assist
return this->BuildBinaryRTL(SMP_ENCRYPTION_OPERATION);
break;
// Carryless multiplication
case NN_pclmulqdq: // Carry-Less Multiplication Quadword
return BuildBinaryIgnoreImmedRTL(SMP_U_MULTIPLY);
break;
#endif // 599 < IDA_SDK_VERSION
SMP_msg("ERROR: Unknown instruction opcode at %lx : %s\n", (unsigned long) this->GetAddr(),
DisAsmText.GetDisAsm(this->GetAddr()));
return false;
break;
} // end switch on opcode
return true;
} // end SMPInstr::BuildRTL()
// Iterate through all reg transfers and call SyncRTLDefUse for each.
void SMPInstr::SyncAllRTs(bool UseFP, sval_t FPDelta) {
for (size_t index = 0; index < this->RTL.GetCount(); ++index) {
this->SyncRTLDefUse(this->RTL.GetRT(index), UseFP, FPDelta);
}
return;
} // end of SMPInstr:SyncAllRTs()
// Ensure that each operand of the RTL is found in the appropriate DEF or USE list.
void SMPInstr::SyncRTLDefUse(SMPRegTransfer *CurrRT, bool UseFP, sval_t FPDelta) {
clc5q
committed
// The ExtraKills are almost never represented in the DEF
// lists. When they are, they are added in MDFixupDefUseLists(), so we ignore them here.
// The only DEFs should come from left operands of SMP_ASSIGN operators, i.e. the effects
// of register transfers.
op_t LeftOp, RightOp;
set<DefOrUse, LessDefUse>::iterator CurrDef, CurrUse;
bool DebugFlag = false;
#if SMP_VERBOSE_DEBUG_BUILD_RTL
DebugFlag |= (0 == strcmp("__libc_csu_fini", this->BasicBlock->GetFunc()->GetFuncName()));
#endif
if (DebugFlag) {
clc5q
committed
SMP_msg("SyncRTLDefUse entered. Dump of USE list:\n");
this->Uses.Dump();
}
LeftOp = CurrRT->GetLeftOperand();
if (SMP_ASSIGN == CurrRT->GetOperator()) {
assert(o_void != LeftOp.type);
assert(o_imm != LeftOp.type);
CurrDef = this->Defs.FindRef(LeftOp);
if (CurrDef == this->GetLastDef() && !LeftOp.is_reg(R_ip)) {
#if SMP_VERBOSE_DEBUG_BUILD_RTL
clc5q
committed
SMP_msg("WARNING: DEF not found for SMP_ASSIGN in %s ; added op:", DisAsmText.GetDisAsm(this->GetAddr()));
clc5q
committed
SMP_msg("\n");
#endif
this->Defs.SetRef(LeftOp, CurrRT->GetOperatorType());
}
}
else { // not SMP_ASSIGN; left operand should be a USE
if (o_void != LeftOp.type) {
CurrUse = this->Uses.FindRef(LeftOp);
if (CurrUse == this->GetLastUse()) {
#if SMP_VERBOSE_DEBUG_BUILD_RTL_DEF_USE
clc5q
committed
SMP_msg("WARNING: USE not found for ");
clc5q
committed
SMP_msg(" in %s ; added\n", DisAsmText.GetDisAsm(this->GetAddr()));
#endif
this->Uses.SetRef(LeftOp);
}
}
}
if (!CurrRT->HasRightSubTree()) {
RightOp = CurrRT->GetRightOperand(); // right operand should be a USE
if (o_void != RightOp.type) {
CurrUse = this->Uses.FindRef(RightOp);
if (CurrUse == this->GetLastUse()) {
#if SMP_VERBOSE_DEBUG_BUILD_RTL_DEF_USE
clc5q
committed
SMP_msg("WARNING: USE not found for ");
clc5q
committed
SMP_msg(" in %s ; added\n", DisAsmText.GetDisAsm(this->GetAddr()));
#endif
this->Uses.SetRef(RightOp);
}
}
}
else { // recurse into right subtree
this->SyncRTLDefUse(CurrRT->GetRightTree(), UseFP, FPDelta);
clc5q
committed
14475
14476
14477
14478
14479
14480
14481
14482
14483
14484
14485
14486
14487
14488
14489
14490
14491
14492
14493
// Guard operands can only be USEs.
SMPGuard *GuardExpr = CurrRT->GetGuard();
if (NULL != GuardExpr) {
LeftOp = GuardExpr->GetLeftOperand();
if ((o_void != LeftOp.type) && (o_imm != LeftOp.type)) {
CurrUse = this->Uses.FindRef(LeftOp);
if (CurrUse == this->GetLastUse()) {
this->Uses.SetRef(LeftOp);
}
}
RightOp = GuardExpr->GetRightOperand();
if ((o_void != RightOp.type) && (o_imm != RightOp.type)) {
CurrUse = this->Uses.FindRef(RightOp);
if (CurrUse == this->GetLastUse()) {
this->Uses.SetRef(RightOp);
}
}
}
return;
} // end of SMPInstr::SyncRTLDefUse()
// SetOperatorType - set the type of the operator, take into account the speculative (profiler) status
void SMPRegTransfer::SetOperatorType(SMPOperandType OpType, const SMPInstr* Instr) {
SMPOperandType OldType = RTop.type;
SMPOperandType NewType = OpType;
if (Instr->GetBlock()->GetFunc()->GetIsSpeculative()) {
NewType = (SMPOperandType) (((int)NewType) | PROF_BASE);
if (!IsProfDerived(OldType))
RTop.NonSpeculativeType = OldType;
}
RTop.type = NewType;
} // end of SMPRegTransfer::SetOperatorType
14512
14513
14514
14515
14516
14517
14518
14519
14520
14521
14522
14523
14524
14525
14526
14527
14528
14529
14530
14531
14532
14533
14534
14535
14536
14537
14538
14539
14540
14541
14542
14543
14544
14545
14546
14547
14548
14549
14550
14551
14552
14553
14554
14555
14556
14557
14558
// Does UseOp arithmetically affect the value of the NonFlagsDef for this RTL?
bool SMPRegTransfer::OperandTransfersValueToDef(op_t UseOp) const {
bool FoundTransfer = false;
op_t DefOp = this->GetLeftOperand();
SMPoperator CurrOp = this->GetOperator();
if ((SMP_ASSIGN == CurrOp) && (DefOp.type != o_void) && (!DefOp.is_reg(MD_FLAGS_REG))) {
// We have an assignment to a non-flag DefOp. The only remaining question is whether
// UseOp appears in the right hand side of the RT as something besides an address register
// inside a memory operand.
if (this->HasRightSubTree()) {
FoundTransfer = this->GetRightTree()->OperandTransfersHelper(UseOp);
}
else {
op_t RightOp = this->GetRightOperand();
if (IsEqOpIgnoreBitwidth(UseOp, RightOp)) {
// Found UseOp.
FoundTransfer = true;
}
}
}
return FoundTransfer;
} // end of SMPRegTransfer::OperandTransfersValueToDef()
// Does UseOp arithmetically affect the value of the NonFlagsDef for this RT?
// Recursive helper for OperandTransfersValueToDef().
bool SMPRegTransfer::OperandTransfersHelper(op_t UseOp) const {
bool FoundTransfer = false;
op_t LeftOp = this->GetLeftOperand();
SMPoperator CurrOp = this->GetOperator();
// Have to check left and right operands to see if they are UseOp.
if (IsEqOpIgnoreBitwidth(UseOp, LeftOp)) {
FoundTransfer = true; // Found UseOp.
}
else if (this->HasRightSubTree()) { // recurse
FoundTransfer = this->GetRightTree()->OperandTransfersHelper(UseOp);
}
else {
op_t RightOp = this->GetRightOperand();
if (IsEqOpIgnoreBitwidth(UseOp, RightOp)) {
// Found UseOp.
FoundTransfer = true;
}
}
return FoundTransfer;
} // end of SMPRegTransfer::OperandTransfersHelper()
// Update the memory source operands to have the new type from profiling info.
void SMPInstr::UpdateMemLoadTypes(SMPOperandType newType) {
bool MemSrc = false;
op_t Opnd;
set<DefOrUse, LessDefUse>::iterator UseIter;
for (UseIter = this->GetFirstUse(); UseIter != this->GetLastUse(); ++UseIter) {
Opnd = UseIter->GetOp();
optype_t CurrType = Opnd.type;
MemSrc = ((CurrType == o_mem) || (CurrType == o_phrase) || (CurrType == o_displ));
if (MemSrc) {
SMPOperandType type = UseIter->GetType();
assert(newType == (NUMERIC|PROF_BASE));
if (type == UNINIT) {
this->SetUseType(Opnd, newType);
break;
}
else if (type >= POINTER) {
this->SetUseType(Opnd, (SMPOperandType)(UNKNOWN|PROF_BASE));
break;
}
}
}
return ;
} // end of SMPInstr::UpdateMemLoadTypes()
clc5q
committed
14584
14585
14586
14587
14588
14589
14590
14591
14592
14593
14594
14595
14596
14597
14598
14599
14600
14601
14602
14603
14604
14605
14606
14607
14608
14609
14610
14611
14612
14613
14614
14615
14616
14617
// Return true if we have register DefOp += ImmOp.
bool SMPInstr::MDIsAddImmediateToReg(op_t &DefOp, op_t &ImmOp) {
bool FoundAddImmed = false;
bool FoundImmed = false;
bool FoundRegUse = false;
if (NN_add == this->SMPcmd.itype) {
set<DefOrUse, LessDefUse>::iterator UseIter = this->GetFirstUse();
while (UseIter != this->GetLastUse()) {
op_t UseOp = UseIter->GetOp();
if (o_imm == UseOp.type) {
ImmOp = UseOp;
FoundImmed = true;
}
else if (o_reg == UseOp.type) {
set<DefOrUse, LessDefUse>::iterator DefIter = this->GetFirstNonFlagsDef();
op_t TempDefOp = DefIter->GetOp();
if (o_reg != TempDefOp.type) {
return false;
}
if (MDLessReg(UseOp.reg, TempDefOp.reg) || MDLessReg(TempDefOp.reg, UseOp.reg)) {
return false;
}
// If we make it here, we have the same register DEFed as we found USEd.
DefOp = TempDefOp;
FoundRegUse = true;
}
++UseIter;
}
FoundAddImmed = (FoundImmed && FoundRegUse);
}
return FoundAddImmed;
} // end of SMPInstr::MDIsAddImmediateToReg()