Tablgen files for really simple instruction selector
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12714 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/X86/Makefile b/lib/Target/X86/Makefile
index b151fa7..896feae 100644
--- a/lib/Target/X86/Makefile
+++ b/lib/Target/X86/Makefile
@@ -13,7 +13,8 @@
# Make sure that tblgen is run, first thing.
$(SourceDepend): X86GenRegisterInfo.h.inc X86GenRegisterNames.inc \
X86GenRegisterInfo.inc X86GenInstrNames.inc \
- X86GenInstrInfo.inc X86GenInstrSelector.inc
+ X86GenInstrInfo.inc X86GenSimpInstrSelector.inc \
+ X86GenInstrSelector.inc
X86GenRegisterNames.inc:: $(SourceDir)/X86.td $(SourceDir)/X86RegisterInfo.td \
$(SourceDir)/../Target.td $(TBLGEN)
@@ -40,10 +41,16 @@
@echo "Building X86.td instruction information with tblgen"
$(VERB) $(TBLGEN) -I $(BUILD_SRC_DIR) $< -gen-instr-desc -o $@
+X86GenSimpInstrSelector.inc:: $(SourceDir)/X86InstrSel.td $(TBLGEN)
+ @echo "Building X86.td simple instruction selector with tblgen"
+ $(VERB) $(TBLGEN) -I $(BUILD_SRC_DIR) $< -gen-simp-instr-sel -o $@
+
X86GenInstrSelector.inc:: $(SourceDir)/X86.td $(SourceDir)/X86InstrInfo.td \
$(SourceDir)/../Target.td $(TBLGEN)
@echo "Building X86.td instruction selector with tblgen"
$(VERB) $(TBLGEN) -I $(BUILD_SRC_DIR) $< -gen-instr-selector -o $@
+
+
clean::
$(VERB) rm -f *.inc
diff --git a/lib/Target/X86/X86.h b/lib/Target/X86/X86.h
index 54e2861..fde6bc6 100644
--- a/lib/Target/X86/X86.h
+++ b/lib/Target/X86/X86.h
@@ -29,6 +29,12 @@
///
FunctionPass *createX86SimpleInstructionSelector(TargetMachine &TM);
+/// createX86ReallySimpleInstructionSelector - This pass converts an LLVM
+/// function into a machine code representation in an even simpler fashion
+/// than above.
+///
+FunctionPass *createX86ReallySimpleInstructionSelector(TargetMachine &TM);
+
/// createX86PatternInstructionSelector - This pass converts an LLVM function
/// into a machine code representation using pattern matching and a machine
/// description file.
diff --git a/lib/Target/X86/X86InstrSel.td b/lib/Target/X86/X86InstrSel.td
new file mode 100644
index 0000000..479e1c0
--- /dev/null
+++ b/lib/Target/X86/X86InstrSel.td
@@ -0,0 +1,393 @@
+//===- X86InstrSel.td - Describe the X86 Instruction Selector -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is used by the instruction selector and is used to map
+// LLVM instructions to a corresponding set of machine instructions
+//
+//
+//===----------------------------------------------------------------------===//
+
+include "../Target.td"
+
+ // ret br switch invoke unwind
+ // add sub mul div rem setcc (eq ne lt gt le ge)
+ // and or xor sbl sbr
+ // malloc free alloca load store
+ // getelementptr phi cast call vanext vaarg
+
+
+class InstrSubclass<int v> {
+ int Value = v;
+}
+
+// provide a grouping of InstrSubclasses
+class InstrSubclassCollection<string pre, string post, list<InstrSubclass> l> {
+ list<InstrSubclass> List = l;
+ string PreCode = pre;
+ string PostCode = post;
+}
+
+// virtual registers
+let Namespace = "Virtual" in {
+ def DestReg : Register;
+ def DestRegp1 : Register; // DestReg+1
+ def Op0Reg : Register;
+ def Op0Regp1 : Register; // Op0Reg+1
+ def Op1Reg : Register;
+ def Op1Regp1 : Register; // Op1Reg+1
+ def TmpReg01 : Register;
+ def TmpReg01p1: Register;
+ def TmpReg02 : Register;
+ def TmpReg02p1: Register;
+ def NullReg : Register; // represents no register
+}
+
+class InstrClass<string n, string fn, string pre, string post, list<InstrSubclassCollection> l> {
+ string FunctionName = fn;
+ string InstructionName = n;
+ string PreCode = pre;
+ string PostCode = post;
+
+ // add lists of what subclasses this InstrClass supports
+ list<InstrSubclassCollection> Supports = l;
+}
+
+
+// helper class to build BMI instruction
+class addedOperand<string op> {
+ string Name = op;
+}
+
+def MBI_Reg : addedOperand<"Reg">;
+def MBI_GlobalAddr : addedOperand<"GlobalAddr">;
+def MBI_ZImm : addedOperand<"ZImm">;
+
+def MBI_DirectMem : addedOperand<"DirectMem">;
+def MBI_RegOffset : addedOperand<"RegOffset">;
+def MBI_FrameRef : addedOperand<"FrameRef">;
+def MBI_ConstPoolRef : addedOperand<"ConstPoolRef">;
+def MBI_CCReg : addedOperand<"CCReg">;
+def MBI_RegDef : addedOperand<"RegDef">;
+def MBI_PCDisp : addedOperand<"PCDisp">;
+def MBI_MReg : addedOperand<"MReg">;
+def MBI_SImm : addedOperand<"SImm">;
+def MBI_MBB : addedOperand<"MBB">;
+def MBI_FrameIndex : addedOperand<"FrameIndex">;
+def MBI_ConstPoolIdx : addedOperand<"ConstPoolIdx">;
+def MBI_ExternSymbol : addedOperand<"ExternSymbol">;
+
+
+class TargInstr<string n, int numops, list<addedOperand> lops> {
+
+ string Name = n; // make this a reference to the Instruction class
+ string Namespace;
+ int NumOperands = numops;
+ list<addedOperand> Params = lops; // will this work for mem-mem instrs, destination is implicitly a register
+
+} //TargInstr
+
+
+let Namespace = "Virtual" in {
+ // virtual instructions for creating registers
+ def CreateRegInt : TargInstr<"CreateRegInt",0,[]>;
+ def CreateRegByte : TargInstr<"CreateRegByte",0,[]>;
+ def CreateRegShort: TargInstr<"CreateRegShort",0,[]>;
+ def CreateRegLong : TargInstr<"CreateRegLong",0,[]>;
+
+ def CreateRegUInt : TargInstr<"CreateRegUInt",0,[]>;
+ def CreateRegUByte : TargInstr<"CreateRegUByte",0,[]>;
+ def CreateRegUShort: TargInstr<"CreateRegUShort",0,[]>;
+ def CreateRegULong : TargInstr<"CreateRegULong",0,[]>;
+
+ def CreateRegFloat : TargInstr<"CreateRegFloat",0,[]>;
+ def CreateRegDouble : TargInstr<"CreateRegDouble",0,[]>;
+ def CreateRegPointer: TargInstr<"CreateRegPointer",0,[]>;
+
+ def NullInstr : TargInstr<"NullInstruction",0,[]>; // ignored
+}
+
+class TargInstrSet<InstrClass c, string pre, string post, list<InstrSubclass> l, list<TargInstr> targs, list<list<string>> r> {
+ InstrClass Class = c;
+
+ list<InstrSubclass> List = l;
+ list<TargInstr> Instructions = targs;
+ list< list<string> > Operands = r; // generalized for all operand types
+
+ string PreCode = pre;
+ string PostCode = post;
+}
+
+
+
+// --------------------------------------------------------------------
+// Begin architecture-specific information
+// --------------------------------------------------------------------
+
+include "X86RegisterInfo.td"
+include "X86InstrSelInfo.td"
+
+
+// set up the subclasses of instructions
+// value is what the subclass's case value
+def cByte : InstrSubclass<1>;
+def cInt : InstrSubclass<2>;
+def cShort : InstrSubclass<3>;
+def cFP : InstrSubclass<4>;
+def cLong : InstrSubclass<5>;
+
+def EQ : InstrSubclass<1>;
+def NE : InstrSubclass<2>;
+def LT : InstrSubclass<3>;
+def GE : InstrSubclass<4>;
+def GT : InstrSubclass<5>;
+def LE : InstrSubclass<6>;
+
+def True : InstrSubclass<1>;
+def False : InstrSubclass<0>;
+
+def NegOne : InstrSubclass<-1>;
+def PosOne : InstrSubclass<1>;
+def Cons :InstrSubclass<2>;
+def Other : InstrSubclass<0>;
+
+def Regular: InstrSubclass<0>;
+def Zero : InstrSubclass<0>;
+
+def NoOps : InstrSubclass<0>;
+def Ops : InstrSubclass<1>;
+
+def Signed : InstrSubclass<0>;
+def Unsigned : InstrSubclass<1>;
+
+def SuccessorIsNextBB : InstrSubclass<0>;
+def SuccessorIsNotNextBB: InstrSubclass<1>;
+
+def Cond: InstrSubclass<0>;
+def Uncond: InstrSubclass<1>;
+
+def ConstTwo: InstrSubclass<2>;
+def ConstNotTwo: InstrSubclass<3>;
+
+def Reg: InstrSubclass<6>;
+
+
+// group subclasses, specify how to determine instruction subclass
+def OperandSize: InstrSubclassCollection<"unsigned OperandSize = getClassB(Op0Val->getType());","", [cByte, cShort, cInt, cFP, cLong]>;
+def Conditional: InstrSubclassCollection<"unsigned Conditional;", "", [EQ, NE, LT, GE, GT, LE]>;
+def SpecialCase: InstrSubclassCollection<"unsigned SpecialCase;", "", [True, False]>;
+
+//TODO write funcs for separating out special cases
+def AddSpecialCases: InstrSubclassCollection<"Subclasses AddSpecialCases = Other;", "", [NegOne,PosOne,Cons,Other]>;
+def SubSpecialCases: InstrSubclassCollection<"unsigned SubSpecialCases = Other;", "", [NegOne,PosOne,Cons,Other]>;
+def XorSpecialCases: InstrSubclassCollection<"unsigned XorSpecialCases = Other;","", [NegOne,Other]>;
+
+
+
+// Instruction subclasses, as defined in llvm/Instructions.h:
+// iTerminators.h : ReturnInst, BranchInst, SwitchInst, InvokeInst, UnwindInst
+// iPHINode.h : PHINode,
+// iOperators.h : SetCondInst,
+// iMemory.h : AllocationInst, MallocInst, AllocaInst, FreeInst, LoadInst, StoreInst, GetElementPtrInst,
+// iOther.h : CastInst, CallInst, ShiftInst, VANextInst, VAArgInst,
+// InstrTypes.h : TerminatorInst, BinaryOperator
+
+// general classes of LLVM instructions, and the subclass sets that apply to them
+def add : InstrClass<"BinaryOperator","Add","","",[AddSpecialCases, OperandSize]>;
+def sub : InstrClass<"BinaryOperator","Sub","","",[SubSpecialCases, OperandSize]>;
+// def mul : InstrClass<"BinaryOperator","Mul","","",[OperandSize]>;
+// def div : InstrClass<"BinaryOperator","Div","","",[OperandSize]>;
+// def rem : InstrClass<"BinaryOperator","Rem","","",[OperandSize]>;
+def logic_and : InstrClass<"BinaryOperator","And","","",[OperandSize]>;
+def logic_or : InstrClass<"BinaryOperator","Or","","",[OperandSize]>;
+def logic_xor : InstrClass<"BinaryOperator","Xor","","",[XorSpecialCases, OperandSize]>;
+// //def mov : InstrClass<"ShiftInst","Mov","","",[OperandSize]>;
+
+// def setcc: InstrClass<"SetCondInst","SetCondInst","","",[OperandSize]>;
+// def branch : InstrClass<"BranchInst","BranchInst","","",[Conditional]>;
+
+// def retrn : InstrClass<"ReturnInst","ReturnInst","","",[]>;
+
+// definition of machine instructions for instruction subclasses
+
+
+// ADD
+
+def ADD_Other_cByte : TargInstrSet<add,"","",[Other,cByte],[CreateRegByte,ADDrr8],[["EAX"],["EAX","Op0Reg","Op1Reg"]]>;
+def ADD_Other_cShort : TargInstrSet<add,"","",[Other,cShort],[ADDrr16],[["DestReg","Op0Reg","Op1Reg"]]>;
+def ADD_Other_cInt : TargInstrSet<add,"","",[Other,cInt],[ADDrr32],[["DestReg","Op0Reg","Op1Reg"]]>;
+def ADD_Other_cLong : TargInstrSet<add,"","",[Other,cLong],[ADDrr32,ADCrr32],[["DestReg","Op0Reg","Op1Reg"],["DestReg","Op0Reg","Op1Reg"]]>;
+def ADD_Other_cFP : TargInstrSet<add,"","",[Other,cFP],[FpADD],[["DestReg","Op0Reg","Op1Reg"]]>;
+def ADD_Constant_cByte : TargInstrSet<add,"","",[Cons,cByte],[ADDri8],[["DestReg","Op0Reg","Op1Reg"]]>;
+def ADD_Constant_cShort :TargInstrSet<add,"","",[Cons,cShort],[ADDri16],[["DestReg","Op0Reg","Op1Reg"]]>;
+def ADD_Constant_cInt :TargInstrSet<add,"","",[Cons,cInt],[ADDri32],[["DestReg","Op0Reg","Op1Reg"]]>;
+def ADD_PosOne_cByte : TargInstrSet<add,"","",[PosOne,cByte],[INCr8],[["DestReg","Op0Reg"]]>;
+def ADD_PosOne_cShort : TargInstrSet<add,"","",[PosOne,cShort],[INCr16],[["DestReg","Op0Reg"]]>;
+def ADD_PosOne_cInt : TargInstrSet<add,"","",[PosOne,cInt],[INCr32],[["DestReg","Op0Reg"]]>;
+def ADD_NegOne_cByte : TargInstrSet<add,"","",[NegOne,cByte],[DECr8],[["DestReg","Op0Reg"]]>;
+def ADD_NegOne_cShort : TargInstrSet<add,"","",[NegOne,cShort],[DECr16],[["DestReg","Op0Reg"]]>;
+def ADD_NegOne_cInt : TargInstrSet<add,"","",[NegOne,cInt],[DECr32],[["DestReg","Op0Reg"]]>;
+
+
+// SUBTRACT
+
+def SUB_Other_cByte : TargInstrSet<sub,"","",[Other,cByte],[CreateRegByte,SUBrr8],[["EAX"],["EAX","Op0Reg","Op1Reg"]]>;
+def SUB_Other_cShort : TargInstrSet<sub,"","",[Other,cShort],[SUBrr16],[["DestReg","Op0Reg","Op1Reg"]]>;
+def SUB_Other_cInt : TargInstrSet<sub,"","",[Other,cInt],[SUBrr32],[["DestReg","Op0Reg","Op1Reg"]]>;
+def SUB_Other_cLong : TargInstrSet<sub,"","",[Other,cLong],[SUBrr32,SUBrr32],[["DestReg","Op0Reg","Op1Reg"],["DestReg","Op0Reg","Op1Reg"]]>;
+def SUB_Other_cFP : TargInstrSet<sub,"","",[Other,cFP],[FpSUB],[["DestReg","Op0Reg","Op1Reg"]]>;
+def SUB_Constant_cByte : TargInstrSet<sub,"","",[Cons,cByte],[SUBri8],[["DestReg","Op0Reg","Op1Reg"]]>;
+def SUB_Constant_cShort :TargInstrSet<sub,"","",[Cons,cShort],[SUBri16],[["DestReg","Op0Reg","Op1Reg"]]>;
+def SUB_Constant_cInt :TargInstrSet<sub,"","",[Cons,cInt],[SUBri32],[["DestReg","Op0Reg","Op1Reg"]]>;
+def SUB_PosOne_cByte : TargInstrSet<sub,"","",[PosOne,cByte],[DECr8],[["DestReg","Op0Reg"]]>;
+def SUB_PosOne_cShort : TargInstrSet<sub,"","",[PosOne,cShort],[DECr16],[["DestReg","Op0Reg"]]>;
+def SUB_PosOne_cInt : TargInstrSet<sub,"","",[PosOne,cInt],[DECr32],[["DestReg","Op0Reg"]]>;
+def SUB_NegOne_cByte : TargInstrSet<sub,"","",[NegOne,cByte],[INCr8],[["DestReg","Op0Reg"]]>;
+def SUB_NegOne_cShort : TargInstrSet<sub,"","",[NegOne,cShort],[INCr16],[["DestReg","Op0Reg"]]>;
+def SUB_NegOne_cInt : TargInstrSet<sub,"","",[NegOne,cInt],[INCr32],[["DestReg","Op0Reg"]]>;
+
+
+// def SHIFT_S_L_Const_Byte :
+// def SHIFT_S_L_Const_Short :
+// def SHIFT_S_L_Const_Int :
+// def SHIFT_S_L_Const_SHLDIR32 :
+// def SHIFT_S_L_Reg_Byte :
+// def SHIFT_S_L_Reg_Short :
+// def SHIFT_S_L_Reg_Int :
+// def SHIFT_S_R_Const_Byte :
+// def SHIFT_S_R_Const_Short :
+// def SHIFT_S_R_Const_Int :
+// def SHIFT_S_R_Const_SHRDIR32 :
+// def SHIFT_S_R_Reg_Byte :
+// def SHIFT_S_R_Reg_Short :
+// def SHIFT_S_R_Reg_Int :
+// def SHIFT_U_L_Const_Byte :
+// def SHIFT_U_L_Const_Short :
+// def SHIFT_U_L_Const_Int :
+// def SHIFT_U_L_Const_SHLDIR32 :
+// def SHIFT_U_L_Reg_Byte :
+// def SHIFT_U_L_Reg_Short :
+// def SHIFT_U_L_Reg_Int :
+// def SHIFT_U_R_Const_Byte :
+// def SHIFT_U_R_Const_Short :
+// def SHIFT_U_R_Const_Int :
+// def SHIFT_U_R_Const_SHRDIR32 :
+// def SHIFT_U_R_Reg_Byte :
+// def SHIFT_U_R_Reg_Short :
+// def SHIFT_U_R_Reg_Int :
+
+
+// def CMP_i_Byte : TargInstrSet<setcc,"","",[Constant,cByte],[CMPri8],[["DestReg","Op0Reg","Op1Val"]]>;
+// def CMP_i_Short : TargInstrSet<setcc,"","",[Constant,cShort],[CMPri16],[["DestReg","Op0Reg","Op1Val"]]>;
+// def CMP_i_Int : TargInstrSet<setcc,"","",[Constant,cInt],[CMPri32],[["DestReg","Op0Reg","Op1Val"]]>;
+// //def CMP_i_Long : // not supported
+// def CMP_z_Byte : TargInstrSet<setcc,"ConstantInt *CI = dyn_cast<ConstantInt>(Op1); uint64_t Op1v = cast<ConstantInt>(CI)->getRawValue(); Op1v &= (1ULL << (8 << Class)) - 1;","",[Zero,cByte],[TESTrr8],[["DestReg","Op0Reg","Op0Reg"]]>;
+// def CMP_z_Short : TargInstrSet<setcc,"ConstantInt *CI = dyn_cast<ConstantInt>(Op1); uint64_t Op1v = cast<ConstantInt>(CI)->getRawValue(); Op1v &= (1ULL << (8 << Class)) - 1;","",[Zero,cShort],[TESTrr16],[["DestReg","Op0Reg","Op0Reg"]]>;
+// def CMP_z_Int : TargInstrSet<setcc,"ConstantInt *CI = dyn_cast<ConstantInt>(Op1); uint64_t Op1v = cast<ConstantInt>(CI)->getRawValue(); Op1v &= (1ULL << (8 << Class)) - 1;","",[Zero,cInt],[TESTrr32],[["DestReg","Op0Reg","Op0Reg"]]>;
+// //def CMP_z_Long : // not supported
+// def CMP_r_Byte : TargInstrSet<setcc,"","",[Regular,cByte],[CMPrr8],[["NullReg","Op0Reg","Op1Reg"]]>;
+// def CMP_r_Short : TargInstrSet<setcc,"","",[Regular,cShort],[CMPrr16],[["NullReg","Op0Reg","Op1Reg"]]>;
+// def CMP_r_Int : TargInstrSet<setcc,"","",[Regular,cInt],[CMPrr32],[["NullReg","Op0Reg","Op1Reg"]]>;
+// //def CMP_r_Long : // two cases of long, depending on num of operands
+// def CMP_r_FP : TargInstrSet<setcc,"","",[Regular,cFP],[FpUCOM,FNSTSWr8,SAHF],[["NullReg","Op0Reg","Op1Reg"],["NullReg"],["NullReg"]]>;
+
+
+// def RET_NoOps : TargInstrSet<retrn,"","",[NoOps],[FP_REG_KILL,RET],[["NullReg"],["NullReg"]]>;
+// def RET_Op_Byte : TargInstrSet<retrn,"promote32(X86::EAX, ValueRecord(Op0Reg, Op0Val->getType()));","",[Ops,cByte],[IMPLICIT_USE],[["NullReg","EAX","ESP"]]>;
+// def RET_Op_Short : TargInstrSet<retrn,"promote32(X86::EAX, ValueRecord(Op0Reg, Op0Val->getType()));","",[Ops,cShort],[IMPLICIT_USE],[["NullReg","EAX","ESP"]]>;
+// def RET_Op_Int : TargInstrSet<retrn,"promote32(X86::EAX, ValueRecord(Op0Reg, Op0Val->getType()));","",[Ops,cInt],[IMPLICIT_USE],[["NullReg","EAX","ESP"]]>;
+// def RET_Op_FP : TargInstrSet<retrn,"","",[Ops,cFP],[FpSETRESULT,IMPLICIT_USE],[["NullReg","Op0Reg"],["NullReg","STO","ESP"]]>;
+// def RET_Op_Long : TargInstrSet<retrn,"","",[Ops,cLong],[MOVrr32,MOVrr32,IMPLICIT_USE],[["EAX","Op0Reg"],["EDX","Op0Reg+1"],["NullReg","EAX","EDX","ESP"]]>;
+
+
+// def BR_Uncond : TargInstrSet<branch,"","",[Uncond],[FP_REG_KILL,JMP],[["NullReg"],["NullReg","I.getSuccessor(0);"]]>;
+// def BR_Cond_S_EQ :
+// def BR_Cond_S_NE
+// def BR_Cond_S_B
+// def BR_Cond_S_AE
+// def BR_Cond_S_A
+// def BR_Cond_S_BE
+// def BR_Cond_U_EQ
+// def BR_Cond_U_NE
+// def BR_Cond_U_LT
+// def BR_Cond_U_GE
+// def BR_Cond_U_GT
+// def BR_Cond_U_LE
+// def BR_Cond_U_S
+// def BR_Cond_U_NS
+
+
+// def CALL_Byte
+// def CALL_Short
+// def CALL_Int
+// def CALL_Long
+// def CALL_FP
+
+
+def AND_Byte : TargInstrSet<logic_and,"","",[cByte],[ANDrr8],[["DestReg","Op0Reg","Op1Reg"]]>;
+def AND_Short : TargInstrSet<logic_and,"","",[cShort],[ANDrr16],[["DestReg","Op0Reg","Op1Reg"]]>;
+def AND_Int : TargInstrSet<logic_and,"","",[cInt],[ANDrr32],[["DestReg","Op0Reg","Op1Reg"]]>;
+def AND_Long : TargInstrSet<logic_and,"","",[cLong],[ANDrr32,ANDrr32],[["DestReg","Op0Reg","Op1Reg"],["DestReg+1","Op0Reg+1","Op1Reg+1"]]>;
+
+
+def OR_Byte : TargInstrSet<logic_or,"","",[cByte],[ORrr8],[["DestReg","Op0Reg","Op1Reg"]]>;
+def OR_Short : TargInstrSet<logic_or,"","",[cShort],[ORrr16],[["DestReg","Op0Reg","Op1Reg"]]>;
+def OR_Int : TargInstrSet<logic_or,"","",[cInt],[ORrr32],[["DestReg","Op0Reg","Op1Reg"]]>;
+def OR_Long : TargInstrSet<logic_or,"","",[cLong],[ORrr32,ORrr32],[["DestReg","Op0Reg","Op1Reg"],["DestReg+1","Op0Reg+1","Op1Reg+1"]]>;
+
+
+def XOR_NegOne_Byte : TargInstrSet<logic_xor,"","",[NegOne,cByte],[NOTr8],[["DestReg","Op0Reg"]]>;
+def XOR_NegOne_Short: TargInstrSet<logic_xor,"","",[NegOne,cShort],[NOTr16],[["DestReg","Op0Reg"]]>;
+def XOR_NegOne_Int : TargInstrSet<logic_xor,"","",[NegOne,cInt],[NOTr32],[["DestReg","Op0Reg"]]>;
+//def XOR_NegOne_Long : // not supported (treat as regular long XOR)
+def XOR_Other_Byte : TargInstrSet<logic_xor,"","",[Other,cByte],[XORrr8],[["DestReg","Op0Reg","Op1Reg"]]>;
+def XOR_Other_Short : TargInstrSet<logic_xor,"","",[Other,cByte],[XORrr16],[["DestReg","Op0Reg","Op1Reg"]]>;
+def XOR_Other_Int : TargInstrSet<logic_xor,"","",[Other,cByte],[XORrr32],[["DestReg","Op0Reg","Op1Reg"]]>;
+def XOR_Other_Long : TargInstrSet<logic_xor,"","",[Other,cLong],[XORrr32,XORrr32],[["DestReg","Op0Reg","Op1Reg"],["DestReg+1","Op0Reg+1","Op1Reg+1"]]>;
+
+
+
+// // TODO support for arbitrary values as operand arguments
+// // or make ConstantInt versions as well-known variables
+// // ConstantInt, unsigned Val
+// def MUL_ConstTwo_Byte : TargInstrSet<mul,"ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(1)); unsigned Val = (unsigned)CI->getRawValue(); unsigned Shift = ExactLog2(Val);","",[ConstTwo,cByte],[SHLir32],[["DestReg","Op0Reg","Shift-1"]]>;
+// def MUL_ConstTwo_Short : TargInstrSet<mul,"ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(1)); unsigned Val = (unsigned)CI->getRawValue(); unsigned Shift = ExactLog2(Val);","",[ConstTwo,cShort],[SHLir32],[["DestReg","Op0Reg","Shift-1"]]>;
+// def MUL_ConstTwo_Int : TargInstrSet<mul,"ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(1)); unsigned Val = (unsigned)CI->getRawValue(); unsigned Shift = ExactLog2(Val);","",[ConstTwo,cInt],[SHLir32],[["DestReg","Op0Reg","Shift-1"]]>;
+// def MUL_ConstNotTwo_Byte : TargInstrSet<mul,"","",[ConstNotTwo,cByte],[CreateRegByte,MOVir8,MOVrr8,MULr8,MOVrr8],[["tmpReg"],["tmpReg","ConstRHS"],["AL","Op0Reg"],["NullReg","Op1Reg"],["DestReg","AL"]]>; //TODO fixme, define ConstRHS
+// def MUL_ConstNotTwo_Short : TargInstrSet<mul,"","",[ConstNotTwo,cShort],[IMULri16],[["DestReg","Op0Reg","Val"]]>;
+// def MUL_ConstNotTwo_Int : TargInstrSet<mul,"","",[ConstNotTwo,cInt],[IMULri32],[["DestReg","Op0Reg","Val"]]>;
+// //def MUL_ConstNotTwo_Long :
+// //def MUL_ConstNotTwo_FP :
+// def MUL_Reg_Byte : TargInstrSet<mul,"","",[Reg,cByte],[MOVrr8,MULr8,MOVrr8],[["AL","Op0Reg"],["NullReg","Op1Reg"],["DestReg","AL"]]>;
+// def MUL_Reg_Short : TargInstrSet<mul,"","",[Reg,cShort],[IMULrr16],[["DestReg","Op0Reg","Op1Reg"]]>;
+// def MUL_Reg_Int : TargInstrSet<mul,"","",[Reg,cInt],[IMULrr32],[["DestReg","Op0Reg","Op1Reg"]]>;
+// //def MUL_Reg_Long : // not supported (assert)
+// def MUL_Reg_FP : TargInstrSet<mul,"","",[Reg,cFP],[FpMUL],[["DestReg","Op0Reg","Op1Reg"]]>;
+
+// def STO_Byte
+// def STO_Short
+// def STO_Int
+// def STO_FP
+// def STO_Long
+
+
+// DIVREM
+
+// CAST
+
+// PHI
+
+// LOAD ARGS TO VIRTUAL REGS
+
+// COPY CONSTANT
+
+//TODO
+// handling various operand options
+// allowing for arbitrary code or operand arguments
+// generate skeletons for selector function
+//
diff --git a/lib/Target/X86/X86InstrSelInfo.td b/lib/Target/X86/X86InstrSelInfo.td
new file mode 100644
index 0000000..f4935fc
--- /dev/null
+++ b/lib/Target/X86/X86InstrSelInfo.td
@@ -0,0 +1,241 @@
+
+let Namespace = "X86" in {
+
+// def PHI : TargInstr<"PHI", 2, [MBI_Reg, MBI_Reg]>;
+// def NOOP : TargInstr<"NOOP", 2, [MBI_Reg, MBI_Reg]>;
+// def ADJCALLSTACKDOWN : TargInstr<"ADJCALLSTACKDOWN", 2, [MBI_Reg, MBI_Reg]>;
+// def ADJCALLSTACKUP : TargInstr<"ADJCALLSTACKUP", 2, [MBI_Reg, MBI_Reg]>;
+def IMPLICIT_USE : TargInstr<"IMPLICIT_USE", 2, [MBI_Reg, MBI_Reg]>;
+def IMPLICIT_DEF : TargInstr<"IMPLICIT_DEF", 0, []>;
+
+def RET : TargInstr<"RET", 0, []>;
+def JMP : TargInstr<"JMP", 1, [MBI_PCDisp]>;
+// def JB : TargInstr<"JB", 2, [MBI_Reg, MBI_Reg]>;
+// def JAE : TargInstr<"JAE", 2, [MBI_Reg, MBI_Reg]>;
+// def JE : TargInstr<"JE", 2, [MBI_Reg, MBI_Reg]>;
+// def JNE : TargInstr<"JNE", 2, [MBI_Reg, MBI_Reg]>;
+// def JBE : TargInstr<"JBE", 2, [MBI_Reg, MBI_Reg]>;
+// def JA : TargInstr<"JA", 2, [MBI_Reg, MBI_Reg]>;
+// def JS : TargInstr<"JS", 2, [MBI_Reg, MBI_Reg]>;
+// def JNS : TargInstr<"JNS", 2, [MBI_Reg, MBI_Reg]>;
+// def JL : TargInstr<"JL", 2, [MBI_Reg, MBI_Reg]>;
+// def JGE : TargInstr<"JGE", 2, [MBI_Reg, MBI_Reg]>;
+// def JLE : TargInstr<"JLE", 2, [MBI_Reg, MBI_Reg]>;
+// def JG : TargInstr<"JG", 2, [MBI_Reg, MBI_Reg]>;
+// def LEAVE : TargInstr<"LEAVE", 2, [MBI_Reg, MBI_Reg]>;
+// def BSWAPr32 : TargInstr<"BSWAPr32", 2, [MBI_Reg, MBI_Reg]>;
+// def XCHGrr8 : TargInstr<"XCHGrr8", 2, [MBI_Reg, MBI_Reg]>;
+// def XCHGrr16 : TargInstr<"XCHGrr16", 2, [MBI_Reg, MBI_Reg]>;
+// def XCHGrr32 : TargInstr<"XCHGrr32", 2, [MBI_Reg, MBI_Reg]>;
+// def LEAr16 : TargInstr<"LEAr16", 2, [MBI_Reg, MBI_Reg]>;
+// def LEAr32 : TargInstr<"LEAr32", 2, [MBI_Reg, MBI_Reg]>;
+def MOVrr8 : TargInstr<"MOV8rr", 1, [MBI_Reg]>;
+def MOVrr16 : TargInstr<"MOV16rr", 1, [MBI_Reg]>;
+def MOVrr32 : TargInstr<"MOV32rr", 1, [MBI_Reg]>;
+def MOVir8 : TargInstr<"MOV8ir", 1, [MBI_ZImm]>;
+def MOVir16 : TargInstr<"MOV16ir", 1, [MBI_ZImm]>;
+def MOVir32 : TargInstr<"MOV32ir", 1, [MBI_ZImm]>;
+// def MOVim8 : TargInstr<"MOVim8", 2, [MBI_Reg, MBI_ZImm]>;
+// def MOVim16 : TargInstr<"MOVim16", 2, [MBI_Reg, MBI_ZImm]>;
+// def MOVim32 : TargInstr<"MOVim32", 2, [MBI_Reg, MBI_ZImm]>;
+def MOVmr8 : TargInstr<"MOV8mr", 4, [MBI_FrameRef]>;
+def MOVmr16 : TargInstr<"MOV16mr", 4, [MBI_FrameRef]>;
+def MOVmr32 : TargInstr<"MOV32mr", 4, [MBI_FrameRef]>;
+def MOVrm8 : TargInstr<"MOV8rm", 5, [MBI_FrameRef, MBI_Reg]>; // 5 Operands?, stores to NULL
+def MOVrm16 : TargInstr<"MOV16rm", 5, [MBI_FrameRef, MBI_Reg]>; // 5 Operands?, stores to NULL
+def MOVrm32 : TargInstr<"MOV32rm", 5, [MBI_FrameRef, MBI_Reg]>; // 5 Operands?, stores to NULL
+def MULr8 : TargInstr<"MUL8r", 1, [MBI_Reg]>;
+// def MULr16 : TargInstr<"MULr16", 2, [MBI_Reg, MBI_Reg]>;
+// def MULr32 : TargInstr<"MULr32", 2, [MBI_Reg, MBI_Reg]>;
+def DIVr8 : TargInstr<"DIV8r", 1, [MBI_Reg]>; // "DestReg" as arg, "1" as the dest
+def DIVr16 : TargInstr<"DIV16r", 1, [MBI_Reg]>;
+def DIVr32 : TargInstr<"DIV32r", 1, [MBI_Reg]>;
+def IDIVr8 : TargInstr<"IDIV8r", 1, [MBI_Reg]>;
+def IDIVr16 : TargInstr<"IDIV16r", 1, [MBI_Reg]>;
+def IDIVr32 : TargInstr<"IDIV32r", 1, [MBI_Reg]>;
+// def CBW : TargInstr<"CBW", 2, [MBI_Reg, MBI_Reg]>;
+// def CWD : TargInstr<"CWD", 2, [MBI_Reg, MBI_Reg]>;
+// def CDQ : TargInstr<"CDQ", 2, [MBI_Reg, MBI_Reg]>;
+
+def NEGr8 : TargInstr<"NEG8r", 1, [MBI_Reg]>;
+def NEGr16 : TargInstr<"NEG16r", 1, [MBI_Reg]>;
+def NEGr32 : TargInstr<"NEG32r", 1, [MBI_Reg]>;
+def NOTr8 : TargInstr<"NOT8r", 1, [MBI_Reg]>;
+def NOTr16 : TargInstr<"NOT16r", 1, [MBI_Reg]>;
+def NOTr32 : TargInstr<"NOT32r", 1, [MBI_Reg]>;
+def INCr8 : TargInstr<"INC8r", 1, [MBI_Reg]>;
+def INCr16 : TargInstr<"INC16r", 1, [MBI_Reg]>;
+def INCr32 : TargInstr<"INC32r", 1, [MBI_Reg]>;
+def DECr8 : TargInstr<"DEC8r", 1, [MBI_Reg]>;
+def DECr16 : TargInstr<"DEC16r", 1, [MBI_Reg]>;
+def DECr32 : TargInstr<"DEC32r", 1, [MBI_Reg]>;
+
+def ADDrr8 : TargInstr<"ADD8rr", 2, [MBI_Reg, MBI_Reg]>;
+def ADDrr16 : TargInstr<"ADD16rr", 2, [MBI_Reg, MBI_Reg]>;
+def ADDrr32 : TargInstr<"ADD32rr", 2, [MBI_Reg, MBI_Reg]>;
+def ADDri8 : TargInstr<"ADD8ri", 2, [MBI_Reg, MBI_ZImm]>;
+def ADDri16 : TargInstr<"ADD16ri", 2, [MBI_Reg, MBI_ZImm]>;
+def ADDri32 : TargInstr<"ADD32ri", 2, [MBI_Reg, MBI_ZImm]>;
+def ADDri16b : TargInstr<"ADD16bri", 2, [MBI_Reg, MBI_ZImm]>;
+def ADDri32b : TargInstr<"ADD32bri", 2, [MBI_Reg, MBI_ZImm]>;
+def ADCrr32 : TargInstr<"ADC32rr", 2, [MBI_Reg, MBI_Reg]>;
+def SUBrr8 : TargInstr<"SUB8rr", 2, [MBI_Reg, MBI_Reg]>;
+def SUBrr16 : TargInstr<"SUB16rr", 2, [MBI_Reg, MBI_Reg]>;
+def SUBrr32 : TargInstr<"SUB32rr", 2, [MBI_Reg, MBI_Reg]>;
+def SUBri8 : TargInstr<"SUB8ri", 2, [MBI_Reg, MBI_ZImm]>;
+def SUBri16 : TargInstr<"SUB16ri", 2, [MBI_Reg, MBI_ZImm]>;
+def SUBri32 : TargInstr<"SUB32ri", 2, [MBI_Reg, MBI_ZImm]>;
+def SUBri16b : TargInstr<"SUB16bri", 2, [MBI_Reg, MBI_ZImm]>;
+def SUBri32b : TargInstr<"SUB32bri", 2, [MBI_Reg, MBI_ZImm]>;
+def SBBrr32 : TargInstr<"SBB32rr", 2, [MBI_Reg, MBI_Reg]>;
+def IMULrr16 : TargInstr<"IMUL16rr", 2, [MBI_Reg, MBI_Reg]>;
+def IMULrr32 : TargInstr<"IMUL32rr", 2, [MBI_Reg, MBI_Reg]>;
+def IMULri16 : TargInstr<"IMUL16ri", 2, [MBI_Reg, MBI_ZImm]>;
+def IMULri32 : TargInstr<"IMUL32ri", 2, [MBI_Reg, MBI_ZImm]>;
+def IMULri16b : TargInstr<"IMUL16bri", 2, [MBI_Reg, MBI_ZImm]>;
+def IMULri32b : TargInstr<"IMUL32bri", 2, [MBI_Reg, MBI_ZImm]>;
+
+def ANDrr8 : TargInstr<"AND8rr", 2, [MBI_Reg, MBI_Reg]>;
+def ANDrr16 : TargInstr<"AND16rr", 2, [MBI_Reg, MBI_Reg]>;
+def ANDrr32 : TargInstr<"AND32rr", 2, [MBI_Reg, MBI_Reg]>;
+def ANDri8 : TargInstr<"AND8ri", 2, [MBI_Reg, MBI_ZImm]>;
+def ANDri16 : TargInstr<"AND16ri", 2, [MBI_Reg, MBI_ZImm]>;
+def ANDri32 : TargInstr<"AND32ri", 2, [MBI_Reg, MBI_ZImm]>;
+def ANDri16b : TargInstr<"AND16bri", 2, [MBI_Reg, MBI_ZImm]>;
+def ANDri32b : TargInstr<"AND32bri", 2, [MBI_Reg, MBI_ZImm]>;
+def ORrr8 : TargInstr<"OR8rr", 2, [MBI_Reg, MBI_Reg]>;
+def ORrr16 : TargInstr<"OR16rr", 2, [MBI_Reg, MBI_Reg]>;
+def ORrr32 : TargInstr<"OR32rr", 2, [MBI_Reg, MBI_Reg]>;
+def ORri8 : TargInstr<"OR8ri", 2, [MBI_Reg, MBI_ZImm]>;
+def ORri16 : TargInstr<"OR16ri", 2, [MBI_Reg, MBI_ZImm]>;
+def ORri32 : TargInstr<"OR32ri", 2, [MBI_Reg, MBI_ZImm]>;
+def ORri16b : TargInstr<"OR16bri", 2, [MBI_Reg, MBI_ZImm]>;
+def ORri32b : TargInstr<"OR32bri", 2, [MBI_Reg, MBI_ZImm]>;
+def XORrr8 : TargInstr<"XOR8rr", 2, [MBI_Reg, MBI_Reg]>;
+def XORrr16 : TargInstr<"XOR16rr", 2, [MBI_Reg, MBI_Reg]>;
+def XORrr32 : TargInstr<"XOR32rr", 2, [MBI_Reg, MBI_Reg]>;
+def XORri8 : TargInstr<"XOR8ri", 2, [MBI_Reg, MBI_ZImm]>;
+def XORri16 : TargInstr<"XOR16ri", 2, [MBI_Reg, MBI_ZImm]>;
+def XORri32 : TargInstr<"XOR32ri", 2, [MBI_Reg, MBI_ZImm]>;
+def XORri16b : TargInstr<"XOR16bri", 2, [MBI_Reg, MBI_ZImm]>;
+def XORri32b : TargInstr<"XOR32bri", 2, [MBI_Reg, MBI_ZImm]>;
+
+def TESTrr8 : TargInstr<"TEST8rr", 2, [MBI_Reg, MBI_Reg]>;
+def TESTrr16 : TargInstr<"TEST16rr", 2, [MBI_Reg, MBI_Reg]>;
+def TESTrr32 : TargInstr<"TEST32rr", 2, [MBI_Reg, MBI_Reg]>;
+def TESTri8 : TargInstr<"TEST8ri", 2, [MBI_Reg, MBI_ZImm]>;
+def TESTri16 : TargInstr<"TEST16ri", 2, [MBI_Reg, MBI_ZImm]>;
+def TESTri32 : TargInstr<"TEST32ri", 2, [MBI_Reg, MBI_ZImm]>;
+
+def SHLrr8 : TargInstr<"SHL8rr", 1, [MBI_Reg]>;
+def SHLrr16 : TargInstr<"SHL16rr", 1, [MBI_Reg]>;
+def SHLrr32 : TargInstr<"SHL32rr", 1, [MBI_Reg]>;
+def SHLir8 : TargInstr<"SHL8ir", 2, [MBI_Reg, MBI_ZImm]>;
+def SHLir16 : TargInstr<"SHL16ir", 2, [MBI_Reg, MBI_ZImm]>;
+def SHLir32 : TargInstr<"SHL32ir", 2, [MBI_Reg, MBI_ZImm]>;
+def SHRrr8 : TargInstr<"SHR8rr", 1, [MBI_Reg]>;
+def SHRrr16 : TargInstr<"SHR16rr", 1, [MBI_Reg]>;
+def SHRrr32 : TargInstr<"SHR32rr", 1, [MBI_Reg]>;
+def SHRir8 : TargInstr<"SHR8ir", 2, [MBI_Reg, MBI_ZImm]>;
+def SHRir16 : TargInstr<"SHR16ir", 2, [MBI_Reg, MBI_ZImm]>;
+def SHRir32 : TargInstr<"SHR32ir", 2, [MBI_Reg, MBI_ZImm]>;
+def SARrr8 : TargInstr<"SAR8rr", 1, [MBI_Reg]>;
+def SARrr16 : TargInstr<"SAR16rr", 1, [MBI_Reg]>;
+def SARrr32 : TargInstr<"SAR32rr", 1, [MBI_Reg]>;
+def SARir8 : TargInstr<"SAR8ir", 2, [MBI_Reg, MBI_ZImm]>;
+def SARir16 : TargInstr<"SAR16ir", 2, [MBI_Reg, MBI_ZImm]>;
+def SARir32 : TargInstr<"SAR32ir", 2, [MBI_Reg, MBI_ZImm]>;
+
+def SHLDrr32 : TargInstr<"SHLD32rr", 2, [MBI_Reg, MBI_Reg]>;
+def SHLDir32 : TargInstr<"SHLD32ir", 3, [MBI_Reg, MBI_Reg, MBI_ZImm]>;
+def SHRDrr32 : TargInstr<"SHRD32rr", 2, [MBI_Reg, MBI_Reg]>;
+def SHRDir32 : TargInstr<"SHRD32ir", 3, [MBI_Reg, MBI_Reg, MBI_ZImm]>;
+
+def SAHF : TargInstr<"SAHF", 0, []>; // store in "1" ?
+// def SETBr : TargInstr<"SETBr", 2, [MBI_Reg, MBI_Reg]>;
+// def SETAEr : TargInstr<"SETAEr", 2, [MBI_Reg, MBI_Reg]>;
+// def SETEr : TargInstr<"SETEr", 2, [MBI_Reg, MBI_Reg]>;
+def SETNEr : TargInstr<"SETNEr", 0, []>;
+// def SETBEr : TargInstr<"SETBEr", 2, [MBI_Reg, MBI_Reg]>;
+// def SETAr : TargInstr<"SETAr", 2, [MBI_Reg, MBI_Reg]>;
+// def SETSr : TargInstr<"SETSr", 2, [MBI_Reg, MBI_Reg]>;
+// def SETNSr : TargInstr<"SETNSr", 2, [MBI_Reg, MBI_Reg]>;
+// def SETLr : TargInstr<"SETLr", 2, [MBI_Reg, MBI_Reg]>;
+// def SETGEr : TargInstr<"SETGEr", 2, [MBI_Reg, MBI_Reg]>;
+// def SETLEr : TargInstr<"SETLEr", 2, [MBI_Reg, MBI_Reg]>;
+// def SETGr : TargInstr<"SETGr", 2, [MBI_Reg, MBI_Reg]>;
+def CMOVErr16 : TargInstr<"CMOVE16rr", 2, [MBI_Reg, MBI_Reg]>;
+def CMOVNErr32: TargInstr<"CMOVNE32rr", 2, [MBI_Reg, MBI_Reg]>;
+
+def CMPrr8 : TargInstr<"CMP8rr", 2, [MBI_Reg, MBI_Reg]>;
+def CMPrr16 : TargInstr<"CMP16rr", 2, [MBI_Reg, MBI_Reg]>;
+def CMPrr32 : TargInstr<"CMP32rr", 2, [MBI_Reg, MBI_Reg]>;
+def CMPri8 : TargInstr<"CMP8ri", 2, [MBI_Reg, MBI_ZImm]>;
+def CMPri16 : TargInstr<"CMP16ri", 2, [MBI_Reg, MBI_ZImm]>;
+def CMPri32 : TargInstr<"CMP32ri", 2, [MBI_Reg, MBI_ZImm]>;
+
+def MOVSXr16r8 : TargInstr<"MOVSX16rr8", 1, [MBI_Reg]>;
+def MOVSXr32r8 : TargInstr<"MOVSX32rr8", 1, [MBI_Reg]>;
+def MOVSXr32r16: TargInstr<"MOVSX32rr16", 1, [MBI_Reg]>;
+def MOVZXr16r8 : TargInstr<"MOVZX16rr8", 1, [MBI_Reg]>;
+def MOVZXr32r8 : TargInstr<"MOVZX32rr8", 1, [MBI_Reg]>;
+def MOVZXr32r16: TargInstr<"MOVZX32rr16", 1, [MBI_Reg]>;
+
+def FP_REG_KILL : TargInstr<"FP_REG_KILL",0, []>;
+
+def FpMOV : TargInstr<"FpMOV", 1, [MBI_Reg]>;
+def FpADD : TargInstr<"FpADD", 2, [MBI_Reg, MBI_Reg]>;
+def FpSUB : TargInstr<"FpSUB", 2, [MBI_Reg, MBI_Reg]>;
+def FpMUL : TargInstr<"FpMUL", 2, [MBI_Reg, MBI_Reg]>;
+def FpDIV : TargInstr<"FpDIV", 2, [MBI_Reg, MBI_Reg]>;
+def FpUCOM : TargInstr<"FpUCOM", 2, [MBI_Reg, MBI_Reg]>;
+// def FpGETRESULT : TargInstr<"FpGETRESULT", 2, [MBI_Reg, MBI_Reg]>;
+def FpSETRESULT : TargInstr<"FpSETRESULT", 1, [MBI_Reg]>;
+// def FLDrr : TargInstr<"FLDrr", 2, [MBI_Reg, MBI_Reg]>;
+def FLDr32 : TargInstr<"FLD32r", 1, [MBI_ConstPoolRef]>; // MBI_FrameRef also? instructions can be passed different operands
+def FLDr64 : TargInstr<"FLD64r", 1, [MBI_ConstPoolRef]>;
+// def FLDr80 : TargInstr<"FLDr80", 2, [MBI_Reg, MBI_Reg]>;
+def FILDr16 : TargInstr<"FILD16r", 5, [MBI_FrameRef]>;
+def FILDr32 : TargInstr<"FILD32r", 5, [MBI_FrameRef]>;
+def FILDr64 : TargInstr<"FILD64r", 5, [MBI_FrameRef]>;
+def FSTr32 : TargInstr<"FST32r", 5, [MBI_FrameRef, MBI_Reg]>; // ?
+// def FSTr64 : TargInstr<"FST64r", 2, [MBI_Reg, MBI_Reg]>;
+// def FSTPr32 : TargInstr<"FSTP32r", 2, [MBI_Reg, MBI_Reg]>;
+// def FSTPr64 : TargInstr<"FSTP64r", 2, [MBI_Reg, MBI_Reg]>;
+// def FSTPr80 : TargInstr<"FSTP80r", 2, [MBI_Reg, MBI_Reg]>;
+// def FSTrr : TargInstr<"FSTrr", 2, [MBI_Reg, MBI_Reg]>;
+// def FSTPrr : TargInstr<"FSTPrr", 2, [MBI_Reg, MBI_Reg]>;
+def FISTr16 : TargInstr<"FIST16r", 5, [MBI_FrameRef, MBI_Reg]>;
+def FISTr32 : TargInstr<"FIST32r", 5, [MBI_FrameRef, MBI_Reg]>;
+// def FISTPr16 : TargInstr<"FISTP16r", 2, [MBI_Reg, MBI_Reg]>;
+// def FISTPr32 : TargInstr<"FISTP32r", 2, [MBI_Reg, MBI_Reg]>;
+def FISTPr64 : TargInstr<"FISTP64r", 5, [MBI_FrameRef, MBI_Reg]>;
+// def FXCH : TargInstr<"FXCH", 2, [MBI_Reg, MBI_Reg]>;
+def FLD0 : TargInstr<"FLD0", 0, []>;
+def FLD1 : TargInstr<"FLD1", 0, []>;
+// def FADDST0r : TargInstr<"FADDST0r", 2, [MBI_Reg, MBI_Reg]>;
+// def FADDrST0 : TargInstr<"FADDrST0", 2, [MBI_Reg, MBI_Reg]>;
+// def FADDPrST0 : TargInstr<"FADDPrST0", 2, [MBI_Reg, MBI_Reg]>;
+// def FSUBRST0r : TargInstr<"FSUBRST0r", 2, [MBI_Reg, MBI_Reg]>;
+// def FSUBrST0 : TargInstr<"FSUBrST0", 2, [MBI_Reg, MBI_Reg]>;
+// def FSUBPrST0 : TargInstr<"FSUBPrST0", 2, [MBI_Reg, MBI_Reg]>;
+// def FSUBST0r : TargInstr<"FSUBST0r", 2, [MBI_Reg, MBI_Reg]>;
+// def FSUBRrST0 : TargInstr<"FSUBRrST0", 2, [MBI_Reg, MBI_Reg]>;
+// def FSUBRPrST0 : TargInstr<"FSUBRPrST0", 2, [MBI_Reg, MBI_Reg]>;
+// def FMULST0r : TargInstr<"FMULST0r", 2, [MBI_Reg, MBI_Reg]>;
+// def FMULrST0 : TargInstr<"FMULrST0", 2, [MBI_Reg, MBI_Reg]>;
+// def FMULPrST0 : TargInstr<"FMULPrST0", 2, [MBI_Reg, MBI_Reg]>;
+// def FDIVRST0r : TargInstr<"FDIVRST0r", 2, [MBI_Reg, MBI_Reg]>;
+// def FDIVrST0 : TargInstr<"FDIVrST0", 2, [MBI_Reg, MBI_Reg]>;
+// def FDIVPrST0 : TargInstr<"FDIVPrST0", 2, [MBI_Reg, MBI_Reg]>;
+// def FDIVST0r : TargInstr<"FDIVST0r", 2, [MBI_Reg, MBI_Reg]>;
+// def FDIVRrST0 : TargInstr<"FDIVRrST0", 2, [MBI_Reg, MBI_Reg]>;
+// def FDIVRPrST0 : TargInstr<"FDIVRPrST0", 2, [MBI_Reg, MBI_Reg]>;
+// def FUCOMr : TargInstr<"FUCOMr", 2, [MBI_Reg, MBI_Reg]>;
+// def FUCOMPr : TargInstr<"FUCOMPr", 2, [MBI_Reg, MBI_Reg]>;
+// def FUCOMPPr : TargInstr<"FUCOMPPr", 2, [MBI_Reg, MBI_Reg]>;
+def FNSTSWr8 : TargInstr<"FNSTSWr8", 0, []>; // store in "0" ?
+// def FNSTCWm16 : TargInstr<"FNSTCWm16", 2, [MBI_Reg, MBI_Reg]>;
+def FLDCWm16 : TargInstr<"FLDCWm16", 4, [MBI_FrameRef]>;
+
+} //namespace
diff --git a/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp
index 31c5e57..0d9a0d6 100644
--- a/lib/Target/X86/X86TargetMachine.cpp
+++ b/lib/Target/X86/X86TargetMachine.cpp
@@ -33,6 +33,8 @@
cl::opt<bool> DisableOutput("disable-x86-llc-output", cl::Hidden,
cl::desc("Disable the X86 asm printer, for use "
"when profiling the code generator."));
+ cl::opt<bool> NoSimpleISel("disable-simple-isel", cl::init(true),
+ cl::desc("Use the hand coded 'simple' X86 instruction selector"));
}
// allocateX86TargetMachine - Allocate and return a subclass of TargetMachine
@@ -67,8 +69,10 @@
// FIXME: Implement the switch instruction in the instruction selector!
PM.add(createLowerSwitchPass());
- if (NoPatternISel)
+ if (NoPatternISel && NoSimpleISel)
PM.add(createX86SimpleInstructionSelector(*this));
+ else if (NoPatternISel)
+ PM.add(createX86ReallySimpleInstructionSelector(*this));
else
PM.add(createX86PatternInstructionSelector(*this));