1//===-- Hexagon.td - Describe the Hexagon Target Machine --*- tablegen -*--===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This is the top level entry point for the Hexagon target.
10//
11//===----------------------------------------------------------------------===//
12
13//===----------------------------------------------------------------------===//
14// Target-independent interfaces which we are implementing
15//===----------------------------------------------------------------------===//
16
17include "llvm/Target/Target.td"
18
19//===----------------------------------------------------------------------===//
20// Hexagon Subtarget features.
21//===----------------------------------------------------------------------===//
22
23// Hexagon Architectures
24include "HexagonDepArch.td"
25
26def ProcTinyCore: SubtargetFeature<"tinycore", "HexagonProcFamily",
27      "TinyCore", "Hexagon Tiny Core">;
28
29// Hexagon ISA Extensions
30def ExtensionZReg: SubtargetFeature<"zreg", "UseZRegOps", "true",
31      "Hexagon ZReg extension instructions">;
32
33def ExtensionHVX: SubtargetFeature<"hvx", "HexagonHVXVersion",
34      "Hexagon::ArchEnum::V60", "Hexagon HVX instructions">;
35def ExtensionHVXV60: SubtargetFeature<"hvxv60", "HexagonHVXVersion",
36      "Hexagon::ArchEnum::V60", "Hexagon HVX instructions",
37      [ExtensionHVX]>;
38def ExtensionHVXV62: SubtargetFeature<"hvxv62", "HexagonHVXVersion",
39      "Hexagon::ArchEnum::V62", "Hexagon HVX instructions",
40      [ExtensionHVX, ExtensionHVXV60]>;
41def ExtensionHVXV65: SubtargetFeature<"hvxv65", "HexagonHVXVersion",
42      "Hexagon::ArchEnum::V65", "Hexagon HVX instructions",
43      [ExtensionHVX, ExtensionHVXV60, ExtensionHVXV62]>;
44def ExtensionHVXV66: SubtargetFeature<"hvxv66", "HexagonHVXVersion",
45      "Hexagon::ArchEnum::V66", "Hexagon HVX instructions",
46      [ExtensionHVX, ExtensionHVXV60, ExtensionHVXV62, ExtensionHVXV65,
47       ExtensionZReg]>;
48def ExtensionHVXV67: SubtargetFeature<"hvxv67", "HexagonHVXVersion",
49      "Hexagon::ArchEnum::V67", "Hexagon HVX instructions",
50      [ExtensionHVXV60, ExtensionHVXV62, ExtensionHVXV65, ExtensionHVXV66]>;
51
52
53def ExtensionHVX64B: SubtargetFeature<"hvx-length64b", "UseHVX64BOps",
54      "true", "Hexagon HVX 64B instructions", [ExtensionHVX]>;
55def ExtensionHVX128B: SubtargetFeature<"hvx-length128b", "UseHVX128BOps",
56      "true", "Hexagon HVX 128B instructions", [ExtensionHVX]>;
57
58def ExtensionAudio: SubtargetFeature<"audio", "UseAudioOps", "true",
59      "Hexagon Audio extension instructions">;
60
61def FeatureCompound: SubtargetFeature<"compound", "UseCompound", "true",
62      "Use compound instructions">;
63def FeaturePackets: SubtargetFeature<"packets", "UsePackets", "true",
64      "Support for instruction packets">;
65def FeaturePreV65: SubtargetFeature<"prev65", "HasPreV65", "true",
66      "Support features deprecated in v65">;
67def FeatureLongCalls: SubtargetFeature<"long-calls", "UseLongCalls", "true",
68      "Use constant-extended calls">;
69def FeatureMemNoShuf: SubtargetFeature<"mem_noshuf", "HasMemNoShuf", "false",
70      "Supports mem_noshuf feature">;
71def FeatureMemops: SubtargetFeature<"memops", "UseMemops", "true",
72      "Use memop instructions">;
73def FeatureNVJ: SubtargetFeature<"nvj", "UseNewValueJumps", "true",
74      "Support for new-value jumps", [FeaturePackets]>;
75def FeatureNVS: SubtargetFeature<"nvs", "UseNewValueStores", "true",
76      "Support for new-value stores", [FeaturePackets]>;
77def FeatureSmallData: SubtargetFeature<"small-data", "UseSmallData", "true",
78      "Allow GP-relative addressing of global variables">;
79def FeatureDuplex: SubtargetFeature<"duplex", "EnableDuplex", "true",
80      "Enable generation of duplex instruction">;
81def FeatureUnsafeFP: SubtargetFeature<"unsafe-fp", "UseUnsafeMath", "true",
82      "Use unsafe FP math">;
83def FeatureReservedR19: SubtargetFeature<"reserved-r19", "ReservedR19",
84      "true", "Reserve register R19">;
85def FeatureNoreturnStackElim: SubtargetFeature<"noreturn-stack-elim",
86      "NoreturnStackElim", "true",
87      "Eliminate stack allocation in a noreturn function when possible">;
88
89//===----------------------------------------------------------------------===//
90// Hexagon Instruction Predicate Definitions.
91//===----------------------------------------------------------------------===//
92
93def UseMEMOPS          : Predicate<"HST->useMemops()">;
94def UseHVX64B          : Predicate<"HST->useHVX64BOps()">,
95                         AssemblerPredicate<(all_of ExtensionHVX64B)>;
96def UseHVX128B         : Predicate<"HST->useHVX128BOps()">,
97                         AssemblerPredicate<(all_of ExtensionHVX128B)>;
98def UseHVX             : Predicate<"HST->useHVXOps()">,
99                         AssemblerPredicate<(all_of ExtensionHVXV60)>;
100def UseHVXV60          : Predicate<"HST->useHVXV60Ops()">,
101                         AssemblerPredicate<(all_of ExtensionHVXV60)>;
102def UseHVXV62          : Predicate<"HST->useHVXV62Ops()">,
103                         AssemblerPredicate<(all_of ExtensionHVXV62)>;
104def UseHVXV65          : Predicate<"HST->useHVXV65Ops()">,
105                         AssemblerPredicate<(all_of ExtensionHVXV65)>;
106def UseHVXV66          : Predicate<"HST->useHVXV66Ops()">,
107                         AssemblerPredicate<(all_of ExtensionHVXV66)>;
108def UseHVXV67          : Predicate<"HST->useHVXV67Ops()">,
109                         AssemblerPredicate<(all_of ExtensionHVXV67)>;
110def UseAudio           : Predicate<"HST->useAudioOps()">,
111                         AssemblerPredicate<(all_of ExtensionAudio)>;
112def UseZReg            : Predicate<"HST->useZRegOps()">,
113                         AssemblerPredicate<(all_of ExtensionZReg)>;
114def UseCompound        : Predicate<"HST->useCompound()">;
115def HasPreV65          : Predicate<"HST->hasPreV65()">,
116                         AssemblerPredicate<(all_of FeaturePreV65)>;
117def HasMemNoShuf       : Predicate<"HST->hasMemNoShuf()">,
118                         AssemblerPredicate<(all_of FeatureMemNoShuf)>;
119def UseUnsafeMath      : Predicate<"HST->useUnsafeMath()">;
120def NotOptTinyCore     : Predicate<"!HST->isTinyCore() ||"
121                                   "MF->getFunction().hasOptSize()"> {
122  let RecomputePerFunction = 1;
123}
124def UseSmallData       : Predicate<"HST->useSmallData()">;
125
126def Hvx64:  HwMode<"+hvx-length64b">;
127def Hvx128: HwMode<"+hvx-length128b">;
128
129//===----------------------------------------------------------------------===//
130// Classes used for relation maps.
131//===----------------------------------------------------------------------===//
132
133// The classes below should remain in hierarchical order...
134class ImmRegShl;
135// ImmRegRel - Filter class used to relate instructions having reg-reg form
136// with their reg-imm counterparts.
137class ImmRegRel;
138// PredRel - Filter class used to relate non-predicated instructions with their
139// predicated forms.
140class PredRel;
141class PredNewRel: PredRel;
142// NewValueRel - Filter class used to relate regular store instructions with
143// their new-value store form.
144class NewValueRel: PredNewRel;
145class AddrModeRel: NewValueRel;
146class PostInc_BaseImm;
147class IntrinsicsRel;
148// ... through here.
149
150//===----------------------------------------------------------------------===//
151// Generate mapping table to relate non-predicate instructions with their
152// predicated formats - true and false.
153//
154
155def getPredOpcode : InstrMapping {
156  let FilterClass = "PredRel";
157  // Instructions with the same BaseOpcode and isNVStore values form a row.
158  let RowFields = ["BaseOpcode", "isNVStore", "PNewValue", "isBrTaken", "isNT"];
159  // Instructions with the same predicate sense form a column.
160  let ColFields = ["PredSense"];
161  // The key column is the unpredicated instructions.
162  let KeyCol = [""];
163  // Value columns are PredSense=true and PredSense=false
164  let ValueCols = [["true"], ["false"]];
165}
166
167//===----------------------------------------------------------------------===//
168// Generate mapping table to relate predicate-true instructions with their
169// predicate-false forms
170//
171def getFalsePredOpcode : InstrMapping {
172  let FilterClass = "PredRel";
173  let RowFields = ["BaseOpcode", "PNewValue", "isNVStore", "isBrTaken", "isNT"];
174  let ColFields = ["PredSense"];
175  let KeyCol = ["true"];
176  let ValueCols = [["false"]];
177}
178
179//===----------------------------------------------------------------------===//
180// Generate mapping table to relate predicate-false instructions with their
181// predicate-true forms
182//
183def getTruePredOpcode : InstrMapping {
184  let FilterClass = "PredRel";
185  let RowFields = ["BaseOpcode", "PNewValue", "isNVStore", "isBrTaken", "isNT"];
186  let ColFields = ["PredSense"];
187  let KeyCol = ["false"];
188  let ValueCols = [["true"]];
189}
190
191//===----------------------------------------------------------------------===//
192// Generate mapping table to relate predicated instructions with their .new
193// format.
194//
195def getPredNewOpcode : InstrMapping {
196  let FilterClass = "PredNewRel";
197  let RowFields = ["BaseOpcode", "PredSense", "isNVStore", "isBrTaken"];
198  let ColFields = ["PNewValue"];
199  let KeyCol = [""];
200  let ValueCols = [["new"]];
201}
202
203//===----------------------------------------------------------------------===//
204// Generate mapping table to relate .new predicated instructions with their old
205// format.
206//
207def getPredOldOpcode : InstrMapping {
208  let FilterClass = "PredNewRel";
209  let RowFields = ["BaseOpcode", "PredSense", "isNVStore", "isBrTaken"];
210  let ColFields = ["PNewValue"];
211  let KeyCol = ["new"];
212  let ValueCols = [[""]];
213}
214
215//===----------------------------------------------------------------------===//
216// Generate mapping table to relate store instructions with their new-value
217// format.
218//
219def getNewValueOpcode : InstrMapping {
220  let FilterClass = "NewValueRel";
221  let RowFields = ["BaseOpcode", "PredSense", "PNewValue", "addrMode", "isNT"];
222  let ColFields = ["NValueST"];
223  let KeyCol = ["false"];
224  let ValueCols = [["true"]];
225}
226
227//===----------------------------------------------------------------------===//
228// Generate mapping table to relate new-value store instructions with their old
229// format.
230//
231def getNonNVStore : InstrMapping {
232  let FilterClass = "NewValueRel";
233  let RowFields = ["BaseOpcode", "PredSense", "PNewValue", "addrMode", "isNT"];
234  let ColFields = ["NValueST"];
235  let KeyCol = ["true"];
236  let ValueCols = [["false"]];
237}
238
239def changeAddrMode_abs_io: InstrMapping {
240  let FilterClass = "AddrModeRel";
241  let RowFields = ["CextOpcode", "PredSense", "PNewValue", "isNVStore",
242                   "isFloat"];
243  let ColFields = ["addrMode"];
244  let KeyCol = ["Absolute"];
245  let ValueCols = [["BaseImmOffset"]];
246}
247
248def changeAddrMode_io_abs: InstrMapping {
249  let FilterClass = "AddrModeRel";
250  let RowFields = ["CextOpcode", "PredSense", "PNewValue", "isNVStore",
251                   "isFloat"];
252  let ColFields = ["addrMode"];
253  let KeyCol = ["BaseImmOffset"];
254  let ValueCols = [["Absolute"]];
255}
256
257def changeAddrMode_io_rr: InstrMapping {
258  let FilterClass = "AddrModeRel";
259  let RowFields = ["CextOpcode", "PredSense", "PNewValue", "isNVStore"];
260  let ColFields = ["addrMode"];
261  let KeyCol = ["BaseImmOffset"];
262  let ValueCols = [["BaseRegOffset"]];
263}
264
265def changeAddrMode_rr_io: InstrMapping {
266  let FilterClass = "AddrModeRel";
267  let RowFields = ["CextOpcode", "PredSense", "PNewValue", "isNVStore"];
268  let ColFields = ["addrMode"];
269  let KeyCol = ["BaseRegOffset"];
270  let ValueCols = [["BaseImmOffset"]];
271}
272
273def changeAddrMode_pi_io: InstrMapping {
274  let FilterClass = "PostInc_BaseImm";
275  let RowFields = ["CextOpcode", "PredSense", "PNewValue", "isNVStore"];
276  let ColFields = ["addrMode"];
277  let KeyCol = ["PostInc"];
278  let ValueCols = [["BaseImmOffset"]];
279}
280
281def changeAddrMode_io_pi: InstrMapping {
282  let FilterClass = "PostInc_BaseImm";
283  let RowFields = ["CextOpcode", "PredSense", "PNewValue", "isNVStore"];
284  let ColFields = ["addrMode"];
285  let KeyCol = ["BaseImmOffset"];
286  let ValueCols = [["PostInc"]];
287}
288
289def changeAddrMode_rr_ur: InstrMapping {
290  let FilterClass = "ImmRegShl";
291  let RowFields = ["CextOpcode", "PredSense", "PNewValue", "isNVStore"];
292  let ColFields = ["addrMode"];
293  let KeyCol = ["BaseRegOffset"];
294  let ValueCols = [["BaseLongOffset"]];
295}
296
297def changeAddrMode_ur_rr : InstrMapping {
298  let FilterClass = "ImmRegShl";
299  let RowFields = ["CextOpcode", "PredSense", "PNewValue", "isNVStore"];
300  let ColFields = ["addrMode"];
301  let KeyCol = ["BaseLongOffset"];
302  let ValueCols = [["BaseRegOffset"]];
303}
304
305def getRegForm : InstrMapping {
306  let FilterClass = "ImmRegRel";
307  let RowFields = ["CextOpcode", "PredSense", "PNewValue"];
308  let ColFields = ["InputType"];
309  let KeyCol = ["imm"];
310  let ValueCols = [["reg"]];
311}
312
313def notTakenBranchPrediction : InstrMapping {
314  let FilterClass = "PredRel";
315  let RowFields = ["BaseOpcode", "PNewValue",  "PredSense", "isBranch", "isPredicated"];
316  let ColFields = ["isBrTaken"];
317  let KeyCol = ["true"];
318  let ValueCols = [["false"]];
319}
320
321def takenBranchPrediction : InstrMapping {
322  let FilterClass = "PredRel";
323  let RowFields = ["BaseOpcode", "PNewValue",  "PredSense", "isBranch", "isPredicated"];
324  let ColFields = ["isBrTaken"];
325  let KeyCol = ["false"];
326  let ValueCols = [["true"]];
327}
328
329def getRealHWInstr : InstrMapping {
330  let FilterClass = "IntrinsicsRel";
331  let RowFields = ["BaseOpcode"];
332  let ColFields = ["InstrType"];
333  let KeyCol = ["Pseudo"];
334  let ValueCols = [["Pseudo"], ["Real"]];
335}
336//===----------------------------------------------------------------------===//
337// Register File, Instruction Descriptions
338//===----------------------------------------------------------------------===//
339include "HexagonSchedule.td"
340include "HexagonRegisterInfo.td"
341include "HexagonOperands.td"
342include "HexagonDepOperands.td"
343include "HexagonDepITypes.td"
344include "HexagonInstrFormats.td"
345include "HexagonDepInstrFormats.td"
346include "HexagonDepInstrInfo.td"
347include "HexagonCallingConv.td"
348include "HexagonPseudo.td"
349include "HexagonPatterns.td"
350include "HexagonPatternsHVX.td"
351include "HexagonPatternsV65.td"
352include "HexagonDepMappings.td"
353include "HexagonIntrinsics.td"
354
355def HexagonInstrInfo : InstrInfo;
356
357//===----------------------------------------------------------------------===//
358// Hexagon processors supported.
359//===----------------------------------------------------------------------===//
360
361class Proc<string Name, SchedMachineModel Model,
362           list<SubtargetFeature> Features>
363 : ProcessorModel<Name, Model, Features>;
364
365def : Proc<"generic", HexagonModelV60,
366           [ArchV5, ArchV55, ArchV60,
367            FeatureCompound, FeatureDuplex, FeaturePreV65, FeatureMemops,
368            FeatureNVJ, FeatureNVS, FeaturePackets, FeatureSmallData]>;
369def : Proc<"hexagonv5",  HexagonModelV5,
370           [ArchV5,
371            FeatureCompound, FeatureDuplex, FeaturePreV65, FeatureMemops,
372            FeatureNVJ, FeatureNVS, FeaturePackets, FeatureSmallData]>;
373def : Proc<"hexagonv55", HexagonModelV55,
374           [ArchV5, ArchV55,
375            FeatureCompound, FeatureDuplex, FeaturePreV65, FeatureMemops,
376            FeatureNVJ, FeatureNVS, FeaturePackets, FeatureSmallData]>;
377def : Proc<"hexagonv60", HexagonModelV60,
378           [ArchV5, ArchV55, ArchV60,
379            FeatureCompound, FeatureDuplex, FeaturePreV65, FeatureMemops,
380            FeatureNVJ, FeatureNVS, FeaturePackets, FeatureSmallData]>;
381def : Proc<"hexagonv62", HexagonModelV62,
382           [ArchV5, ArchV55, ArchV60, ArchV62,
383            FeatureCompound, FeatureDuplex, FeaturePreV65, FeatureMemops,
384            FeatureNVJ, FeatureNVS, FeaturePackets, FeatureSmallData]>;
385def : Proc<"hexagonv65", HexagonModelV65,
386           [ArchV5, ArchV55, ArchV60, ArchV62, ArchV65,
387            FeatureCompound, FeatureDuplex, FeatureMemNoShuf, FeatureMemops,
388            FeatureNVJ, FeatureNVS, FeaturePackets, FeatureSmallData]>;
389def : Proc<"hexagonv66", HexagonModelV66,
390           [ArchV5, ArchV55, ArchV60, ArchV62, ArchV65, ArchV66,
391            FeatureCompound, FeatureDuplex, FeatureMemNoShuf, FeatureMemops,
392            FeatureNVJ, FeatureNVS, FeaturePackets, FeatureSmallData]>;
393def : Proc<"hexagonv67", HexagonModelV67,
394           [ArchV5, ArchV55, ArchV60, ArchV62, ArchV65, ArchV66, ArchV67,
395            FeatureCompound, FeatureDuplex, FeatureMemNoShuf, FeatureMemops,
396            FeatureNVJ, FeatureNVS, FeaturePackets, FeatureSmallData]>;
397// Need to update the correct features for tiny core.
398// Disable NewValueJumps since the packetizer is unable to handle a packet with
399// a new value jump and another SLOT0 instruction.
400def : Proc<"hexagonv67t", HexagonModelV67T,
401           [ArchV5, ArchV55, ArchV60, ArchV62, ArchV65, ArchV66, ArchV67,
402            ProcTinyCore, ExtensionAudio,
403            FeatureCompound, FeatureMemNoShuf, FeatureMemops,
404            FeatureNVS, FeaturePackets, FeatureSmallData]>;
405
406//===----------------------------------------------------------------------===//
407// Declare the target which we are implementing
408//===----------------------------------------------------------------------===//
409
410def HexagonAsmParser : AsmParser {
411  let ShouldEmitMatchRegisterAltName = 1;
412  bit HasMnemonicFirst = 0;
413}
414
415def HexagonAsmParserVariant : AsmParserVariant {
416  int Variant = 0;
417  string TokenizingCharacters = "#()=:.<>!+*-|^&";
418  string BreakCharacters = "";
419}
420
421def HexagonAsmWriter : AsmWriter {
422  string AsmWriterClassName  = "InstPrinter";
423  bit isMCAsmWriter = 1;
424}
425
426def Hexagon : Target {
427  let InstructionSet = HexagonInstrInfo;
428  let AssemblyParsers = [HexagonAsmParser];
429  let AssemblyParserVariants = [HexagonAsmParserVariant];
430  let AssemblyWriters = [HexagonAsmWriter];
431  let AllowRegisterRenaming = 1;
432}
433