Skip to content
Snippets Groups Projects
SMPDataFlowAnalysis.cpp 285 KiB
Newer Older
	InsertResult = UnsignedArgPositionMap.insert(MapEntry);
	assert(InsertResult.second);

	// <stdio.h>
	MapEntry.first = string("setvbuf");
	MapEntry.second = STARS_ARG_POS_3;
	InsertResult = UnsignedArgPositionMap.insert(MapEntry);
	assert(InsertResult.second);

	return;
}

// Return unsigned arg position bitset for call name from the unsigned arg map.
// If we don't care find the call name, we return 0 in ArgPosBits.
void GetUnsignedArgPositionsForCallName(string CalleeName, unsigned int &ArgPosBits) {
	map<string, unsigned int>::iterator MapIter;

	ArgPosBits = 0; // Change if found later
	MapIter = UnsignedArgPositionMap.find(CalleeName);

	if (MapIter != UnsignedArgPositionMap.end()) { // found it
		ArgPosBits = MapIter->second;
	}
	return;
}

// Map of function names to arguments that are dangerous to supply
//  with user-tainted input values.
static map<string, unsigned int> TaintWarningArgPositionMap;

void InitTaintWarningArgPositionMap(void) {
	pair<string, unsigned int> MapEntry;
	pair<map<string, unsigned int>::iterator, bool> InsertResult;

	// <string.h>
	MapEntry.first = string("memchr");
	MapEntry.second = STARS_ARG_POS_2;
	InsertResult = TaintWarningArgPositionMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = string("memcmp");
	MapEntry.second = STARS_ARG_POS_2;
	InsertResult = TaintWarningArgPositionMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = string("memcpy");
	MapEntry.second = STARS_ARG_POS_2;
	InsertResult = TaintWarningArgPositionMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = string("memmove");
	MapEntry.second = STARS_ARG_POS_2;
	InsertResult = TaintWarningArgPositionMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = string("memset");
	MapEntry.second = STARS_ARG_POS_2;
	InsertResult = TaintWarningArgPositionMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = string("strncat");
	MapEntry.second = STARS_ARG_POS_2;
	InsertResult = TaintWarningArgPositionMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = string("strncmp");
	MapEntry.second = STARS_ARG_POS_2;
	InsertResult = TaintWarningArgPositionMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = string("strncpy");
	MapEntry.second = STARS_ARG_POS_2;
	InsertResult = TaintWarningArgPositionMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = string("strxfrm");
	MapEntry.second = STARS_ARG_POS_2;
	InsertResult = TaintWarningArgPositionMap.insert(MapEntry);
	assert(InsertResult.second);

	// <stdlib.h>
	MapEntry.first = string("malloc");
	MapEntry.second = STARS_ARG_POS_0;
	InsertResult = TaintWarningArgPositionMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = string("calloc");
	MapEntry.second = (STARS_ARG_POS_0 | STARS_ARG_POS_1);
	InsertResult = TaintWarningArgPositionMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = string("realloc");
	MapEntry.second = STARS_ARG_POS_1;
	InsertResult = TaintWarningArgPositionMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = string("bsearch");
	MapEntry.second = (STARS_ARG_POS_2 | STARS_ARG_POS_3);
	InsertResult = TaintWarningArgPositionMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = string("qsort");
	MapEntry.second = (STARS_ARG_POS_1 | STARS_ARG_POS_2);
	InsertResult = TaintWarningArgPositionMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = string("mblen");
	MapEntry.second = STARS_ARG_POS_1;
	InsertResult = TaintWarningArgPositionMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = string("mbtowc");
	MapEntry.second = STARS_ARG_POS_2;
	InsertResult = TaintWarningArgPositionMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = string("mbstowcs");
	MapEntry.second = STARS_ARG_POS_2;
	InsertResult = TaintWarningArgPositionMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = string("wcstombs");
	MapEntry.second = STARS_ARG_POS_2;
	InsertResult = TaintWarningArgPositionMap.insert(MapEntry);
	assert(InsertResult.second);

	// <stdio.h>
	MapEntry.first = string("setvbuf");
	MapEntry.second = STARS_ARG_POS_3;
	InsertResult = TaintWarningArgPositionMap.insert(MapEntry);
	assert(InsertResult.second);

	return;
}

// Return unsigned arg position bitset for call name from the taint warning map.
// If we don't care find the call name, we return 0 in ArgPosBits.
void GetTaintWarningArgPositionsForCallName(string CalleeName, unsigned int &ArgPosBits) {
	map<string, unsigned int>::iterator MapIter;

	ArgPosBits = 0; // Change if found later
	MapIter = TaintWarningArgPositionMap.find(CalleeName);

	if (MapIter != TaintWarningArgPositionMap.end()) { // found it
		ArgPosBits = MapIter->second;
	}
	return;
}

// Utility to count bits set in an unsigned int, e.g. ArgPosBits.
unsigned int CountBitsSet(unsigned int ArgPosBits) {
	unsigned int count; // count accumulates the total bits set in ArgPosBits
	for (count = 0; ArgPosBits; ++count) {
		ArgPosBits &= (ArgPosBits - 1); // clear the least significant bit set
	}
	// Brian Kernighan's method goes through as many iterations as there are set bits. 
	//  So if we have a 32-bit word with only the high bit set, then it will only go once through the loop.
	// Published in 1988, the C Programming Language 2nd Ed. (by Brian W. Kernighan and Dennis M. Ritchie) mentions this in exercise 2-9.
	//  On April 19, 2006 Don Knuth pointed out to me that this method "was first published by Peter Wegner in CACM 3 (1960), 322.
	//  (Also discovered independently by Derrick Lehmer and published in 1964 in a book edited by Beckenbach.)"
	return count;
}

// Initialize the FG info for the return register from any library function
//  whose name implies that we know certain return values (e.g. atoi() returns
//  a signed integer, while strtoul() returns an unsigned long).
void GetLibFuncFGInfo(string FuncName, struct FineGrainedInfo &InitFGInfo) {
	map<string, struct FineGrainedInfo>::iterator FindIter;

	FindIter = ReturnRegisterTypeMap.find(FuncName);
	if (FindIter == ReturnRegisterTypeMap.end()) { // not found
		InitFGInfo.SignMiscInfo = 0;
		InitFGInfo.SizeInfo = 0;
	}
	else { // found
		InitFGInfo = FindIter->second;
	}
	return;
} // end of GetLibFuncFGInfo()

// Initialize the lookup maps that are used to define the FG info that can
//  be inferred from a library function name.
void InitLibFuncFGInfoMaps(void) {
	op_t DummyOp = InitOp;
	struct FineGrainedInfo FGEntry;
	pair<string, struct FineGrainedInfo> MapEntry;
	pair<map<string, struct FineGrainedInfo>::iterator, bool> InsertResult;

	// Add functions that return signed integers.
	FGEntry.SignMiscInfo = FG_MASK_SIGNED;
	FGEntry.SizeInfo = (FG_MASK_INTEGER | ComputeOperandBitWidthMask(DummyOp, sizeof(int)));
	MapEntry.second = FGEntry;

	MapEntry.first = "atoi";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "strcmp";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "strncmp";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "memcmp";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "isalnum";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "isalpha";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "islower";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "isupper";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "isdigit";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "isxdigit";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "iscntrl";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "isgraph";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "isblank";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "isspace";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "isprint";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "ispunct";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	// Functions that return signed longs.
	if (sizeof(long int) != sizeof(int)) {
		FGEntry.SizeInfo = (FG_MASK_INTEGER | ComputeOperandBitWidthMask(DummyOp, sizeof(long int)));
		MapEntry.second = FGEntry;
	}

	MapEntry.first = "atol";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "strtol";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	// Functions that return signed long longs.
	if (sizeof(long long int) != sizeof(long int)) {
		FGEntry.SizeInfo = (FG_MASK_INTEGER | ComputeOperandBitWidthMask(DummyOp, sizeof(long long int)));
		MapEntry.second = FGEntry;
	}

	MapEntry.first = "atoll";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "strtoll";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	// Functions that return unsigned long longs.
	FGEntry.SignMiscInfo = FG_MASK_UNSIGNED;
	MapEntry.second = FGEntry;

	MapEntry.first = "strtoull";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	// Functions that return unsigned longs.
	if (sizeof(long long int) != sizeof(long int)) {
		FGEntry.SizeInfo = (FG_MASK_INTEGER | ComputeOperandBitWidthMask(DummyOp, sizeof(long int)));
		MapEntry.second = FGEntry;
	}

	MapEntry.first = "strtoul";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	// Functions that return size_t.
	FGEntry.SizeInfo = (FG_MASK_INTEGER | ComputeOperandBitWidthMask(DummyOp, sizeof(size_t)));
	FGEntry.SignMiscInfo = FG_MASK_UNSIGNED;
	MapEntry.second = FGEntry;

	MapEntry.first = "strlen";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "strxfrm";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "strspn";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "strcspn";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	// Functions that return (char *).
	FGEntry.SizeInfo = (FG_MASK_DATAPOINTER | ComputeOperandBitWidthMask(DummyOp, sizeof(char *)));
	FGEntry.SignMiscInfo = FG_MASK_UNSIGNED;
	MapEntry.second = FGEntry;

	MapEntry.first = "strcpy";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "strncpy";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "strcat";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "strncat";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "strcoll";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "strchr";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "strrchr";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "strpbrk";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "strstr";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "strtok";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "strerror";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	// Functions that return (void *).
	if (sizeof(void *) != sizeof(char *)) {
		FGEntry.SizeInfo = (FG_MASK_DATAPOINTER | ComputeOperandBitWidthMask(DummyOp, sizeof(void *)));
		MapEntry.second = FGEntry;
	}

	MapEntry.first = "malloc";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "calloc";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "realloc";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "memchr";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "memcpy";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "mempcpy";  // non-standard, found in glibc
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "memmove";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	MapEntry.first = "memset";
	InsertResult = ReturnRegisterTypeMap.insert(MapEntry);
	assert(InsertResult.second);

	// Functions that return bool.
	FGEntry.SizeInfo = (FG_MASK_INTEGER | ComputeOperandBitWidthMask(DummyOp, sizeof(bool)));
	FGEntry.SignMiscInfo = FG_MASK_UNSIGNED;
	MapEntry.second = FGEntry;


	// NOTE: Add <math.h> functions later.

	return;
} // end of InitLibFuncFGInfoMaps()

clc5q's avatar
clc5q committed
// Initialize the DFACategory[] array to define instruction classes
//   for the purposes of data flow analysis.
void InitDFACategory(void) {
	// Default category is 0, not the start or end of a basic block.
	(void) memset(DFACategory, 0, sizeof(DFACategory));

DFACategory[NN_call] = CALL;                // Call Procedure
DFACategory[NN_callfi] = INDIR_CALL;              // Indirect Call Far Procedure
DFACategory[NN_callni] = INDIR_CALL;              // Indirect Call Near Procedure

DFACategory[NN_hlt] = HALT;                 // Halt

DFACategory[NN_int] = INDIR_CALL;                 // Call to Interrupt Procedure
DFACategory[NN_into] = INDIR_CALL;                // Call to Interrupt Procedure if Overflow Flag = 1
DFACategory[NN_int3] = INDIR_CALL;                // Trap to Debugger
clc5q's avatar
clc5q committed
DFACategory[NN_iretw] = RETURN;               // Interrupt Return
DFACategory[NN_iret] = RETURN;                // Interrupt Return
DFACategory[NN_iretd] = RETURN;               // Interrupt Return (use32)
DFACategory[NN_iretq] = RETURN;               // Interrupt Return (use64)
DFACategory[NN_ja] = COND_BRANCH;                  // Jump if Above (CF=0 & ZF=0)
DFACategory[NN_jae] = COND_BRANCH;                 // Jump if Above or Equal (CF=0)
DFACategory[NN_jb] = COND_BRANCH;                  // Jump if Below (CF=1)
DFACategory[NN_jbe] = COND_BRANCH;                 // Jump if Below or Equal (CF=1 | ZF=1)
DFACategory[NN_jc] = COND_BRANCH;                  // Jump if Carry (CF=1)
DFACategory[NN_jcxz] = COND_BRANCH;                // Jump if CX is 0
DFACategory[NN_jecxz] = COND_BRANCH;               // Jump if ECX is 0
DFACategory[NN_jrcxz] = COND_BRANCH;               // Jump if RCX is 0
DFACategory[NN_je] = COND_BRANCH;                  // Jump if Equal (ZF=1)
DFACategory[NN_jg] = COND_BRANCH;                  // Jump if Greater (ZF=0 & SF=OF)
DFACategory[NN_jge] = COND_BRANCH;                 // Jump if Greater or Equal (SF=OF)
DFACategory[NN_jl] = COND_BRANCH;                  // Jump if Less (SF!=OF)
DFACategory[NN_jle] = COND_BRANCH;                 // Jump if Less or Equal (ZF=1 | SF!=OF)
DFACategory[NN_jna] = COND_BRANCH;                 // Jump if Not Above (CF=1 | ZF=1)
DFACategory[NN_jnae] = COND_BRANCH;                // Jump if Not Above or Equal (CF=1)
DFACategory[NN_jnb] = COND_BRANCH;                 // Jump if Not Below (CF=0)
DFACategory[NN_jnbe] = COND_BRANCH;                // Jump if Not Below or Equal (CF=0 & ZF=0)
DFACategory[NN_jnc] = COND_BRANCH;                 // Jump if Not Carry (CF=0)
DFACategory[NN_jne] = COND_BRANCH;                 // Jump if Not Equal (ZF=0)
DFACategory[NN_jng] = COND_BRANCH;                 // Jump if Not Greater (ZF=1 | SF!=OF)
DFACategory[NN_jnge] = COND_BRANCH;                // Jump if Not Greater or Equal (ZF=1)
DFACategory[NN_jnl] = COND_BRANCH;                 // Jump if Not Less (SF=OF)
DFACategory[NN_jnle] = COND_BRANCH;                // Jump if Not Less or Equal (ZF=0 & SF=OF)
DFACategory[NN_jno] = COND_BRANCH;                 // Jump if Not Overflow (OF=0)
DFACategory[NN_jnp] = COND_BRANCH;                 // Jump if Not Parity (PF=0)
DFACategory[NN_jns] = COND_BRANCH;                 // Jump if Not Sign (SF=0)
DFACategory[NN_jnz] = COND_BRANCH;                 // Jump if Not Zero (ZF=0)
DFACategory[NN_jo] = COND_BRANCH;                  // Jump if Overflow (OF=1)
DFACategory[NN_jp] = COND_BRANCH;                  // Jump if Parity (PF=1)
DFACategory[NN_jpe] = COND_BRANCH;                 // Jump if Parity Even (PF=1)
DFACategory[NN_jpo] = COND_BRANCH;                 // Jump if Parity Odd  (PF=0)
DFACategory[NN_js] = COND_BRANCH;                  // Jump if Sign (SF=1)
DFACategory[NN_jz] = COND_BRANCH;                  // Jump if Zero (ZF=1)
DFACategory[NN_jmp] = JUMP;                 // Jump
DFACategory[NN_jmpfi] = INDIR_JUMP;               // Indirect Far Jump
DFACategory[NN_jmpni] = INDIR_JUMP;               // Indirect Near Jump
DFACategory[NN_jmpshort] = JUMP;            // Jump Short (only in 64-bit mode)

DFACategory[NN_loopw] = COND_BRANCH;               // Loop while ECX != 0
DFACategory[NN_loop] = COND_BRANCH;                // Loop while CX != 0
DFACategory[NN_loopd] = COND_BRANCH;               // Loop while ECX != 0
DFACategory[NN_loopq] = COND_BRANCH;               // Loop while RCX != 0
DFACategory[NN_loopwe] = COND_BRANCH;              // Loop while CX != 0 and ZF=1
DFACategory[NN_loope] = COND_BRANCH;               // Loop while rCX != 0 and ZF=1
DFACategory[NN_loopde] = COND_BRANCH;              // Loop while ECX != 0 and ZF=1
DFACategory[NN_loopqe] = COND_BRANCH;              // Loop while RCX != 0 and ZF=1
DFACategory[NN_loopwne] = COND_BRANCH;             // Loop while CX != 0 and ZF=0
DFACategory[NN_loopne] = COND_BRANCH;              // Loop while rCX != 0 and ZF=0
DFACategory[NN_loopdne] = COND_BRANCH;             // Loop while ECX != 0 and ZF=0
DFACategory[NN_loopqne] = COND_BRANCH;             // Loop while RCX != 0 and ZF=0

DFACategory[NN_retn] = RETURN;                // Return Near from Procedure
DFACategory[NN_retf] = RETURN;                // Return Far from Procedure

//
//      Pentium instructions
//

DFACategory[NN_rsm] = HALT;                 // Resume from System Management Mode

//      Pentium II instructions

DFACategory[NN_sysenter] = CALL;            // Fast Transition to System Call Entry Point
DFACategory[NN_sysexit] = CALL;             // Fast Transition from System Call Entry Point

// AMD syscall/sysret instructions  NOTE: not AMD, found in Intel manual

DFACategory[NN_syscall] = CALL;             // Low latency system call
DFACategory[NN_sysret] = CALL;              // Return from system call

// VMX instructions

DFACategory[NN_vmcall] = INDIR_CALL;              // Call to VM Monitor

// Added with x86-64

// Geode LX 3DNow! extensions

// SSE2 pseudoinstructions

// SSSE4.1 instructions

// SSSE4.2 instructions

// AMD SSE4a instructions

// xsave/xrstor instructions

// Intel Safer Mode Extensions (SMX)

// AMD-V Virtualization ISA Extension

// VMX+ instructions

// Intel Atom instructions

// Intel AES instructions

// Carryless multiplication

// Returns modified by operand size prefixes

DFACategory[NN_retnw] = RETURN;               // Return Near from Procedure (use16)
DFACategory[NN_retnd] = RETURN;               // Return Near from Procedure (use32)
DFACategory[NN_retnq] = RETURN;               // Return Near from Procedure (use64)
DFACategory[NN_retfw] = RETURN;               // Return Far from Procedure (use16)
DFACategory[NN_retfd] = RETURN;               // Return Far from Procedure (use32)
DFACategory[NN_retfq] = RETURN;               // Return Far from Procedure (use64)

// RDRAND support

// new GPR instructions

// new AVX instructions

// Transactional Synchronization Extensions

// Virtual PC synthetic instructions

clc5q's avatar
clc5q committed
  return;

} // end InitDFACategory()

// Initialize the SMPDefsFlags[] array to define how we emit
//   optimizing annotations.
void InitSMPDefsFlags(void) {
	// Default value is true. Many instructions set the flags.
	(void) memset(SMPDefsFlags, true, sizeof(SMPDefsFlags));

SMPDefsFlags[NN_null] = false;            // Unknown Operation
SMPDefsFlags[NN_bound] = false;               // Check Array Index Against Bounds
SMPDefsFlags[NN_call] = false;                // Call Procedure
SMPDefsFlags[NN_callfi] = false;              // Indirect Call Far Procedure
SMPDefsFlags[NN_callni] = false;              // Indirect Call Near Procedure
SMPDefsFlags[NN_cbw] = false;                 // AL -> AX (with sign)           
SMPDefsFlags[NN_cwde] = false;                // AX -> EAX (with sign)            
SMPDefsFlags[NN_cdqe] = false;                // EAX -> RAX (with sign)           
SMPDefsFlags[NN_clts] = false;                // Clear Task-Switched Flag in CR0
SMPDefsFlags[NN_cwd] = false;                 // AX -> DX:AX (with sign)
SMPDefsFlags[NN_cdq] = false;                 // EAX -> EDX:EAX (with sign)
SMPDefsFlags[NN_cqo] = false;                 // RAX -> RDX:RAX (with sign)
SMPDefsFlags[NN_enterw] = false;              // Make Stack Frame for Procedure Parameters   
SMPDefsFlags[NN_enter] = false;               // Make Stack Frame for Procedure Parameters   
SMPDefsFlags[NN_enterd] = false;              // Make Stack Frame for Procedure Parameters   
SMPDefsFlags[NN_enterq] = false;              // Make Stack Frame for Procedure Parameters   
SMPDefsFlags[NN_hlt] = false;                 // Halt
SMPDefsFlags[NN_in] = false;                  // Input from Port                          
SMPDefsFlags[NN_ins] = false;                 // Input Byte(s) from Port to String        
SMPDefsFlags[NN_iretw] = false;               // Interrupt Return
SMPDefsFlags[NN_iret] = false;                // Interrupt Return
SMPDefsFlags[NN_iretd] = false;               // Interrupt Return (use32)
SMPDefsFlags[NN_iretq] = false;               // Interrupt Return (use64)
SMPDefsFlags[NN_ja] = false;                  // Jump if Above (CF=0 & ZF=0)
SMPDefsFlags[NN_jae] = false;                 // Jump if Above or Equal (CF=0)
SMPDefsFlags[NN_jb] = false;                  // Jump if Below (CF=1)
SMPDefsFlags[NN_jbe] = false;                 // Jump if Below or Equal (CF=1 | ZF=1)
SMPDefsFlags[NN_jc] = false;                  // Jump if Carry (CF=1)
SMPDefsFlags[NN_jcxz] = false;                // Jump if CX is 0
SMPDefsFlags[NN_jecxz] = false;               // Jump if ECX is 0
SMPDefsFlags[NN_jrcxz] = false;               // Jump if RCX is 0
SMPDefsFlags[NN_je] = false;                  // Jump if Equal (ZF=1)
SMPDefsFlags[NN_jg] = false;                  // Jump if Greater (ZF=0 & SF=OF)
SMPDefsFlags[NN_jge] = false;                 // Jump if Greater or Equal (SF=OF)
SMPDefsFlags[NN_jl] = false;                  // Jump if Less (SF!=OF)
SMPDefsFlags[NN_jle] = false;                 // Jump if Less or Equal (ZF=1 | SF!=OF)
SMPDefsFlags[NN_jna] = false;                 // Jump if Not Above (CF=1 | ZF=1)
SMPDefsFlags[NN_jnae] = false;                // Jump if Not Above or Equal (CF=1)
SMPDefsFlags[NN_jnb] = false;                 // Jump if Not Below (CF=0)
SMPDefsFlags[NN_jnbe] = false;                // Jump if Not Below or Equal (CF=0 & ZF=0)
SMPDefsFlags[NN_jnc] = false;                 // Jump if Not Carry (CF=0)
SMPDefsFlags[NN_jne] = false;                 // Jump if Not Equal (ZF=0)
SMPDefsFlags[NN_jng] = false;                 // Jump if Not Greater (ZF=1 | SF!=OF)
SMPDefsFlags[NN_jnge] = false;                // Jump if Not Greater or Equal (ZF=1)
SMPDefsFlags[NN_jnl] = false;                 // Jump if Not Less (SF=OF)
SMPDefsFlags[NN_jnle] = false;                // Jump if Not Less or Equal (ZF=0 & SF=OF)
SMPDefsFlags[NN_jno] = false;                 // Jump if Not Overflow (OF=0)
SMPDefsFlags[NN_jnp] = false;                 // Jump if Not Parity (PF=0)
SMPDefsFlags[NN_jns] = false;                 // Jump if Not Sign (SF=0)
SMPDefsFlags[NN_jnz] = false;                 // Jump if Not Zero (ZF=0)
SMPDefsFlags[NN_jo] = false;                  // Jump if Overflow (OF=1)
SMPDefsFlags[NN_jp] = false;                  // Jump if Parity (PF=1)
SMPDefsFlags[NN_jpe] = false;                 // Jump if Parity Even (PF=1)
SMPDefsFlags[NN_jpo] = false;                 // Jump if Parity Odd  (PF=0)
SMPDefsFlags[NN_js] = false;                  // Jump if Sign (SF=1)
SMPDefsFlags[NN_jz] = false;                  // Jump if Zero (ZF=1)
SMPDefsFlags[NN_jmp] = false;                 // Jump
SMPDefsFlags[NN_jmpfi] = false;               // Indirect Far Jump
SMPDefsFlags[NN_jmpni] = false;               // Indirect Near Jump
SMPDefsFlags[NN_jmpshort] = false;            // Jump Short (not used)
SMPDefsFlags[NN_lahf] = false;                // Load Flags into AH Register
SMPDefsFlags[NN_lea] = false;                 // Load Effective Address            
SMPDefsFlags[NN_leavew] = false;              // High Level Procedure Exit         
SMPDefsFlags[NN_leave] = false;               // High Level Procedure Exit         
SMPDefsFlags[NN_leaved] = false;              // High Level Procedure Exit         
SMPDefsFlags[NN_leaveq] = false;              // High Level Procedure Exit         
SMPDefsFlags[NN_lgdt] = false;                // Load Global Descriptor Table Register
SMPDefsFlags[NN_lidt] = false;                // Load Interrupt Descriptor Table Register
SMPDefsFlags[NN_lgs] = false;                 // Load Full Pointer to GS:xx
SMPDefsFlags[NN_lss] = false;                 // Load Full Pointer to SS:xx
SMPDefsFlags[NN_lds] = false;                 // Load Full Pointer to DS:xx
SMPDefsFlags[NN_les] = false;                 // Load Full Pointer to ES:xx
SMPDefsFlags[NN_lfs] = false;                 // Load Full Pointer to FS:xx
SMPDefsFlags[NN_loopwe] = false;              // Loop while CX != 0 and ZF=1
SMPDefsFlags[NN_loope] = false;               // Loop while rCX != 0 and ZF=1
SMPDefsFlags[NN_loopde] = false;              // Loop while ECX != 0 and ZF=1
SMPDefsFlags[NN_loopqe] = false;              // Loop while RCX != 0 and ZF=1
SMPDefsFlags[NN_loopwne] = false;             // Loop while CX != 0 and ZF=0
SMPDefsFlags[NN_loopne] = false;              // Loop while rCX != 0 and ZF=0
SMPDefsFlags[NN_loopdne] = false;             // Loop while ECX != 0 and ZF=0
SMPDefsFlags[NN_loopqne] = false;             // Loop while RCX != 0 and ZF=0
SMPDefsFlags[NN_ltr] = false;                 // Load Task Register
SMPDefsFlags[NN_mov] = false;                 // Move Data
SMPDefsFlags[NN_movsp] = true;                // Move to/from Special Registers
SMPDefsFlags[NN_movs] = false;                // Move Byte(s) from String to String
SMPDefsFlags[NN_movsx] = false;               // Move with Sign-Extend
SMPDefsFlags[NN_movzx] = false;               // Move with Zero-Extend
SMPDefsFlags[NN_nop] = false;                 // No Operation
SMPDefsFlags[NN_not] = false;                 // One's Complement Negation
SMPDefsFlags[NN_out] = false;                 // Output to Port
SMPDefsFlags[NN_outs] = false;                // Output Byte(s) to Port
SMPDefsFlags[NN_pop] = false;                 // Pop a word from the Stack
SMPDefsFlags[NN_popaw] = false;               // Pop all General Registers
SMPDefsFlags[NN_popa] = false;                // Pop all General Registers
SMPDefsFlags[NN_popad] = false;               // Pop all General Registers (use32)
SMPDefsFlags[NN_popaq] = false;               // Pop all General Registers (use64)
SMPDefsFlags[NN_push] = false;                // Push Operand onto the Stack
SMPDefsFlags[NN_pushaw] = false;              // Push all General Registers
SMPDefsFlags[NN_pusha] = false;               // Push all General Registers
SMPDefsFlags[NN_pushad] = false;              // Push all General Registers (use32)
SMPDefsFlags[NN_pushaq] = false;              // Push all General Registers (use64)
SMPDefsFlags[NN_pushfw] = false;              // Push Flags Register onto the Stack
SMPDefsFlags[NN_pushf] = false;               // Push Flags Register onto the Stack
SMPDefsFlags[NN_pushfd] = false;              // Push Flags Register onto the Stack (use32)
SMPDefsFlags[NN_pushfq] = false;              // Push Flags Register onto the Stack (use64)
SMPDefsFlags[NN_rep] = false;                 // Repeat String Operation
SMPDefsFlags[NN_repe] = false;                // Repeat String Operation while ZF=1
SMPDefsFlags[NN_repne] = false;               // Repeat String Operation while ZF=0
SMPDefsFlags[NN_retn] = false;                // Return Near from Procedure
SMPDefsFlags[NN_retf] = false;                // Return Far from Procedure
SMPDefsFlags[NN_sahf] = true;                 // Store AH into flags
SMPDefsFlags[NN_shl] = true;                  // Shift Logical Left
SMPDefsFlags[NN_shr] = true;                  // Shift Logical Right
SMPDefsFlags[NN_seta] = false;                // Set Byte if Above (CF=0 & ZF=0)
SMPDefsFlags[NN_setae] = false;               // Set Byte if Above or Equal (CF=0)
SMPDefsFlags[NN_setb] = false;                // Set Byte if Below (CF=1)
SMPDefsFlags[NN_setbe] = false;               // Set Byte if Below or Equal (CF=1 | ZF=1)
SMPDefsFlags[NN_setc] = false;                // Set Byte if Carry (CF=1)
SMPDefsFlags[NN_sete] = false;                // Set Byte if Equal (ZF=1)
SMPDefsFlags[NN_setg] = false;                // Set Byte if Greater (ZF=0 & SF=OF)
SMPDefsFlags[NN_setge] = false;               // Set Byte if Greater or Equal (SF=OF)
SMPDefsFlags[NN_setl] = false;                // Set Byte if Less (SF!=OF)
SMPDefsFlags[NN_setle] = false;               // Set Byte if Less or Equal (ZF=1 | SF!=OF)
SMPDefsFlags[NN_setna] = false;               // Set Byte if Not Above (CF=1 | ZF=1)
SMPDefsFlags[NN_setnae] = false;              // Set Byte if Not Above or Equal (CF=1)
SMPDefsFlags[NN_setnb] = false;               // Set Byte if Not Below (CF=0)
SMPDefsFlags[NN_setnbe] = false;              // Set Byte if Not Below or Equal (CF=0 & ZF=0)
SMPDefsFlags[NN_setnc] = false;               // Set Byte if Not Carry (CF=0)
SMPDefsFlags[NN_setne] = false;               // Set Byte if Not Equal (ZF=0)
SMPDefsFlags[NN_setng] = false;               // Set Byte if Not Greater (ZF=1 | SF!=OF)
SMPDefsFlags[NN_setnge] = false;              // Set Byte if Not Greater or Equal (ZF=1)
SMPDefsFlags[NN_setnl] = false;               // Set Byte if Not Less (SF=OF)
SMPDefsFlags[NN_setnle] = false;              // Set Byte if Not Less or Equal (ZF=0 & SF=OF)
SMPDefsFlags[NN_setno] = false;               // Set Byte if Not Overflow (OF=0)
SMPDefsFlags[NN_setnp] = false;               // Set Byte if Not Parity (PF=0)
SMPDefsFlags[NN_setns] = false;               // Set Byte if Not Sign (SF=0)
SMPDefsFlags[NN_setnz] = false;               // Set Byte if Not Zero (ZF=0)
SMPDefsFlags[NN_seto] = false;                // Set Byte if Overflow (OF=1)
SMPDefsFlags[NN_setp] = false;                // Set Byte if Parity (PF=1)
SMPDefsFlags[NN_setpe] = false;               // Set Byte if Parity Even (PF=1)
SMPDefsFlags[NN_setpo] = false;               // Set Byte if Parity Odd  (PF=0)
SMPDefsFlags[NN_sets] = false;                // Set Byte if Sign (SF=1)
SMPDefsFlags[NN_setz] = false;                // Set Byte if Zero (ZF=1)
SMPDefsFlags[NN_sgdt] = false;                // Store Global Descriptor Table Register
SMPDefsFlags[NN_sidt] = false;                // Store Interrupt Descriptor Table Register
SMPDefsFlags[NN_sldt] = false;                // Store Local Descriptor Table Register
SMPDefsFlags[NN_str] = false;                 // Store Task Register
SMPDefsFlags[NN_wait] = false;                // Wait until BUSY# Pin is Inactive (HIGH)
SMPDefsFlags[NN_xchg] = false;                // Exchange Register/Memory with Register
SMPDefsFlags[NN_xlat] = false;                // Table Lookup Translation

//
//      486 instructions
//

SMPDefsFlags[NN_bswap] = false;               // Swap bytes in register
SMPDefsFlags[NN_invd] = false;                // Invalidate Data Cache
SMPDefsFlags[NN_wbinvd] = false;              // Invalidate Data Cache (write changes)
SMPDefsFlags[NN_invlpg] = false;              // Invalidate TLB entry

//
//      Pentium instructions
//

SMPDefsFlags[NN_rdmsr] = false;               // Read Machine Status Register
SMPDefsFlags[NN_wrmsr] = false;               // Write Machine Status Register
SMPDefsFlags[NN_cpuid] = false;               // Get CPU ID
SMPDefsFlags[NN_rdtsc] = false;               // Read Time Stamp Counter

//
//      Pentium Pro instructions
//

SMPDefsFlags[NN_cmova] = false;               // Move if Above (CF=0 & ZF=0)
SMPDefsFlags[NN_cmovb] = false;               // Move if Below (CF=1)
SMPDefsFlags[NN_cmovbe] = false;              // Move if Below or Equal (CF=1 | ZF=1)
SMPDefsFlags[NN_cmovg] = false;               // Move if Greater (ZF=0 & SF=OF)
SMPDefsFlags[NN_cmovge] = false;              // Move if Greater or Equal (SF=OF)
SMPDefsFlags[NN_cmovl] = false;               // Move if Less (SF!=OF)
SMPDefsFlags[NN_cmovle] = false;              // Move if Less or Equal (ZF=1 | SF!=OF)
SMPDefsFlags[NN_cmovnb] = false;              // Move if Not Below (CF=0)
SMPDefsFlags[NN_cmovno] = false;              // Move if Not Overflow (OF=0)
SMPDefsFlags[NN_cmovnp] = false;              // Move if Not Parity (PF=0)
SMPDefsFlags[NN_cmovns] = false;              // Move if Not Sign (SF=0)
SMPDefsFlags[NN_cmovnz] = false;              // Move if Not Zero (ZF=0)
SMPDefsFlags[NN_cmovo] = false;               // Move if Overflow (OF=1)
SMPDefsFlags[NN_cmovp] = false;               // Move if Parity (PF=1)
SMPDefsFlags[NN_cmovs] = false;               // Move if Sign (SF=1)
SMPDefsFlags[NN_cmovz] = false;               // Move if Zero (ZF=1)
SMPDefsFlags[NN_fcmovb] = false;              // Floating Move if Below          
SMPDefsFlags[NN_fcmove] = false;              // Floating Move if Equal          
SMPDefsFlags[NN_fcmovbe] = false;             // Floating Move if Below or Equal 
SMPDefsFlags[NN_fcmovu] = false;              // Floating Move if Unordered      
SMPDefsFlags[NN_fcmovnb] = false;             // Floating Move if Not Below      
SMPDefsFlags[NN_fcmovne] = false;             // Floating Move if Not Equal      
SMPDefsFlags[NN_fcmovnbe] = false;            // Floating Move if Not Below or Equal
SMPDefsFlags[NN_fcmovnu] = false;             // Floating Move if Not Unordered     
SMPDefsFlags[NN_rdpmc] = false;               // Read Performance Monitor Counter

//
//      FPP instructions
//

SMPDefsFlags[NN_fld] = false;                 // Load Real              
SMPDefsFlags[NN_fst] = false;                 // Store Real            
SMPDefsFlags[NN_fstp] = false;                // Store Real and Pop   
SMPDefsFlags[NN_fxch] = false;                // Exchange Registers
SMPDefsFlags[NN_fild] = false;                // Load Integer           
SMPDefsFlags[NN_fist] = false;                // Store Integer
SMPDefsFlags[NN_fistp] = false;               // Store Integer and Pop
SMPDefsFlags[NN_fbld] = false;                // Load BCD
SMPDefsFlags[NN_fbstp] = false;               // Store BCD and Pop
SMPDefsFlags[NN_fadd] = false;                // Add Real
SMPDefsFlags[NN_faddp] = false;               // Add Real and Pop
SMPDefsFlags[NN_fiadd] = false;               // Add Integer
SMPDefsFlags[NN_fsub] = false;                // Subtract Real
SMPDefsFlags[NN_fsubp] = false;               // Subtract Real and Pop
SMPDefsFlags[NN_fisub] = false;               // Subtract Integer
SMPDefsFlags[NN_fsubr] = false;               // Subtract Real Reversed
SMPDefsFlags[NN_fsubrp] = false;              // Subtract Real Reversed and Pop
SMPDefsFlags[NN_fisubr] = false;              // Subtract Integer Reversed
SMPDefsFlags[NN_fmul] = false;                // Multiply Real
SMPDefsFlags[NN_fmulp] = false;               // Multiply Real and Pop
SMPDefsFlags[NN_fimul] = false;               // Multiply Integer
SMPDefsFlags[NN_fdiv] = false;                // Divide Real
SMPDefsFlags[NN_fdivp] = false;               // Divide Real and Pop
SMPDefsFlags[NN_fidiv] = false;               // Divide Integer
SMPDefsFlags[NN_fdivr] = false;               // Divide Real Reversed
SMPDefsFlags[NN_fdivrp] = false;              // Divide Real Reversed and Pop
SMPDefsFlags[NN_fidivr] = false;              // Divide Integer Reversed
SMPDefsFlags[NN_fsqrt] = false;               // Square Root
SMPDefsFlags[NN_fscale] = false;              // Scale:  st(0) <- st(0) * 2^st(1)
SMPDefsFlags[NN_fprem] = false;               // Partial Remainder
SMPDefsFlags[NN_frndint] = false;             // Round to Integer
SMPDefsFlags[NN_fxtract] = false;             // Extract exponent and significand
SMPDefsFlags[NN_fabs] = false;                // Absolute value
SMPDefsFlags[NN_fchs] = false;                // Change Sign
SMPDefsFlags[NN_ficom] = false;               // Compare Integer
SMPDefsFlags[NN_ficomp] = false;              // Compare Integer and Pop
SMPDefsFlags[NN_ftst] = false;                // Test
SMPDefsFlags[NN_fxam] = false;                // Examine
SMPDefsFlags[NN_fptan] = false;               // Partial tangent
SMPDefsFlags[NN_fpatan] = false;              // Partial arctangent
SMPDefsFlags[NN_f2xm1] = false;               // 2^x - 1
SMPDefsFlags[NN_fyl2x] = false;               // Y * lg2(X)
SMPDefsFlags[NN_fyl2xp1] = false;             // Y * lg2(X+1)
SMPDefsFlags[NN_fldz] = false;                // Load +0.0
SMPDefsFlags[NN_fld1] = false;                // Load +1.0
SMPDefsFlags[NN_fldpi] = false;               // Load PI=3.14...
SMPDefsFlags[NN_fldl2t] = false;              // Load lg2(10)
SMPDefsFlags[NN_fldl2e] = false;              // Load lg2(e)
SMPDefsFlags[NN_fldlg2] = false;              // Load lg10(2)
SMPDefsFlags[NN_fldln2] = false;              // Load ln(2)
SMPDefsFlags[NN_finit] = false;               // Initialize Processor
SMPDefsFlags[NN_fninit] = false;              // Initialize Processor (no wait)
SMPDefsFlags[NN_fsetpm] = false;              // Set Protected Mode
SMPDefsFlags[NN_fldcw] = false;               // Load Control Word
SMPDefsFlags[NN_fstcw] = false;               // Store Control Word
SMPDefsFlags[NN_fnstcw] = false;              // Store Control Word (no wait)
SMPDefsFlags[NN_fstsw] = false;               // Store Status Word to memory or AX
SMPDefsFlags[NN_fnstsw] = false;              // Store Status Word (no wait) to memory or AX
SMPDefsFlags[NN_fclex] = false;               // Clear Exceptions
SMPDefsFlags[NN_fnclex] = false;              // Clear Exceptions (no wait)
SMPDefsFlags[NN_fstenv] = false;              // Store Environment
SMPDefsFlags[NN_fnstenv] = false;             // Store Environment (no wait)
SMPDefsFlags[NN_fldenv] = false;              // Load Environment
SMPDefsFlags[NN_fsave] = false;               // Save State
SMPDefsFlags[NN_fnsave] = false;              // Save State (no wait)
SMPDefsFlags[NN_frstor] = false;              // Restore State      
SMPDefsFlags[NN_fincstp] = false;             // Increment Stack Pointer
SMPDefsFlags[NN_fdecstp] = false;             // Decrement Stack Pointer
SMPDefsFlags[NN_ffree] = false;               // Free Register
SMPDefsFlags[NN_fnop] = false;                // No Operation
SMPDefsFlags[NN_feni] = false;                // (8087 only)
SMPDefsFlags[NN_fneni] = false;               // (no wait) (8087 only)
SMPDefsFlags[NN_fdisi] = false;               // (8087 only)
SMPDefsFlags[NN_fndisi] = false;              // (no wait) (8087 only)

//
//      80387 instructions
//

SMPDefsFlags[NN_fprem1] = false;              // Partial Remainder ( < half )
SMPDefsFlags[NN_fsincos] = false;             // t<-cos(st); st<-sin(st); push t
SMPDefsFlags[NN_fsin] = false;                // Sine
SMPDefsFlags[NN_fcos] = false;                // Cosine
SMPDefsFlags[NN_fucom] = false;               // Compare Unordered Real
SMPDefsFlags[NN_fucomp] = false;              // Compare Unordered Real and Pop
SMPDefsFlags[NN_fucompp] = false;             // Compare Unordered Real and Pop Twice

//
//      Instructions added 28.02.96
//

SMPDefsFlags[NN_svdc] = false;                // Save Register and Descriptor
SMPDefsFlags[NN_rsdc] = false;                // Restore Register and Descriptor
SMPDefsFlags[NN_svldt] = false;               // Save LDTR and Descriptor
SMPDefsFlags[NN_rsldt] = false;               // Restore LDTR and Descriptor
SMPDefsFlags[NN_svts] = false;                // Save TR and Descriptor
SMPDefsFlags[NN_rsts] = false;                // Restore TR and Descriptor
SMPDefsFlags[NN_icebp] = false;               // ICE Break Point

//
//      MMX instructions
//

SMPDefsFlags[NN_emms] = false;                // Empty MMX state
SMPDefsFlags[NN_movd] = false;                // Move 32 bits
SMPDefsFlags[NN_movq] = false;                // Move 64 bits
SMPDefsFlags[NN_packsswb] = false;            // Pack with Signed Saturation (Word->Byte)
SMPDefsFlags[NN_packssdw] = false;            // Pack with Signed Saturation (Dword->Word)
SMPDefsFlags[NN_packuswb] = false;            // Pack with Unsigned Saturation (Word->Byte)
SMPDefsFlags[NN_paddb] = false;               // Packed Add Byte
SMPDefsFlags[NN_paddw] = false;               // Packed Add Word
SMPDefsFlags[NN_paddd] = false;               // Packed Add Dword
SMPDefsFlags[NN_paddsb] = false;              // Packed Add with Saturation (Byte)
SMPDefsFlags[NN_paddsw] = false;              // Packed Add with Saturation (Word)
SMPDefsFlags[NN_paddusb] = false;             // Packed Add Unsigned with Saturation (Byte)
SMPDefsFlags[NN_paddusw] = false;             // Packed Add Unsigned with Saturation (Word)
SMPDefsFlags[NN_pand] = false;                // Bitwise Logical And
SMPDefsFlags[NN_pandn] = false;               // Bitwise Logical And Not
SMPDefsFlags[NN_pcmpeqb] = false;             // Packed Compare for Equal (Byte)
SMPDefsFlags[NN_pcmpeqw] = false;             // Packed Compare for Equal (Word)
SMPDefsFlags[NN_pcmpeqd] = false;             // Packed Compare for Equal (Dword)
SMPDefsFlags[NN_pcmpgtb] = false;             // Packed Compare for Greater Than (Byte)
SMPDefsFlags[NN_pcmpgtw] = false;             // Packed Compare for Greater Than (Word)
SMPDefsFlags[NN_pcmpgtd] = false;             // Packed Compare for Greater Than (Dword)
SMPDefsFlags[NN_pmaddwd] = false;             // Packed Multiply and Add
SMPDefsFlags[NN_pmulhw] = false;              // Packed Multiply High
SMPDefsFlags[NN_pmullw] = false;              // Packed Multiply Low
SMPDefsFlags[NN_por] = false;                 // Bitwise Logical Or
SMPDefsFlags[NN_psllw] = false;               // Packed Shift Left Logical (Word)
SMPDefsFlags[NN_pslld] = false;               // Packed Shift Left Logical (Dword)
SMPDefsFlags[NN_psllq] = false;               // Packed Shift Left Logical (Qword)
SMPDefsFlags[NN_psraw] = false;               // Packed Shift Right Arithmetic (Word)
SMPDefsFlags[NN_psrad] = false;               // Packed Shift Right Arithmetic (Dword)
SMPDefsFlags[NN_psrlw] = false;               // Packed Shift Right Logical (Word)
SMPDefsFlags[NN_psrld] = false;               // Packed Shift Right Logical (Dword)
SMPDefsFlags[NN_psrlq] = false;               // Packed Shift Right Logical (Qword)
SMPDefsFlags[NN_psubb] = false;               // Packed Subtract Byte
SMPDefsFlags[NN_psubw] = false;               // Packed Subtract Word
SMPDefsFlags[NN_psubd] = false;               // Packed Subtract Dword
SMPDefsFlags[NN_psubsb] = false;              // Packed Subtract with Saturation (Byte)
SMPDefsFlags[NN_psubsw] = false;              // Packed Subtract with Saturation (Word)
SMPDefsFlags[NN_psubusb] = false;             // Packed Subtract Unsigned with Saturation (Byte)
SMPDefsFlags[NN_psubusw] = false;             // Packed Subtract Unsigned with Saturation (Word)
SMPDefsFlags[NN_punpckhbw] = false;           // Unpack High Packed Data (Byte->Word)
SMPDefsFlags[NN_punpckhwd] = false;           // Unpack High Packed Data (Word->Dword)
SMPDefsFlags[NN_punpckhdq] = false;           // Unpack High Packed Data (Dword->Qword)
SMPDefsFlags[NN_punpcklbw] = false;           // Unpack Low Packed Data (Byte->Word)
SMPDefsFlags[NN_punpcklwd] = false;           // Unpack Low Packed Data (Word->Dword)
SMPDefsFlags[NN_punpckldq] = false;           // Unpack Low Packed Data (Dword->Qword)
SMPDefsFlags[NN_pxor] = false;                // Bitwise Logical Exclusive Or

//
//      Undocumented Deschutes processor instructions
//

SMPDefsFlags[NN_fxsave] = false;              // Fast save FP context        
SMPDefsFlags[NN_fxrstor] = false;             // Fast restore FP context     

//      Pentium II instructions

SMPDefsFlags[NN_sysexit] = false;             // Fast Transition from System Call Entry Point

//      3DNow! instructions

SMPDefsFlags[NN_pavgusb] = false;             // Packed 8-bit Unsigned Integer Averaging
SMPDefsFlags[NN_pfadd] = false;               // Packed Floating-Point Addition
SMPDefsFlags[NN_pfsub] = false;               // Packed Floating-Point Subtraction
SMPDefsFlags[NN_pfsubr] = false;              // Packed Floating-Point Reverse Subtraction
SMPDefsFlags[NN_pfacc] = false;               // Packed Floating-Point Accumulate
SMPDefsFlags[NN_pfcmpge] = false;             // Packed Floating-Point Comparison, Greater or Equal
SMPDefsFlags[NN_pfcmpgt] = false;             // Packed Floating-Point Comparison, Greater
SMPDefsFlags[NN_pfcmpeq] = false;             // Packed Floating-Point Comparison, Equal
SMPDefsFlags[NN_pfmin] = false;               // Packed Floating-Point Minimum
SMPDefsFlags[NN_pfmax] = false;               // Packed Floating-Point Maximum
SMPDefsFlags[NN_pi2fd] = false;               // Packed 32-bit Integer to Floating-Point
SMPDefsFlags[NN_pf2id] = false;               // Packed Floating-Point to 32-bit Integer
SMPDefsFlags[NN_pfrcp] = false;               // Packed Floating-Point Reciprocal Approximation
SMPDefsFlags[NN_pfrsqrt] = false;             // Packed Floating-Point Reciprocal Square Root Approximation
SMPDefsFlags[NN_pfmul] = false;               // Packed Floating-Point Multiplication
SMPDefsFlags[NN_pfrcpit1] = false;            // Packed Floating-Point Reciprocal First Iteration Step
SMPDefsFlags[NN_pfrsqit1] = false;            // Packed Floating-Point Reciprocal Square Root First Iteration Step
SMPDefsFlags[NN_pfrcpit2] = false;            // Packed Floating-Point Reciprocal Second Iteration Step
SMPDefsFlags[NN_pmulhrw] = false;             // Packed Floating-Point 16-bit Integer Multiply with rounding
SMPDefsFlags[NN_femms] = false;               // Faster entry/exit of the MMX or floating-point state
SMPDefsFlags[NN_prefetch] = false;            // Prefetch at least a 32-byte line into L1 data cache
SMPDefsFlags[NN_prefetchw] = false;           // Prefetch processor cache line into L1 data cache (mark as modified)


//      Pentium III instructions

SMPDefsFlags[NN_addps] = false;               // Packed Single-FP Add
SMPDefsFlags[NN_addss] = false;               // Scalar Single-FP Add
SMPDefsFlags[NN_andnps] = false;              // Bitwise Logical And Not for Single-FP
SMPDefsFlags[NN_andps] = false;               // Bitwise Logical And for Single-FP
SMPDefsFlags[NN_cmpps] = false;               // Packed Single-FP Compare
SMPDefsFlags[NN_cmpss] = false;               // Scalar Single-FP Compare
SMPDefsFlags[NN_cvtpi2ps] = false;            // Packed signed INT32 to Packed Single-FP conversion
SMPDefsFlags[NN_cvtps2pi] = false;            // Packed Single-FP to Packed INT32 conversion
SMPDefsFlags[NN_cvtsi2ss] = false;            // Scalar signed INT32 to Single-FP conversion
SMPDefsFlags[NN_cvtss2si] = false;            // Scalar Single-FP to signed INT32 conversion
SMPDefsFlags[NN_cvttps2pi] = false;           // Packed Single-FP to Packed INT32 conversion (truncate)
SMPDefsFlags[NN_cvttss2si] = false;           // Scalar Single-FP to signed INT32 conversion (truncate)
SMPDefsFlags[NN_divps] = false;               // Packed Single-FP Divide
SMPDefsFlags[NN_divss] = false;               // Scalar Single-FP Divide
SMPDefsFlags[NN_ldmxcsr] = false;             // Load Streaming SIMD Extensions Technology Control/Status Register
SMPDefsFlags[NN_maxps] = false;               // Packed Single-FP Maximum
SMPDefsFlags[NN_maxss] = false;               // Scalar Single-FP Maximum
SMPDefsFlags[NN_minps] = false;               // Packed Single-FP Minimum
SMPDefsFlags[NN_minss] = false;               // Scalar Single-FP Minimum
SMPDefsFlags[NN_movaps] = false;              // Move Aligned Four Packed Single-FP  
SMPDefsFlags[NN_movhlps] = false;             // Move High to Low Packed Single-FP
SMPDefsFlags[NN_movhps] = false;              // Move High Packed Single-FP
SMPDefsFlags[NN_movlhps] = false;             // Move Low to High Packed Single-FP
SMPDefsFlags[NN_movlps] = false;              // Move Low Packed Single-FP
SMPDefsFlags[NN_movmskps] = false;            // Move Mask to Register
SMPDefsFlags[NN_movss] = false;               // Move Scalar Single-FP
SMPDefsFlags[NN_movups] = false;              // Move Unaligned Four Packed Single-FP
SMPDefsFlags[NN_mulps] = false;               // Packed Single-FP Multiply
SMPDefsFlags[NN_mulss] = false;               // Scalar Single-FP Multiply
SMPDefsFlags[NN_orps] = false;                // Bitwise Logical OR for Single-FP Data
SMPDefsFlags[NN_rcpps] = false;               // Packed Single-FP Reciprocal
SMPDefsFlags[NN_rcpss] = false;               // Scalar Single-FP Reciprocal
SMPDefsFlags[NN_rsqrtps] = false;             // Packed Single-FP Square Root Reciprocal
SMPDefsFlags[NN_rsqrtss] = false;             // Scalar Single-FP Square Root Reciprocal
SMPDefsFlags[NN_shufps] = false;              // Shuffle Single-FP
SMPDefsFlags[NN_sqrtps] = false;              // Packed Single-FP Square Root
SMPDefsFlags[NN_sqrtss] = false;              // Scalar Single-FP Square Root