Tablgen files for really simple instruction selector
authorJakub Staszak <kuba@gcc.gnu.org>
Tue, 6 Apr 2004 19:34:00 +0000 (19:34 +0000)
committerJakub Staszak <kuba@gcc.gnu.org>
Tue, 6 Apr 2004 19:34:00 +0000 (19:34 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12714 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/Makefile
lib/Target/X86/X86.h
lib/Target/X86/X86InstrSel.td [new file with mode: 0644]
lib/Target/X86/X86InstrSelInfo.td [new file with mode: 0644]
lib/Target/X86/X86TargetMachine.cpp

index b151fa7ecf71d9b8c4f431eb64b3b0fdd92fe711..896feae08dd55f3f3f03f93cf1d9ebf23f79e0e9 100644 (file)
@@ -13,7 +13,8 @@ include $(LEVEL)/Makefile.common
 # 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 @@ X86GenInstrInfo.inc:: $(SourceDir)/X86.td $(SourceDir)/X86InstrInfo.td \
        @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
index 54e2861a5f6e8d173029b5671d748f8bb7ba22c5..fde6bc61081efab61079cf18fddcdca2347bc99e 100644 (file)
@@ -29,6 +29,12 @@ class IntrinsicLowering;
 ///
 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 (file)
index 0000000..479e1c0
--- /dev/null
@@ -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 (file)
index 0000000..f4935fc
--- /dev/null
@@ -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
index 31c5e578ea1d755b9b3a6215fc94908ae099a472..0d9a0d6e40eafd79339cbd185232a093e73ad2ee 100644 (file)
@@ -33,6 +33,8 @@ namespace {
   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 @@ bool X86TargetMachine::addPassesToEmitAssembly(PassManager &PM,
   // 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));