Skip to content
Snippets Groups Projects
SMPInstr.cpp 640 KiB
Newer Older
16001 16002 16003 16004 16005 16006 16007 16008 16009 16010 16011 16012 16013 16014 16015 16016 16017 16018 16019 16020 16021 16022 16023 16024 16025 16026 16027 16028 16029 16030 16031 16032 16033 16034 16035 16036 16037 16038 16039 16040 16041 16042 16043 16044 16045 16046 16047 16048 16049 16050 16051 16052 16053 16054 16055 16056 16057 16058 16059 16060 16061 16062 16063 16064 16065 16066 16067 16068 16069 16070 16071 16072 16073 16074 16075 16076 16077 16078 16079 16080 16081 16082 16083 16084 16085 16086 16087 16088 16089 16090 16091 16092 16093 16094 16095 16096 16097 16098 16099 16100 16101 16102 16103 16104 16105 16106 16107 16108 16109 16110 16111 16112 16113 16114 16115 16116 16117 16118 16119 16120 16121 16122 16123 16124 16125 16126 16127 16128 16129 16130 16131 16132 16133 16134 16135 16136 16137 16138 16139 16140 16141 16142 16143 16144 16145 16146 16147 16148 16149 16150 16151 16152 16153 16154 16155 16156 16157 16158 16159 16160 16161 16162 16163 16164 16165 16166 16167 16168 16169 16170 16171 16172 16173 16174 16175 16176 16177 16178 16179 16180 16181 16182 16183 16184 16185 16186 16187 16188 16189 16190 16191 16192 16193 16194 16195 16196 16197 16198 16199 16200 16201 16202 16203 16204 16205 16206 16207 16208 16209 16210 16211 16212 16213 16214 16215 16216 16217 16218 16219 16220 16221 16222 16223 16224 16225 16226 16227 16228 16229 16230 16231 16232 16233 16234 16235 16236 16237 16238 16239 16240 16241 16242 16243 16244 16245 16246 16247 16248 16249 16250 16251 16252 16253 16254 16255 16256 16257 16258 16259 16260 16261 16262 16263 16264 16265 16266 16267 16268 16269 16270 16271 16272 16273 16274 16275 16276 16277 16278 16279 16280 16281 16282 16283 16284 16285 16286 16287 16288 16289 16290 16291 16292 16293 16294 16295 16296 16297 16298 16299 16300 16301 16302 16303 16304 16305 16306 16307 16308 16309 16310 16311 16312 16313 16314 16315 16316 16317 16318 16319 16320 16321 16322 16323 16324 16325 16326 16327 16328 16329 16330 16331 16332 16333 16334 16335 16336 16337 16338 16339 16340 16341 16342 16343 16344 16345 16346 16347 16348 16349 16350 16351 16352 16353 16354 16355 16356 16357 16358 16359 16360 16361 16362 16363 16364 16365 16366 16367 16368 16369 16370 16371 16372 16373 16374 16375 16376 16377 16378 16379 16380 16381 16382 16383 16384 16385 16386 16387 16388 16389 16390 16391 16392 16393 16394 16395 16396 16397 16398
		case NN_vfnmadd213ss:         // Fused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values
		case NN_vfnmadd231pd:         // Fused Negative Multiply-Add of Packed Double-Precision Floating-Point Values
		case NN_vfnmadd231ps:         // Fused Negative Multiply-Add of Packed Single-Precision Floating-Point Values
		case NN_vfnmadd231sd:         // Fused Negative Multiply-Add of Scalar Double-Precision Floating-Point Values
		case NN_vfnmadd231ss:         // Fused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values
		case NN_vfnmsub132pd:         // Fused Negative Multiply-Subtract of Packed Double-Precision Floating-Point Values
		case NN_vfnmsub132ps:         // Fused Negative Multiply-Subtract of Packed Single-Precision Floating-Point Values
		case NN_vfnmsub132sd:         // Fused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values
		case NN_vfnmsub132ss:         // Fused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values
		case NN_vfnmsub213pd:         // Fused Negative Multiply-Subtract of Packed Double-Precision Floating-Point Values
		case NN_vfnmsub213ps:         // Fused Negative Multiply-Subtract of Packed Single-Precision Floating-Point Values
		case NN_vfnmsub213sd:         // Fused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values
		case NN_vfnmsub213ss:         // Fused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values
		case NN_vfnmsub231pd:         // Fused Negative Multiply-Subtract of Packed Double-Precision Floating-Point Values
		case NN_vfnmsub231ps:         // Fused Negative Multiply-Subtract of Packed Single-Precision Floating-Point Values
		case NN_vfnmsub231sd:         // Fused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values
		case NN_vfnmsub231ss:         // Fused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values
			return this->BuildBinaryRTL(SMP_BINARY_FLOATING_ARITHMETIC);
			break;

		case NN_vgatherdps:           // Gather Packed SP FP Values Using Signed Dword Indices
		case NN_vgatherdpd:           // Gather Packed DP FP Values Using Signed Dword Indices
		case NN_vgatherqps:           // Gather Packed SP FP Values Using Signed Qword Indices
		case NN_vgatherqpd:           // Gather Packed DP FP Values Using Signed Qword Indices
			return this->BuildMoveRTL(SMP_NULL_OPERATOR);
			break;

		case NN_vhaddpd:              // Add horizontally packed DP FP numbers
		case NN_vhaddps:              // Add horizontally packed SP FP numbers
		case NN_vhsubpd:              // Sub horizontally packed DP FP numbers
		case NN_vhsubps:              // Sub horizontally packed SP FP numbers
			return this->BuildBinaryRTL(SMP_BINARY_FLOATING_ARITHMETIC);
			break;

		case NN_vinsertf128:          // Insert Packed Floating-Point Values
		case NN_vinserti128:          // Insert Packed Integer Values
		case NN_vinsertps:            // Insert Packed Single Precision Floating-Point Value
		case NN_vlddqu:               // Load Unaligned Packed Integer Values
		case NN_vldmxcsr:             // Load Streaming SIMD Extensions Technology Control/Status Register
			return false;
			break;

		case NN_vmaskmovdqu:          // Store Selected Bytes of Double Quadword with NT Hint
		case NN_vmaskmovpd:           // Conditionally Load Packed Double-Precision Floating-Point Values
		case NN_vmaskmovps:           // Conditionally Load Packed Single-Precision Floating-Point Values
			return this->BuildMoveRTL(SMP_NULL_OPERATOR);
			break;

		case NN_vmaxpd:               // Return Maximum Packed Double-Precision Floating-Point Values
		case NN_vmaxps:               // Packed Single-FP Maximum
		case NN_vmaxsd:               // Return Maximum Scalar Double-Precision Floating-Point Value
		case NN_vmaxss:               // Scalar Single-FP Maximum
		case NN_vminpd:               // Return Minimum Packed Double-Precision Floating-Point Values
		case NN_vminps:               // Packed Single-FP Minimum
		case NN_vminsd:               // Return Minimum Scalar Double-Precision Floating-Point Value
		case NN_vminss:               // Scalar Single-FP Minimum
			return this->BuildBinaryRTL(SMP_BINARY_FLOATING_ARITHMETIC);
			break;

		case NN_vmovapd:              // Move Aligned Packed Double-Precision Floating-Point Values
		case NN_vmovaps:              // Move Aligned Four Packed Single-FP
		case NN_vmovd:                // Move 32 bits
		case NN_vmovddup:             // Move One Double-FP and Duplicate
		case NN_vmovdqa:              // Move Aligned Double Quadword
		case NN_vmovdqu:              // Move Unaligned Double Quadword
		case NN_vmovhlps:             // Move High to Low Packed Single-FP
		case NN_vmovhpd:              // Move High Packed Double-Precision Floating-Point Values
		case NN_vmovhps:              // Move High Packed Single-FP
		case NN_vmovlhps:             // Move Low to High Packed Single-FP
		case NN_vmovlpd:              // Move Low Packed Double-Precision Floating-Point Values
		case NN_vmovlps:              // Move Low Packed Single-FP
		case NN_vmovmskpd:            // Extract Packed Double-Precision Floating-Point Sign Mask
		case NN_vmovmskps:            // Move Mask to Register
		case NN_vmovntdq:             // Store Double Quadword Using Non-Temporal Hint
		case NN_vmovntdqa:            // Load Double Quadword Non-Temporal Aligned Hint
		case NN_vmovntpd:             // Store Packed Double-Precision Floating-Point Values Using Non-Temporal Hint
		case NN_vmovntps:             // Move Aligned Four Packed Single-FP Non Temporal
		case NN_vmovntsd:             // Move Non-Temporal Scalar Double-Precision Floating-Point
		case NN_vmovntss:             // Move Non-Temporal Scalar Single-Precision Floating-Point
		case NN_vmovq:                // Move 64 bits
		case NN_vmovsd:               // Move Scalar Double-Precision Floating-Point Values
		case NN_vmovshdup:            // Move Packed Single-FP High and Duplicate
		case NN_vmovsldup:            // Move Packed Single-FP Low and Duplicate
		case NN_vmovss:               // Move Scalar Single-FP
		case NN_vmovupd:              // Move Unaligned Packed Double-Precision Floating-Point Values
		case NN_vmovups:              // Move Unaligned Four Packed Single-FP
			return this->BuildMoveRTL(SMP_NULL_OPERATOR);
			break;

		case NN_vmpsadbw:             // Compute Multiple Packed Sums of Absolute Difference
		case NN_vmulpd:               // Multiply Packed Double-Precision Floating-Point Values
		case NN_vmulps:               // Packed Single-FP Multiply
		case NN_vmulsd:               // Multiply Scalar Double-Precision Floating-Point Values
		case NN_vmulss:               // Scalar Single-FP Multiply
		case NN_vorpd:                // Bitwise Logical OR of Double-Precision Floating-Point Values
		case NN_vorps:                // Bitwise Logical OR for Single-FP Data
		case NN_vpabsb:               // Packed Absolute Value Byte
		case NN_vpabsd:               // Packed Absolute Value Doubleword
		case NN_vpabsw:               // Packed Absolute Value Word
		case NN_vpackssdw:            // Pack with Signed Saturation (Dword->Word)
		case NN_vpacksswb:            // Pack with Signed Saturation (Word->Byte)
		case NN_vpackusdw:            // Pack with Unsigned Saturation
		case NN_vpackuswb:            // Pack with Unsigned Saturation (Word->Byte)
		case NN_vpaddb:               // Packed Add Byte
		case NN_vpaddd:               // Packed Add Dword
		case NN_vpaddq:               // Add Packed Quadword Integers
		case NN_vpaddsb:              // Packed Add with Saturation (Byte)
		case NN_vpaddsw:              // Packed Add with Saturation (Word)
		case NN_vpaddusb:             // Packed Add Unsigned with Saturation (Byte)
		case NN_vpaddusw:             // Packed Add Unsigned with Saturation (Word)
		case NN_vpaddw:               // Packed Add Word
		case NN_vpalignr:             // Packed Align Right
		case NN_vpand:                // Bitwise Logical And
		case NN_vpandn:               // Bitwise Logical And Not
		case NN_vpavgb:               // Packed Average (Byte)
		case NN_vpavgw:               // Packed Average (Word)
			return this->BuildBinaryRTL(SMP_BINARY_FLOATING_ARITHMETIC);
			break;

		case NN_vpblendd:             // Blend Packed Dwords
		case NN_vpblendvb:            // Variable Blend Packed Bytes
		case NN_vpblendw:             // Blend Packed Words
			return this->BuildBinaryRTL(SMP_SHUFFLE);
			break;

		case NN_vpbroadcastb:         // Broadcast a Byte Integer
		case NN_vpbroadcastd:         // Broadcast a Dword Integer
		case NN_vpbroadcastq:         // Broadcast a Qword Integer
		case NN_vpbroadcastw:         // Broadcast a Word Integer
		case NN_vpclmulqdq:           // Carry-Less Multiplication Quadword
		case NN_vpcmpeqb:             // Packed Compare for Equal (Byte)
		case NN_vpcmpeqd:             // Packed Compare for Equal (Dword)
		case NN_vpcmpeqq:             // Compare Packed Qword Data for Equal
		case NN_vpcmpeqw:             // Packed Compare for Equal (Word)
		case NN_vpcmpestri:           // Packed Compare Explicit Length Strings, Return Index
		case NN_vpcmpestrm:           // Packed Compare Explicit Length Strings, Return Mask
		case NN_vpcmpgtb:             // Packed Compare for Greater Than (Byte)
		case NN_vpcmpgtd:             // Packed Compare for Greater Than (Dword)
		case NN_vpcmpgtq:             // Compare Packed Data for Greater Than
		case NN_vpcmpgtw:             // Packed Compare for Greater Than (Word)
		case NN_vpcmpistri:           // Packed Compare Implicit Length Strings, Return Index
		case NN_vpcmpistrm:           // Packed Compare Implicit Length Strings, Return Mask
		case NN_vperm2f128:           // Permute Floating-Point Values
		case NN_vperm2i128:           // Permute Integer Values
		case NN_vpermd:               // Full Doublewords Element Permutation
		case NN_vpermilpd:            // Permute Double-Precision Floating-Point Values
		case NN_vpermilps:            // Permute Single-Precision Floating-Point Values
		case NN_vpermpd:              // Permute Double-Precision Floating-Point Elements
		case NN_vpermps:              // Permute Single-Precision Floating-Point Elements
		case NN_vpermq:               // Qwords Element Permutation
		case NN_vpextrb:              // Extract Byte
		case NN_vpextrd:              // Extract Dword
		case NN_vpextrq:              // Extract Qword
		case NN_vpextrw:              // Extract Word
		case NN_vpgatherdd:           // Gather Packed Dword Values Using Signed Dword Indices
		case NN_vpgatherdq:           // Gather Packed Qword Values Using Signed Dword Indices
		case NN_vpgatherqd:           // Gather Packed Dword Values Using Signed Qword Indices
		case NN_vpgatherqq:           // Gather Packed Qword Values Using Signed Qword Indices
			return this->BuildBinaryRTL(SMP_BINARY_FLOATING_ARITHMETIC);
			break;

		case NN_vphaddd:              // Packed Horizontal Add Doubleword
		case NN_vphaddsw:             // Packed Horizontal Add and Saturate
		case NN_vphaddw:              // Packed Horizontal Add Word
		case NN_vphminposuw:          // Packed Horizontal Word Minimum
		case NN_vphsubd:              // Packed Horizontal Subtract Doubleword
		case NN_vphsubsw:             // Packed Horizontal Subtract and Saturate
		case NN_vphsubw:              // Packed Horizontal Subtract Word
			return this->BuildBinaryRTL(SMP_BINARY_FLOATING_ARITHMETIC);
			break;

		case NN_vpinsrb:              // Insert Byte
		case NN_vpinsrd:              // Insert Dword
		case NN_vpinsrq:              // Insert Qword
		case NN_vpinsrw:              // Insert Word
			return false;
			break;

		case NN_vpmaddubsw:           // Multiply and Add Packed Signed and Unsigned Bytes
		case NN_vpmaddwd:             // Packed Multiply and Add
			return this->BuildBinaryRTL(SMP_BINARY_FLOATING_ARITHMETIC);
			break;

		case NN_vpmaskmovd:           // Conditionally Store Dword Values Using Mask
		case NN_vpmaskmovq:           // Conditionally Store Qword Values Using Mask
			return false;
			break;

		case NN_vpmaxsb:              // Maximum of Packed Signed Byte Integers
		case NN_vpmaxsd:              // Maximum of Packed Signed Dword Integers
		case NN_vpmaxsw:              // Packed Signed Integer Word Maximum
			return this->BuildBinaryRTL(SMP_MAX_S);
			break;

		case NN_vpmaxub:              // Packed Unsigned Integer Byte Maximum
		case NN_vpmaxud:              // Maximum of Packed Unsigned Dword Integers
		case NN_vpmaxuw:              // Maximum of Packed Word Integers
			return this->BuildBinaryRTL(SMP_MAX_U);
			break;

		case NN_vpminsb:              // Minimum of Packed Signed Byte Integers
		case NN_vpminsd:              // Minimum of Packed Signed Dword Integers
		case NN_vpminsw:              // Packed Signed Integer Word Minimum
			return this->BuildBinaryRTL(SMP_MIN_S);
			break;

		case NN_vpminub:              // Packed Unsigned Integer Byte Minimum
		case NN_vpminud:              // Minimum of Packed Unsigned Dword Integers
		case NN_vpminuw:              // Minimum of Packed Word Integers
			return this->BuildBinaryRTL(SMP_MIN_U);
			break;

		case NN_vpmovmskb:            // Move Byte Mask to Integer
			return this->BuildMoveRTL(SMP_NULL_OPERATOR);
			break;

		case NN_vpmovsxbd:            // Packed Move with Sign Extend
		case NN_vpmovsxbq:            // Packed Move with Sign Extend
		case NN_vpmovsxbw:            // Packed Move with Sign Extend
		case NN_vpmovsxdq:            // Packed Move with Sign Extend
		case NN_vpmovsxwd:            // Packed Move with Sign Extend
		case NN_vpmovsxwq:            // Packed Move with Sign Extend
			return this->BuildUnary2OpndRTL(SMP_SIGN_EXTEND);
			break;

		case NN_vpmovzxbd:            // Packed Move with Zero Extend
		case NN_vpmovzxbq:            // Packed Move with Zero Extend
		case NN_vpmovzxbw:            // Packed Move with Zero Extend
		case NN_vpmovzxdq:            // Packed Move with Zero Extend
		case NN_vpmovzxwd:            // Packed Move with Zero Extend
		case NN_vpmovzxwq:            // Packed Move with Zero Extend
			return this->BuildUnary2OpndRTL(SMP_ZERO_EXTEND);
			break;

		case NN_vpmuldq:              // Multiply Packed Signed Dword Integers
		case NN_vpmulhrsw:            // Packed Multiply High with Round and Scale
		case NN_vpmulhuw:             // Packed Multiply High Unsigned
		case NN_vpmulhw:              // Packed Multiply High
		case NN_vpmulld:              // Multiply Packed Signed Dword Integers and Store Low Result
		case NN_vpmullw:              // Packed Multiply Low
		case NN_vpmuludq:             // Multiply Packed Unsigned Doubleword Integers
		case NN_vpor:                 // Bitwise Logical Or
		case NN_vpsadbw:              // Packed Sum of Absolute Differences
			return this->BuildBinaryRTL(SMP_BINARY_FLOATING_ARITHMETIC);
			break;

		case NN_vpshufb:              // Packed Shuffle Bytes
		case NN_vpshufd:              // Shuffle Packed Doublewords
		case NN_vpshufhw:             // Shuffle Packed High Words
		case NN_vpshuflw:             // Shuffle Packed Low Words
			return this->BuildBinaryRTL(SMP_SHUFFLE);
			break;

		case NN_vpsignb:              // Packed SIGN Byte
		case NN_vpsignd:              // Packed SIGN Doubleword
		case NN_vpsignw:              // Packed SIGN Word
			return false;
			break;

		case NN_vpslld:               // Packed Shift Left Logical (Dword)
		case NN_vpslldq:              // Shift Double Quadword Left Logical
		case NN_vpsllq:               // Packed Shift Left Logical (Qword)
		case NN_vpsllvd:              // Variable Bit Shift Left Logical (Dword)
		case NN_vpsllvq:              // Variable Bit Shift Left Logical (Qword)
		case NN_vpsllw:               // Packed Shift Left Logical (Word)
		case NN_vpsrad:               // Packed Shift Right Arithmetic (Dword)
		case NN_vpsravd:              // Variable Bit Shift Right Arithmetic
		case NN_vpsraw:               // Packed Shift Right Arithmetic (Word)
		case NN_vpsrld:               // Packed Shift Right Logical (Dword)
		case NN_vpsrldq:              // Shift Double Quadword Right Logical (Qword)
		case NN_vpsrlq:               // Packed Shift Right Logical (Qword)
		case NN_vpsrlvd:              // Variable Bit Shift Right Logical (Dword)
		case NN_vpsrlvq:              // Variable Bit Shift Right Logical (Qword)
		case NN_vpsrlw:               // Packed Shift Right Logical (Word)
			return this->BuildBinaryRTL(SMP_BINARY_FLOATING_ARITHMETIC);
			break;

		case NN_vpsubb:               // Packed Subtract Byte
		case NN_vpsubd:               // Packed Subtract Dword
		case NN_vpsubq:               // Subtract Packed Quadword Integers
		case NN_vpsubsb:              // Packed Subtract with Saturation (Byte)
		case NN_vpsubsw:              // Packed Subtract with Saturation (Word)
		case NN_vpsubusb:             // Packed Subtract Unsigned with Saturation (Byte)
		case NN_vpsubusw:             // Packed Subtract Unsigned with Saturation (Word)
		case NN_vpsubw:               // Packed Subtract Word
			return this->BuildBinaryRTL(SMP_BINARY_FLOATING_ARITHMETIC);
			break;

		case NN_vptest:               // Logical Compare
			return false;
			break;

		case NN_vpunpckhbw:           // Unpack High Packed Data (Byte->Word)
		case NN_vpunpckhdq:           // Unpack High Packed Data (Dword->Qword)
		case NN_vpunpckhqdq:          // Unpack High Packed Data (Qword->Xmmword)
		case NN_vpunpckhwd:           // Unpack High Packed Data (Word->Dword)
		case NN_vpunpcklbw:           // Unpack Low Packed Data (Byte->Word)
		case NN_vpunpckldq:           // Unpack Low Packed Data (Dword->Qword)
		case NN_vpunpcklqdq:          // Unpack Low Packed Data (Qword->Xmmword)
		case NN_vpunpcklwd:           // Unpack Low Packed Data (Word->Dword)
			return this->BuildBinaryRTL(SMP_INTERLEAVE);
			break;

		case NN_vpxor:                // Bitwise Logical Exclusive Or
		case NN_vrcpps:               // Packed Single-FP Reciprocal
		case NN_vrcpss:               // Scalar Single-FP Reciprocal
			return this->BuildBinaryRTL(SMP_BINARY_FLOATING_ARITHMETIC);
			break;

		case NN_vroundpd:             // Round Packed Double Precision Floating-Point Values
		case NN_vroundps:             // Round Packed Single Precision Floating-Point Values
		case NN_vroundsd:             // Round Scalar Double Precision Floating-Point Values
		case NN_vroundss:             // Round Scalar Single Precision Floating-Point Values
		case NN_vrsqrtps:             // Packed Single-FP Square Root Reciprocal
		case NN_vrsqrtss:             // Scalar Single-FP Square Root Reciprocal
			return false;
			break;

		case NN_vshufpd:              // Shuffle Packed Double-Precision Floating-Point Values
		case NN_vshufps:              // Shuffle Single-FP
			return this->BuildBinaryRTL(SMP_SHUFFLE);
			break;

		case NN_vsqrtpd:              // Compute Square Roots of Packed Double-Precision Floating-Point Values
		case NN_vsqrtps:              // Packed Single-FP Square Root
		case NN_vsqrtsd:              // Compute Square Rootof Scalar Double-Precision Floating-Point Value
		case NN_vsqrtss:              // Scalar Single-FP Square Root
		case NN_vstmxcsr:             // Store Streaming SIMD Extensions Technology Control/Status Register
			return false;
			break;

		case NN_vsubpd:               // Subtract Packed Double-Precision Floating-Point Values
		case NN_vsubps:               // Packed Single-FP Subtract
		case NN_vsubsd:               // Subtract Scalar Double-Precision Floating-Point Values
		case NN_vsubss:               // Scalar Single-FP Subtract
			return this->BuildBinaryRTL(SMP_BINARY_FLOATING_ARITHMETIC);
			break;

		case NN_vtestpd:              // Packed Double-Precision Floating-Point Bit Test
		case NN_vtestps:              // Packed Single-Precision Floating-Point Bit Test
		case NN_vucomisd:             // Unordered Compare Scalar Ordered Double-Precision Floating-Point Values and Set EFLAGS
		case NN_vucomiss:             // Scalar Unordered Single-FP Compare and Set EFLAGS
			return false;
			break;

		case NN_vunpckhpd:            // Unpack and Interleave High Packed Double-Precision Floating-Point Values
		case NN_vunpckhps:            // Unpack High Packed Single-FP Data
		case NN_vunpcklpd:            // Unpack and Interleave Low Packed Double-Precision Floating-Point Values
		case NN_vunpcklps:            // Unpack Low Packed Single-FP Data
			return this->BuildBinaryRTL(SMP_INTERLEAVE);
			break;

		case NN_vxorpd:               // Bitwise Logical OR of Double-Precision Floating-Point Values
		case NN_vxorps:               // Bitwise Logical XOR for Single-FP Data
			return this->BuildBinaryRTL(SMP_BINARY_FLOATING_ARITHMETIC);
			break;

		case NN_vzeroall:             // Zero All YMM Registers
		case NN_vzeroupper:           // Zero Upper Bits of YMM Registers
			NopRT = new SMPRegTransfer;
			NopRT->SetParentInst(this);
			NopRT->SetOperator(SMP_NULL_OPERATOR);
			this->RTL.push_back(NopRT);
			NopRT = NULL;
			return true;

// Transactional Synchronization Extensions

		case NN_xabort:               // Transaction Abort
		case NN_xbegin:               // Transaction Begin
		case NN_xend:                 // Transaction End
		case NN_xtest:                // Test If In Transactional Execution
			return false;
			break;

// Virtual PC synthetic instructions

		case NN_vmgetinfo:            // Virtual PC - Get VM Information
		case NN_vmsetinfo:            // Virtual PC - Set VM Information
		case NN_vmdxdsbl:             // Virtual PC - Disable Direct Execution
		case NN_vmdxenbl:             // Virtual PC - Enable Direct Execution
		case NN_vmcpuid:              // Virtual PC - Virtualized CPU Information
		case NN_vmhlt:                // Virtual PC - Halt
		case NN_vmsplaf:              // Virtual PC - Spin Lock Acquisition Failed
		case NN_vmpushfd:             // Virtual PC - Push virtualized flags register
		case NN_vmpopfd:              // Virtual PC - Pop virtualized flags register
		case NN_vmcli:                // Virtual PC - Clear Interrupt Flag
		case NN_vmsti:                // Virtual PC - Set Interrupt Flag
		case NN_vmiretd:              // Virtual PC - Return From Interrupt
		case NN_vmsgdt:               // Virtual PC - Store Global Descriptor Table
		case NN_vmsidt:               // Virtual PC - Store Interrupt Descriptor Table
		case NN_vmsldt:               // Virtual PC - Store Local Descriptor Table
		case NN_vmstr:                // Virtual PC - Store Task Register
		case NN_vmsdte:               // Virtual PC - Store to Descriptor Table Entry
		case NN_vpcext:               // Virtual PC - ISA extension
			return false;
			break;

#endif // 599 < IDA_SDK_VERSION

			SMP_msg("ERROR: Unknown instruction opcode at %lx : %s\n", (unsigned long) 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(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) {
	// 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()));
		SMP_msg("SyncRTLDefUse entered. Dump of USE list:\n");
	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
			SMP_msg("WARNING: DEF not found for SMP_ASSIGN in %s ; added op:", DisAsmText.GetDisAsm(this->GetAddr()));
			PrintOperand(LeftOp);
			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
				PrintOperand(LeftOp);
				SMP_msg(" in %s ; added\n", DisAsmText.GetDisAsm(this->GetAddr()));
				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
				PrintOperand(RightOp);
				SMP_msg(" in %s ; added\n", DisAsmText.GetDisAsm(this->GetAddr()));
				this->Uses.SetRef(RightOp);
			}
		}
	}
	else { // recurse into right subtree
		this->SyncRTLDefUse(CurrRT->GetRightTree(), UseFP, FPDelta);

	// 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 NewType = OpType;
	if (Instr->GetBlock()->GetFunc()->GetIsSpeculative()) {
		NewType = (SMPOperandType) (((int)NewType) | PROF_BASE);
#if SMP_TRACK_NONSPEC_OPER_TYPE
		SMPOperandType OldType = RTop.type;
		if (!IsProfDerived(OldType))
			RTop.NonSpeculativeType = OldType;
#endif
	}

	RTop.type = NewType; 
} // end of SMPRegTransfer::SetOperatorType

// 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();
	// 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()

// 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()