1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
//===- Target.td - Target Independent TableGen interface --------*- 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 defines the target-independent interfaces which should be
// implemented by each target which is using a TableGen based code generator.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
//
// Value types - These values correspond to the register types defined in the
// ValueTypes.h file. If you update anything here, you must update it there as
// well!
//
class ValueType<int size, int value> {
string Namespace = "MVT";
int Size = size;
int Value = 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 {
string Namespace = "";
string Name = "";
}
// 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<string n> : Register {
let Name = n;
}
// 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<Register reg, list<Register> aliases> {
Register Reg = reg;
list<Register> Aliases = aliases;
}
// RegisterClass - Now that all of the registers are defined, and aliases
// between registers are defined, specify which registers belong to which
// register classes. This also defines the default allocation order of
// registers by register allocators.
//
class RegisterClass<ValueType regType, int alignment, list<Register> regList> {
// RegType - Specify the ValueType of the registers in this register class.
// Note that all registers in a register class must have the same ValueType.
//
ValueType RegType = regType;
// Alignment - Specify the alignment required of the registers when they are
// stored or loaded to memory.
//
int Size = RegType.Size;
int Alignment = alignment;
// MemberList - Specify which registers are in this class. If the
// allocation_order_* method are not specified, this also defines the order of
// allocation used by the register allocator.
//
list<Register> MemberList = regList;
// Methods - This member can be used to insert arbitrary code into a generated
// register class. The normal usage of this is to overload virtual methods.
code Methods = [{}];
// isDummyClass - If this is set to true, this register class is not really
// part of the target, it is just used for other purposes.
bit isDummyClass = 0;
}
//===----------------------------------------------------------------------===//
// 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 Namespace = "";
list<Register> Uses = []; // Default to using no non-operand registers
list<Register> 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 isCall = 0; // Is this instruction a call instruction?
bit isTwoAddress = 0; // Is this a two address instruction?
bit isTerminator = 0; // Is this part of the terminator for a basic block?
// Pattern - Set to the DAG pattern for this instruction, if we know of one,
// otherwise, uninitialized.
dag Pattern;
}
class Expander<dag pattern, list<dag> result> {
dag Pattern = pattern;
list<dag> Result = result;
}
// InstrInfo - This class should only be instantiated once to provide parameters
// which are global to the the target machine.
//
class InstrInfo {
Instruction PHIInst;
// If the target wants to associate some target-specific information with each
// instruction, it should provide these two lists to indicate how to assemble
// the target specific information into the 32 bits available.
//
list<string> TSFlagsFields = [];
list<int> TSFlagsShifts = [];
}
//===----------------------------------------------------------------------===//
// Target - This class contains the "global" target information
//
class Target {
// CalleeSavedRegisters - As you might guess, this is a list of the callee
// saved registers for a target.
list<Register> CalleeSavedRegisters = [];
// PointerType - Specify the value type to be used to represent pointers in
// this target. Typically this is an i32 or i64 type.
ValueType PointerType;
// InstructionSet - Instruction set description for this target
InstrInfo InstructionSet;
}
//===----------------------------------------------------------------------===//
// DAG node definitions used by the instruction selector...
//
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<DagNodeValType ret, list<DagNodeValType> args> {
DagNodeValType RetType = ret;
list<DagNodeValType> ArgTypes = args;
string EnumName = ?;
}
// BuiltinDagNodes are built into the instruction selector and correspond to
// enum values.
class BuiltinDagNode<DagNodeValType Ret, list<DagNodeValType> Args,
string Ename> : DagNode<Ret, Args> {
let EnumName = Ename;
}
// Magic nodes...
def Void : RegisterClass<isVoid,0,[]> { let isDummyClass = 1; }
def set : DagNode<DNVT_void, [DNVT_val, DNVT_arg0]>;
def chain : BuiltinDagNode<DNVT_void, [DNVT_void, DNVT_void], "ChainNode">;
def blockchain : BuiltinDagNode<DNVT_void, [DNVT_void, DNVT_void],
"BlockChainNode">;
def ChainExpander : Expander<(chain Void, Void), []>;
def BlockChainExpander : Expander<(blockchain Void, Void), []>;
// Terminals...
def imm : BuiltinDagNode<DNVT_val, [], "Constant">;
def frameidx : BuiltinDagNode<DNVT_ptr, [], "FrameIndex">;
def basicblock : BuiltinDagNode<DNVT_ptr, [], "BasicBlock">;
// Arithmetic...
def plus : BuiltinDagNode<DNVT_arg0, [DNVT_arg1, DNVT_arg0], "Plus">;
def minus : BuiltinDagNode<DNVT_arg0, [DNVT_arg1, DNVT_arg0], "Minus">;
def times : BuiltinDagNode<DNVT_arg0, [DNVT_arg1, DNVT_arg0], "Times">;
def sdiv : BuiltinDagNode<DNVT_arg0, [DNVT_arg1, DNVT_arg0], "SDiv">;
def udiv : BuiltinDagNode<DNVT_arg0, [DNVT_arg1, DNVT_arg0], "UDiv">;
def srem : BuiltinDagNode<DNVT_arg0, [DNVT_arg1, DNVT_arg0], "SRem">;
def urem : BuiltinDagNode<DNVT_arg0, [DNVT_arg1, DNVT_arg0], "URem">;
def and : BuiltinDagNode<DNVT_arg0, [DNVT_arg1, DNVT_arg0], "And">;
def or : BuiltinDagNode<DNVT_arg0, [DNVT_arg1, DNVT_arg0], "Or">;
def xor : BuiltinDagNode<DNVT_arg0, [DNVT_arg1, DNVT_arg0], "Xor">;
// Comparisons...
def seteq : BuiltinDagNode<DNVT_i8 , [DNVT_arg1, DNVT_arg0], "SetEQ">;
def setne : BuiltinDagNode<DNVT_i8 , [DNVT_arg1, DNVT_arg0], "SetNE">;
def setlt : BuiltinDagNode<DNVT_i8 , [DNVT_arg1, DNVT_arg0], "SetLT">;
def setle : BuiltinDagNode<DNVT_i8 , [DNVT_arg1, DNVT_arg0], "SetLE">;
def setgt : BuiltinDagNode<DNVT_i8 , [DNVT_arg1, DNVT_arg0], "SetGT">;
def setge : BuiltinDagNode<DNVT_i8 , [DNVT_arg1, DNVT_arg0], "SetGE">;
def load : BuiltinDagNode<DNVT_val, [DNVT_ptr], "Load">;
//def store : BuiltinDagNode<DNVT_Void, [DNVT_ptr, DNVT_val]>;
// Other...
def ret : BuiltinDagNode<DNVT_void, [DNVT_val], "Ret">;
def retvoid : BuiltinDagNode<DNVT_void, [], "RetVoid">;
def br : BuiltinDagNode<DNVT_void, [DNVT_ptr], "Br">;
def brcond : BuiltinDagNode<DNVT_void, [DNVT_i8, DNVT_ptr, DNVT_ptr],
"BrCond">;
def unspec1 : BuiltinDagNode<DNVT_any , [DNVT_val], "Unspec1">;
def unspec2 : BuiltinDagNode<DNVT_any , [DNVT_val, DNVT_val], "Unspec2">;
//===----------------------------------------------------------------------===//
// DAG nonterminals definitions used by the instruction selector...
//
class Nonterminal<dag pattern> {
dag Pattern = pattern;
bit BuiltIn = 0;
}
|