From 0a8fd30c1bb4f324a9bca9b7b7c0efb0fa341112 Mon Sep 17 00:00:00 2001 From: Jakub Staszak Date: Tue, 6 Apr 2004 19:34:00 +0000 Subject: [PATCH] Tablgen files for really simple instruction selector git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12714 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/Makefile | 9 +- lib/Target/X86/X86.h | 6 + lib/Target/X86/X86InstrSel.td | 393 ++++++++++++++++++++++++++++ lib/Target/X86/X86InstrSelInfo.td | 241 +++++++++++++++++ lib/Target/X86/X86TargetMachine.cpp | 6 +- 5 files changed, 653 insertions(+), 2 deletions(-) create mode 100644 lib/Target/X86/X86InstrSel.td create mode 100644 lib/Target/X86/X86InstrSelInfo.td diff --git a/lib/Target/X86/Makefile b/lib/Target/X86/Makefile index b151fa7ecf7..896feae08dd 100644 --- a/lib/Target/X86/Makefile +++ b/lib/Target/X86/Makefile @@ -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 diff --git a/lib/Target/X86/X86.h b/lib/Target/X86/X86.h index 54e2861a5f6..fde6bc61081 100644 --- a/lib/Target/X86/X86.h +++ b/lib/Target/X86/X86.h @@ -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 index 00000000000..479e1c0d05e --- /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 Value = v; +} + +// provide a grouping of InstrSubclasses +class InstrSubclassCollection l> { + list 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 l> { + string FunctionName = fn; + string InstructionName = n; + string PreCode = pre; + string PostCode = post; + + // add lists of what subclasses this InstrClass supports + list Supports = l; +} + + +// helper class to build BMI instruction +class addedOperand { + 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 lops> { + + string Name = n; // make this a reference to the Instruction class + string Namespace; + int NumOperands = numops; + list 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 l, list targs, list> r> { + InstrClass Class = c; + + list List = l; + list Instructions = targs; + list< list > 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; +def ADD_Other_cShort : TargInstrSet; +def ADD_Other_cInt : TargInstrSet; +def ADD_Other_cLong : TargInstrSet; +def ADD_Other_cFP : TargInstrSet; +def ADD_Constant_cByte : TargInstrSet; +def ADD_Constant_cShort :TargInstrSet; +def ADD_Constant_cInt :TargInstrSet; +def ADD_PosOne_cByte : TargInstrSet; +def ADD_PosOne_cShort : TargInstrSet; +def ADD_PosOne_cInt : TargInstrSet; +def ADD_NegOne_cByte : TargInstrSet; +def ADD_NegOne_cShort : TargInstrSet; +def ADD_NegOne_cInt : TargInstrSet; + + +// SUBTRACT + +def SUB_Other_cByte : TargInstrSet; +def SUB_Other_cShort : TargInstrSet; +def SUB_Other_cInt : TargInstrSet; +def SUB_Other_cLong : TargInstrSet; +def SUB_Other_cFP : TargInstrSet; +def SUB_Constant_cByte : TargInstrSet; +def SUB_Constant_cShort :TargInstrSet; +def SUB_Constant_cInt :TargInstrSet; +def SUB_PosOne_cByte : TargInstrSet; +def SUB_PosOne_cShort : TargInstrSet; +def SUB_PosOne_cInt : TargInstrSet; +def SUB_NegOne_cByte : TargInstrSet; +def SUB_NegOne_cShort : TargInstrSet; +def SUB_NegOne_cInt : TargInstrSet; + + +// 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; +// def CMP_i_Short : TargInstrSet; +// def CMP_i_Int : TargInstrSet; +// //def CMP_i_Long : // not supported +// def CMP_z_Byte : TargInstrSet(Op1); uint64_t Op1v = cast(CI)->getRawValue(); Op1v &= (1ULL << (8 << Class)) - 1;","",[Zero,cByte],[TESTrr8],[["DestReg","Op0Reg","Op0Reg"]]>; +// def CMP_z_Short : TargInstrSet(Op1); uint64_t Op1v = cast(CI)->getRawValue(); Op1v &= (1ULL << (8 << Class)) - 1;","",[Zero,cShort],[TESTrr16],[["DestReg","Op0Reg","Op0Reg"]]>; +// def CMP_z_Int : TargInstrSet(Op1); uint64_t Op1v = cast(CI)->getRawValue(); Op1v &= (1ULL << (8 << Class)) - 1;","",[Zero,cInt],[TESTrr32],[["DestReg","Op0Reg","Op0Reg"]]>; +// //def CMP_z_Long : // not supported +// def CMP_r_Byte : TargInstrSet; +// def CMP_r_Short : TargInstrSet; +// def CMP_r_Int : TargInstrSet; +// //def CMP_r_Long : // two cases of long, depending on num of operands +// def CMP_r_FP : TargInstrSet; + + +// def RET_NoOps : TargInstrSet; +// def RET_Op_Byte : TargInstrSetgetType()));","",[Ops,cByte],[IMPLICIT_USE],[["NullReg","EAX","ESP"]]>; +// def RET_Op_Short : TargInstrSetgetType()));","",[Ops,cShort],[IMPLICIT_USE],[["NullReg","EAX","ESP"]]>; +// def RET_Op_Int : TargInstrSetgetType()));","",[Ops,cInt],[IMPLICIT_USE],[["NullReg","EAX","ESP"]]>; +// def RET_Op_FP : TargInstrSet; +// def RET_Op_Long : TargInstrSet; + + +// def BR_Uncond : TargInstrSet; +// 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; +def AND_Short : TargInstrSet; +def AND_Int : TargInstrSet; +def AND_Long : TargInstrSet; + + +def OR_Byte : TargInstrSet; +def OR_Short : TargInstrSet; +def OR_Int : TargInstrSet; +def OR_Long : TargInstrSet; + + +def XOR_NegOne_Byte : TargInstrSet; +def XOR_NegOne_Short: TargInstrSet; +def XOR_NegOne_Int : TargInstrSet; +//def XOR_NegOne_Long : // not supported (treat as regular long XOR) +def XOR_Other_Byte : TargInstrSet; +def XOR_Other_Short : TargInstrSet; +def XOR_Other_Int : TargInstrSet; +def XOR_Other_Long : TargInstrSet; + + + +// // TODO support for arbitrary values as operand arguments +// // or make ConstantInt versions as well-known variables +// // ConstantInt, unsigned Val +// def MUL_ConstTwo_Byte : TargInstrSet(I.getOperand(1)); unsigned Val = (unsigned)CI->getRawValue(); unsigned Shift = ExactLog2(Val);","",[ConstTwo,cByte],[SHLir32],[["DestReg","Op0Reg","Shift-1"]]>; +// def MUL_ConstTwo_Short : TargInstrSet(I.getOperand(1)); unsigned Val = (unsigned)CI->getRawValue(); unsigned Shift = ExactLog2(Val);","",[ConstTwo,cShort],[SHLir32],[["DestReg","Op0Reg","Shift-1"]]>; +// def MUL_ConstTwo_Int : TargInstrSet(I.getOperand(1)); unsigned Val = (unsigned)CI->getRawValue(); unsigned Shift = ExactLog2(Val);","",[ConstTwo,cInt],[SHLir32],[["DestReg","Op0Reg","Shift-1"]]>; +// def MUL_ConstNotTwo_Byte : TargInstrSet; //TODO fixme, define ConstRHS +// def MUL_ConstNotTwo_Short : TargInstrSet; +// def MUL_ConstNotTwo_Int : TargInstrSet; +// //def MUL_ConstNotTwo_Long : +// //def MUL_ConstNotTwo_FP : +// def MUL_Reg_Byte : TargInstrSet; +// def MUL_Reg_Short : TargInstrSet; +// def MUL_Reg_Int : TargInstrSet; +// //def MUL_Reg_Long : // not supported (assert) +// def MUL_Reg_FP : TargInstrSet; + +// 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 00000000000..f4935fcb8c9 --- /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 31c5e578ea1..0d9a0d6e40e 100644 --- a/lib/Target/X86/X86TargetMachine.cpp +++ b/lib/Target/X86/X86TargetMachine.cpp @@ -33,6 +33,8 @@ namespace { cl::opt DisableOutput("disable-x86-llc-output", cl::Hidden, cl::desc("Disable the X86 asm printer, for use " "when profiling the code generator.")); + cl::opt 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)); -- 2.34.1