Newer
Older
9001
9002
9003
9004
9005
9006
9007
9008
9009
9010
9011
9012
9013
9014
9015
9016
9017
9018
9019
9020
9021
9022
9023
9024
9025
9026
9027
9028
9029
9030
9031
9032
9033
9034
case NN_fldz: // Load +0.0
case NN_fld1: // Load +1.0
case NN_fldpi: // Load PI=3.14...
case NN_fldl2t: // Load lg2(10)
case NN_fldl2e: // Load lg2(e)
case NN_fldlg2: // Load lg10(2)
case NN_fldln2: // Load ln(2)
case NN_finit: // Initialize Processor
case NN_fninit: // Initialize Processor (no wait)
case NN_fsetpm: // Set Protected Mode
case NN_fldcw: // Load Control Word
case NN_fstcw: // Store Control Word
case NN_fnstcw: // Store Control Word (no wait)
case NN_fstsw: // Store Status Word
case NN_fnstsw: // Store Status Word (no wait)
case NN_fclex: // Clear Exceptions
case NN_fnclex: // Clear Exceptions (no wait)
// Floating point stack and control word and flags operations
// with no memory operands are no-ops to us.
NopRT = new SMPRegTransfer;
NopRT->SetOperator(SMP_NULL_OPERATOR);
this->RTL.push_back(NopRT);
NopRT = NULL;
return true;
case NN_fstenv: // Store Environment
case NN_fnstenv: // Store Environment (no wait)
case NN_fldenv: // Load Environment
case NN_fsave: // Save State
case NN_fnsave: // Save State (no wait)
case NN_frstor: // Restore State
case NN_fincstp: // Increment Stack Pointer
case NN_fdecstp: // Decrement Stack Pointer
case NN_ffree: // Free Register
return false;
break;
case NN_fnop: // No Operation
NopRT = new SMPRegTransfer;
NopRT->SetOperator(SMP_NULL_OPERATOR);
this->RTL.push_back(NopRT);
NopRT = NULL;
return true;
9045
9046
9047
9048
9049
9050
9051
9052
9053
9054
9055
9056
9057
9058
9059
9060
9061
9062
9063
9064
9065
9066
9067
9068
9069
9070
9071
9072
9073
9074
9075
9076
9077
9078
9079
9080
9081
9082
9083
9084
9085
case NN_feni: // (8087 only)
case NN_fneni: // (no wait) (8087 only)
case NN_fdisi: // (8087 only)
case NN_fndisi: // (no wait) (8087 only)
return false;
break;
//
// 80387 instructions
//
case NN_fprem1: // Partial Remainder ( < half )
case NN_fsincos: // t<-cos(st); st<-sin(st); push t
case NN_fsin: // Sine
case NN_fcos: // Cosine
case NN_fucom: // Compare Unordered Real
case NN_fucomp: // Compare Unordered Real and Pop
case NN_fucompp: // Compare Unordered Real and Pop Twice
// Floating point stack and control word and flags operations
// with no memory operands are no-ops to us.
NopRT = new SMPRegTransfer;
NopRT->SetOperator(SMP_NULL_OPERATOR);
this->RTL.push_back(NopRT);
NopRT = NULL;
return true;
//
// Instructions added 28.02.96
//
case NN_setalc: // Set AL to Carry Flag
case NN_svdc: // Save Register and Descriptor
case NN_rsdc: // Restore Register and Descriptor
case NN_svldt: // Save LDTR and Descriptor
case NN_rsldt: // Restore LDTR and Descriptor
case NN_svts: // Save TR and Descriptor
case NN_rsts: // Restore TR and Descriptor
case NN_icebp: // ICE Break Point
case NN_loadall: // Load the entire CPU state from ES:EDI
return false;
break;
//
// MMX instructions
//
case NN_emms: // Empty MMX state
return false;
break;
case NN_movd: // Move 32 bits
case NN_movq: // Move 64 bits
return this->BuildMoveRTL(SMP_NULL_OPERATOR);
break;
case NN_packsswb: // Pack with Signed Saturation (Word->Byte)
case NN_packssdw: // Pack with Signed Saturation (Dword->Word)
case NN_packuswb: // Pack with Unsigned Saturation (Word->Byte)
case NN_paddb: // Packed Add Byte
case NN_paddw: // Packed Add Word
case NN_paddd: // Packed Add Dword
case NN_paddsb: // Packed Add with Saturation (Byte)
case NN_paddsw: // Packed Add with Saturation (Word)
case NN_paddusb: // Packed Add Unsigned with Saturation (Byte)
case NN_paddusw: // Packed Add Unsigned with Saturation (Word)
return false;
break;
case NN_pand: // Bitwise Logical And
return this->BuildBinaryRTL(SMP_BITWISE_AND);
break;
case NN_pandn: // Bitwise Logical And Not
return this->BuildBinaryRTL(SMP_BITWISE_AND_NOT);
break;
case NN_pcmpeqb: // Packed Compare for Equal (Byte)
case NN_pcmpeqw: // Packed Compare for Equal (Word)
case NN_pcmpeqd: // Packed Compare for Equal (Dword)
return this->BuildBinaryRTL(SMP_COMPARE_EQ_AND_SET);
break;
case NN_pcmpgtb: // Packed Compare for Greater Than (Byte)
case NN_pcmpgtw: // Packed Compare for Greater Than (Word)
case NN_pcmpgtd: // Packed Compare for Greater Than (Dword)
return this->BuildBinaryRTL(SMP_COMPARE_EQ_AND_SET);
break;
case NN_pmaddwd: // Packed Multiply and Add
case NN_pmulhw: // Packed Multiply High
case NN_pmullw: // Packed Multiply Low
return false;
break;
case NN_por: // Bitwise Logical Or
return this->BuildBinaryRTL(SMP_BITWISE_OR);
break;
case NN_psllw: // Packed Shift Left Logical (Word)
case NN_pslld: // Packed Shift Left Logical (Dword)
case NN_psllq: // Packed Shift Left Logical (Qword)
return this->BuildBinaryRTL(SMP_U_LEFT_SHIFT);
break;
case NN_psraw: // Packed Shift Right Arithmetic (Word)
case NN_psrad: // Packed Shift Right Arithmetic (Dword)
return this->BuildBinaryRTL(SMP_S_RIGHT_SHIFT);
break;
case NN_psrlw: // Packed Shift Right Logical (Word)
case NN_psrld: // Packed Shift Right Logical (Dword)
case NN_psrlq: // Packed Shift Right Logical (Qword)
return this->BuildBinaryRTL(SMP_U_RIGHT_SHIFT);
break;
case NN_psubb: // Packed Subtract Byte
case NN_psubw: // Packed Subtract Word
case NN_psubd: // Packed Subtract Dword
return this->BuildBinaryRTL(SMP_SUBTRACT);
break;
case NN_psubsb: // Packed Subtract with Saturation (Byte)
case NN_psubsw: // Packed Subtract with Saturation (Word)
return this->BuildBinaryRTL(SMP_SUBTRACT);
break;
case NN_psubusb: // Packed Subtract Unsigned with Saturation (Byte)
case NN_psubusw: // Packed Subtract Unsigned with Saturation (Word)
return this->BuildBinaryRTL(SMP_SUBTRACT);
break;
case NN_punpckhbw: // Unpack High Packed Data (Byte->Word)
case NN_punpckhwd: // Unpack High Packed Data (Word->Dword)
case NN_punpckhdq: // Unpack High Packed Data (Dword->Qword)
case NN_punpcklbw: // Unpack Low Packed Data (Byte->Word)
case NN_punpcklwd: // Unpack Low Packed Data (Word->Dword)
case NN_punpckldq: // Unpack Low Packed Data (Dword->Qword)
return this->BuildBinaryRTL(SMP_INTERLEAVE);
break;
case NN_pxor: // Bitwise Logical Exclusive Or
return this->BuildBinaryRTL(SMP_BITWISE_XOR);
break;
//
// Undocumented Deschutes processor instructions
//
case NN_fxsave: // Fast save FP context
case NN_fxrstor: // Fast restore FP context
return false;
break;
// Pentium II instructions
case NN_sysenter: // Fast Transition to System Call Entry Point
case NN_sysexit: // Fast Transition from System Call Entry Point
return false;
break;
9206
9207
9208
9209
9210
9211
9212
9213
9214
9215
9216
9217
9218
9219
9220
9221
9222
9223
9224
9225
9226
9227
9228
// 3DNow! instructions
case NN_pavgusb: // Packed 8-bit Unsigned Integer Averaging
case NN_pfadd: // Packed Floating-Point Addition
case NN_pfsub: // Packed Floating-Point Subtraction
case NN_pfsubr: // Packed Floating-Point Reverse Subtraction
case NN_pfacc: // Packed Floating-Point Accumulate
case NN_pfcmpge: // Packed Floating-Point Comparison: Greater or Equal
case NN_pfcmpgt: // Packed Floating-Point Comparison: Greater
case NN_pfcmpeq: // Packed Floating-Point Comparison: Equal
case NN_pfmin: // Packed Floating-Point Minimum
case NN_pfmax: // Packed Floating-Point Maximum
case NN_pi2fd: // Packed 32-bit Integer to Floating-Point
case NN_pf2id: // Packed Floating-Point to 32-bit Integer
case NN_pfrcp: // Packed Floating-Point Reciprocal Approximation
case NN_pfrsqrt: // Packed Floating-Point Reciprocal Square Root Approximation
case NN_pfmul: // Packed Floating-Point Multiplication
case NN_pfrcpit1: // Packed Floating-Point Reciprocal First Iteration Step
case NN_pfrsqit1: // Packed Floating-Point Reciprocal Square Root First Iteration Step
case NN_pfrcpit2: // Packed Floating-Point Reciprocal Second Iteration Step
case NN_pmulhrw: // Packed Floating-Point 16-bit Integer Multiply with rounding
case NN_femms: // Faster entry/exit of the MMX or floating-point state
return false;
break;
case NN_prefetch: // Prefetch at least a 32-byte line into L1 data cache
case NN_prefetchw: // Prefetch processor cache line into L1 data cache (mark as modified)
// Prefetch opcodes are no-ops to us.
NopRT = new SMPRegTransfer;
NopRT->SetOperator(SMP_NULL_OPERATOR);
this->RTL.push_back(NopRT);
NopRT = NULL;
return true;
// Pentium III instructions
case NN_addps: // Packed Single-FP Add
case NN_addss: // Scalar Single-FP Add
case NN_andnps: // Bitwise Logical And Not for Single-FP
case NN_andps: // Bitwise Logical And for Single-FP
case NN_cmpps: // Packed Single-FP Compare
case NN_cmpss: // Scalar Single-FP Compare
case NN_comiss: // Scalar Ordered Single-FP Compare and Set EFLAGS
case NN_cvtpi2ps: // Packed signed INT32 to Packed Single-FP conversion
case NN_cvtps2pi: // Packed Single-FP to Packed INT32 conversion
case NN_cvtsi2ss: // Scalar signed INT32 to Single-FP conversion
case NN_cvtss2si: // Scalar Single-FP to signed INT32 conversion
case NN_cvttps2pi: // Packed Single-FP to Packed INT32 conversion (truncate)
case NN_cvttss2si: // Scalar Single-FP to signed INT32 conversion (truncate)
case NN_divps: // Packed Single-FP Divide
case NN_divss: // Scalar Single-FP Divide
return false;
break;
case NN_ldmxcsr: // Load Streaming SIMD Extensions Technology Control/Status Register
return this->BuildMoveRTL(SMP_NULL_OPERATOR);
break;
case NN_maxps: // Packed Single-FP Maximum
case NN_maxss: // Scalar Single-FP Maximum
case NN_minps: // Packed Single-FP Minimum
case NN_minss: // Scalar Single-FP Minimum
return false;
break;
case NN_movaps: // Move Aligned Four Packed Single-FP
case NN_movhlps: // Move High to Low Packed Single-FP
case NN_movhps: // Move High Packed Single-FP
case NN_movlhps: // Move Low to High Packed Single-FP
case NN_movlps: // Move Low Packed Single-FP
case NN_movmskps: // Move Mask to Register
case NN_movss: // Move Scalar Single-FP
case NN_movups: // Move Unaligned Four Packed Single-FP
return this->BuildMoveRTL(SMP_NULL_OPERATOR);
break;
case NN_mulps: // Packed Single-FP Multiply
case NN_mulss: // Scalar Single-FP Multiply
case NN_orps: // Bitwise Logical OR for Single-FP Data
case NN_rcpps: // Packed Single-FP Reciprocal
case NN_rcpss: // Scalar Single-FP Reciprocal
case NN_rsqrtps: // Packed Single-FP Square Root Reciprocal
case NN_rsqrtss: // Scalar Single-FP Square Root Reciprocal
case NN_shufps: // Shuffle Single-FP
case NN_sqrtps: // Packed Single-FP Square Root
case NN_sqrtss: // Scalar Single-FP Square Root
return false;
break;
case NN_stmxcsr: // Store Streaming SIMD Extensions Technology Control/Status Register
return this->BuildMoveRTL(SMP_NULL_OPERATOR);
break;
case NN_subps: // Packed Single-FP Subtract
case NN_subss: // Scalar Single-FP Subtract
case NN_ucomiss: // Scalar Unordered Single-FP Compare and Set EFLAGS
case NN_unpckhps: // Unpack High Packed Single-FP Data
case NN_unpcklps: // Unpack Low Packed Single-FP Data
case NN_xorps: // Bitwise Logical XOR for Single-FP Data
case NN_pavgb: // Packed Average (Byte)
case NN_pavgw: // Packed Average (Word)
case NN_pextrw: // Extract Word
case NN_pinsrw: // Insert Word
case NN_pmaxsw: // Packed Signed Integer Word Maximum
case NN_pmaxub: // Packed Unsigned Integer Byte Maximum
case NN_pminsw: // Packed Signed Integer Word Minimum
case NN_pminub: // Packed Unsigned Integer Byte Minimum
return false;
break;
case NN_pmovmskb: // Move Byte Mask to Integer
return this->BuildBinaryRTL(SMP_SHUFFLE);
break;
case NN_pmulhuw: // Packed Multiply High Unsigned
case NN_psadbw: // Packed Sum of Absolute Differences
return false;
break;
case NN_pshufw: // Packed Shuffle Word
return this->BuildBinaryRTL(SMP_SHUFFLE);
break;
case NN_maskmovq: // Byte Mask write
return false;
break;
case NN_movntps: // Move Aligned Four Packed Single-FP Non Temporal
case NN_movntq: // Move 64 Bits Non Temporal
return this->BuildMoveRTL(SMP_NULL_OPERATOR);
break;
case NN_prefetcht0: // Prefetch to all cache levels
case NN_prefetcht1: // Prefetch to all cache levels
case NN_prefetcht2: // Prefetch to L2 cache
case NN_prefetchnta: // Prefetch to L1 cache
case NN_sfence: // Store Fence
// Cache prefetch and store fence opcodes are no-ops to us.
NopRT = new SMPRegTransfer;
NopRT->SetOperator(SMP_NULL_OPERATOR);
this->RTL.push_back(NopRT);
NopRT = NULL;
return true;
// Pentium III Pseudo instructions
case NN_cmpeqps: // Packed Single-FP Compare EQ
case NN_cmpltps: // Packed Single-FP Compare LT
case NN_cmpleps: // Packed Single-FP Compare LE
case NN_cmpunordps: // Packed Single-FP Compare UNORD
case NN_cmpneqps: // Packed Single-FP Compare NOT EQ
case NN_cmpnltps: // Packed Single-FP Compare NOT LT
case NN_cmpnleps: // Packed Single-FP Compare NOT LE
case NN_cmpordps: // Packed Single-FP Compare ORDERED
case NN_cmpeqss: // Scalar Single-FP Compare EQ
case NN_cmpltss: // Scalar Single-FP Compare LT
case NN_cmpless: // Scalar Single-FP Compare LE
case NN_cmpunordss: // Scalar Single-FP Compare UNORD
case NN_cmpneqss: // Scalar Single-FP Compare NOT EQ
case NN_cmpnltss: // Scalar Single-FP Compare NOT LT
case NN_cmpnless: // Scalar Single-FP Compare NOT LE
case NN_cmpordss: // Scalar Single-FP Compare ORDERED
return false;
break;
// AMD K7 instructions
case NN_pf2iw: // Packed Floating-Point to Integer with Sign Extend
case NN_pfnacc: // Packed Floating-Point Negative Accumulate
case NN_pfpnacc: // Packed Floating-Point Mixed Positive-Negative Accumulate
case NN_pi2fw: // Packed 16-bit Integer to Floating-Point
case NN_pswapd: // Packed Swap Double Word
return false;
break;
// Undocumented FP instructions (thanks to norbert.juffa@adm.com)
case NN_fstp1: // Alias of Store Real and Pop
case NN_fcom2: // Alias of Compare Real
case NN_fcomp3: // Alias of Compare Real and Pop
case NN_fxch4: // Alias of Exchange Registers
case NN_fcomp5: // Alias of Compare Real and Pop
case NN_ffreep: // Free Register and Pop
case NN_fxch7: // Alias of Exchange Registers
case NN_fstp8: // Alias of Store Real and Pop
case NN_fstp9: // Alias of Store Real and Pop
return false;
break;
9395
9396
9397
9398
9399
9400
9401
9402
9403
9404
9405
9406
9407
9408
9409
9410
9411
9412
9413
9414
9415
9416
9417
9418
9419
9420
9421
9422
9423
9424
9425
9426
9427
9428
9429
9430
// Pentium 4 instructions
case NN_addpd: // Add Packed Double-Precision Floating-Point Values
case NN_addsd: // Add Scalar Double-Precision Floating-Point Values
case NN_andnpd: // Bitwise Logical AND NOT of Packed Double-Precision Floating-Point Values
case NN_andpd: // Bitwise Logical AND of Packed Double-Precision Floating-Point Values
case NN_clflush: // Flush Cache Line
case NN_cmppd: // Compare Packed Double-Precision Floating-Point Values
case NN_cmpsd: // Compare Scalar Double-Precision Floating-Point Values
case NN_comisd: // Compare Scalar Ordered Double-Precision Floating-Point Values and Set EFLAGS
case NN_cvtdq2pd: // Convert Packed Doubleword Integers to Packed Single-Precision Floating-Point Values
case NN_cvtdq2ps: // Convert Packed Doubleword Integers to Packed Double-Precision Floating-Point Values
case NN_cvtpd2dq: // Convert Packed Double-Precision Floating-Point Values to Packed Doubleword Integers
case NN_cvtpd2pi: // Convert Packed Double-Precision Floating-Point Values to Packed Doubleword Integers
case NN_cvtpd2ps: // Convert Packed Double-Precision Floating-Point Values to Packed Single-Precision Floating-Point Values
case NN_cvtpi2pd: // Convert Packed Doubleword Integers to Packed Double-Precision Floating-Point Values
case NN_cvtps2dq: // Convert Packed Single-Precision Floating-Point Values to Packed Doubleword Integers
case NN_cvtps2pd: // Convert Packed Single-Precision Floating-Point Values to Packed Double-Precision Floating-Point Values
case NN_cvtsd2si: // Convert Scalar Double-Precision Floating-Point Value to Doubleword Integer
case NN_cvtsd2ss: // Convert Scalar Double-Precision Floating-Point Value to Scalar Single-Precision Floating-Point Value
case NN_cvtsi2sd: // Convert Doubleword Integer to Scalar Double-Precision Floating-Point Value
case NN_cvtss2sd: // Convert Scalar Single-Precision Floating-Point Value to Scalar Double-Precision Floating-Point Value
case NN_cvttpd2dq: // Convert With Truncation Packed Double-Precision Floating-Point Values to Packed Doubleword Integers
case NN_cvttpd2pi: // Convert with Truncation Packed Double-Precision Floating-Point Values to Packed Doubleword Integers
case NN_cvttps2dq: // Convert With Truncation Packed Single-Precision Floating-Point Values to Packed Doubleword Integers
case NN_cvttsd2si: // Convert with Truncation Scalar Double-Precision Floating-Point Value to Doubleword Integer
case NN_divpd: // Divide Packed Double-Precision Floating-Point Values
case NN_divsd: // Divide Scalar Double-Precision Floating-Point Values
case NN_lfence: // Load Fence
case NN_maskmovdqu: // Store Selected Bytes of Double Quadword
case NN_maxpd: // Return Maximum Packed Double-Precision Floating-Point Values
case NN_maxsd: // Return Maximum Scalar Double-Precision Floating-Point Value
case NN_mfence: // Memory Fence
case NN_minpd: // Return Minimum Packed Double-Precision Floating-Point Values
case NN_minsd: // Return Minimum Scalar Double-Precision Floating-Point Value
return false;
break;
case NN_movapd: // Move Aligned Packed Double-Precision Floating-Point Values
case NN_movdq2q: // Move Quadword from XMM to MMX Register
case NN_movdqa: // Move Aligned Double Quadword
case NN_movdqu: // Move Unaligned Double Quadword
case NN_movhpd: // Move High Packed Double-Precision Floating-Point Values
case NN_movlpd: // Move Low Packed Double-Precision Floating-Point Values
return this->BuildMoveRTL(SMP_NULL_OPERATOR);
break;
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
case NN_paddq: // Add Packed Quadword Integers
case NN_pause: // Spin Loop Hint
case NN_pmuludq: // Multiply Packed Unsigned Doubleword Integers
return false;
break;
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
case NN_subpd: // Subtract Packed Double-Precision Floating-Point Values
case NN_subsd: // Subtract Scalar Double-Precision Floating-Point Values
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 false;
break;
// 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
case NN_fisttp: // Store ST in intXX (chop) and pop
case NN_lddqu: // Load unaligned integer 128-bit
return false;
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
case NN_pmaddubsw: // Multiply and Add Packed Signed and Unsigned Bytes
case NN_phsubsw: // Packed Horizontal Subtract and Saturate
case NN_phaddsw: // Packed Horizontal Add and Saturate
case NN_phaddw: // Packed Horizontal Add Word
case NN_phaddd: // Packed Horizontal Add Doubleword
case NN_phsubw: // Packed Horizontal Subtract Word
case NN_phsubd: // Packed Horizontal Subtract Doubleword
return false;
break;
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 false;
break;
// 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;
default:
clc5q
committed
SMP_msg("ERROR: Unknown instruction opcode at %x : %s\n", this->GetAddr(),
DisAsmText.GetDisAsm(this->GetAddr()));
break;
} // end switch on opcode
return true;
} // end SMPInstr::BuildRTL()
// Iterate through all reg transfers and call SyncRTLDefUse for each.
void SMPInstr::SyncAllRTs(void) {
for (size_t index = 0; index < this->RTL.GetCount(); ++index) {
this->SyncRTLDefUse(this->RTL.GetRT(index));
}
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) {
// The Guard expression and ExtraKills are almost never represented in the DEF and USE
// 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());
}
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
// Update the memory source operands to have the new type
void SMPInstr::UpdateMemLoadTypes(SMPOperandType newType) {
bool MemSrc = false;
op_t Opnd;
for (int i = 0; i < UA_MAXOP; ++i) {
Opnd = this->SMPcmd.Operands[i];
optype_t CurrType = Opnd.type;
if (this->features & UseMacros[i]) { // USE
MemSrc = ((CurrType == o_mem) || (CurrType == o_phrase) || (CurrType == o_displ));
if (MemSrc) {
set<DefOrUse, LessDefUse>::iterator use = this->FindUse(Opnd);
SMPOperandType type = use->GetType();
assert(newType == (NUMERIC|PROF_BASE));
switch (type) {
case UNINIT:
case CODEPTR:
this->SetUseType(Opnd,newType);
break;
case POINTER:
this->SetUseType(Opnd, (SMPOperandType)(UNKNOWN|PROF_BASE));
break;
default:
break;
}
}
}
}
return ;
} // end of SMPInstr::UpdateMemLoadTypes()
clc5q
committed
9720
9721
9722
9723
9724
9725
9726
9727
9728
9729
9730
9731
9732
9733
9734
9735
9736
9737
9738
9739
9740
9741
9742
9743
9744
9745
9746
9747
9748
9749
9750
9751
9752
9753
// 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()