X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FTarget.td;h=bdaa05bf518e8ee8ec249bd7143d99d8e31984e9;hb=f311e8b901bbaa2d4749d257461866861501edf2;hp=546eeec3c4c490966f959c2b0bf0a2e342845121;hpb=76bf868ff31ea6424bb4e8f774b0d76ef3f6cade;p=oota-llvm.git diff --git a/lib/Target/Target.td b/lib/Target/Target.td index 546eeec3c4c..bdaa05bf518 100644 --- a/lib/Target/Target.td +++ b/lib/Target/Target.td @@ -1,4 +1,11 @@ -//===- Target.td - Target Independent TableGen interface --------*- C++ -*-===// +//===- Target.td - Target Independent TableGen interface ---*- tablegen -*-===// +// +// 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 defines the target-independent interfaces which should be // implemented by each target which is using a TableGen based code generator. @@ -9,50 +16,62 @@ //===----------------------------------------------------------------------===// // // Value types - These values correspond to the register types defined in the -// ValueTypes.h file. +// ValueTypes.h file. If you update anything here, you must update it there as +// well! // -class ValueType { string Namespace = "MVT"; int Size = size; } - -def i1 : ValueType<1>; // One bit boolean value -def i8 : ValueType<8>; // 8-bit integer value -def i16 : ValueType<16>; // 16-bit integer value -def i32 : ValueType<32>; // 32-bit integer value -def i64 : ValueType<64>; // 64-bit integer value -def i128 : ValueType<128>; // 128-bit integer value -def f32 : ValueType<32>; // 32-bit floating point value -def f64 : ValueType<64>; // 64-bit floating point value -def f80 : ValueType<80>; // 80-bit floating point value -def f128 : ValueType<128>; // 128-bit floating point value +class ValueType { + string Namespace = "MVT"; + int Size = size; + int Value = value; +} +def OtherVT: ValueType<0 , 0>; // "Other" value +def i1 : ValueType<1 , 1>; // One bit boolean value +def i8 : ValueType<8 , 2>; // 8-bit integer value +def i16 : ValueType<16 , 3>; // 16-bit integer value +def i32 : ValueType<32 , 4>; // 32-bit integer value +def i64 : ValueType<64 , 5>; // 64-bit integer value +def i128 : ValueType<128, 5>; // 128-bit integer value +def f32 : ValueType<32 , 7>; // 32-bit floating point value +def f64 : ValueType<64 , 8>; // 64-bit floating point value +def f80 : ValueType<80 , 9>; // 80-bit floating point value +def f128 : ValueType<128, 9>; // 128-bit floating point value +def isVoid : ValueType<0 , 11>; // Produces no value //===----------------------------------------------------------------------===// // Register file description - These classes are used to fill in the target // description classes in llvm/Target/MRegisterInfo.h -// Register - You should define one instance of this class for each register in -// the target machine. -// -class Register { +// Register - You should define one instance of this class for each register +// in the target machine. String n will become the "name" of the register. +class RegisterBase { string Namespace = ""; - string Name = ""; + string Name = n; + + // SpillSize - If this value is set to a non-zero value, it is the size in + // bits of the spill slot required to hold this register. If this value is + // set to zero, the information is inferred from any register classes the + // register belongs to. + int SpillSize = 0; + + // SpillAlignment - This value is used to specify the alignment required for + // spilling the register. Like SpillSize, this should only be explicitly + // specified if the register is not in a register class. + int SpillAlignment = 0; } -// NamedReg - If the name for the 'def' of the register should not become the -// "name" of the register, you can use this to specify a custom name instead. -// -class NamedReg : Register { - set Name = n; +class Register : RegisterBase { + list Aliases = []; } -// RegisterAliases - You should define instances of this class to indicate which -// registers in the register file are aliased together. This allows the code -// generator to be careful not to put two values with overlapping live ranges -// into registers which alias. -// -class RegisterAliases aliases> { - Register Reg = reg; - list Aliases = aliases; +// RegisterGroup - This can be used to define instances of Register which +// need to specify aliases. +// List "aliases" specifies which registers are aliased to this one. This +// allows the code generator to be careful not to put two values with +// overlapping live ranges into registers which alias. +class RegisterGroup aliases> : Register { + let Aliases = aliases; } // RegisterClass - Now that all of the registers are defined, and aliases @@ -88,29 +107,64 @@ class RegisterClass regList> { // Instruction set description - These classes correspond to the C++ classes in // the Target/TargetInstrInfo.h file. // - class Instruction { - string Name; // The opcode string for this instruction + string Name = ""; // The opcode string for this instruction string Namespace = ""; - list Uses = []; // Default to using no non-operand registers - list Defs = []; // Default to modifying no non-operand registers + dag OperandList; // An dag containing the MI operand list. + string AsmString = ""; // The .s format to print the instruction with. + + // Pattern - Set to the DAG pattern for this instruction, if we know of one, + // otherwise, uninitialized. + list Pattern; + + // The follow state will eventually be inferred automatically from the + // instruction pattern. + + list Uses = []; // Default to using no non-operand registers + list Defs = []; // Default to modifying no non-operand registers // These bits capture information about the high-level semantics of the // instruction. bit isReturn = 0; // Is this instruction a return instruction? bit isBranch = 0; // Is this instruction a branch instruction? + bit isBarrier = 0; // Can control flow fall through this instruction? bit isCall = 0; // Is this instruction a call instruction? + bit isLoad = 0; // Is this instruction a load instruction? + bit isStore = 0; // Is this instruction a store instruction? bit isTwoAddress = 0; // Is this a two address instruction? + bit isConvertibleToThreeAddress = 0; // Can this 2-addr instruction promote? + bit isCommutable = 0; // Is this 3 operand instruction commutable? bit isTerminator = 0; // Is this part of the terminator for a basic block? + bit hasDelaySlot = 0; // Does this instruction have an delay slot? } + +/// ops definition - This is just a simple marker used to identify the operands +/// list for an instruction. This should be used like this: +/// (ops R32:$dst, R32:$src) or something similar. +def ops; + +/// Operand Types - These provide the built-in operand types that may be used +/// by a target. Targets can optionally provide their own operand types as +/// needed, though this should not be needed for RISC targets. +class Operand { + int NumMIOperands = 1; + ValueType Type = ty; + string PrintMethod = "printOperand"; +} + +def i1imm : Operand; +def i8imm : Operand; +def i16imm : Operand; +def i32imm : Operand; +def i64imm : Operand; + // InstrInfo - This class should only be instantiated once to provide parameters // which are global to the the target machine. // class InstrInfo { Instruction PHIInst; - Instruction NOOPInst; // If the target wants to associate some target-specific information with each // instruction, it should provide these two lists to indicate how to assemble @@ -118,7 +172,40 @@ class InstrInfo { // list TSFlagsFields = []; list TSFlagsShifts = []; + + // Target can specify its instructions in either big or little-endian formats. + // For instance, while both Sparc and PowerPC are big-endian platforms, the + // Sparc manual specifies its instructions in the format [31..0] (big), while + // PowerPC specifies them using the format [0..31] (little). + bit isLittleEndianEncoding = 0; +} + +//===----------------------------------------------------------------------===// +// AsmWriter - This class can be implemented by targets that need to customize +// the format of the .s file writer. +// +// Subtargets can have multiple different asmwriters (e.g. AT&T vs Intel syntax +// on X86 for example). +// +class AsmWriter { + // AsmWriterClassName - This specifies the suffix to use for the asmwriter + // class. Generated AsmWriter classes are always prefixed with the target + // name. + string AsmWriterClassName = "AsmPrinter"; + + // InstFormatName - AsmWriters can specify the name of the format string to + // print instructions with. + string InstFormatName = "AsmString"; + + // Variant - AsmWriters can be of multiple different variants. Variants are + // used to support targets that need to emit assembly code in ways that are + // mostly the same for different targets, but have minor differences in + // syntax. If the asmstring contains {|} characters in them, this integer + // will specify which alternative to use. For example "{x|y|z}" with Variant + // == 1, will expand to "y". + int Variant = 0; } +def DefaultAsmWriter : AsmWriter; //===----------------------------------------------------------------------===// @@ -133,6 +220,101 @@ class Target { // this target. Typically this is an i32 or i64 type. ValueType PointerType; - // InstructionSet - Instruction set description for this target + // InstructionSet - Instruction set description for this target. InstrInfo InstructionSet; + + // AssemblyWriters - The AsmWriter instances available for this target. + list AssemblyWriters = [DefaultAsmWriter]; +} + + +//===----------------------------------------------------------------------===// +// DAG node definitions used by the instruction selector. +// +// NOTE: all of this is a work-in-progress and should be ignored for now. +// +/* +class Expander result> { + dag Pattern = pattern; + list Result = result; } + +class DagNodeValType; +def DNVT_any : DagNodeValType; // No constraint on tree node +def DNVT_void : DagNodeValType; // Tree node always returns void +def DNVT_val : DagNodeValType; // A non-void type +def DNVT_arg0 : DagNodeValType; // Tree node returns same type as Arg0 +def DNVT_arg1 : DagNodeValType; // Tree node returns same type as Arg1 +def DNVT_ptr : DagNodeValType; // The target pointer type +def DNVT_i8 : DagNodeValType; // Always have an i8 value + +class DagNode args> { + DagNodeValType RetType = ret; + list ArgTypes = args; + string EnumName = ?; +} + +// BuiltinDagNodes are built into the instruction selector and correspond to +// enum values. +class BuiltinDagNode Args, + string Ename> : DagNode { + let EnumName = Ename; +} + +// Magic nodes... +def Void : RegisterClass { let isDummyClass = 1; } +def set : DagNode; +def chain : BuiltinDagNode; +def blockchain : BuiltinDagNode; +def ChainExpander : Expander<(chain Void, Void), []>; +def BlockChainExpander : Expander<(blockchain Void, Void), []>; + + +// Terminals... +def imm : BuiltinDagNode; +def frameidx : BuiltinDagNode; +def basicblock : BuiltinDagNode; + +// Arithmetic... +def plus : BuiltinDagNode; +def minus : BuiltinDagNode; +def times : BuiltinDagNode; +def sdiv : BuiltinDagNode; +def udiv : BuiltinDagNode; +def srem : BuiltinDagNode; +def urem : BuiltinDagNode; +def and : BuiltinDagNode; +def or : BuiltinDagNode; +def xor : BuiltinDagNode; + +// Comparisons... +def seteq : BuiltinDagNode; +def setne : BuiltinDagNode; +def setlt : BuiltinDagNode; +def setle : BuiltinDagNode; +def setgt : BuiltinDagNode; +def setge : BuiltinDagNode; + +def load : BuiltinDagNode; +//def store : BuiltinDagNode; + +// Other... +def ret : BuiltinDagNode; +def retvoid : BuiltinDagNode; +def br : BuiltinDagNode; +def brcond : BuiltinDagNode; + +def unspec1 : BuiltinDagNode; +def unspec2 : BuiltinDagNode; + +//===----------------------------------------------------------------------===// +// DAG nonterminals definitions used by the instruction selector... +// +class Nonterminal { + dag Pattern = pattern; + bit BuiltIn = 0; +} + +*/