/* * SMPDataFlowAnalysis.cpp - <see below>. * * Copyright (c) 2000, 2001, 2010 - University of Virginia * * This file is part of the Memory Error Detection System (MEDS) infrastructure. * This file may be used and modified for non-commercial purposes as long as * all copyright, permission, and nonwarranty notices are preserved. * Redistribution is prohibited without prior written consent from the University * of Virginia. * * Please contact the authors for restrictions applying to commercial use. * * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * Author: University of Virginia * e-mail: jwd@virginia.com * URL : http://www.cs.virginia.edu/ * * Additional copyrights 2010, 2011 by Zephyr Software LLC * e-mail: {clc,jwd}@zephyr-software.com * URL : http://www.zephyr-software.com/ * */ // // SMPDataFlowAnalysis.cpp // // This module contains common types an helper classes needed for the // SMP project (Software Memory Protection). // #include <list> #include <set> #include <vector> #include <algorithm> #include <cstring> #include <pro.h> #include <assert.h> #include <ida.hpp> #include <idp.hpp> #include <allins.hpp> #include <auto.hpp> #include <bytes.hpp> #include <funcs.hpp> #include <intel.hpp> #include <loader.hpp> #include <lines.hpp> #include <name.hpp> #include "SMPDataFlowAnalysis.h" #include "SMPStaticAnalyzer.h" #include "SMPInstr.h" #include "SMPBasicBlock.h" #include "SMPFunction.h" // Set these to 1 for debugging output #define SMP_DEBUG_CONTROLFLOW 0 // tells what processing stage is entered #define SMP_DEBUG_CHUNKS 1 // tracking down tail chunks for functions #define SMP_DEBUG_FRAMEFIXUP 0 // Fixing up stack frame info the way we want the offsets #define SMP_DEBUG_OPERAND_TYPES 1 // leave on; warnings that should never happen #if IDA_SDK_VERSION > 560 #define MAX_IDA_REG R_mxcsr #else #define MAX_IDA_REG 80 #endif const char *RegNames[MAX_IDA_REG + 1] = { "EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15", "AL", "CL", "DL", "BL", "AH", "CH", "DH", "BH", "SPL", "BPL", "SIL", "DIL", "EIP", "ES", "CS", "SS", "DS", "FS", "GS", "CF", "ZF", "SF", "OF", "PF", "AF", "TF", "IF", "DF", "EFLAGS", "FPU_ST0", "FPU_ST1", "FPU_ST2", "FPU_ST3", "FPU_ST4", "FPU_ST5", "FPU_ST6", "FPU_ST7", "FPU_CTRL", "FPU_STAT", "FPU_TAGS", "MMX0", "MMX1", "MMX2", "MMX3", "MMX4", "MMX5", "MMX6", "MMX7", "XMM0", "XMM1", "XMM2", "XMM3", "XMM4", "XMM5", "XMM6", "XMM7", "XMM8", "XMM9", "XMM10", "XMM11", "XMM12", "XMM13", "XMM14", "XMM15", "MXCSR" }; // Define instruction categories for data flow analysis. SMPitype DFACategory[NN_last+1]; // Define instruction categories for data type analysis. int SMPTypeCategory[NN_last+1]; // Define which instructions define and use the CPU flags. bool SMPDefsFlags[NN_last + 1]; bool SMPUsesFlags[NN_last + 1]; // Get the size in bytes of the data type of an operand. size_t GetOpDataSize(op_t DataOp) { size_t DataSize; switch (DataOp.dtyp) { case dt_byte: DataSize = 1; break; case dt_word: DataSize = 2; break; case dt_dword: case dt_float: case dt_code: case dt_unicode: case dt_string: DataSize = 4; break; case dt_double: case dt_qword: DataSize = 8; break; case dt_packreal: DataSize = 12; break; case dt_byte16: DataSize = 16; break; case dt_fword: DataSize = 6; break; case dt_3byte: DataSize = 3; break; default: msg("WARNING: unexpected data type %d in GetOpDataSize() :", DataOp.dtyp); PrintOperand(DataOp); msg("\n"); DataSize = 4; break; } return DataSize; } // end of GetOpDataSize() // We need to make subword registers equal to their containing registers when we // do comparisons, so that we will realize that register EAX is killed by a prior DEF // of register AL, for example, and vice versa. To keep sets ordered strictly, // we also have to make AL and AH be equal to each other as well as equal to EAX. #define FIRST_x86_SUBWORD_REG R_al #define LAST_x86_SUBWORD_REG R_bh bool MDLessReg(const ushort Reg1, const ushort Reg2) { ushort SReg1 = MDCanonicalizeSubReg(Reg1); ushort SReg2 = MDCanonicalizeSubReg(Reg2); return (SReg1 < SReg2); } // end of MDLessReg() ushort MDCanonicalizeSubReg(const ushort Reg1) { bool Subword = ((Reg1 >= FIRST_x86_SUBWORD_REG) && (Reg1 <= LAST_x86_SUBWORD_REG)); ushort SReg1 = Reg1; if (Subword) { // See enumeration RegNo in intel.hpp. if (SReg1 < 20) // AL, CL, DL or BL SReg1 -= 16; else // AH, CH, DH or BH SReg1 -= 20; } return SReg1; } // end of MDCanonicalizeSubReg() // In SSA computations, we are storing the GlobalNames index into the op_t fields // n, offb, and offo. This function extracts an unsigned int from these three 8-bit // fields. unsigned int ExtractGlobalIndex(op_t GlobalOp) { unsigned int index = 0; index |= (((unsigned int) GlobalOp.offo) & 0x000000ff); index <<= 8; index |= (((unsigned int) GlobalOp.offb) & 0x000000ff); index <<= 8; index |= (((unsigned int) GlobalOp.n) & 0x000000ff); return index; } void SetGlobalIndex(op_t *TempOp, size_t index) { TempOp->n = (char) (index & 0x000000ff); TempOp->offb = (char) ((index & 0x0000ff00) >> 8); TempOp->offo = (char) ((index & 0x00ff0000) >> 16); return; } // Return true if CurrOp could be an indirect memory reference. bool MDIsIndirectMemoryOpnd(op_t CurrOp, bool UseFP) { bool indirect = false; if ((CurrOp.type != o_mem) && (CurrOp.type != o_phrase) && (CurrOp.type != o_displ)) return false; if (CurrOp.hasSIB) { int BaseReg = sib_base(CurrOp); short IndexReg = sib_index(CurrOp); if ((R_none != IndexReg) && (R_sp != IndexReg)) { if ((R_bp == IndexReg) && UseFP) ; else indirect = true; } if (0 != sib_scale(CurrOp)) indirect = true; if (R_none != BaseReg) { if ((BaseReg == R_bp) && (CurrOp.type == o_mem)) { ; // EBP ==> no base register for o_mem type } else if ((BaseReg == R_bp) && UseFP) ; // EBP used as frame pointer for direct access else if (BaseReg == R_sp) ; // ESP used as stack pointer for direct access else indirect = true; // conservative; some register used for addressing // other than a stack or frame pointer } } // end if hasSIB else { // no SIB; can have base register only ushort BaseReg = CurrOp.reg; if (CurrOp.type == o_mem) { // no base register for o_mem if (!((0 == BaseReg) || (R_bp == BaseReg))) { msg("base reg %d ignored \n", BaseReg); } } else if ((BaseReg == R_bp) && UseFP) ; // EBP used as frame pointer for direct access else if (BaseReg == R_sp) ; // ESP used as stack pointer for direct access else { indirect = true; } } return indirect; } // end MDIsIndirectMemoryOpnd() // Extract the base and index registers and scale factor and displacement from the // memory operand. void MDExtractAddressFields(op_t MemOp, int &BaseReg, int &IndexReg, ushort &Scale, ea_t &Offset) { assert((MemOp.type == o_phrase) || (MemOp.type == o_displ) || (MemOp.type == o_mem)); Scale = 0; BaseReg = R_none; IndexReg = R_none; Offset = MemOp.addr; if (MemOp.hasSIB) { BaseReg = sib_base(MemOp); IndexReg = (int) sib_index(MemOp); if (R_sp == IndexReg) // signifies no index register IndexReg = R_none; if (R_none != IndexReg) { Scale = (ushort) sib_scale(MemOp); } if (R_none != BaseReg) { if ((BaseReg == R_bp) && (MemOp.type == o_mem)) { BaseReg = R_none; // **!!** BaseReg allowed for o_mem with SIB byte??? } } } else { // no SIB byte; can have base reg but no index reg or scale factor BaseReg = (int) MemOp.reg; // cannot be R_none for no SIB case if (MemOp.type == o_mem) { BaseReg = R_none; // no Base register for o_mem operands } } return; } // end of MDExtractAddressFields() // MACHINE DEPENDENT: Is operand a stack memory access? bool MDIsStackAccessOpnd(op_t CurrOp, bool UseFP) { int BaseReg; int IndexReg; ushort ScaleFactor; ea_t offset; if ((o_displ != CurrOp.type) && (o_phrase != CurrOp.type)) { return false; } MDExtractAddressFields(CurrOp, BaseReg, IndexReg, ScaleFactor, offset); return ((BaseReg == R_sp) || (UseFP && (BaseReg == R_bp))); } // end of MDIsStackAccessOpnd() // MACHINE DEPENDENT: Is operand a caller-saved register? bool MDIsCallerSavedReg(op_t CurrOp) { if (o_reg != CurrOp.type) return false; ushort CurrReg = MDCanonicalizeSubReg(CurrOp.reg); return ((R_ax == CurrReg) || (R_cx == CurrReg) || (R_dx == CurrReg)); } // end of MDIsCallerSavedReg() // DEBUG Print DEF and/or USE for an operand. void PrintDefUse(ulong feature, int OpNum) { // CF_ macros number the operands from 1 to 6, while OpNum // is a 0 to 5 index into the insn_t.Operands[] array. // OpNum == -1 is a signal that this is a DEF or USE or VarKillSet etc. // operand and not an instruction operand. if (-1 == OpNum) return; switch (OpNum) { case 0: if (feature & CF_CHG1) msg(" DEF"); if (feature & CF_USE1) msg(" USE"); break; case 1: if (feature & CF_CHG2) msg(" DEF"); if (feature & CF_USE2) msg(" USE"); break; case 2: if (feature & CF_CHG3) msg(" DEF"); if (feature & CF_USE3) msg(" USE"); break; case 3: if (feature & CF_CHG4) msg(" DEF"); if (feature & CF_USE4) msg(" USE"); break; case 4: if (feature & CF_CHG5) msg(" DEF"); if (feature & CF_USE5) msg(" USE"); break; case 5: if (feature & CF_CHG6) msg(" DEF"); if (feature & CF_USE6) msg(" USE"); break; } return; } // end PrintDefUse() // DEBUG print SIB info for an operand. void PrintSIB(op_t Opnd) { int BaseReg; int IndexReg; ushort ScaleFactor; ea_t offset; #define NAME_LEN 5 char BaseName[NAME_LEN] = {'N', 'o', 'n', 'e', '\0'}; char IndexName[NAME_LEN] = {'N', 'o', 'n', 'e', '\0'}; MDExtractAddressFields(Opnd, BaseReg, IndexReg, ScaleFactor, offset); if (BaseReg != R_none) qstrncpy(BaseName, RegNames[BaseReg], NAME_LEN - 1); if (IndexReg != R_none) { qstrncpy(IndexName, RegNames[IndexReg], NAME_LEN -1); } msg(" Base %s Index %s Scale %d", BaseName, IndexName, ScaleFactor); } // end PrintSIB() // Debug: print one operand from an instruction or DEF or USE list. void PrintOneOperand(op_t Opnd, ulong features, int OpNum) { if (Opnd.type != o_void) { PrintOperand(Opnd); PrintDefUse(features, OpNum); } return; } // end of PrintOneOperand() // Debug: print one operand. void PrintOperand(op_t Opnd) { if (Opnd.type == o_void) return; else if (Opnd.type == o_mem) { msg(" Operand: memory : addr: %x", Opnd.addr); if (Opnd.hasSIB) { PrintSIB(Opnd); } } else if (Opnd.type == o_phrase) { msg(" Operand: memory phrase :"); if (Opnd.hasSIB) { // has SIB info PrintSIB(Opnd); } else { // no SIB info ushort BaseReg = Opnd.phrase; msg(" reg %s", RegNames[BaseReg]); } if (Opnd.addr != 0) { msg(" \n WARNING: addr for o_phrase type: %x\n", Opnd.addr); } } else if (Opnd.type == o_displ) { msg(" Operand: memory displ :"); ea_t offset = Opnd.addr; if (Opnd.hasSIB) { PrintSIB(Opnd); msg(" displ %d", offset); } else { ushort BaseReg = Opnd.reg; msg(" reg %s displ %d", RegNames[BaseReg], offset); } } else if (Opnd.type == o_reg) { msg(" Operand: register %s", RegNames[Opnd.reg]); } else if (Opnd.type == o_imm) { msg(" Operand: immed %d", Opnd.value); } else if (Opnd.type == o_far) { msg(" Operand: FarPtrImmed addr: %x", Opnd.addr); } else if (Opnd.type == o_near) { msg(" Operand: NearPtrImmed addr: %x", Opnd.addr); } else if (Opnd.type == o_trreg) { msg(" Operand: TaskReg reg: %d", Opnd.reg); } else if (Opnd.type == o_dbreg) { msg(" Operand: DebugReg reg: %d", Opnd.reg); } else if (Opnd.type == o_crreg) { msg(" Operand: ControlReg reg: %d", Opnd.reg); } else if (Opnd.type == o_fpreg) { msg(" Operand: FloatReg reg: %d", Opnd.reg); } else if (Opnd.type == o_mmxreg) { msg(" Operand: MMXReg reg: %d", Opnd.reg); } else if (Opnd.type == o_xmmreg) { msg(" Operand: XMMReg reg: %d", Opnd.reg); } else { msg(" Operand: unknown"); } if (!(Opnd.showed())) msg(" HIDDEN "); return; } // end of PrintOperand() // Print an operand that has no features flags or operand position number, such // as the op_t types found in lists and sets throughout the blocks, phi functions, etc. void PrintListOperand(op_t Opnd, int SSANum) { if (Opnd.type != o_void) { PrintOperand(Opnd); msg(" SSANum: %d ", SSANum); } return; } // end of PrintListOperand() // MACHINE DEPENDENT: Is operand type a known type that we want to analyze? bool MDKnownOperandType(op_t TempOp) { bool GoodOpType = ((TempOp.type >= o_reg) && (TempOp.type <= o_xmmreg)); #if SMP_DEBUG_OPERAND_TYPES if (!GoodOpType && (o_void != TempOp.type)) { msg("WARNING: Operand type %d \n", TempOp.type); } #endif return GoodOpType; } // Meet function over any two types in the type lattice. SMPOperandType SMPTypeMeet(SMPOperandType Type1, SMPOperandType Type2) { SMPOperandType MeetType = UNKNOWN; bool ProfDerived = IsProfDerived(Type1) || IsProfDerived(Type2); if (IsEqType(UNINIT, Type1)) MeetType = Type2; else if (IsEqType(UNINIT, Type2) || IsEqType(Type1, Type2) || IsUnknown(Type1)) MeetType = Type1; else if (IsNumeric(Type1)) { if (IsNumeric(Type2)) // one is NUMERIC, one is CODEPTR MeetType = NUMERIC; else if (IsDataPtr(Type2) || IsUnknown(Type2)) MeetType = UNKNOWN; else msg("ERROR #1 in SMPTypeMeet.\n"); } else if (IsDataPtr(Type1)) { if (IsDataPtr(Type2)) // two different POINTER subtypes MeetType = POINTER; else if (IsNumeric(Type2) || IsUnknown(Type2)) MeetType = UNKNOWN; else msg("ERROR #2 in SMPTypeMeet.\n"); } if (ProfDerived && IsNotEqType(UNINIT, MeetType)) MeetType = MakeProfDerived(MeetType); return MeetType; } // end of SMPTypeMeet() // ***************************************************************** // Class DefOrUse // ***************************************************************** // Default constructor to make the compilers happy. DefOrUse::DefOrUse(void) { this->Operand.type = o_void; this->OpType = UNINIT; this->NonSpeculativeOpType = UNINIT; this->SSANumber = -2; this->MetadataStatus = DEF_METADATA_UNANALYZED; return; } // Constructor. DefOrUse::DefOrUse(op_t Ref, SMPOperandType Type, int SSASub) { if (o_reg == Ref.type) { // We want to map AH, AL, and AX to EAX, etc. throughout our data flow analysis // and type inference systems. Ref.reg = MDCanonicalizeSubReg(Ref.reg); } this->Operand = Ref; this->OpType = Type; assert(!IsProfDerived(Type)); this->NonSpeculativeOpType = Type; this->SSANumber = SSASub; this->MetadataStatus = DEF_METADATA_UNANALYZED; this->IndWrite = false; return; } // Copy constructor. DefOrUse::DefOrUse(const DefOrUse &CopyIn) { *this = CopyIn; return; } // Assignment operator for copy constructor use. DefOrUse &DefOrUse::operator=(const DefOrUse &rhs) { this->Operand = rhs.Operand; this->OpType = rhs.OpType; this->NonSpeculativeOpType = rhs.NonSpeculativeOpType; this->SSANumber = rhs.SSANumber; this->MetadataStatus = rhs.MetadataStatus; this->IndWrite = rhs.IndWrite; return *this; } // Set the operand type for this DEF or USE - don't forget to take // into account the speculative (profiler) status. void DefOrUse::SetType(SMPOperandType Type, const SMPInstr *Instr) { SMPOperandType OldType = this->OpType; SMPOperandType NewType = Type; if (Instr->GetBlock()->GetFunc()->GetIsSpeculative()) { NewType = (SMPOperandType)(((int)NewType) | PROF_BASE); if (!IsProfDerived(OldType)) this->NonSpeculativeOpType = OldType; } this->OpType = NewType; } // Set the indirect memory write flag. void DefOrUse::SetIndWrite(bool IndMemWrite) { this->IndWrite = IndMemWrite; return; } // Debug printing. void DefOrUse::Dump(void) const { PrintListOperand(this->Operand, this->SSANumber); if (IsEqType(this->OpType , NUMERIC)) msg("N "); else if (IsEqType(this->OpType , CODEPTR)) msg("C "); else if (IsEqType(this->OpType , POINTER)) msg("P "); else if (IsEqType(this->OpType , STACKPTR)) msg("S "); else if (IsEqType(this->OpType , GLOBALPTR)) msg("G "); else if (IsEqType(this->OpType , HEAPPTR)) msg("H "); else if (IsEqType(this->OpType , PTROFFSET)) msg("O "); else if (IsEqType(this->OpType , UNKNOWN)) msg("U "); /* emit the profile bit */ if (IsProfDerived(this->OpType)) msg("Pr "); // Don't write anything for UNINIT OpType // Emit the metadata status. if (DEF_METADATA_UNUSED == this->MetadataStatus) msg("Mn "); else if (DEF_METADATA_USED == this->MetadataStatus) msg("Mu "); else if (DEF_METADATA_REDUNDANT == this->MetadataStatus) msg("Mr "); // Is the DEF possibly aliased because of an indirect write in // the DEF-USE chain? if (this->IndWrite) msg("Al* "); return; } // end of DefOrUse::Dump() // ***************************************************************** // Class DefOrUseSet // ***************************************************************** // Default constructor. DefOrUseSet::DefOrUseSet(void) { this->Refs.clear(); return; } // Destructor. DefOrUseSet::~DefOrUseSet() { this->Refs.clear(); return; } // Find the reference for a given operand type. set<DefOrUse, LessDefUse>::iterator DefOrUseSet::FindRef(op_t SearchOp) { set<DefOrUse, LessDefUse>::iterator CurrRef; DefOrUse DummyRef(SearchOp); CurrRef = this->Refs.find(DummyRef); return CurrRef; } // Set a Def or Use into the list, along with its type. void DefOrUseSet::SetRef(op_t Ref, SMPOperandType Type, int SSASub) { DefOrUse CurrRef(Ref, Type, SSASub); this->Refs.insert(CurrRef); return; } // Change the SSA subscript for a reference. set<DefOrUse, LessDefUse>::iterator DefOrUseSet::SetSSANum(op_t CurrOp, int NewSSASub) { // To change a field within a set, we must grab a copy, change the copy, // delete the old set member, and insert the updated copy as a new member. set<DefOrUse, LessDefUse>::iterator CurrRef = this->FindRef(CurrOp); assert(CurrRef != this->Refs.end()); set<DefOrUse, LessDefUse>::iterator NextRef = CurrRef; ++NextRef; DefOrUse NewCopy = (*CurrRef); NewCopy.SetSSANum(NewSSASub); this->Refs.erase(CurrRef); CurrRef = this->Refs.insert(NextRef, NewCopy); return CurrRef; } // end of DefOrUseSet::SetSSANum() // Change the operand type for a reference. set<DefOrUse, LessDefUse>::iterator DefOrUseSet::SetType(op_t CurrOp, SMPOperandType Type, const SMPInstr* Instr) { // To change a field within a set, we must grab a copy, change the copy, // delete the old set member, and insert the updated copy as a new member. set<DefOrUse, LessDefUse>::iterator CurrRef = this->FindRef(CurrOp); assert(CurrRef != this->Refs.end()); #if 1 if (o_imm == CurrOp.type) { if (UNINIT != CurrRef->GetType() && Type!=CurrRef->GetType() ) { msg("ERROR: Changing type of immediate from %d to %d : ", CurrRef->GetType(), Type); CurrRef->Dump(); msg("\n"); } } #endif DefOrUse NewCopy = (*CurrRef); NewCopy.SetType(Type,Instr); this->Refs.erase(CurrRef); pair<set<DefOrUse, LessDefUse>::iterator, bool> InsertResult; InsertResult = this->Refs.insert(NewCopy); assert(InsertResult.second); CurrRef = InsertResult.first; return CurrRef; } // end of DefOrUseSet::SetType() // Change the Metadata type for a reference. set<DefOrUse, LessDefUse>::iterator DefOrUseSet::SetMetadata(op_t CurrOp, SMPMetadataType Status) { // To change a field within a set, we must grab a copy, change the copy, // delete the old set member, and insert the updated copy as a new member. set<DefOrUse, LessDefUse>::iterator CurrRef = this->FindRef(CurrOp); assert(CurrRef != this->Refs.end()); DefOrUse NewCopy = (*CurrRef); NewCopy.SetMetadataStatus(Status); this->Refs.erase(CurrRef); pair<set<DefOrUse, LessDefUse>::iterator, bool> InsertResult; InsertResult = this->Refs.insert(NewCopy); assert(InsertResult.second); CurrRef = InsertResult.first; return CurrRef; } // end of DefOrUseSet::SetMetadata() // Change the indirect write status for a reference. set<DefOrUse, LessDefUse>::iterator DefOrUseSet::SetIndWrite(op_t CurrOp, bool IndWriteFlag) { // To change a field within a set, we must grab a copy, change the copy, // delete the old set member, and insert the updated copy as a new member. set<DefOrUse, LessDefUse>::iterator CurrRef = this->FindRef(CurrOp); assert(CurrRef != this->Refs.end()); DefOrUse NewCopy = (*CurrRef); NewCopy.SetIndWrite(IndWriteFlag); this->Refs.erase(CurrRef); pair<set<DefOrUse, LessDefUse>::iterator, bool> InsertResult; InsertResult = this->Refs.insert(NewCopy); assert(InsertResult.second); CurrRef = InsertResult.first; return CurrRef; } // end of DefOrUseSet::SetIndWrite() // Debug printing. void DefOrUseSet::Dump(void) { set<DefOrUse, LessDefUse>::iterator CurrRef; for (CurrRef = this->Refs.begin(); CurrRef != this->Refs.end(); ++CurrRef) { CurrRef->Dump(); } msg("\n"); return; } // Do all types agree, ignoring any flags registers in the set? This is used // for conditional move instructions; if all types agree, it does not matter // whether the move happens or not. bool DefOrUseSet::TypesAgreeNoFlags(void) { bool FoundFirstUse = false; set<DefOrUse, LessDefUse>::iterator CurrUse; SMPOperandType UseType = UNINIT; for (CurrUse = this->Refs.begin(); CurrUse != this->Refs.end(); ++CurrUse) { if (!(CurrUse->GetOp().is_reg(X86_FLAGS_REG))) { // ignore flags if (!FoundFirstUse) { FoundFirstUse = true; UseType = CurrUse->GetType(); } else { if (IsNotEqType(CurrUse->GetType(), UseType)) { return false; // inconsistent types } } } } return true; } // end of DefOrUseSet::TypesAgreeNoFlags() // ***************************************************************** // Class DefOrUseList // ***************************************************************** // Default constructor. DefOrUseList::DefOrUseList(void) { this->Refs.clear(); return; } // Set a Def or Use into the list, along with its type. void DefOrUseList::SetRef(op_t Ref, SMPOperandType Type, int SSASub) { DefOrUse CurrRef(Ref, Type, SSASub); this->Refs.push_back(CurrRef); return; } // Get a reference by index. DefOrUse DefOrUseList::GetRef(size_t index) const { return Refs[index]; } // Change the SSA subscript for a reference. void DefOrUseList::SetSSANum(size_t index, int NewSSASub) { this->Refs[index].SetSSANum(NewSSASub); return; } // Change the operand type for a reference. void DefOrUseList::SetType(size_t index, SMPOperandType Type, const SMPInstr* Instr) { this->Refs[index].SetType(Type,Instr); return; } // Debug printing. void DefOrUseList::Dump(void) const { for (size_t index = 0; index < this->Refs.size(); ++index) { Refs[index].Dump(); } msg("\n"); return; } // Erase duplicate entries, in case SMPInstr::MDFixupDefUseLists() adds one. void DefOrUseList::EraseDuplicates(void) { set<op_t, LessOp> TempRefs; // Use STL set to find duplicates set<op_t, LessOp>::iterator TempIter; vector<DefOrUse>::iterator RefIter; RefIter = this->Refs.begin(); while (RefIter != this->Refs.end()) { TempIter = TempRefs.find(RefIter->GetOp()); if (TempIter == TempRefs.end()) { // not already in set TempRefs.insert(RefIter->GetOp()); ++RefIter; } else { // found it in set already RefIter = this->Refs.erase(RefIter); } } return; } // end of DefOrUseList::EraseDuplicates() // ***************************************************************** // Class SMPPhiFunction // ***************************************************************** // Constructor SMPPhiFunction::SMPPhiFunction(int GlobIndex, const DefOrUse &Def) { this->index = GlobIndex; this->DefName = Def; this->SubscriptedOps.clear(); return; } // Add a phi item to the list void SMPPhiFunction::PushBack(DefOrUse Ref) { this->SubscriptedOps.SetRef(Ref.GetOp(), Ref.GetType(), Ref.GetSSANum()); return; } // Set the SSA number of the defined variable. void SMPPhiFunction::SetSSADef(int NewSSASub) { this->DefName.SetSSANum(NewSSASub); return; } // Set the SSA number of the input variable. void SMPPhiFunction::SetSSARef(size_t index, int NewSSASub) { this->SubscriptedOps.SetSSANum(index, NewSSASub); return; } // Set the type of the defined variable. void SMPPhiFunction::SetDefType(SMPOperandType Type, const SMPInstr* Instr) { this->DefName.SetType(Type, Instr); return; } // Set the type of the input variable. void SMPPhiFunction::SetRefType(size_t index, SMPOperandType Type, const SMPInstr* Instr) { this->SubscriptedOps.SetType(index, Type, Instr); return; } // Set the metadata status of the DEF variable. void SMPPhiFunction::SetDefMetadata(SMPMetadataType Status) { this->DefName.SetMetadataStatus(Status); return; } // end of SMPPhiFunction::SetDefMetadata() // Does at least one USE have a type other than UNINIT? bool SMPPhiFunction::HasTypedUses(void) { size_t index; for (index = 0; index < this->GetPhiListSize(); ++index) { if (UNINIT != this->GetUseType(index)) return true; } return false; } // end of SMPPhiFunction::HasTypedUses() // Return the result of applying the conditional type propagation meet operator // over all the USE types. SMPOperandType SMPPhiFunction::ConditionalMeetType(void) const { SMPOperandType MeetType; SMPOperandType PtrType = UNINIT; SMPOperandType NumericType = UNINIT; // can end up NUMERIC or CODEPTR bool FoundUNINIT = false; // any USE type UNINIT? bool FoundNUMERIC = false; // any USE type NUMERIC? bool FoundPOINTER = false; // includes all POINTER subtypes bool FoundUNKNOWN = false; // any USE type UNKNOWN? bool ProfilerDerived = false; // was any USE type Profiler-derived? for (size_t index = 0; index < this->GetPhiListSize(); ++index) { SMPOperandType UseType = this->GetUseType(index); if (IsEqType(UseType, UNINIT)) FoundUNINIT = true; else if (IsNumeric(UseType)) { FoundNUMERIC = true; if (IsEqType(NumericType, CODEPTR)) { // Already refined. If current type agrees, leave it // alone, else revert to generic type NUMERIC. if (IsNotEqType(UseType, NumericType)) NumericType = NUMERIC; } else { // Have not yet refined NumericType; might still be UNINIT. if (IsEqType(UNINIT, NumericType)) NumericType = UseType; else { // NumericType is NUMERIC; leave it as NUMERIC. assert(IsEqType(NUMERIC, NumericType)); } } } else if (IsDataPtr(UseType)) { FoundPOINTER = true; // Perform a meet over the pointer types. if (IsRefinedDataPtr(PtrType)) { // Already refined. If current type agrees, leave it // alone, else revert to generic type POINTER. if (IsNotEqType(UseType, PtrType)) PtrType = POINTER; } else { // Have not yet refined PtrType; might still be UNINIT. if (IsEqType(UNINIT, PtrType)) PtrType = UseType; else { // PtrType is POINTER because we saw POINTER or // had a conflict between pointer refinements; leave // it as POINTER. assert(IsEqType(POINTER, PtrType)); } } } else if (IsUnknown(UseType)) FoundUNKNOWN = true; if (IsProfDerived(UseType)) ProfilerDerived = true; } // Use the boolean flags to compute the meet function. if (FoundUNKNOWN || (FoundNUMERIC && FoundPOINTER)) MeetType = UNKNOWN; else if (FoundNUMERIC) MeetType = NumericType; else if (FoundPOINTER) MeetType = PtrType; else { assert(FoundUNINIT); MeetType = UNINIT; } if (ProfilerDerived) MeetType = MakeProfDerived(MeetType); return MeetType; } // end of SMPPhiFunction::ConditionalMeetType() // Debug printing. void SMPPhiFunction::Dump(void) const { msg(" DEF: "); this->DefName.Dump(); msg(" USEs: "); this->SubscriptedOps.Dump(); return; } // ***************************************************************** // Class SMPDefUseChain // ***************************************************************** // Constructors SMPDefUseChain::SMPDefUseChain(void) { this->SSAName.type = o_void; this->RefInstrs.clear(); this->RefInstrs.push_back(BADADDR); this->IndWrite = false; return; } SMPDefUseChain::SMPDefUseChain(op_t Name, ea_t Def) { if (o_reg == Name.type) { // We want to map AH, AL, and AX to EAX, etc. throughout our data flow analysis // and type inference systems. Name.reg = MDCanonicalizeSubReg(Name.reg); } this->SSAName = Name; this->RefInstrs.push_back(Def); this->IndWrite = false; return; } // Set the variable name. void SMPDefUseChain::SetName(op_t Name) { if (o_reg == Name.type) { // We want to map AH, AL, and AX to EAX, etc. throughout our data flow analysis // and type inference systems. Name.reg = MDCanonicalizeSubReg(Name.reg); } this->SSAName = Name; return; } // Set the DEF instruction. void SMPDefUseChain::SetDef(ea_t Def) { this->RefInstrs[0] = Def; return; } // Push a USE onto the list void SMPDefUseChain::PushUse(ea_t Use) { this->RefInstrs.push_back(Use); return; } // Set the indirect memory write flag. void SMPDefUseChain::SetIndWrite(bool IndMemWrite) { this->IndWrite = IndMemWrite; return; } // DEBUG dump. void SMPDefUseChain::Dump(int SSANum) { msg("DEF-USE chain for: "); PrintListOperand(this->SSAName, SSANum); if (this->RefInstrs.size() < 1) { msg(" no references.\n"); return; } msg("\n DEF: %x USEs: ", this->RefInstrs.at(0)); size_t index; for (index = 1; index < this->RefInstrs.size(); ++index) msg("%x ", this->RefInstrs.at(index)); msg("\n"); return; } // end of SMPDefUseChain::Dump() // ***************************************************************** // Class SMPDUChainArray // ***************************************************************** SMPDUChainArray::SMPDUChainArray(void) { this->SSAName.type = o_void; this->DUChains.clear(); return; } SMPDUChainArray::SMPDUChainArray(op_t Name) { if (o_reg == Name.type) { // We want to map AH, AL, and AX to EAX, etc. throughout our data flow analysis // and type inference systems. Name.reg = MDCanonicalizeSubReg(Name.reg); } this->SSAName = Name; this->DUChains.clear(); return; } void SMPDUChainArray::SetName(op_t Name) { if (o_reg == Name.type) { // We want to map AH, AL, and AX to EAX, etc. throughout our data flow analysis // and type inference systems. Name.reg = MDCanonicalizeSubReg(Name.reg); } this->SSAName = Name; return; } // DEBUG dump. void SMPDUChainArray::Dump(void) { size_t index; for (index = 0; index < this->DUChains.size(); ++index) { this->DUChains.at(index).Dump((int) index); } return; } // ***************************************************************** // Class SMPCompleteDUChains // ***************************************************************** // DEBUG dump. void SMPCompleteDUChains::Dump(void) { size_t index; for (index = 0; index < this->ChainsByName.size(); ++index) { this->ChainsByName.at(index).Dump(); } return; } // end of SMPCompleteDUChains::Dump() // 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 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 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] = false; // 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_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_shl] = false; // Shift Logical Left SMPDefsFlags[NN_shr] = false; // 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 // // 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 SMPDefsFlags[NN_stmxcsr] = false; // Store Streaming SIMD Extensions Technology Control/Status Register SMPDefsFlags[NN_subps] = false; // Packed Single-FP Subtract SMPDefsFlags[NN_subss] = false; // Scalar Single-FP Subtract SMPDefsFlags[NN_unpckhps] = false; // Unpack High Packed Single-FP Data SMPDefsFlags[NN_unpcklps] = false; // Unpack Low Packed Single-FP Data SMPDefsFlags[NN_xorps] = false; // Bitwise Logical XOR for Single-FP Data SMPDefsFlags[NN_pavgb] = false; // Packed Average (Byte) SMPDefsFlags[NN_pavgw] = false; // Packed Average (Word) SMPDefsFlags[NN_pextrw] = false; // Extract Word SMPDefsFlags[NN_pinsrw] = false; // Insert Word SMPDefsFlags[NN_pmaxsw] = false; // Packed Signed Integer Word Maximum SMPDefsFlags[NN_pmaxub] = false; // Packed Unsigned Integer Byte Maximum SMPDefsFlags[NN_pminsw] = false; // Packed Signed Integer Word Minimum SMPDefsFlags[NN_pminub] = false; // Packed Unsigned Integer Byte Minimum SMPDefsFlags[NN_pmovmskb] = false; // Move Byte Mask to Integer SMPDefsFlags[NN_pmulhuw] = false; // Packed Multiply High Unsigned SMPDefsFlags[NN_psadbw] = false; // Packed Sum of Absolute Differences SMPDefsFlags[NN_pshufw] = false; // Packed Shuffle Word SMPDefsFlags[NN_maskmovq] = false; // Byte Mask write SMPDefsFlags[NN_movntps] = false; // Move Aligned Four Packed Single-FP Non Temporal SMPDefsFlags[NN_movntq] = false; // Move 64 Bits Non Temporal SMPDefsFlags[NN_prefetcht0] = false; // Prefetch to all cache levels SMPDefsFlags[NN_prefetcht1] = false; // Prefetch to all cache levels SMPDefsFlags[NN_prefetcht2] = false; // Prefetch to L2 cache SMPDefsFlags[NN_prefetchnta] = false; // Prefetch to L1 cache SMPDefsFlags[NN_sfence] = false; // Store Fence // Pentium III Pseudo instructions SMPDefsFlags[NN_cmpeqps] = false; // Packed Single-FP Compare EQ SMPDefsFlags[NN_cmpltps] = false; // Packed Single-FP Compare LT SMPDefsFlags[NN_cmpleps] = false; // Packed Single-FP Compare LE SMPDefsFlags[NN_cmpunordps] = false; // Packed Single-FP Compare UNORD SMPDefsFlags[NN_cmpneqps] = false; // Packed Single-FP Compare NOT EQ SMPDefsFlags[NN_cmpnltps] = false; // Packed Single-FP Compare NOT LT SMPDefsFlags[NN_cmpnleps] = false; // Packed Single-FP Compare NOT LE SMPDefsFlags[NN_cmpordps] = false; // Packed Single-FP Compare ORDERED SMPDefsFlags[NN_cmpeqss] = false; // Scalar Single-FP Compare EQ SMPDefsFlags[NN_cmpltss] = false; // Scalar Single-FP Compare LT SMPDefsFlags[NN_cmpless] = false; // Scalar Single-FP Compare LE SMPDefsFlags[NN_cmpunordss] = false; // Scalar Single-FP Compare UNORD SMPDefsFlags[NN_cmpneqss] = false; // Scalar Single-FP Compare NOT EQ SMPDefsFlags[NN_cmpnltss] = false; // Scalar Single-FP Compare NOT LT SMPDefsFlags[NN_cmpnless] = false; // Scalar Single-FP Compare NOT LE SMPDefsFlags[NN_cmpordss] = false; // Scalar Single-FP Compare ORDERED // AMD K7 instructions // Revisit AMD if we port to it. SMPDefsFlags[NN_pf2iw] = false; // Packed Floating-Point to Integer with Sign Extend SMPDefsFlags[NN_pfnacc] = false; // Packed Floating-Point Negative Accumulate SMPDefsFlags[NN_pfpnacc] = false; // Packed Floating-Point Mixed Positive-Negative Accumulate SMPDefsFlags[NN_pi2fw] = false; // Packed 16-bit Integer to Floating-Point SMPDefsFlags[NN_pswapd] = false; // Packed Swap Double Word // Undocumented FP instructions (thanks to norbert.juffa@adm.com) SMPDefsFlags[NN_fstp1] = false; // Alias of Store Real and Pop SMPDefsFlags[NN_fxch4] = false; // Alias of Exchange Registers SMPDefsFlags[NN_ffreep] = false; // Free Register and Pop SMPDefsFlags[NN_fxch7] = false; // Alias of Exchange Registers SMPDefsFlags[NN_fstp8] = false; // Alias of Store Real and Pop SMPDefsFlags[NN_fstp9] = false; // Alias of Store Real and Pop // Pentium 4 instructions SMPDefsFlags[NN_addpd] = false; // Add Packed Double-Precision Floating-Point Values SMPDefsFlags[NN_addsd] = false; // Add Scalar Double-Precision Floating-Point Values SMPDefsFlags[NN_andnpd] = false; // Bitwise Logical AND NOT of Packed Double-Precision Floating-Point Values SMPDefsFlags[NN_andpd] = false; // Bitwise Logical AND of Packed Double-Precision Floating-Point Values SMPDefsFlags[NN_clflush] = false; // Flush Cache Line SMPDefsFlags[NN_cmppd] = false; // Compare Packed Double-Precision Floating-Point Values SMPDefsFlags[NN_cmpsd] = false; // Compare Scalar Double-Precision Floating-Point Values SMPDefsFlags[NN_cvtdq2pd] = false; // Convert Packed Doubleword Integers to Packed Single-Precision Floating-Point Values SMPDefsFlags[NN_cvtdq2ps] = false; // Convert Packed Doubleword Integers to Packed Double-Precision Floating-Point Values SMPDefsFlags[NN_cvtpd2dq] = false; // Convert Packed Double-Precision Floating-Point Values to Packed Doubleword Integers SMPDefsFlags[NN_cvtpd2pi] = false; // Convert Packed Double-Precision Floating-Point Values to Packed Doubleword Integers SMPDefsFlags[NN_cvtpd2ps] = false; // Convert Packed Double-Precision Floating-Point Values to Packed Single-Precision Floating-Point Values SMPDefsFlags[NN_cvtpi2pd] = false; // Convert Packed Doubleword Integers to Packed Double-Precision Floating-Point Values SMPDefsFlags[NN_cvtps2dq] = false; // Convert Packed Single-Precision Floating-Point Values to Packed Doubleword Integers SMPDefsFlags[NN_cvtps2pd] = false; // Convert Packed Single-Precision Floating-Point Values to Packed Double-Precision Floating-Point Values SMPDefsFlags[NN_cvtsd2si] = false; // Convert Scalar Double-Precision Floating-Point Value to Doubleword Integer SMPDefsFlags[NN_cvtsd2ss] = false; // Convert Scalar Double-Precision Floating-Point Value to Scalar Single-Precision Floating-Point Value SMPDefsFlags[NN_cvtsi2sd] = false; // Convert Doubleword Integer to Scalar Double-Precision Floating-Point Value SMPDefsFlags[NN_cvtss2sd] = false; // Convert Scalar Single-Precision Floating-Point Value to Scalar Double-Precision Floating-Point Value SMPDefsFlags[NN_cvttpd2dq] = false; // Convert With Truncation Packed Double-Precision Floating-Point Values to Packed Doubleword Integers SMPDefsFlags[NN_cvttpd2pi] = false; // Convert with Truncation Packed Double-Precision Floating-Point Values to Packed Doubleword Integers SMPDefsFlags[NN_cvttps2dq] = false; // Convert With Truncation Packed Single-Precision Floating-Point Values to Packed Doubleword Integers SMPDefsFlags[NN_cvttsd2si] = false; // Convert with Truncation Scalar Double-Precision Floating-Point Value to Doubleword Integer SMPDefsFlags[NN_divpd] = false; // Divide Packed Double-Precision Floating-Point Values SMPDefsFlags[NN_divsd] = false; // Divide Scalar Double-Precision Floating-Point Values SMPDefsFlags[NN_lfence] = false; // Load Fence SMPDefsFlags[NN_maskmovdqu] = false; // Store Selected Bytes of Double Quadword SMPDefsFlags[NN_maxpd] = false; // Return Maximum Packed Double-Precision Floating-Point Values SMPDefsFlags[NN_maxsd] = false; // Return Maximum Scalar Double-Precision Floating-Point Value SMPDefsFlags[NN_mfence] = false; // Memory Fence SMPDefsFlags[NN_minpd] = false; // Return Minimum Packed Double-Precision Floating-Point Values SMPDefsFlags[NN_minsd] = false; // Return Minimum Scalar Double-Precision Floating-Point Value SMPDefsFlags[NN_movapd] = false; // Move Aligned Packed Double-Precision Floating-Point Values SMPDefsFlags[NN_movdq2q] = false; // Move Quadword from XMM to MMX Register SMPDefsFlags[NN_movdqa] = false; // Move Aligned Double Quadword SMPDefsFlags[NN_movdqu] = false; // Move Unaligned Double Quadword SMPDefsFlags[NN_movhpd] = false; // Move High Packed Double-Precision Floating-Point Values SMPDefsFlags[NN_movlpd] = false; // Move Low Packed Double-Precision Floating-Point Values SMPDefsFlags[NN_movmskpd] = false; // Extract Packed Double-Precision Floating-Point Sign Mask SMPDefsFlags[NN_movntdq] = false; // Store Double Quadword Using Non-Temporal Hint SMPDefsFlags[NN_movnti] = false; // Store Doubleword Using Non-Temporal Hint SMPDefsFlags[NN_movntpd] = false; // Store Packed Double-Precision Floating-Point Values Using Non-Temporal Hint SMPDefsFlags[NN_movq2dq] = false; // Move Quadword from MMX to XMM Register SMPDefsFlags[NN_movsd] = false; // Move Scalar Double-Precision Floating-Point Values SMPDefsFlags[NN_movupd] = false; // Move Unaligned Packed Double-Precision Floating-Point Values SMPDefsFlags[NN_mulpd] = false; // Multiply Packed Double-Precision Floating-Point Values SMPDefsFlags[NN_mulsd] = false; // Multiply Scalar Double-Precision Floating-Point Values SMPDefsFlags[NN_orpd] = false; // Bitwise Logical OR of Double-Precision Floating-Point Values SMPDefsFlags[NN_paddq] = false; // Add Packed Quadword Integers SMPDefsFlags[NN_pause] = false; // Spin Loop Hint SMPDefsFlags[NN_pmuludq] = false; // Multiply Packed Unsigned Doubleword Integers SMPDefsFlags[NN_pshufd] = false; // Shuffle Packed Doublewords SMPDefsFlags[NN_pshufhw] = false; // Shuffle Packed High Words SMPDefsFlags[NN_pshuflw] = false; // Shuffle Packed Low Words SMPDefsFlags[NN_pslldq] = false; // Shift Double Quadword Left Logical SMPDefsFlags[NN_psrldq] = false; // Shift Double Quadword Right Logical SMPDefsFlags[NN_psubq] = false; // Subtract Packed Quadword Integers SMPDefsFlags[NN_punpckhqdq] = false; // Unpack High Data SMPDefsFlags[NN_punpcklqdq] = false; // Unpack Low Data SMPDefsFlags[NN_shufpd] = false; // Shuffle Packed Double-Precision Floating-Point Values SMPDefsFlags[NN_sqrtpd] = false; // Compute Square Roots of Packed Double-Precision Floating-Point Values SMPDefsFlags[NN_sqrtsd] = false; // Compute Square Rootof Scalar Double-Precision Floating-Point Value SMPDefsFlags[NN_subpd] = false; // Subtract Packed Double-Precision Floating-Point Values SMPDefsFlags[NN_subsd] = false; // Subtract Scalar Double-Precision Floating-Point Values SMPDefsFlags[NN_unpckhpd] = false; // Unpack and Interleave High Packed Double-Precision Floating-Point Values SMPDefsFlags[NN_unpcklpd] = false; // Unpack and Interleave Low Packed Double-Precision Floating-Point Values SMPDefsFlags[NN_xorpd] = false; // Bitwise Logical OR of Double-Precision Floating-Point Values // AMD syscall/sysret instructions NOTE: not AMD, found in Intel manual // AMD64 instructions NOTE: not AMD, found in Intel manual SMPDefsFlags[NN_swapgs] = false; // Exchange GS base with KernelGSBase MSR // New Pentium instructions (SSE3) SMPDefsFlags[NN_movddup] = false; // Move One Double-FP and Duplicate SMPDefsFlags[NN_movshdup] = false; // Move Packed Single-FP High and Duplicate SMPDefsFlags[NN_movsldup] = false; // Move Packed Single-FP Low and Duplicate // Missing AMD64 instructions NOTE: also found in Intel manual SMPDefsFlags[NN_movsxd] = false; // Move with Sign-Extend Doubleword // SSE3 instructions SMPDefsFlags[NN_addsubpd] = false; // Add /Sub packed DP FP numbers SMPDefsFlags[NN_addsubps] = false; // Add /Sub packed SP FP numbers SMPDefsFlags[NN_haddpd] = false; // Add horizontally packed DP FP numbers SMPDefsFlags[NN_haddps] = false; // Add horizontally packed SP FP numbers SMPDefsFlags[NN_hsubpd] = false; // Sub horizontally packed DP FP numbers SMPDefsFlags[NN_hsubps] = false; // Sub horizontally packed SP FP numbers SMPDefsFlags[NN_monitor] = false; // Set up a linear address range to be monitored by hardware SMPDefsFlags[NN_mwait] = false; // Wait until write-back store performed within the range specified by the MONITOR instruction SMPDefsFlags[NN_fisttp] = false; // Store ST in intXX (chop) and pop SMPDefsFlags[NN_lddqu] = false; // Load unaligned integer 128-bit // SSSE3 instructions SMPDefsFlags[NN_psignb] = false; // Packed SIGN Byte SMPDefsFlags[NN_psignw] = false; // Packed SIGN Word SMPDefsFlags[NN_psignd] = false; // Packed SIGN Doubleword SMPDefsFlags[NN_pshufb] = false; // Packed Shuffle Bytes SMPDefsFlags[NN_pmulhrsw] = false; // Packed Multiply High with Round and Scale SMPDefsFlags[NN_pmaddubsw] = false; // Multiply and Add Packed Signed and Unsigned Bytes SMPDefsFlags[NN_phsubsw] = false; // Packed Horizontal Subtract and Saturate SMPDefsFlags[NN_phaddsw] = false; // Packed Horizontal Add and Saturate SMPDefsFlags[NN_phaddw] = false; // Packed Horizontal Add Word SMPDefsFlags[NN_phaddd] = false; // Packed Horizontal Add Doubleword SMPDefsFlags[NN_phsubw] = false; // Packed Horizontal Subtract Word SMPDefsFlags[NN_phsubd] = false; // Packed Horizontal Subtract Doubleword SMPDefsFlags[NN_palignr] = false; // Packed Align Right SMPDefsFlags[NN_pabsb] = false; // Packed Absolute Value Byte SMPDefsFlags[NN_pabsw] = false; // Packed Absolute Value Word SMPDefsFlags[NN_pabsd] = false; // Packed Absolute Value Doubleword // VMX instructions #if 599 < IDA_SDK_VERSION // Added with x86-64 SMPDefsFlags[NN_rdtscp] = false; // Read Time-Stamp Counter and Processor ID // Geode LX 3DNow! extensions SMPDefsFlags[NN_pfrcpv] = false; // Reciprocal Approximation for a Pair of 32-bit Floats SMPDefsFlags[NN_pfrsqrtv] = false; // Reciprocal Square Root Approximation for a Pair of 32-bit Floats // SSE2 pseudoinstructions SMPDefsFlags[NN_cmpeqpd] = false; // Packed Double-FP Compare EQ SMPDefsFlags[NN_cmpltpd] = false; // Packed Double-FP Compare LT SMPDefsFlags[NN_cmplepd] = false; // Packed Double-FP Compare LE SMPDefsFlags[NN_cmpunordpd] = false; // Packed Double-FP Compare UNORD SMPDefsFlags[NN_cmpneqpd] = false; // Packed Double-FP Compare NOT EQ SMPDefsFlags[NN_cmpnltpd] = false; // Packed Double-FP Compare NOT LT SMPDefsFlags[NN_cmpnlepd] = false; // Packed Double-FP Compare NOT LE SMPDefsFlags[NN_cmpordpd] = false; // Packed Double-FP Compare ORDERED SMPDefsFlags[NN_cmpeqsd] = false; // Scalar Double-FP Compare EQ SMPDefsFlags[NN_cmpltsd] = false; // Scalar Double-FP Compare LT SMPDefsFlags[NN_cmplesd] = false; // Scalar Double-FP Compare LE SMPDefsFlags[NN_cmpunordsd] = false; // Scalar Double-FP Compare UNORD SMPDefsFlags[NN_cmpneqsd] = false; // Scalar Double-FP Compare NOT EQ SMPDefsFlags[NN_cmpnltsd] = false; // Scalar Double-FP Compare NOT LT SMPDefsFlags[NN_cmpnlesd] = false; // Scalar Double-FP Compare NOT LE SMPDefsFlags[NN_cmpordsd] = false; // Scalar Double-FP Compare ORDERED // SSSE4.1 instructions SMPDefsFlags[NN_blendpd] = false; // Blend Packed Double Precision Floating-Point Values SMPDefsFlags[NN_blendps] = false; // Blend Packed Single Precision Floating-Point Values SMPDefsFlags[NN_blendvpd] = false; // Variable Blend Packed Double Precision Floating-Point Values SMPDefsFlags[NN_blendvps] = false; // Variable Blend Packed Single Precision Floating-Point Values SMPDefsFlags[NN_dppd] = false; // Dot Product of Packed Double Precision Floating-Point Values SMPDefsFlags[NN_dpps] = false; // Dot Product of Packed Single Precision Floating-Point Values SMPDefsFlags[NN_extractps] = 2; // Extract Packed Single Precision Floating-Point Value SMPDefsFlags[NN_insertps] = false; // Insert Packed Single Precision Floating-Point Value SMPDefsFlags[NN_movntdqa] = false; // Load Double Quadword Non-Temporal Aligned Hint SMPDefsFlags[NN_mpsadbw] = false; // Compute Multiple Packed Sums of Absolute Difference SMPDefsFlags[NN_packusdw] = false; // Pack with Unsigned Saturation SMPDefsFlags[NN_pblendvb] = false; // Variable Blend Packed Bytes SMPDefsFlags[NN_pblendw] = false; // Blend Packed Words SMPDefsFlags[NN_pcmpeqq] = false; // Compare Packed Qword Data for Equal SMPDefsFlags[NN_pextrb] = false; // Extract Byte SMPDefsFlags[NN_pextrd] = false; // Extract Dword SMPDefsFlags[NN_pextrq] = false; // Extract Qword SMPDefsFlags[NN_phminposuw] = false; // Packed Horizontal Word Minimum SMPDefsFlags[NN_pinsrb] = false; // Insert Byte SMPDefsFlags[NN_pinsrd] = false; // Insert Dword SMPDefsFlags[NN_pinsrq] = false; // Insert Qword SMPDefsFlags[NN_pmaxsb] = false; // Maximum of Packed Signed Byte Integers SMPDefsFlags[NN_pmaxsd] = false; // Maximum of Packed Signed Dword Integers SMPDefsFlags[NN_pmaxud] = false; // Maximum of Packed Unsigned Dword Integers SMPDefsFlags[NN_pmaxuw] = false; // Maximum of Packed Word Integers SMPDefsFlags[NN_pminsb] = false; // Minimum of Packed Signed Byte Integers SMPDefsFlags[NN_pminsd] = false; // Minimum of Packed Signed Dword Integers SMPDefsFlags[NN_pminud] = false; // Minimum of Packed Unsigned Dword Integers SMPDefsFlags[NN_pminuw] = false; // Minimum of Packed Word Integers SMPDefsFlags[NN_pmovsxbw] = false; // Packed Move with Sign Extend SMPDefsFlags[NN_pmovsxbd] = false; // Packed Move with Sign Extend SMPDefsFlags[NN_pmovsxbq] = false; // Packed Move with Sign Extend SMPDefsFlags[NN_pmovsxwd] = false; // Packed Move with Sign Extend SMPDefsFlags[NN_pmovsxwq] = false; // Packed Move with Sign Extend SMPDefsFlags[NN_pmovsxdq] = false; // Packed Move with Sign Extend SMPDefsFlags[NN_pmovzxbw] = false; // Packed Move with Zero Extend SMPDefsFlags[NN_pmovzxbd] = false; // Packed Move with Zero Extend SMPDefsFlags[NN_pmovzxbq] = false; // Packed Move with Zero Extend SMPDefsFlags[NN_pmovzxwd] = false; // Packed Move with Zero Extend SMPDefsFlags[NN_pmovzxwq] = false; // Packed Move with Zero Extend SMPDefsFlags[NN_pmovzxdq] = false; // Packed Move with Zero Extend SMPDefsFlags[NN_pmuldq] = false; // Multiply Packed Signed Dword Integers SMPDefsFlags[NN_pmulld] = false; // Multiply Packed Signed Dword Integers and Store Low Result SMPDefsFlags[NN_roundpd] = false; // Round Packed Double Precision Floating-Point Values SMPDefsFlags[NN_roundps] = false; // Round Packed Single Precision Floating-Point Values SMPDefsFlags[NN_roundsd] = false; // Round Scalar Double Precision Floating-Point Values SMPDefsFlags[NN_roundss] = false; // Round Scalar Single Precision Floating-Point Values // SSSE4.2 instructions SMPDefsFlags[NN_crc32] = false; // Accumulate CRC32 Value SMPDefsFlags[NN_pcmpgtq] = false; // Compare Packed Data for Greater Than // AMD SSE4a instructions SMPDefsFlags[NN_extrq] = false; // Extract Field From Register SMPDefsFlags[NN_insertq] = false; // Insert Field SMPDefsFlags[NN_movntsd] = false; // Move Non-Temporal Scalar Double-Precision Floating-Point SMPDefsFlags[NN_movntss] = false; // Move Non-Temporal Scalar Single-Precision Floating-Point // xsave/xrstor instructions SMPDefsFlags[NN_xgetbv] = false; // Get Value of Extended Control Register SMPDefsFlags[NN_xrstor] = false; // Restore Processor Extended States SMPDefsFlags[NN_xsave] = false; // Save Processor Extended States SMPDefsFlags[NN_xsetbv] = false; // Set Value of Extended Control Register // Intel Safer Mode Extensions (SMX) // AMD-V Virtualization ISA Extension SMPDefsFlags[NN_invlpga] = false; // Invalidate TLB Entry in a Specified ASID SMPDefsFlags[NN_skinit] = false; // Secure Init and Jump with Attestation SMPDefsFlags[NN_vmexit] = false; // Stop Executing Guest, Begin Executing Host SMPDefsFlags[NN_vmload] = false; // Load State from VMCB SMPDefsFlags[NN_vmmcall] = false; // Call VMM SMPDefsFlags[NN_vmrun] = false; // Run Virtual Machine SMPDefsFlags[NN_vmsave] = false; // Save State to VMCB // VMX+ instructions SMPDefsFlags[NN_invept] = false; // Invalidate Translations Derived from EPT SMPDefsFlags[NN_invvpid] = false; // Invalidate Translations Based on VPID // Intel Atom instructions SMPDefsFlags[NN_movbe] = false; // Move Data After Swapping Bytes // Intel AES instructions SMPDefsFlags[NN_aesenc] = false; // Perform One Round of an AES Encryption Flow SMPDefsFlags[NN_aesenclast] = false; // Perform the Last Round of an AES Encryption Flow SMPDefsFlags[NN_aesdec] = false; // Perform One Round of an AES Decryption Flow SMPDefsFlags[NN_aesdeclast] = false; // Perform the Last Round of an AES Decryption Flow SMPDefsFlags[NN_aesimc] = false; // Perform the AES InvMixColumn Transformation SMPDefsFlags[NN_aeskeygenassist] = false; // AES Round Key Generation Assist // Carryless multiplication SMPDefsFlags[NN_pclmulqdq] = false; // Carry-Less Multiplication Quadword #endif // 599 < IDA_SDK_VERSION SMPDefsFlags[NN_last] = false; return; } // end InitSMPDefsFlags() // Initialize the SMPUsesFlags[] array to define how we emit // optimizing annotations. void InitSMPUsesFlags(void) { // Default value is false. Few instructions use the flags. (void) memset(SMPUsesFlags, false, sizeof(SMPUsesFlags)); SMPUsesFlags[NN_null] = true; // Unknown Operation #if 1 SMPUsesFlags[NN_aaa] = true; // ASCII adjust after addition SMPUsesFlags[NN_aas] = true; // ASCII adjust after subtraction #endif SMPUsesFlags[NN_adc] = true; // Add with Carry SMPUsesFlags[NN_cmps] = true; // Compare Strings (uses DF direction flag) SMPUsesFlags[NN_into] = true; // Call to Interrupt Procedure if Overflow Flag = 1 SMPUsesFlags[NN_ja] = true; // Jump if Above (CF=0 & ZF=0) SMPUsesFlags[NN_jae] = true; // Jump if Above or Equal (CF=0) SMPUsesFlags[NN_jb] = true; // Jump if Below (CF=1) SMPUsesFlags[NN_jbe] = true; // Jump if Below or Equal (CF=1 | ZF=1) SMPUsesFlags[NN_jc] = true; // Jump if Carry (CF=1) SMPUsesFlags[NN_jcxz] = true; // Jump if CX is 0 SMPUsesFlags[NN_jecxz] = true; // Jump if ECX is 0 SMPUsesFlags[NN_jrcxz] = true; // Jump if RCX is 0 SMPUsesFlags[NN_je] = true; // Jump if Equal (ZF=1) SMPUsesFlags[NN_jg] = true; // Jump if Greater (ZF=0 & SF=OF) SMPUsesFlags[NN_jge] = true; // Jump if Greater or Equal (SF=OF) SMPUsesFlags[NN_jl] = true; // Jump if Less (SF!=OF) SMPUsesFlags[NN_jle] = true; // Jump if Less or Equal (ZF=1 | SF!=OF) SMPUsesFlags[NN_jna] = true; // Jump if Not Above (CF=1 | ZF=1) SMPUsesFlags[NN_jnae] = true; // Jump if Not Above or Equal (CF=1) SMPUsesFlags[NN_jnb] = true; // Jump if Not Below (CF=0) SMPUsesFlags[NN_jnbe] = true; // Jump if Not Below or Equal (CF=0 & ZF=0) SMPUsesFlags[NN_jnc] = true; // Jump if Not Carry (CF=0) SMPUsesFlags[NN_jne] = true; // Jump if Not Equal (ZF=0) SMPUsesFlags[NN_jng] = true; // Jump if Not Greater (ZF=1 | SF!=OF) SMPUsesFlags[NN_jnge] = true; // Jump if Not Greater or Equal (ZF=1) SMPUsesFlags[NN_jnl] = true; // Jump if Not Less (SF=OF) SMPUsesFlags[NN_jnle] = true; // Jump if Not Less or Equal (ZF=0 & SF=OF) SMPUsesFlags[NN_jno] = true; // Jump if Not Overflow (OF=0) SMPUsesFlags[NN_jnp] = true; // Jump if Not Parity (PF=0) SMPUsesFlags[NN_jns] = true; // Jump if Not Sign (SF=0) SMPUsesFlags[NN_jnz] = true; // Jump if Not Zero (ZF=0) SMPUsesFlags[NN_jo] = true; // Jump if Overflow (OF=1) SMPUsesFlags[NN_jp] = true; // Jump if Parity (PF=1) SMPUsesFlags[NN_jpe] = true; // Jump if Parity Even (PF=1) SMPUsesFlags[NN_jpo] = true; // Jump if Parity Odd (PF=0) SMPUsesFlags[NN_js] = true; // Jump if Sign (SF=1) SMPUsesFlags[NN_jz] = true; // Jump if Zero (ZF=1) SMPUsesFlags[NN_lahf] = true; // Load Flags into AH Register SMPUsesFlags[NN_loopwe] = true; // Loop while CX != 0 and ZF=1 SMPUsesFlags[NN_loope] = true; // Loop while rCX != 0 and ZF=1 SMPUsesFlags[NN_loopde] = true; // Loop while ECX != 0 and ZF=1 SMPUsesFlags[NN_loopqe] = true; // Loop while RCX != 0 and ZF=1 SMPUsesFlags[NN_loopwne] = true; // Loop while CX != 0 and ZF=0 SMPUsesFlags[NN_loopne] = true; // Loop while rCX != 0 and ZF=0 SMPUsesFlags[NN_loopdne] = true; // Loop while ECX != 0 and ZF=0 SMPUsesFlags[NN_loopqne] = true; // Loop while RCX != 0 and ZF=0 SMPUsesFlags[NN_movs] = true; // Move String (uses flags if REP prefix) SMPUsesFlags[NN_pushfw] = true; // Push Flags Register onto the Stack SMPUsesFlags[NN_pushf] = true; // Push Flags Register onto the Stack SMPUsesFlags[NN_pushfd] = true; // Push Flags Register onto the Stack (use32) SMPUsesFlags[NN_pushfq] = true; // Push Flags Register onto the Stack (use64) SMPUsesFlags[NN_repe] = true; // Repeat String Operation while ZF=1 SMPUsesFlags[NN_repne] = true; // Repeat String Operation while ZF=0 #if 0 SMPUsesFlags[NN_sahf] = true; // Store AH into Flags Register SMPUsesFlags[NN_shl] = true; // Shift Logical Left SMPUsesFlags[NN_shr] = true; // Shift Logical Right #endif SMPUsesFlags[NN_sbb] = true; // Integer Subtraction with Borrow SMPUsesFlags[NN_scas] = true; // Compare String (uses DF direction flag) SMPUsesFlags[NN_seta] = true; // Set Byte if Above (CF=0 & ZF=0) SMPUsesFlags[NN_setae] = true; // Set Byte if Above or Equal (CF=0) SMPUsesFlags[NN_setb] = true; // Set Byte if Below (CF=1) SMPUsesFlags[NN_setbe] = true; // Set Byte if Below or Equal (CF=1 | ZF=1) SMPUsesFlags[NN_setc] = true; // Set Byte if Carry (CF=1) SMPUsesFlags[NN_sete] = true; // Set Byte if Equal (ZF=1) SMPUsesFlags[NN_setg] = true; // Set Byte if Greater (ZF=0 & SF=OF) SMPUsesFlags[NN_setge] = true; // Set Byte if Greater or Equal (SF=OF) SMPUsesFlags[NN_setl] = true; // Set Byte if Less (SF!=OF) SMPUsesFlags[NN_setle] = true; // Set Byte if Less or Equal (ZF=1 | SF!=OF) SMPUsesFlags[NN_setna] = true; // Set Byte if Not Above (CF=1 | ZF=1) SMPUsesFlags[NN_setnae] = true; // Set Byte if Not Above or Equal (CF=1) SMPUsesFlags[NN_setnb] = true; // Set Byte if Not Below (CF=0) SMPUsesFlags[NN_setnbe] = true; // Set Byte if Not Below or Equal (CF=0 & ZF=0) SMPUsesFlags[NN_setnc] = true; // Set Byte if Not Carry (CF=0) SMPUsesFlags[NN_setne] = true; // Set Byte if Not Equal (ZF=0) SMPUsesFlags[NN_setng] = true; // Set Byte if Not Greater (ZF=1 | SF!=OF) SMPUsesFlags[NN_setnge] = true; // Set Byte if Not Greater or Equal (ZF=1) SMPUsesFlags[NN_setnl] = true; // Set Byte if Not Less (SF=OF) SMPUsesFlags[NN_setnle] = true; // Set Byte if Not Less or Equal (ZF=0 & SF=OF) SMPUsesFlags[NN_setno] = true; // Set Byte if Not Overflow (OF=0) SMPUsesFlags[NN_setnp] = true; // Set Byte if Not Parity (PF=0) SMPUsesFlags[NN_setns] = true; // Set Byte if Not Sign (SF=0) SMPUsesFlags[NN_setnz] = true; // Set Byte if Not Zero (ZF=0) SMPUsesFlags[NN_seto] = true; // Set Byte if Overflow (OF=1) SMPUsesFlags[NN_setp] = true; // Set Byte if Parity (PF=1) SMPUsesFlags[NN_setpe] = true; // Set Byte if Parity Even (PF=1) SMPUsesFlags[NN_setpo] = true; // Set Byte if Parity Odd (PF=0) SMPUsesFlags[NN_sets] = true; // Set Byte if Sign (SF=1) SMPUsesFlags[NN_setz] = true; // Set Byte if Zero (ZF=1) SMPUsesFlags[NN_stos] = true; // Store String // // 486 instructions // // // Pentium instructions // SMPUsesFlags[NN_cpuid] = true; // Get CPU ID #if 0 SMPUsesFlags[NN_cmpxchg8b] = true; // Compare and Exchange Eight Bytes #endif // // Pentium Pro instructions // SMPUsesFlags[NN_cmova] = true; // Move if Above (CF=0 & ZF=0) SMPUsesFlags[NN_cmovb] = true; // Move if Below (CF=1) SMPUsesFlags[NN_cmovbe] = true; // Move if Below or Equal (CF=1 | ZF=1) SMPUsesFlags[NN_cmovg] = true; // Move if Greater (ZF=0 & SF=OF) SMPUsesFlags[NN_cmovge] = true; // Move if Greater or Equal (SF=OF) SMPUsesFlags[NN_cmovl] = true; // Move if Less (SF!=OF) SMPUsesFlags[NN_cmovle] = true; // Move if Less or Equal (ZF=1 | SF!=OF) SMPUsesFlags[NN_cmovnb] = true; // Move if Not Below (CF=0) SMPUsesFlags[NN_cmovno] = true; // Move if Not Overflow (OF=0) SMPUsesFlags[NN_cmovnp] = true; // Move if Not Parity (PF=0) SMPUsesFlags[NN_cmovns] = true; // Move if Not Sign (SF=0) SMPUsesFlags[NN_cmovnz] = true; // Move if Not Zero (ZF=0) SMPUsesFlags[NN_cmovo] = true; // Move if Overflow (OF=1) SMPUsesFlags[NN_cmovp] = true; // Move if Parity (PF=1) SMPUsesFlags[NN_cmovs] = true; // Move if Sign (SF=1) SMPUsesFlags[NN_cmovz] = true; // Move if Zero (ZF=1) SMPUsesFlags[NN_fcmovb] = true; // Floating Move if Below SMPUsesFlags[NN_fcmove] = true; // Floating Move if Equal SMPUsesFlags[NN_fcmovbe] = true; // Floating Move if Below or Equal SMPUsesFlags[NN_fcmovu] = true; // Floating Move if Unordered SMPUsesFlags[NN_fcmovnb] = true; // Floating Move if Not Below SMPUsesFlags[NN_fcmovne] = true; // Floating Move if Not Equal SMPUsesFlags[NN_fcmovnbe] = true; // Floating Move if Not Below or Equal SMPUsesFlags[NN_fcmovnu] = true; // Floating Move if Not Unordered // // FPP instructions // // // 80387 instructions // // // Instructions added 28.02.96 // SMPUsesFlags[NN_setalc] = true; // Set AL to Carry Flag // // MMX instructions // // // Undocumented Deschutes processor instructions // // Pentium II instructions // 3DNow! instructions // Pentium III instructions // Pentium III Pseudo instructions // AMD K7 instructions // Revisit AMD if we port to it. // Undocumented FP instructions (thanks to norbert.juffa@adm.com) // Pentium 4 instructions // AMD syscall/sysret instructions NOTE: not AMD, found in Intel manual // AMD64 instructions NOTE: not AMD, found in Intel manual // New Pentium instructions (SSE3) // Missing AMD64 instructions NOTE: also found in Intel manual // SSE3 instructions // SSSE3 instructions // VMX instructions // 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 SMPUsesFlags[NN_last] = false; return; } // end InitSMPUsesFlags() // Initialize the SMPTypeCategory[] array to define how we infer // numeric or pointer operand types for optimizing annotations. void InitTypeCategory(void) { // Default category is 0, no type inference without knowing context. (void) memset(SMPTypeCategory, 0, sizeof(SMPTypeCategory)); // Category 1 instructions will need no mmStrata instrumentation // and are irrelevant to our type system, so we do not attempt // to make type inferences. Many of these operate on numeric // operands such as floating point or MMX/SSE registers. mmStrata // assumes that such registers are always numeric, so we do not // need annotations informing mmStrata that FP/MMX/SSE regs are numeric. // Category 2 instructions always have a result type of 'n' (number). // Category 3 instructions have a result type of 'n' (number) // whenever the second source operand is an operand of type 'n'. // NOTE: MOV is the only current example, and this will take some thought if // other examples arise. // Category 4 instructions have a result type identical to the 1st source operand type. // NOTE: This is currently set for single-operand instructions such as // INC, DEC. As a result, these are treated pretty much as if // they were category 1 instructions, as there is no metadata update, // even if the operand is a memory operand. // If new instructions are added to this category that are not single // operand and do require some updating, the category should be split. // Category 5 instructions have a result type identical to the 1st source operand // type whenever the 2nd source operand is an operand of type 'n' & vice versa. // Examples are add, sub, adc, and sbb. There are subtle exceptions // handled in the SMPInstr::EmitTypeAnnotations() method. // Category 6 instructions always have a result type of 'p' (pointer). // Category 7 instructions are category 2 instructions with two destinations, // such as multiply and divide instructions that affect EDX:EAX. There are // forms of these instructions that only have one destination, so they have // to be distinguished via the operand info. // Category 8 instructions implicitly write a numeric value to EDX:EAX, but // EDX and EAX are not listed as operands. RDTSC, RDPMC, RDMSR, and other // instructions that copy machine registers into EDX:EAX are category 8. // Some instructions in category 8 also write to ECX. // Category 9 instructions are floating point instructions that either // have a memory destination (treat as category 13) or a FP reg destination // (treat as category 1, as FP regs are always 'n' and ignored in our system). // Category 10 instructions have 'n' results if the sources are all 'n'; // we cannot infer the type of the result if the sources are of mixed types. // Bitwise OR and AND and LEA (load effective address) are examples. // Category 11 instructions need to have their types and locations on the stack // frame tracked, e.g. push and pop instructions. No direct type inference. // Category 12 instructions are similar to category 10, except that we do not // output 'n' annotations when all sources are 'n'; rather, the instruction can // be simply ignored (not instrumented by mmStrata) in that case. Conditional // exchange instructions are examples; we do or do not // move a numeric value into a register that already has numeric metadata. // Category 13 instructions imply that their memory destination is 'n'. // Category 14 instructions imply that their reg or memory source operand is 'n'; // if source is not memory, they are category 1 (inferences, but no instrumentation). // There should never be a memory destination (usual destination is fpreg or flags). // Category 15 instructions always have 'n' source AND destination operands; // if addressed using indirect or indexed addressing, they are a subset of category 0 // (must be instrumented by mmStrata to keep index in bounds). Memory destinations // are common in this category. // NOTE: The Memory Monitor SDT needs just three categories, corresponding // to categories 0, 1, and all others. For all categories > 1, the // annotation should tell the SDT exactly how to update its metadata. // For example, a division instruction will write type 'n' (NUM) as // the metadata for result registers EDX:EAX. So, the annotation should // list 'n', EDX, EAX, and a terminator of ZZ. CWD (convert word to // doubleword) should have a list of n EAX ZZ. SMPTypeCategory[NN_null] = 0; // Unknown Operation SMPTypeCategory[NN_aaa] = 2; // ASCII Adjust after Addition SMPTypeCategory[NN_aad] = 2; // ASCII Adjust AX before Division SMPTypeCategory[NN_aam] = 2; // ASCII Adjust AX after Multiply SMPTypeCategory[NN_aas] = 2; // ASCII Adjust AL after Subtraction SMPTypeCategory[NN_adc] = 5; // Add with Carry SMPTypeCategory[NN_add] = 5; // Add SMPTypeCategory[NN_and] = 10; // Logical AND SMPTypeCategory[NN_arpl] = 1; // Adjust RPL Field of Selector SMPTypeCategory[NN_bound] = 1; // Check Array Index Against Bounds SMPTypeCategory[NN_bsf] = 2; // Bit Scan Forward SMPTypeCategory[NN_bsr] = 2; // Bit Scan Reverse SMPTypeCategory[NN_bt] = 2; // Bit Test SMPTypeCategory[NN_btc] = 2; // Bit Test and Complement SMPTypeCategory[NN_btr] = 2; // Bit Test and Reset SMPTypeCategory[NN_bts] = 2; // Bit Test and Set SMPTypeCategory[NN_call] = 1; // Call Procedure SMPTypeCategory[NN_callfi] = 1; // Indirect Call Far Procedure SMPTypeCategory[NN_callni] = 1; // Indirect Call Near Procedure SMPTypeCategory[NN_cbw] = 2; // AL -> AX (with sign) ** No ops? SMPTypeCategory[NN_cwde] = 2; // AX -> EAX (with sign) ** SMPTypeCategory[NN_cdqe] = 2; // EAX -> RAX (with sign) ** SMPTypeCategory[NN_clc] = 1; // Clear Carry Flag SMPTypeCategory[NN_cld] = 1; // Clear Direction Flag SMPTypeCategory[NN_cli] = 1; // Clear Interrupt Flag SMPTypeCategory[NN_clts] = 1; // Clear Task-Switched Flag in CR0 SMPTypeCategory[NN_cmc] = 1; // Complement Carry Flag SMPTypeCategory[NN_cmp] = 1; // Compare Two Operands SMPTypeCategory[NN_cmps] = 14; // Compare Strings SMPTypeCategory[NN_cwd] = 2; // AX -> DX:AX (with sign) SMPTypeCategory[NN_cdq] = 2; // EAX -> EDX:EAX (with sign) SMPTypeCategory[NN_cqo] = 2; // RAX -> RDX:RAX (with sign) SMPTypeCategory[NN_daa] = 2; // Decimal Adjust AL after Addition SMPTypeCategory[NN_das] = 2; // Decimal Adjust AL after Subtraction SMPTypeCategory[NN_dec] = 4; // Decrement by 1 SMPTypeCategory[NN_div] = 7; // Unsigned Divide SMPTypeCategory[NN_enterw] = 0; // Make Stack Frame for Procedure Parameters ** SMPTypeCategory[NN_enter] = 0; // Make Stack Frame for Procedure Parameters ** SMPTypeCategory[NN_enterd] = 0; // Make Stack Frame for Procedure Parameters ** SMPTypeCategory[NN_enterq] = 0; // Make Stack Frame for Procedure Parameters ** SMPTypeCategory[NN_hlt] = 0; // Halt SMPTypeCategory[NN_idiv] = 7; // Signed Divide SMPTypeCategory[NN_imul] = 7; // Signed Multiply SMPTypeCategory[NN_in] = 0; // Input from Port ** SMPTypeCategory[NN_inc] = 4; // Increment by 1 SMPTypeCategory[NN_ins] = 2; // Input Byte(s) from Port to String ** SMPTypeCategory[NN_int] = 0; // Call to Interrupt Procedure SMPTypeCategory[NN_into] = 0; // Call to Interrupt Procedure if Overflow Flag = 1 SMPTypeCategory[NN_int3] = 0; // Trap to Debugger SMPTypeCategory[NN_iretw] = 0; // Interrupt Return SMPTypeCategory[NN_iret] = 0; // Interrupt Return SMPTypeCategory[NN_iretd] = 0; // Interrupt Return (use32) SMPTypeCategory[NN_iretq] = 0; // Interrupt Return (use64) SMPTypeCategory[NN_ja] = 1; // Jump if Above (CF=0 & ZF=0) SMPTypeCategory[NN_jae] = 1; // Jump if Above or Equal (CF=0) SMPTypeCategory[NN_jb] = 1; // Jump if Below (CF=1) SMPTypeCategory[NN_jbe] = 1; // Jump if Below or Equal (CF=1 | ZF=1) SMPTypeCategory[NN_jc] = 1; // Jump if Carry (CF=1) SMPTypeCategory[NN_jcxz] = 1; // Jump if CX is 0 SMPTypeCategory[NN_jecxz] = 1; // Jump if ECX is 0 SMPTypeCategory[NN_jrcxz] = 1; // Jump if RCX is 0 SMPTypeCategory[NN_je] = 1; // Jump if Equal (ZF=1) SMPTypeCategory[NN_jg] = 1; // Jump if Greater (ZF=0 & SF=OF) SMPTypeCategory[NN_jge] = 1; // Jump if Greater or Equal (SF=OF) SMPTypeCategory[NN_jl] = 1; // Jump if Less (SF!=OF) SMPTypeCategory[NN_jle] = 1; // Jump if Less or Equal (ZF=1 | SF!=OF) SMPTypeCategory[NN_jna] = 1; // Jump if Not Above (CF=1 | ZF=1) SMPTypeCategory[NN_jnae] = 1; // Jump if Not Above or Equal (CF=1) SMPTypeCategory[NN_jnb] = 1; // Jump if Not Below (CF=0) SMPTypeCategory[NN_jnbe] = 1; // Jump if Not Below or Equal (CF=0 & ZF=0) SMPTypeCategory[NN_jnc] = 1; // Jump if Not Carry (CF=0) SMPTypeCategory[NN_jne] = 1; // Jump if Not Equal (ZF=0) SMPTypeCategory[NN_jng] = 1; // Jump if Not Greater (ZF=1 | SF!=OF) SMPTypeCategory[NN_jnge] = 1; // Jump if Not Greater or Equal (ZF=1) SMPTypeCategory[NN_jnl] = 1; // Jump if Not Less (SF=OF) SMPTypeCategory[NN_jnle] = 1; // Jump if Not Less or Equal (ZF=0 & SF=OF) SMPTypeCategory[NN_jno] = 1; // Jump if Not Overflow (OF=0) SMPTypeCategory[NN_jnp] = 1; // Jump if Not Parity (PF=0) SMPTypeCategory[NN_jns] = 1; // Jump if Not Sign (SF=0) SMPTypeCategory[NN_jnz] = 1; // Jump if Not Zero (ZF=0) SMPTypeCategory[NN_jo] = 1; // Jump if Overflow (OF=1) SMPTypeCategory[NN_jp] = 1; // Jump if Parity (PF=1) SMPTypeCategory[NN_jpe] = 1; // Jump if Parity Even (PF=1) SMPTypeCategory[NN_jpo] = 1; // Jump if Parity Odd (PF=0) SMPTypeCategory[NN_js] = 1; // Jump if Sign (SF=1) SMPTypeCategory[NN_jz] = 1; // Jump if Zero (ZF=1) SMPTypeCategory[NN_jmp] = 1; // Jump SMPTypeCategory[NN_jmpfi] = 1; // Indirect Far Jump SMPTypeCategory[NN_jmpni] = 1; // Indirect Near Jump SMPTypeCategory[NN_jmpshort] = 1; // Jump Short (not used) SMPTypeCategory[NN_lahf] = 2; // Load Flags into AH Register SMPTypeCategory[NN_lar] = 2; // Load Access Rights Byte SMPTypeCategory[NN_lea] = 10; // Load Effective Address ** SMPTypeCategory[NN_leavew] = 0; // High Level Procedure Exit ** SMPTypeCategory[NN_leave] = 0; // High Level Procedure Exit ** SMPTypeCategory[NN_leaved] = 0; // High Level Procedure Exit ** SMPTypeCategory[NN_leaveq] = 0; // High Level Procedure Exit ** SMPTypeCategory[NN_lgdt] = 0; // Load Global Descriptor Table Register SMPTypeCategory[NN_lidt] = 0; // Load Interrupt Descriptor Table Register SMPTypeCategory[NN_lgs] = 6; // Load Full Pointer to GS:xx SMPTypeCategory[NN_lss] = 6; // Load Full Pointer to SS:xx SMPTypeCategory[NN_lds] = 6; // Load Full Pointer to DS:xx SMPTypeCategory[NN_les] = 6; // Load Full Pointer to ES:xx SMPTypeCategory[NN_lfs] = 6; // Load Full Pointer to FS:xx SMPTypeCategory[NN_lldt] = 0; // Load Local Descriptor Table Register SMPTypeCategory[NN_lmsw] = 1; // Load Machine Status Word SMPTypeCategory[NN_lock] = 1; // Assert LOCK# Signal Prefix SMPTypeCategory[NN_lods] = 0; // Load String SMPTypeCategory[NN_loopw] = 1; // Loop while ECX != 0 SMPTypeCategory[NN_loop] = 1; // Loop while CX != 0 SMPTypeCategory[NN_loopd] = 1; // Loop while ECX != 0 SMPTypeCategory[NN_loopq] = 1; // Loop while RCX != 0 SMPTypeCategory[NN_loopwe] = 1; // Loop while CX != 0 and ZF=1 SMPTypeCategory[NN_loope] = 1; // Loop while rCX != 0 and ZF=1 SMPTypeCategory[NN_loopde] = 1; // Loop while ECX != 0 and ZF=1 SMPTypeCategory[NN_loopqe] = 1; // Loop while RCX != 0 and ZF=1 SMPTypeCategory[NN_loopwne] = 1; // Loop while CX != 0 and ZF=0 SMPTypeCategory[NN_loopne] = 1; // Loop while rCX != 0 and ZF=0 SMPTypeCategory[NN_loopdne] = 1; // Loop while ECX != 0 and ZF=0 SMPTypeCategory[NN_loopqne] = 1; // Loop while RCX != 0 and ZF=0 SMPTypeCategory[NN_lsl] = 6; // Load Segment Limit SMPTypeCategory[NN_ltr] = 1; // Load Task Register SMPTypeCategory[NN_mov] = 3; // Move Data SMPTypeCategory[NN_movsp] = 3; // Move to/from Special Registers SMPTypeCategory[NN_movs] = 0; // Move Byte(s) from String to String SMPTypeCategory[NN_movsx] = 3; // Move with Sign-Extend SMPTypeCategory[NN_movzx] = 3; // Move with Zero-Extend SMPTypeCategory[NN_mul] = 7; // Unsigned Multiplication of AL or AX SMPTypeCategory[NN_neg] = 2; // Two's Complement Negation SMPTypeCategory[NN_nop] = 1; // No Operation SMPTypeCategory[NN_not] = 2; // One's Complement Negation SMPTypeCategory[NN_or] = 10; // Logical Inclusive OR SMPTypeCategory[NN_out] = 0; // Output to Port SMPTypeCategory[NN_outs] = 0; // Output Byte(s) to Port SMPTypeCategory[NN_pop] = 11; // Pop a word from the Stack SMPTypeCategory[NN_popaw] = 11; // Pop all General Registers SMPTypeCategory[NN_popa] = 11; // Pop all General Registers SMPTypeCategory[NN_popad] = 11; // Pop all General Registers (use32) SMPTypeCategory[NN_popaq] = 11; // Pop all General Registers (use64) SMPTypeCategory[NN_popfw] = 11; // Pop Stack into Flags Register ** SMPTypeCategory[NN_popf] = 11; // Pop Stack into Flags Register ** SMPTypeCategory[NN_popfd] = 11; // Pop Stack into Eflags Register ** SMPTypeCategory[NN_popfq] = 11; // Pop Stack into Rflags Register ** SMPTypeCategory[NN_push] = 11; // Push Operand onto the Stack SMPTypeCategory[NN_pushaw] = 11; // Push all General Registers SMPTypeCategory[NN_pusha] = 11; // Push all General Registers SMPTypeCategory[NN_pushad] = 11; // Push all General Registers (use32) SMPTypeCategory[NN_pushaq] = 11; // Push all General Registers (use64) SMPTypeCategory[NN_pushfw] = 11; // Push Flags Register onto the Stack SMPTypeCategory[NN_pushf] = 11; // Push Flags Register onto the Stack SMPTypeCategory[NN_pushfd] = 11; // Push Flags Register onto the Stack (use32) SMPTypeCategory[NN_pushfq] = 11; // Push Flags Register onto the Stack (use64) SMPTypeCategory[NN_rcl] = 2; // Rotate Through Carry Left SMPTypeCategory[NN_rcr] = 2; // Rotate Through Carry Right SMPTypeCategory[NN_rol] = 2; // Rotate Left SMPTypeCategory[NN_ror] = 2; // Rotate Right SMPTypeCategory[NN_rep] = 0; // Repeat String Operation SMPTypeCategory[NN_repe] = 0; // Repeat String Operation while ZF=1 SMPTypeCategory[NN_repne] = 0; // Repeat String Operation while ZF=0 SMPTypeCategory[NN_retn] = 0; // Return Near from Procedure SMPTypeCategory[NN_retf] = 0; // Return Far from Procedure SMPTypeCategory[NN_sahf] = 14; // Store AH into Flags Register SMPTypeCategory[NN_sal] = 2; // Shift Arithmetic Left SMPTypeCategory[NN_sar] = 2; // Shift Arithmetic Right SMPTypeCategory[NN_shl] = 2; // Shift Logical Left SMPTypeCategory[NN_shr] = 2; // Shift Logical Right SMPTypeCategory[NN_sbb] = 5; // Integer Subtraction with Borrow SMPTypeCategory[NN_scas] = 14; // Compare String SMPTypeCategory[NN_seta] = 2; // Set Byte if Above (CF=0 & ZF=0) SMPTypeCategory[NN_setae] = 2; // Set Byte if Above or Equal (CF=0) SMPTypeCategory[NN_setb] = 2; // Set Byte if Below (CF=1) SMPTypeCategory[NN_setbe] = 2; // Set Byte if Below or Equal (CF=1 | ZF=1) SMPTypeCategory[NN_setc] = 2; // Set Byte if Carry (CF=1) SMPTypeCategory[NN_sete] = 2; // Set Byte if Equal (ZF=1) SMPTypeCategory[NN_setg] = 2; // Set Byte if Greater (ZF=0 & SF=OF) SMPTypeCategory[NN_setge] = 2; // Set Byte if Greater or Equal (SF=OF) SMPTypeCategory[NN_setl] = 2; // Set Byte if Less (SF!=OF) SMPTypeCategory[NN_setle] = 2; // Set Byte if Less or Equal (ZF=1 | SF!=OF) SMPTypeCategory[NN_setna] = 2; // Set Byte if Not Above (CF=1 | ZF=1) SMPTypeCategory[NN_setnae] = 2; // Set Byte if Not Above or Equal (CF=1) SMPTypeCategory[NN_setnb] = 2; // Set Byte if Not Below (CF=0) SMPTypeCategory[NN_setnbe] = 2; // Set Byte if Not Below or Equal (CF=0 & ZF=0) SMPTypeCategory[NN_setnc] = 2; // Set Byte if Not Carry (CF=0) SMPTypeCategory[NN_setne] = 2; // Set Byte if Not Equal (ZF=0) SMPTypeCategory[NN_setng] = 2; // Set Byte if Not Greater (ZF=1 | SF!=OF) SMPTypeCategory[NN_setnge] = 2; // Set Byte if Not Greater or Equal (ZF=1) SMPTypeCategory[NN_setnl] = 2; // Set Byte if Not Less (SF=OF) SMPTypeCategory[NN_setnle] = 2; // Set Byte if Not Less or Equal (ZF=0 & SF=OF) SMPTypeCategory[NN_setno] = 2; // Set Byte if Not Overflow (OF=0) SMPTypeCategory[NN_setnp] = 2; // Set Byte if Not Parity (PF=0) SMPTypeCategory[NN_setns] = 2; // Set Byte if Not Sign (SF=0) SMPTypeCategory[NN_setnz] = 2; // Set Byte if Not Zero (ZF=0) SMPTypeCategory[NN_seto] = 2; // Set Byte if Overflow (OF=1) SMPTypeCategory[NN_setp] = 2; // Set Byte if Parity (PF=1) SMPTypeCategory[NN_setpe] = 2; // Set Byte if Parity Even (PF=1) SMPTypeCategory[NN_setpo] = 2; // Set Byte if Parity Odd (PF=0) SMPTypeCategory[NN_sets] = 2; // Set Byte if Sign (SF=1) SMPTypeCategory[NN_setz] = 2; // Set Byte if Zero (ZF=1) SMPTypeCategory[NN_sgdt] = 0; // Store Global Descriptor Table Register SMPTypeCategory[NN_sidt] = 0; // Store Interrupt Descriptor Table Register SMPTypeCategory[NN_shld] = 2; // Double Precision Shift Left SMPTypeCategory[NN_shrd] = 2; // Double Precision Shift Right SMPTypeCategory[NN_sldt] = 6; // Store Local Descriptor Table Register SMPTypeCategory[NN_smsw] = 2; // Store Machine Status Word SMPTypeCategory[NN_stc] = 1; // Set Carry Flag SMPTypeCategory[NN_std] = 1; // Set Direction Flag SMPTypeCategory[NN_sti] = 1; // Set Interrupt Flag SMPTypeCategory[NN_stos] = 0; // Store String SMPTypeCategory[NN_str] = 6; // Store Task Register SMPTypeCategory[NN_sub] = 5; // Integer Subtraction SMPTypeCategory[NN_test] = 1; // Logical Compare SMPTypeCategory[NN_verr] = 1; // Verify a Segment for Reading SMPTypeCategory[NN_verw] = 1; // Verify a Segment for Writing SMPTypeCategory[NN_wait] = 1; // Wait until BUSY# Pin is Inactive (HIGH) SMPTypeCategory[NN_xchg] = 12; // Exchange Register/Memory with Register SMPTypeCategory[NN_xlat] = 0; // Table Lookup Translation SMPTypeCategory[NN_xor] = 2; // Logical Exclusive OR // // 486 instructions // SMPTypeCategory[NN_cmpxchg] = 12; // Compare and Exchange SMPTypeCategory[NN_bswap] = 1; // Swap bytes in register SMPTypeCategory[NN_xadd] = 12; // t<-dest; dest<-src+dest; src<-t SMPTypeCategory[NN_invd] = 1; // Invalidate Data Cache SMPTypeCategory[NN_wbinvd] = 1; // Invalidate Data Cache (write changes) SMPTypeCategory[NN_invlpg] = 1; // Invalidate TLB entry // // Pentium instructions // SMPTypeCategory[NN_rdmsr] = 8; // Read Machine Status Register SMPTypeCategory[NN_wrmsr] = 1; // Write Machine Status Register SMPTypeCategory[NN_cpuid] = 8; // Get CPU ID SMPTypeCategory[NN_cmpxchg8b] = 12; // Compare and Exchange Eight Bytes SMPTypeCategory[NN_rdtsc] = 8; // Read Time Stamp Counter SMPTypeCategory[NN_rsm] = 1; // Resume from System Management Mode // // Pentium Pro instructions // SMPTypeCategory[NN_cmova] = 0; // Move if Above (CF=0 & ZF=0) SMPTypeCategory[NN_cmovb] = 0; // Move if Below (CF=1) SMPTypeCategory[NN_cmovbe] = 0; // Move if Below or Equal (CF=1 | ZF=1) SMPTypeCategory[NN_cmovg] = 0; // Move if Greater (ZF=0 & SF=OF) SMPTypeCategory[NN_cmovge] = 0; // Move if Greater or Equal (SF=OF) SMPTypeCategory[NN_cmovl] = 0; // Move if Less (SF!=OF) SMPTypeCategory[NN_cmovle] = 0; // Move if Less or Equal (ZF=1 | SF!=OF) SMPTypeCategory[NN_cmovnb] = 0; // Move if Not Below (CF=0) SMPTypeCategory[NN_cmovno] = 0; // Move if Not Overflow (OF=0) SMPTypeCategory[NN_cmovnp] = 0; // Move if Not Parity (PF=0) SMPTypeCategory[NN_cmovns] = 0; // Move if Not Sign (SF=0) SMPTypeCategory[NN_cmovnz] = 0; // Move if Not Zero (ZF=0) SMPTypeCategory[NN_cmovo] = 0; // Move if Overflow (OF=1) SMPTypeCategory[NN_cmovp] = 0; // Move if Parity (PF=1) SMPTypeCategory[NN_cmovs] = 0; // Move if Sign (SF=1) SMPTypeCategory[NN_cmovz] = 0; // Move if Zero (ZF=1) SMPTypeCategory[NN_fcmovb] = 1; // Floating Move if Below SMPTypeCategory[NN_fcmove] = 1; // Floating Move if Equal SMPTypeCategory[NN_fcmovbe] = 1; // Floating Move if Below or Equal SMPTypeCategory[NN_fcmovu] = 1; // Floating Move if Unordered SMPTypeCategory[NN_fcmovnb] = 1; // Floating Move if Not Below SMPTypeCategory[NN_fcmovne] = 1; // Floating Move if Not Equal SMPTypeCategory[NN_fcmovnbe] = 1; // Floating Move if Not Below or Equal SMPTypeCategory[NN_fcmovnu] = 1; // Floating Move if Not Unordered SMPTypeCategory[NN_fcomi] = 1; // FP Compare, result in EFLAGS SMPTypeCategory[NN_fucomi] = 1; // FP Unordered Compare, result in EFLAGS SMPTypeCategory[NN_fcomip] = 1; // FP Compare, result in EFLAGS, pop stack SMPTypeCategory[NN_fucomip] = 1; // FP Unordered Compare, result in EFLAGS, pop stack SMPTypeCategory[NN_rdpmc] = 8; // Read Performance Monitor Counter // // FPP instructions // SMPTypeCategory[NN_fld] = 14; // Load Real ** Infer src is 'n' SMPTypeCategory[NN_fst] = 9; // Store Real SMPTypeCategory[NN_fstp] = 9; // Store Real and Pop SMPTypeCategory[NN_fxch] = 1; // Exchange Registers SMPTypeCategory[NN_fild] = 14; // Load Integer ** Infer src is 'n' SMPTypeCategory[NN_fist] = 13; // Store Integer SMPTypeCategory[NN_fistp] = 13; // Store Integer and Pop SMPTypeCategory[NN_fbld] = 1; // Load BCD SMPTypeCategory[NN_fbstp] = 13; // Store BCD and Pop SMPTypeCategory[NN_fadd] = 14; // Add Real SMPTypeCategory[NN_faddp] = 14; // Add Real and Pop SMPTypeCategory[NN_fiadd] = 14; // Add Integer SMPTypeCategory[NN_fsub] = 14; // Subtract Real SMPTypeCategory[NN_fsubp] = 14; // Subtract Real and Pop SMPTypeCategory[NN_fisub] = 14; // Subtract Integer SMPTypeCategory[NN_fsubr] = 14; // Subtract Real Reversed SMPTypeCategory[NN_fsubrp] = 14; // Subtract Real Reversed and Pop SMPTypeCategory[NN_fisubr] = 14; // Subtract Integer Reversed SMPTypeCategory[NN_fmul] = 14; // Multiply Real SMPTypeCategory[NN_fmulp] = 14; // Multiply Real and Pop SMPTypeCategory[NN_fimul] = 14; // Multiply Integer SMPTypeCategory[NN_fdiv] = 14; // Divide Real SMPTypeCategory[NN_fdivp] = 14; // Divide Real and Pop SMPTypeCategory[NN_fidiv] = 14; // Divide Integer SMPTypeCategory[NN_fdivr] = 14; // Divide Real Reversed SMPTypeCategory[NN_fdivrp] = 14; // Divide Real Reversed and Pop SMPTypeCategory[NN_fidivr] = 14; // Divide Integer Reversed SMPTypeCategory[NN_fsqrt] = 1; // Square Root SMPTypeCategory[NN_fscale] = 1; // Scale: st(0) <- st(0) * 2^st(1) SMPTypeCategory[NN_fprem] = 1; // Partial Remainder SMPTypeCategory[NN_frndint] = 1; // Round to Integer SMPTypeCategory[NN_fxtract] = 1; // Extract exponent and significand SMPTypeCategory[NN_fabs] = 1; // Absolute value SMPTypeCategory[NN_fchs] = 1; // Change Sign SMPTypeCategory[NN_fcom] = 1; // Compare Real SMPTypeCategory[NN_fcomp] = 1; // Compare Real and Pop SMPTypeCategory[NN_fcompp] = 1; // Compare Real and Pop Twice SMPTypeCategory[NN_ficom] = 1; // Compare Integer SMPTypeCategory[NN_ficomp] = 1; // Compare Integer and Pop SMPTypeCategory[NN_ftst] = 1; // Test SMPTypeCategory[NN_fxam] = 1; // Examine SMPTypeCategory[NN_fptan] = 1; // Partial tangent SMPTypeCategory[NN_fpatan] = 1; // Partial arctangent SMPTypeCategory[NN_f2xm1] = 1; // 2^x - 1 SMPTypeCategory[NN_fyl2x] = 1; // Y * lg2(X) SMPTypeCategory[NN_fyl2xp1] = 1; // Y * lg2(X+1) SMPTypeCategory[NN_fldz] = 1; // Load +0.0 SMPTypeCategory[NN_fld1] = 1; // Load +1.0 SMPTypeCategory[NN_fldpi] = 1; // Load PI=3.14... SMPTypeCategory[NN_fldl2t] = 1; // Load lg2(10) SMPTypeCategory[NN_fldl2e] = 1; // Load lg2(e) SMPTypeCategory[NN_fldlg2] = 1; // Load lg10(2) SMPTypeCategory[NN_fldln2] = 1; // Load ln(2) SMPTypeCategory[NN_finit] = 1; // Initialize Processor SMPTypeCategory[NN_fninit] = 1; // Initialize Processor (no wait) SMPTypeCategory[NN_fsetpm] = 1; // Set Protected Mode SMPTypeCategory[NN_fldcw] = 14; // Load Control Word SMPTypeCategory[NN_fstcw] = 13; // Store Control Word SMPTypeCategory[NN_fnstcw] = 13; // Store Control Word (no wait) SMPTypeCategory[NN_fstsw] = 2; // Store Status Word to memory or AX SMPTypeCategory[NN_fnstsw] = 2; // Store Status Word (no wait) to memory or AX SMPTypeCategory[NN_fclex] = 1; // Clear Exceptions SMPTypeCategory[NN_fnclex] = 1; // Clear Exceptions (no wait) SMPTypeCategory[NN_fstenv] = 13; // Store Environment SMPTypeCategory[NN_fnstenv] = 13; // Store Environment (no wait) SMPTypeCategory[NN_fldenv] = 14; // Load Environment SMPTypeCategory[NN_fsave] = 13; // Save State SMPTypeCategory[NN_fnsave] = 13; // Save State (no wait) SMPTypeCategory[NN_frstor] = 14; // Restore State ** infer src is 'n' SMPTypeCategory[NN_fincstp] = 1; // Increment Stack Pointer SMPTypeCategory[NN_fdecstp] = 1; // Decrement Stack Pointer SMPTypeCategory[NN_ffree] = 1; // Free Register SMPTypeCategory[NN_fnop] = 1; // No Operation SMPTypeCategory[NN_feni] = 1; // (8087 only) SMPTypeCategory[NN_fneni] = 1; // (no wait) (8087 only) SMPTypeCategory[NN_fdisi] = 1; // (8087 only) SMPTypeCategory[NN_fndisi] = 1; // (no wait) (8087 only) // // 80387 instructions // SMPTypeCategory[NN_fprem1] = 1; // Partial Remainder ( < half ) SMPTypeCategory[NN_fsincos] = 1; // t<-cos(st); st<-sin(st); push t SMPTypeCategory[NN_fsin] = 1; // Sine SMPTypeCategory[NN_fcos] = 1; // Cosine SMPTypeCategory[NN_fucom] = 1; // Compare Unordered Real SMPTypeCategory[NN_fucomp] = 1; // Compare Unordered Real and Pop SMPTypeCategory[NN_fucompp] = 1; // Compare Unordered Real and Pop Twice // // Instructions added 28.02.96 // SMPTypeCategory[NN_setalc] = 2; // Set AL to Carry Flag ** SMPTypeCategory[NN_svdc] = 0; // Save Register and Descriptor SMPTypeCategory[NN_rsdc] = 0; // Restore Register and Descriptor SMPTypeCategory[NN_svldt] = 0; // Save LDTR and Descriptor SMPTypeCategory[NN_rsldt] = 0; // Restore LDTR and Descriptor SMPTypeCategory[NN_svts] = 1; // Save TR and Descriptor SMPTypeCategory[NN_rsts] = 1; // Restore TR and Descriptor SMPTypeCategory[NN_icebp] = 1; // ICE Break Point SMPTypeCategory[NN_loadall] = 0; // Load the entire CPU state from ES:EDI ??? // // MMX instructions // SMPTypeCategory[NN_emms] = 1; // Empty MMX state SMPTypeCategory[NN_movd] = 15; // Move 32 bits SMPTypeCategory[NN_movq] = 15; // Move 64 bits SMPTypeCategory[NN_packsswb] = 14; // Pack with Signed Saturation (Word->Byte) SMPTypeCategory[NN_packssdw] = 14; // Pack with Signed Saturation (Dword->Word) SMPTypeCategory[NN_packuswb] = 14; // Pack with Unsigned Saturation (Word->Byte) SMPTypeCategory[NN_paddb] = 14; // Packed Add Byte SMPTypeCategory[NN_paddw] = 14; // Packed Add Word SMPTypeCategory[NN_paddd] = 14; // Packed Add Dword SMPTypeCategory[NN_paddsb] = 14; // Packed Add with Saturation (Byte) SMPTypeCategory[NN_paddsw] = 14; // Packed Add with Saturation (Word) SMPTypeCategory[NN_paddusb] = 14; // Packed Add Unsigned with Saturation (Byte) SMPTypeCategory[NN_paddusw] = 14; // Packed Add Unsigned with Saturation (Word) SMPTypeCategory[NN_pand] = 14; // Bitwise Logical And SMPTypeCategory[NN_pandn] = 14; // Bitwise Logical And Not SMPTypeCategory[NN_pcmpeqb] = 14; // Packed Compare for Equal (Byte) SMPTypeCategory[NN_pcmpeqw] = 14; // Packed Compare for Equal (Word) SMPTypeCategory[NN_pcmpeqd] = 14; // Packed Compare for Equal (Dword) SMPTypeCategory[NN_pcmpgtb] = 14; // Packed Compare for Greater Than (Byte) SMPTypeCategory[NN_pcmpgtw] = 14; // Packed Compare for Greater Than (Word) SMPTypeCategory[NN_pcmpgtd] = 14; // Packed Compare for Greater Than (Dword) SMPTypeCategory[NN_pmaddwd] = 14; // Packed Multiply and Add SMPTypeCategory[NN_pmulhw] = 14; // Packed Multiply High SMPTypeCategory[NN_pmullw] = 14; // Packed Multiply Low SMPTypeCategory[NN_por] = 14; // Bitwise Logical Or SMPTypeCategory[NN_psllw] = 14; // Packed Shift Left Logical (Word) SMPTypeCategory[NN_pslld] = 14; // Packed Shift Left Logical (Dword) SMPTypeCategory[NN_psllq] = 14; // Packed Shift Left Logical (Qword) SMPTypeCategory[NN_psraw] = 14; // Packed Shift Right Arithmetic (Word) SMPTypeCategory[NN_psrad] = 14; // Packed Shift Right Arithmetic (Dword) SMPTypeCategory[NN_psrlw] = 14; // Packed Shift Right Logical (Word) SMPTypeCategory[NN_psrld] = 14; // Packed Shift Right Logical (Dword) SMPTypeCategory[NN_psrlq] = 14; // Packed Shift Right Logical (Qword) SMPTypeCategory[NN_psubb] = 14; // Packed Subtract Byte SMPTypeCategory[NN_psubw] = 14; // Packed Subtract Word SMPTypeCategory[NN_psubd] = 14; // Packed Subtract Dword SMPTypeCategory[NN_psubsb] = 14; // Packed Subtract with Saturation (Byte) SMPTypeCategory[NN_psubsw] = 14; // Packed Subtract with Saturation (Word) SMPTypeCategory[NN_psubusb] = 14; // Packed Subtract Unsigned with Saturation (Byte) SMPTypeCategory[NN_psubusw] = 14; // Packed Subtract Unsigned with Saturation (Word) SMPTypeCategory[NN_punpckhbw] = 14; // Unpack High Packed Data (Byte->Word) SMPTypeCategory[NN_punpckhwd] = 14; // Unpack High Packed Data (Word->Dword) SMPTypeCategory[NN_punpckhdq] = 14; // Unpack High Packed Data (Dword->Qword) SMPTypeCategory[NN_punpcklbw] = 14; // Unpack Low Packed Data (Byte->Word) SMPTypeCategory[NN_punpcklwd] = 14; // Unpack Low Packed Data (Word->Dword) SMPTypeCategory[NN_punpckldq] = 14; // Unpack Low Packed Data (Dword->Qword) SMPTypeCategory[NN_pxor] = 14; // Bitwise Logical Exclusive Or // // Undocumented Deschutes processor instructions // SMPTypeCategory[NN_fxsave] = 1; // Fast save FP context ** to where? SMPTypeCategory[NN_fxrstor] = 1; // Fast restore FP context ** from where? // Pentium II instructions SMPTypeCategory[NN_sysenter] = 1; // Fast Transition to System Call Entry Point SMPTypeCategory[NN_sysexit] = 1; // Fast Transition from System Call Entry Point // 3DNow! instructions SMPTypeCategory[NN_pavgusb] = 14; // Packed 8-bit Unsigned Integer Averaging SMPTypeCategory[NN_pfadd] = 14; // Packed Floating-Point Addition SMPTypeCategory[NN_pfsub] = 14; // Packed Floating-Point Subtraction SMPTypeCategory[NN_pfsubr] = 14; // Packed Floating-Point Reverse Subtraction SMPTypeCategory[NN_pfacc] = 14; // Packed Floating-Point Accumulate SMPTypeCategory[NN_pfcmpge] = 14; // Packed Floating-Point Comparison, Greater or Equal SMPTypeCategory[NN_pfcmpgt] = 14; // Packed Floating-Point Comparison, Greater SMPTypeCategory[NN_pfcmpeq] = 14; // Packed Floating-Point Comparison, Equal SMPTypeCategory[NN_pfmin] = 14; // Packed Floating-Point Minimum SMPTypeCategory[NN_pfmax] = 14; // Packed Floating-Point Maximum SMPTypeCategory[NN_pi2fd] = 14; // Packed 32-bit Integer to Floating-Point SMPTypeCategory[NN_pf2id] = 14; // Packed Floating-Point to 32-bit Integer SMPTypeCategory[NN_pfrcp] = 14; // Packed Floating-Point Reciprocal Approximation SMPTypeCategory[NN_pfrsqrt] = 14; // Packed Floating-Point Reciprocal Square Root Approximation SMPTypeCategory[NN_pfmul] = 14; // Packed Floating-Point Multiplication SMPTypeCategory[NN_pfrcpit1] = 14; // Packed Floating-Point Reciprocal First Iteration Step SMPTypeCategory[NN_pfrsqit1] = 14; // Packed Floating-Point Reciprocal Square Root First Iteration Step SMPTypeCategory[NN_pfrcpit2] = 14; // Packed Floating-Point Reciprocal Second Iteration Step SMPTypeCategory[NN_pmulhrw] = 14; // Packed Floating-Point 16-bit Integer Multiply with rounding SMPTypeCategory[NN_femms] = 1; // Faster entry/exit of the MMX or floating-point state SMPTypeCategory[NN_prefetch] = 1; // Prefetch at least a 32-byte line into L1 data cache SMPTypeCategory[NN_prefetchw] = 1; // Prefetch processor cache line into L1 data cache (mark as modified) // Pentium III instructions SMPTypeCategory[NN_addps] = 14; // Packed Single-FP Add SMPTypeCategory[NN_addss] = 14; // Scalar Single-FP Add SMPTypeCategory[NN_andnps] = 14; // Bitwise Logical And Not for Single-FP SMPTypeCategory[NN_andps] = 14; // Bitwise Logical And for Single-FP SMPTypeCategory[NN_cmpps] = 14; // Packed Single-FP Compare SMPTypeCategory[NN_cmpss] = 14; // Scalar Single-FP Compare SMPTypeCategory[NN_comiss] = 14; // Scalar Ordered Single-FP Compare and Set EFLAGS SMPTypeCategory[NN_cvtpi2ps] = 14; // Packed signed INT32 to Packed Single-FP conversion SMPTypeCategory[NN_cvtps2pi] = 14; // Packed Single-FP to Packed INT32 conversion SMPTypeCategory[NN_cvtsi2ss] = 14; // Scalar signed INT32 to Single-FP conversion SMPTypeCategory[NN_cvtss2si] = 14; // Scalar Single-FP to signed INT32 conversion SMPTypeCategory[NN_cvttps2pi] = 14; // Packed Single-FP to Packed INT32 conversion (truncate) SMPTypeCategory[NN_cvttss2si] = 14; // Scalar Single-FP to signed INT32 conversion (truncate) SMPTypeCategory[NN_divps] = 14; // Packed Single-FP Divide SMPTypeCategory[NN_divss] = 14; // Scalar Single-FP Divide SMPTypeCategory[NN_ldmxcsr] = 14; // Load Streaming SIMD Extensions Technology Control/Status Register SMPTypeCategory[NN_maxps] = 14; // Packed Single-FP Maximum SMPTypeCategory[NN_maxss] = 14; // Scalar Single-FP Maximum SMPTypeCategory[NN_minps] = 14; // Packed Single-FP Minimum SMPTypeCategory[NN_minss] = 14; // Scalar Single-FP Minimum SMPTypeCategory[NN_movaps] = 15; // Move Aligned Four Packed Single-FP ** infer memsrc 'n'? SMPTypeCategory[NN_movhlps] = 15; // Move High to Low Packed Single-FP SMPTypeCategory[NN_movhps] = 15; // Move High Packed Single-FP SMPTypeCategory[NN_movlhps] = 15; // Move Low to High Packed Single-FP SMPTypeCategory[NN_movlps] = 15; // Move Low Packed Single-FP SMPTypeCategory[NN_movmskps] = 15; // Move Mask to Register SMPTypeCategory[NN_movss] = 15; // Move Scalar Single-FP SMPTypeCategory[NN_movups] = 15; // Move Unaligned Four Packed Single-FP SMPTypeCategory[NN_mulps] = 14; // Packed Single-FP Multiply SMPTypeCategory[NN_mulss] = 14; // Scalar Single-FP Multiply SMPTypeCategory[NN_orps] = 14; // Bitwise Logical OR for Single-FP Data SMPTypeCategory[NN_rcpps] = 14; // Packed Single-FP Reciprocal SMPTypeCategory[NN_rcpss] = 14; // Scalar Single-FP Reciprocal SMPTypeCategory[NN_rsqrtps] = 14; // Packed Single-FP Square Root Reciprocal SMPTypeCategory[NN_rsqrtss] = 14; // Scalar Single-FP Square Root Reciprocal SMPTypeCategory[NN_shufps] = 14; // Shuffle Single-FP SMPTypeCategory[NN_sqrtps] = 14; // Packed Single-FP Square Root SMPTypeCategory[NN_sqrtss] = 14; // Scalar Single-FP Square Root SMPTypeCategory[NN_stmxcsr] = 15; // Store Streaming SIMD Extensions Technology Control/Status Register ** Infer dest is 'n' SMPTypeCategory[NN_subps] = 14; // Packed Single-FP Subtract SMPTypeCategory[NN_subss] = 14; // Scalar Single-FP Subtract SMPTypeCategory[NN_ucomiss] = 14; // Scalar Unordered Single-FP Compare and Set EFLAGS SMPTypeCategory[NN_unpckhps] = 14; // Unpack High Packed Single-FP Data SMPTypeCategory[NN_unpcklps] = 14; // Unpack Low Packed Single-FP Data SMPTypeCategory[NN_xorps] = 14; // Bitwise Logical XOR for Single-FP Data SMPTypeCategory[NN_pavgb] = 14; // Packed Average (Byte) SMPTypeCategory[NN_pavgw] = 14; // Packed Average (Word) SMPTypeCategory[NN_pextrw] = 2; // Extract Word SMPTypeCategory[NN_pinsrw] = 14; // Insert Word SMPTypeCategory[NN_pmaxsw] = 14; // Packed Signed Integer Word Maximum SMPTypeCategory[NN_pmaxub] = 14; // Packed Unsigned Integer Byte Maximum SMPTypeCategory[NN_pminsw] = 14; // Packed Signed Integer Word Minimum SMPTypeCategory[NN_pminub] = 14; // Packed Unsigned Integer Byte Minimum SMPTypeCategory[NN_pmovmskb] = 2; // Move Byte Mask to Integer SMPTypeCategory[NN_pmulhuw] = 14; // Packed Multiply High Unsigned SMPTypeCategory[NN_psadbw] = 14; // Packed Sum of Absolute Differences SMPTypeCategory[NN_pshufw] = 14; // Packed Shuffle Word SMPTypeCategory[NN_maskmovq] = 15; // Byte Mask write ** Infer dest is 'n' SMPTypeCategory[NN_movntps] = 13; // Move Aligned Four Packed Single-FP Non Temporal * infer dest is 'n' SMPTypeCategory[NN_movntq] = 13; // Move 64 Bits Non Temporal ** Infer dest is 'n' SMPTypeCategory[NN_prefetcht0] = 1; // Prefetch to all cache levels SMPTypeCategory[NN_prefetcht1] = 1; // Prefetch to all cache levels SMPTypeCategory[NN_prefetcht2] = 1; // Prefetch to L2 cache SMPTypeCategory[NN_prefetchnta] = 1; // Prefetch to L1 cache SMPTypeCategory[NN_sfence] = 1; // Store Fence // Pentium III Pseudo instructions SMPTypeCategory[NN_cmpeqps] = 14; // Packed Single-FP Compare EQ SMPTypeCategory[NN_cmpltps] = 14; // Packed Single-FP Compare LT SMPTypeCategory[NN_cmpleps] = 14; // Packed Single-FP Compare LE SMPTypeCategory[NN_cmpunordps] = 14; // Packed Single-FP Compare UNORD SMPTypeCategory[NN_cmpneqps] = 14; // Packed Single-FP Compare NOT EQ SMPTypeCategory[NN_cmpnltps] = 14; // Packed Single-FP Compare NOT LT SMPTypeCategory[NN_cmpnleps] = 14; // Packed Single-FP Compare NOT LE SMPTypeCategory[NN_cmpordps] = 14; // Packed Single-FP Compare ORDERED SMPTypeCategory[NN_cmpeqss] = 14; // Scalar Single-FP Compare EQ SMPTypeCategory[NN_cmpltss] = 14; // Scalar Single-FP Compare LT SMPTypeCategory[NN_cmpless] = 14; // Scalar Single-FP Compare LE SMPTypeCategory[NN_cmpunordss] = 14; // Scalar Single-FP Compare UNORD SMPTypeCategory[NN_cmpneqss] = 14; // Scalar Single-FP Compare NOT EQ SMPTypeCategory[NN_cmpnltss] = 14; // Scalar Single-FP Compare NOT LT SMPTypeCategory[NN_cmpnless] = 14; // Scalar Single-FP Compare NOT LE SMPTypeCategory[NN_cmpordss] = 14; // Scalar Single-FP Compare ORDERED // AMD K7 instructions // Revisit AMD if we port to it. SMPTypeCategory[NN_pf2iw] = 15; // Packed Floating-Point to Integer with Sign Extend SMPTypeCategory[NN_pfnacc] = 15; // Packed Floating-Point Negative Accumulate SMPTypeCategory[NN_pfpnacc] = 15; // Packed Floating-Point Mixed Positive-Negative Accumulate SMPTypeCategory[NN_pi2fw] = 15; // Packed 16-bit Integer to Floating-Point SMPTypeCategory[NN_pswapd] = 15; // Packed Swap Double Word // Undocumented FP instructions (thanks to norbert.juffa@adm.com) SMPTypeCategory[NN_fstp1] = 9; // Alias of Store Real and Pop SMPTypeCategory[NN_fcom2] = 1; // Alias of Compare Real SMPTypeCategory[NN_fcomp3] = 1; // Alias of Compare Real and Pop SMPTypeCategory[NN_fxch4] = 1; // Alias of Exchange Registers SMPTypeCategory[NN_fcomp5] = 1; // Alias of Compare Real and Pop SMPTypeCategory[NN_ffreep] = 1; // Free Register and Pop SMPTypeCategory[NN_fxch7] = 1; // Alias of Exchange Registers SMPTypeCategory[NN_fstp8] = 9; // Alias of Store Real and Pop SMPTypeCategory[NN_fstp9] = 9; // Alias of Store Real and Pop // Pentium 4 instructions SMPTypeCategory[NN_addpd] = 14; // Add Packed Double-Precision Floating-Point Values SMPTypeCategory[NN_addsd] = 14; // Add Scalar Double-Precision Floating-Point Values SMPTypeCategory[NN_andnpd] = 14; // Bitwise Logical AND NOT of Packed Double-Precision Floating-Point Values SMPTypeCategory[NN_andpd] = 14; // Bitwise Logical AND of Packed Double-Precision Floating-Point Values SMPTypeCategory[NN_clflush] = 1; // Flush Cache Line SMPTypeCategory[NN_cmppd] = 14; // Compare Packed Double-Precision Floating-Point Values SMPTypeCategory[NN_cmpsd] = 14; // Compare Scalar Double-Precision Floating-Point Values SMPTypeCategory[NN_comisd] = 14; // Compare Scalar Ordered Double-Precision Floating-Point Values and Set EFLAGS SMPTypeCategory[NN_cvtdq2pd] = 14; // Convert Packed Doubleword Integers to Packed Single-Precision Floating-Point Values SMPTypeCategory[NN_cvtdq2ps] = 14; // Convert Packed Doubleword Integers to Packed Double-Precision Floating-Point Values SMPTypeCategory[NN_cvtpd2dq] = 14; // Convert Packed Double-Precision Floating-Point Values to Packed Doubleword Integers SMPTypeCategory[NN_cvtpd2pi] = 14; // Convert Packed Double-Precision Floating-Point Values to Packed Doubleword Integers SMPTypeCategory[NN_cvtpd2ps] = 14; // Convert Packed Double-Precision Floating-Point Values to Packed Single-Precision Floating-Point Values SMPTypeCategory[NN_cvtpi2pd] = 14; // Convert Packed Doubleword Integers to Packed Double-Precision Floating-Point Values SMPTypeCategory[NN_cvtps2dq] = 14; // Convert Packed Single-Precision Floating-Point Values to Packed Doubleword Integers SMPTypeCategory[NN_cvtps2pd] = 14; // Convert Packed Single-Precision Floating-Point Values to Packed Double-Precision Floating-Point Values SMPTypeCategory[NN_cvtsd2si] = 14; // Convert Scalar Double-Precision Floating-Point Value to Doubleword Integer SMPTypeCategory[NN_cvtsd2ss] = 14; // Convert Scalar Double-Precision Floating-Point Value to Scalar Single-Precision Floating-Point Value SMPTypeCategory[NN_cvtsi2sd] = 14; // Convert Doubleword Integer to Scalar Double-Precision Floating-Point Value SMPTypeCategory[NN_cvtss2sd] = 14; // Convert Scalar Single-Precision Floating-Point Value to Scalar Double-Precision Floating-Point Value SMPTypeCategory[NN_cvttpd2dq] = 14; // Convert With Truncation Packed Double-Precision Floating-Point Values to Packed Doubleword Integers SMPTypeCategory[NN_cvttpd2pi] = 14; // Convert with Truncation Packed Double-Precision Floating-Point Values to Packed Doubleword Integers SMPTypeCategory[NN_cvttps2dq] = 14; // Convert With Truncation Packed Single-Precision Floating-Point Values to Packed Doubleword Integers SMPTypeCategory[NN_cvttsd2si] = 14; // Convert with Truncation Scalar Double-Precision Floating-Point Value to Doubleword Integer SMPTypeCategory[NN_divpd] = 14; // Divide Packed Double-Precision Floating-Point Values SMPTypeCategory[NN_divsd] = 14; // Divide Scalar Double-Precision Floating-Point Values SMPTypeCategory[NN_lfence] = 1; // Load Fence SMPTypeCategory[NN_maskmovdqu] = 13; // Store Selected Bytes of Double Quadword ** Infer dest is 'n' SMPTypeCategory[NN_maxpd] = 14; // Return Maximum Packed Double-Precision Floating-Point Values SMPTypeCategory[NN_maxsd] = 14; // Return Maximum Scalar Double-Precision Floating-Point Value SMPTypeCategory[NN_mfence] = 1; // Memory Fence SMPTypeCategory[NN_minpd] = 14; // Return Minimum Packed Double-Precision Floating-Point Values SMPTypeCategory[NN_minsd] = 14; // Return Minimum Scalar Double-Precision Floating-Point Value SMPTypeCategory[NN_movapd] = 15; // Move Aligned Packed Double-Precision Floating-Point Values ** Infer dest is 'n' SMPTypeCategory[NN_movdq2q] = 15; // Move Quadword from XMM to MMX Register SMPTypeCategory[NN_movdqa] = 15; // Move Aligned Double Quadword ** Infer dest is 'n' SMPTypeCategory[NN_movdqu] = 15; // Move Unaligned Double Quadword ** Infer dest is 'n' SMPTypeCategory[NN_movhpd] = 15; // Move High Packed Double-Precision Floating-Point Values ** Infer dest is 'n' SMPTypeCategory[NN_movlpd] = 15; // Move Low Packed Double-Precision Floating-Point Values ** Infer dest is 'n' SMPTypeCategory[NN_movmskpd] = 15; // Extract Packed Double-Precision Floating-Point Sign Mask SMPTypeCategory[NN_movntdq] = 13; // Store Double Quadword Using Non-Temporal Hint SMPTypeCategory[NN_movnti] = 13; // Store Doubleword Using Non-Temporal Hint SMPTypeCategory[NN_movntpd] = 13; // Store Packed Double-Precision Floating-Point Values Using Non-Temporal Hint SMPTypeCategory[NN_movq2dq] = 1; // Move Quadword from MMX to XMM Register SMPTypeCategory[NN_movsd] = 15; // Move Scalar Double-Precision Floating-Point Values SMPTypeCategory[NN_movupd] = 15; // Move Unaligned Packed Double-Precision Floating-Point Values SMPTypeCategory[NN_mulpd] = 14; // Multiply Packed Double-Precision Floating-Point Values SMPTypeCategory[NN_mulsd] = 14; // Multiply Scalar Double-Precision Floating-Point Values SMPTypeCategory[NN_orpd] = 14; // Bitwise Logical OR of Double-Precision Floating-Point Values SMPTypeCategory[NN_paddq] = 14; // Add Packed Quadword Integers SMPTypeCategory[NN_pause] = 1; // Spin Loop Hint SMPTypeCategory[NN_pmuludq] = 14; // Multiply Packed Unsigned Doubleword Integers SMPTypeCategory[NN_pshufd] = 14; // Shuffle Packed Doublewords SMPTypeCategory[NN_pshufhw] = 14; // Shuffle Packed High Words SMPTypeCategory[NN_pshuflw] = 14; // Shuffle Packed Low Words SMPTypeCategory[NN_pslldq] = 14; // Shift Double Quadword Left Logical SMPTypeCategory[NN_psrldq] = 14; // Shift Double Quadword Right Logical SMPTypeCategory[NN_psubq] = 14; // Subtract Packed Quadword Integers SMPTypeCategory[NN_punpckhqdq] = 14; // Unpack High Data SMPTypeCategory[NN_punpcklqdq] = 14; // Unpack Low Data SMPTypeCategory[NN_shufpd] = 14; // Shuffle Packed Double-Precision Floating-Point Values SMPTypeCategory[NN_sqrtpd] = 1; // Compute Square Roots of Packed Double-Precision Floating-Point Values SMPTypeCategory[NN_sqrtsd] = 14; // Compute Square Rootof Scalar Double-Precision Floating-Point Value SMPTypeCategory[NN_subpd] = 14; // Subtract Packed Double-Precision Floating-Point Values SMPTypeCategory[NN_subsd] = 14; // Subtract Scalar Double-Precision Floating-Point Values SMPTypeCategory[NN_ucomisd] = 14; // Unordered Compare Scalar Ordered Double-Precision Floating-Point Values and Set EFLAGS SMPTypeCategory[NN_unpckhpd] = 14; // Unpack and Interleave High Packed Double-Precision Floating-Point Values SMPTypeCategory[NN_unpcklpd] = 14; // Unpack and Interleave Low Packed Double-Precision Floating-Point Values SMPTypeCategory[NN_xorpd] = 14; // Bitwise Logical OR of Double-Precision Floating-Point Values // AMD syscall/sysret instructions NOTE: not AMD, found in Intel manual SMPTypeCategory[NN_syscall] = 1; // Low latency system call SMPTypeCategory[NN_sysret] = 1; // Return from system call // AMD64 instructions NOTE: not AMD, found in Intel manual SMPTypeCategory[NN_swapgs] = 1; // Exchange GS base with KernelGSBase MSR // New Pentium instructions (SSE3) SMPTypeCategory[NN_movddup] = 14; // Move One Double-FP and Duplicate SMPTypeCategory[NN_movshdup] = 14; // Move Packed Single-FP High and Duplicate SMPTypeCategory[NN_movsldup] = 14; // Move Packed Single-FP Low and Duplicate // Missing AMD64 instructions NOTE: also found in Intel manual SMPTypeCategory[NN_movsxd] = 2; // Move with Sign-Extend Doubleword SMPTypeCategory[NN_cmpxchg16b] = 0; // Compare and Exchange 16 Bytes // SSE3 instructions SMPTypeCategory[NN_addsubpd] = 14; // Add /Sub packed DP FP numbers SMPTypeCategory[NN_addsubps] = 14; // Add /Sub packed SP FP numbers SMPTypeCategory[NN_haddpd] = 14; // Add horizontally packed DP FP numbers SMPTypeCategory[NN_haddps] = 14; // Add horizontally packed SP FP numbers SMPTypeCategory[NN_hsubpd] = 14; // Sub horizontally packed DP FP numbers SMPTypeCategory[NN_hsubps] = 14; // Sub horizontally packed SP FP numbers SMPTypeCategory[NN_monitor] = 1; // Set up a linear address range to be monitored by hardware SMPTypeCategory[NN_mwait] = 1; // Wait until write-back store performed within the range specified by the MONITOR instruction SMPTypeCategory[NN_fisttp] = 13; // Store ST in intXX (chop) and pop SMPTypeCategory[NN_lddqu] = 14; // Load unaligned integer 128-bit // SSSE3 instructions SMPTypeCategory[NN_psignb] = 14; // Packed SIGN Byte SMPTypeCategory[NN_psignw] = 14; // Packed SIGN Word SMPTypeCategory[NN_psignd] = 14; // Packed SIGN Doubleword SMPTypeCategory[NN_pshufb] = 14; // Packed Shuffle Bytes SMPTypeCategory[NN_pmulhrsw] = 14; // Packed Multiply High with Round and Scale SMPTypeCategory[NN_pmaddubsw] = 14; // Multiply and Add Packed Signed and Unsigned Bytes SMPTypeCategory[NN_phsubsw] = 14; // Packed Horizontal Subtract and Saturate SMPTypeCategory[NN_phaddsw] = 14; // Packed Horizontal Add and Saturate SMPTypeCategory[NN_phaddw] = 14; // Packed Horizontal Add Word SMPTypeCategory[NN_phaddd] = 14; // Packed Horizontal Add Doubleword SMPTypeCategory[NN_phsubw] = 14; // Packed Horizontal Subtract Word SMPTypeCategory[NN_phsubd] = 14; // Packed Horizontal Subtract Doubleword SMPTypeCategory[NN_palignr] = 15; // Packed Align Right SMPTypeCategory[NN_pabsb] = 14; // Packed Absolute Value Byte SMPTypeCategory[NN_pabsw] = 14; // Packed Absolute Value Word SMPTypeCategory[NN_pabsd] = 14; // Packed Absolute Value Doubleword // VMX instructions SMPTypeCategory[NN_vmcall] = 1; // Call to VM Monitor SMPTypeCategory[NN_vmclear] = 0; // Clear Virtual Machine Control Structure SMPTypeCategory[NN_vmlaunch] = 1; // Launch Virtual Machine SMPTypeCategory[NN_vmresume] = 1; // Resume Virtual Machine SMPTypeCategory[NN_vmptrld] = 6; // Load Pointer to Virtual Machine Control Structure SMPTypeCategory[NN_vmptrst] = 0; // Store Pointer to Virtual Machine Control Structure SMPTypeCategory[NN_vmread] = 0; // Read Field from Virtual Machine Control Structure SMPTypeCategory[NN_vmwrite] = 0; // Write Field from Virtual Machine Control Structure SMPTypeCategory[NN_vmxoff] = 1; // Leave VMX Operation SMPTypeCategory[NN_vmxon] = 1; // Enter VMX Operation #if 599 < IDA_SDK_VERSION SMPTypeCategory[NN_ud2] = 1; // Undefined Instruction // Added with x86-64 SMPTypeCategory[NN_rdtscp] = 8; // Read Time-Stamp Counter and Processor ID // Geode LX 3DNow! extensions SMPTypeCategory[NN_pfrcpv] = 1; // Reciprocal Approximation for a Pair of 32-bit Floats SMPTypeCategory[NN_pfrsqrtv] = 1; // Reciprocal Square Root Approximation for a Pair of 32-bit Floats // SSE2 pseudoinstructions SMPTypeCategory[NN_cmpeqpd] = 1; // Packed Double-FP Compare EQ SMPTypeCategory[NN_cmpltpd] = 1; // Packed Double-FP Compare LT SMPTypeCategory[NN_cmplepd] = 1; // Packed Double-FP Compare LE SMPTypeCategory[NN_cmpunordpd] = 1; // Packed Double-FP Compare UNORD SMPTypeCategory[NN_cmpneqpd] = 1; // Packed Double-FP Compare NOT EQ SMPTypeCategory[NN_cmpnltpd] = 1; // Packed Double-FP Compare NOT LT SMPTypeCategory[NN_cmpnlepd] = 1; // Packed Double-FP Compare NOT LE SMPTypeCategory[NN_cmpordpd] = 1; // Packed Double-FP Compare ORDERED SMPTypeCategory[NN_cmpeqsd] = 1; // Scalar Double-FP Compare EQ SMPTypeCategory[NN_cmpltsd] = 1; // Scalar Double-FP Compare LT SMPTypeCategory[NN_cmplesd] = 1; // Scalar Double-FP Compare LE SMPTypeCategory[NN_cmpunordsd] = 1; // Scalar Double-FP Compare UNORD SMPTypeCategory[NN_cmpneqsd] = 1; // Scalar Double-FP Compare NOT EQ SMPTypeCategory[NN_cmpnltsd] = 1; // Scalar Double-FP Compare NOT LT SMPTypeCategory[NN_cmpnlesd] = 1; // Scalar Double-FP Compare NOT LE SMPTypeCategory[NN_cmpordsd] = 1; // Scalar Double-FP Compare ORDERED // SSSE4.1 instructions SMPTypeCategory[NN_blendpd] = 14; // Blend Packed Double Precision Floating-Point Values SMPTypeCategory[NN_blendps] = 14; // Blend Packed Single Precision Floating-Point Values SMPTypeCategory[NN_blendvpd] = 14; // Variable Blend Packed Double Precision Floating-Point Values SMPTypeCategory[NN_blendvps] = 14; // Variable Blend Packed Single Precision Floating-Point Values SMPTypeCategory[NN_dppd] = 14; // Dot Product of Packed Double Precision Floating-Point Values SMPTypeCategory[NN_dpps] = 14; // Dot Product of Packed Single Precision Floating-Point Values SMPTypeCategory[NN_extractps] = 2; // Extract Packed Single Precision Floating-Point Value SMPTypeCategory[NN_insertps] = 14; // Insert Packed Single Precision Floating-Point Value SMPTypeCategory[NN_movntdqa] = 0; // Load Double Quadword Non-Temporal Aligned Hint SMPTypeCategory[NN_mpsadbw] = 1; // Compute Multiple Packed Sums of Absolute Difference SMPTypeCategory[NN_packusdw] = 14; // Pack with Unsigned Saturation SMPTypeCategory[NN_pblendvb] = 14; // Variable Blend Packed Bytes SMPTypeCategory[NN_pblendw] = 14; // Blend Packed Words SMPTypeCategory[NN_pcmpeqq] = 14; // Compare Packed Qword Data for Equal SMPTypeCategory[NN_pextrb] = 15; // Extract Byte SMPTypeCategory[NN_pextrd] = 15; // Extract Dword SMPTypeCategory[NN_pextrq] = 15; // Extract Qword SMPTypeCategory[NN_phminposuw] = 14; // Packed Horizontal Word Minimum SMPTypeCategory[NN_pinsrb] = 14; // Insert Byte !!! Could this be used as a generic move??? SMPTypeCategory[NN_pinsrd] = 14; // Insert Dword !!! Could this be used as a generic move??? SMPTypeCategory[NN_pinsrq] = 14; // Insert Qword !!! Could this be used as a generic move??? SMPTypeCategory[NN_pmaxsb] = 14; // Maximum of Packed Signed Byte Integers SMPTypeCategory[NN_pmaxsd] = 14; // Maximum of Packed Signed Dword Integers SMPTypeCategory[NN_pmaxud] = 14; // Maximum of Packed Unsigned Dword Integers SMPTypeCategory[NN_pmaxuw] = 14; // Maximum of Packed Word Integers SMPTypeCategory[NN_pminsb] = 14; // Minimum of Packed Signed Byte Integers SMPTypeCategory[NN_pminsd] = 14; // Minimum of Packed Signed Dword Integers SMPTypeCategory[NN_pminud] = 14; // Minimum of Packed Unsigned Dword Integers SMPTypeCategory[NN_pminuw] = 14; // Minimum of Packed Word Integers SMPTypeCategory[NN_pmovsxbw] = 14; // Packed Move with Sign Extend SMPTypeCategory[NN_pmovsxbd] = 14; // Packed Move with Sign Extend SMPTypeCategory[NN_pmovsxbq] = 14; // Packed Move with Sign Extend SMPTypeCategory[NN_pmovsxwd] = 14; // Packed Move with Sign Extend SMPTypeCategory[NN_pmovsxwq] = 14; // Packed Move with Sign Extend SMPTypeCategory[NN_pmovsxdq] = 14; // Packed Move with Sign Extend SMPTypeCategory[NN_pmovzxbw] = 14; // Packed Move with Zero Extend SMPTypeCategory[NN_pmovzxbd] = 14; // Packed Move with Zero Extend SMPTypeCategory[NN_pmovzxbq] = 14; // Packed Move with Zero Extend SMPTypeCategory[NN_pmovzxwd] = 14; // Packed Move with Zero Extend SMPTypeCategory[NN_pmovzxwq] = 14; // Packed Move with Zero Extend SMPTypeCategory[NN_pmovzxdq] = 14; // Packed Move with Zero Extend SMPTypeCategory[NN_pmuldq] = 14; // Multiply Packed Signed Dword Integers SMPTypeCategory[NN_pmulld] = 14; // Multiply Packed Signed Dword Integers and Store Low Result SMPTypeCategory[NN_ptest] = 1; // Logical Compare SMPTypeCategory[NN_roundpd] = 14; // Round Packed Double Precision Floating-Point Values SMPTypeCategory[NN_roundps] = 14; // Round Packed Single Precision Floating-Point Values SMPTypeCategory[NN_roundsd] = 14; // Round Scalar Double Precision Floating-Point Values SMPTypeCategory[NN_roundss] = 14; // Round Scalar Single Precision Floating-Point Values // SSSE4.2 instructions SMPTypeCategory[NN_crc32] = 14; // Accumulate CRC32 Value SMPTypeCategory[NN_pcmpestri] = 2; // Packed Compare Explicit Length Strings, Return Index SMPTypeCategory[NN_pcmpestrm] = 2; // Packed Compare Explicit Length Strings, Return Mask SMPTypeCategory[NN_pcmpistri] = 2; // Packed Compare Implicit Length Strings, Return Index SMPTypeCategory[NN_pcmpistrm] = 2; // Packed Compare Implicit Length Strings, Return Mask SMPTypeCategory[NN_pcmpgtq] = 14; // Compare Packed Data for Greater Than SMPTypeCategory[NN_popcnt] = 2; // Return the Count of Number of Bits Set to 1 // AMD SSE4a instructions SMPTypeCategory[NN_extrq] = 14; // Extract Field From Register SMPTypeCategory[NN_insertq] = 14; // Insert Field SMPTypeCategory[NN_movntsd] = 13; // Move Non-Temporal Scalar Double-Precision Floating-Point !!! Could this be used as a generic move??? SMPTypeCategory[NN_movntss] = 13; // Move Non-Temporal Scalar Single-Precision Floating-Point !!! Could this be used as a generic move??? SMPTypeCategory[NN_lzcnt] = 2; // Leading Zero Count // xsave/xrstor instructions SMPTypeCategory[NN_xgetbv] = 8; // Get Value of Extended Control Register SMPTypeCategory[NN_xrstor] = 0; // Restore Processor Extended States SMPTypeCategory[NN_xsave] = 1; // Save Processor Extended States SMPTypeCategory[NN_xsetbv] = 1; // Set Value of Extended Control Register // Intel Safer Mode Extensions (SMX) SMPTypeCategory[NN_getsec] = 1; // Safer Mode Extensions (SMX) Instruction // AMD-V Virtualization ISA Extension SMPTypeCategory[NN_clgi] = 0; // Clear Global Interrupt Flag SMPTypeCategory[NN_invlpga] = 1; // Invalidate TLB Entry in a Specified ASID SMPTypeCategory[NN_skinit] = 1; // Secure Init and Jump with Attestation SMPTypeCategory[NN_stgi] = 0; // Set Global Interrupt Flag SMPTypeCategory[NN_vmexit] = 1; // Stop Executing Guest, Begin Executing Host SMPTypeCategory[NN_vmload] = 0; // Load State from VMCB SMPTypeCategory[NN_vmmcall] = 1; // Call VMM SMPTypeCategory[NN_vmrun] = 1; // Run Virtual Machine SMPTypeCategory[NN_vmsave] = 0; // Save State to VMCB // VMX+ instructions SMPTypeCategory[NN_invept] = 1; // Invalidate Translations Derived from EPT SMPTypeCategory[NN_invvpid] = 1; // Invalidate Translations Based on VPID // Intel Atom instructions // !!!! continue work here SMPTypeCategory[NN_movbe] = 3; // Move Data After Swapping Bytes // Intel AES instructions SMPTypeCategory[NN_aesenc] = 14; // Perform One Round of an AES Encryption Flow SMPTypeCategory[NN_aesenclast] = 14; // Perform the Last Round of an AES Encryption Flow SMPTypeCategory[NN_aesdec] = 14; // Perform One Round of an AES Decryption Flow SMPTypeCategory[NN_aesdeclast] = 14; // Perform the Last Round of an AES Decryption Flow SMPTypeCategory[NN_aesimc] = 14; // Perform the AES InvMixColumn Transformation SMPTypeCategory[NN_aeskeygenassist] = 14; // AES Round Key Generation Assist // Carryless multiplication SMPTypeCategory[NN_pclmulqdq] = 14; // Carry-Less Multiplication Quadword #endif // 599 < IDA_SDK_VERSION SMPTypeCategory[NN_last] = 1; return; } // end InitTypeCategory()