xref: /freebsd/contrib/llvm-project/llvm/lib/Target/M68k/M68kInstrInfo.td (revision f126890ac5386406dadf7c4cfa9566cbb56537c5)
1//===-- M68kInstrInfo.td - Main M68k Instruction Definition -*- 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/// \file
10/// This file describes the M68k instruction set, defining the instructions
11/// and properties of the instructions which are needed for code generation,
12/// machine code emission, and analysis.
13///
14//===----------------------------------------------------------------------===//
15
16include "M68kInstrFormats.td"
17
18//===----------------------------------------------------------------------===//
19// Profiles
20//===----------------------------------------------------------------------===//
21
22def MxSDT_CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
23def MxSDT_CallSeqEnd   : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
24
25def MxSDT_Call    : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>;
26
27def MxSDT_Ret     : SDTypeProfile<0, -1, [
28  /* ADJ */ SDTCisVT<0, i32>
29]>;
30
31def MxSDT_TCRet   : SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisVT<1, i32>]>;
32
33def MxSDT_Wrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
34
35def MxSDT_UnArithCCROut : SDTypeProfile<2, 1, [
36  /* RES */ SDTCisInt<0>,
37  /* CCR */ SDTCisVT<1, i8>,
38  /* OPD */ SDTCisSameAs<0, 2>
39]>;
40
41// RES, CCR <- op LHS, RHS
42def MxSDT_BiArithCCROut : SDTypeProfile<2, 2, [
43  /* RES */ SDTCisInt<0>,
44  /* CCR */ SDTCisVT<1, i8>,
45  /* LHS */ SDTCisSameAs<0, 2>,
46  /* RHS */ SDTCisSameAs<0, 3>
47]>;
48
49// RES, CCR <- op LHS, RHS, CCR
50def MxSDT_BiArithCCRInOut : SDTypeProfile<2, 3, [
51  /* RES 1 */ SDTCisInt<0>,
52  /*   CCR */ SDTCisVT<1, i8>,
53  /*   LHS */ SDTCisSameAs<0, 2>,
54  /*   RHS */ SDTCisSameAs<0, 3>,
55  /*   CCR */ SDTCisSameAs<1, 4>
56]>;
57
58// RES1, RES2, CCR <- op LHS, RHS
59def MxSDT_2BiArithCCROut : SDTypeProfile<3, 2, [
60  /* RES 1 */ SDTCisInt<0>,
61  /* RES 2 */ SDTCisSameAs<0, 1>,
62  /*   CCR */ SDTCisVT<1, i8>,
63  /*   LHS */ SDTCisSameAs<0, 2>,
64  /*   RHS */ SDTCisSameAs<0, 3>
65]>;
66
67def MxSDT_CmpTest : SDTypeProfile<1, 2, [
68   /* CCR */ SDTCisVT<0, i8>,
69   /* Ops */ SDTCisSameAs<1, 2>
70]>;
71
72def MxSDT_Cmov : SDTypeProfile<1, 4, [
73  /*  ARG */ SDTCisSameAs<0, 1>,
74  /*  ARG */ SDTCisSameAs<1, 2>,
75  /* Cond */ SDTCisVT<3, i8>,
76  /*  CCR */ SDTCisVT<4, i8>
77]>;
78
79def MxSDT_BrCond : SDTypeProfile<0, 3, [
80  /* Dest */ SDTCisVT<0, OtherVT>,
81  /* Cond */ SDTCisVT<1, i8>,
82  /*  CCR */ SDTCisVT<2, i8>
83]>;
84
85def MxSDT_SetCC : SDTypeProfile<1, 2, [
86  /* BOOL */ SDTCisVT<0, i8>,
87  /* Cond */ SDTCisVT<1, i8>,
88  /*  CCR */ SDTCisVT<2, i8>
89]>;
90
91def MxSDT_SetCC_C : SDTypeProfile<1, 2, [
92  /* BOOL */ SDTCisInt<0>,
93  /* Cond */ SDTCisVT<1, i8>,
94  /*  CCR */ SDTCisVT<2, i8>
95]>;
96
97
98def MxSDT_SEG_ALLOCA : SDTypeProfile<1, 1,[
99  /*  MEM */ SDTCisVT<0, iPTR>,
100  /* SIZE */ SDTCisVT<1, iPTR>
101]>;
102
103
104//===----------------------------------------------------------------------===//
105// Nodes
106//===----------------------------------------------------------------------===//
107
108def MxCallSeqStart : SDNode<"ISD::CALLSEQ_START", MxSDT_CallSeqStart,
109                            [SDNPHasChain, SDNPOutGlue]>;
110
111def MxCallSeqEnd   : SDNode<"ISD::CALLSEQ_END", MxSDT_CallSeqEnd,
112                            [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
113
114def MxCall         : SDNode<"M68kISD::CALL", MxSDT_Call,
115                            [SDNPHasChain, SDNPOutGlue,
116                             SDNPOptInGlue, SDNPVariadic]>;
117
118def MxRet   : SDNode<"M68kISD::RET", MxSDT_Ret,
119                     [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
120
121def MxTCRet : SDNode<"M68kISD::TC_RETURN", MxSDT_TCRet,
122                     [SDNPHasChain,  SDNPOptInGlue, SDNPVariadic]>;
123
124def MxWrapper   : SDNode<"M68kISD::Wrapper",   MxSDT_Wrapper>;
125def MxWrapperPC : SDNode<"M68kISD::WrapperPC", MxSDT_Wrapper>;
126
127def MxAdd  : SDNode<"M68kISD::ADD",  MxSDT_BiArithCCROut, [SDNPCommutative]>;
128def MxSub  : SDNode<"M68kISD::SUB",  MxSDT_BiArithCCROut>;
129def MxOr   : SDNode<"M68kISD::OR",   MxSDT_BiArithCCROut, [SDNPCommutative]>;
130def MxXor  : SDNode<"M68kISD::XOR",  MxSDT_BiArithCCROut, [SDNPCommutative]>;
131def MxAnd  : SDNode<"M68kISD::AND",  MxSDT_BiArithCCROut, [SDNPCommutative]>;
132
133def MxAddX : SDNode<"M68kISD::ADDX", MxSDT_BiArithCCRInOut>;
134def MxSubX : SDNode<"M68kISD::SUBX", MxSDT_BiArithCCRInOut>;
135
136def MxSMul : SDNode<"M68kISD::SMUL", MxSDT_BiArithCCROut, [SDNPCommutative]>;
137def MxUMul : SDNode<"M68kISD::UMUL", MxSDT_2BiArithCCROut, [SDNPCommutative]>;
138
139def MxCmp     : SDNode<"M68kISD::CMP", MxSDT_CmpTest>;
140def MxBtst    : SDNode<"M68kISD::BTST", MxSDT_CmpTest>;
141
142def MxCmov    : SDNode<"M68kISD::CMOV",        MxSDT_Cmov>;
143def MxBrCond  : SDNode<"M68kISD::BRCOND",      MxSDT_BrCond, [SDNPHasChain]>;
144def MxSetCC   : SDNode<"M68kISD::SETCC",       MxSDT_SetCC>;
145def MxSetCC_C : SDNode<"M68kISD::SETCC_CARRY", MxSDT_SetCC_C>;
146
147
148def MxSegAlloca : SDNode<"M68kISD::SEG_ALLOCA", MxSDT_SEG_ALLOCA,
149                         [SDNPHasChain]>;
150
151
152//===----------------------------------------------------------------------===//
153// Operands
154//===----------------------------------------------------------------------===//
155
156/// Size is the size of the data, either bits of a register or number of bits
157/// addressed in memory. Size id is a letter that identifies size.
158class MxSize<int num, string id, string full> {
159  int Num = num;
160  string Id = id;
161  string Full = full;
162}
163
164def MxSize8  : MxSize<8,  "b", "byte">;
165def MxSize16 : MxSize<16, "w", "word">;
166def MxSize32 : MxSize<32, "l", "long">;
167def MxSizeF32 : MxSize<32, "s", "f32">;
168def MxSizeF64 : MxSize<64, "d", "f64">;
169def MxSizeF80 : MxSize<80, "x", "f80">;
170
171class MxOpClass<string name,
172                list<AsmOperandClass> superClasses = []> : AsmOperandClass {
173  let Name = name;
174  let ParserMethod = "parseMemOp";
175  let SuperClasses = superClasses;
176}
177
178def MxRegClass : MxOpClass<"Reg">;
179// Splitting asm register class to avoid ambiguous on operands'
180// MatchClassKind. For instance, without this separation,
181// both ADD32dd and ADD32dr has {MCK_RegClass, MCK_RegClass} for
182// their operands, which makes AsmParser unable to pick the correct
183// one in a deterministic way.
184let RenderMethod = "addRegOperands", SuperClasses = [MxRegClass]in {
185  def MxARegClass : MxOpClass<"AReg">;
186  def MxDRegClass : MxOpClass<"DReg">;
187
188  def MxFPDRegClass : MxOpClass<"FPDReg">;
189}
190
191class MxOperand<ValueType vt, MxSize size, string letter, RegisterClass rc, dag pat = (null_frag)> {
192  ValueType VT = vt;
193  string Letter = letter;
194  MxSize Size = size;
195  RegisterClass RC = rc;
196  dag Pat = pat;
197}
198
199class MxRegOp<ValueType vt,
200              RegisterClass rc,
201              MxSize size,
202              string letter,
203              string pm = "printOperand">
204    : RegisterOperand<rc, pm>,
205      MxOperand<vt, size, letter, rc> {
206  let ParserMatchClass = MxRegClass;
207}
208
209// REGISTER DIRECT. The operand is in the data register specified by
210// the effective address register field.
211def MxXRD16 : MxRegOp<i16, XR16, MxSize16, "r">;
212def MxXRD32 : MxRegOp<i32, XR32, MxSize32, "r">;
213
214def MxXRD16_TC : MxRegOp<i16, XR16_TC, MxSize16, "r">;
215def MxXRD32_TC : MxRegOp<i32, XR32_TC, MxSize32, "r">;
216
217// DATA REGISTER DIRECT. The operand is in the data register specified by
218// the effective address register field.
219let ParserMatchClass = MxDRegClass in {
220  def MxDRD8  : MxRegOp<i8,  DR8,  MxSize8,  "d">;
221  def MxDRD16 : MxRegOp<i16, DR16, MxSize16, "d">;
222  def MxDRD32 : MxRegOp<i32, DR32, MxSize32, "d">;
223
224  def MxDRD16_TC : MxRegOp<i16, DR16_TC, MxSize16, "d">;
225  def MxDRD32_TC : MxRegOp<i32, DR32_TC, MxSize32, "d">;
226}
227
228// ADDRESS REGISTER DIRECT. The operand is in the address register specified by
229// the effective address register field.
230let ParserMatchClass = MxARegClass in {
231  def MxARD16 : MxRegOp<i16, AR16, MxSize16, "a">;
232  def MxARD32 : MxRegOp<i32, AR32, MxSize32, "a">;
233
234  def MxARD16_TC : MxRegOp<i16, AR16_TC, MxSize16, "a">;
235  def MxARD32_TC : MxRegOp<i32, AR32_TC, MxSize32, "a">;
236}
237
238// FLOATING POINT DATA REGISTER.
239let ParserMatchClass = MxFPDRegClass in {
240  def MxFPR32 : MxRegOp<f32, FPDR32, MxSizeF32, "fp">;
241  def MxFPR64 : MxRegOp<f64, FPDR64, MxSizeF64, "fp">;
242  def MxFPR80 : MxRegOp<f80, FPDR80, MxSizeF80, "fp">;
243}
244
245class MxMemOp<dag ops, MxSize size, string letter,
246              string printMethod = "printOperand",
247              AsmOperandClass parserMatchClass = ImmAsmOperand>
248    : Operand<iPTR>, MxOperand<iPTR, size, letter, ?> {
249  let PrintMethod = printMethod;
250  let MIOperandInfo = ops;
251  let ParserMatchClass = parserMatchClass;
252  let OperandType = "OPERAND_MEMORY";
253}
254
255// ADDRESS REGISTER INDIRECT. The address of the operand is in the address
256// register specified by the register field. The reference is classified as
257// a data reference with the exception of the jump and jump-to-subroutine
258// instructions.
259def MxARI         : MxOpClass<"ARI">;
260def MxARI8        : MxMemOp<(ops AR32), MxSize8,  "j", "printARI8Mem", MxARI>;
261def MxARI16       : MxMemOp<(ops AR32), MxSize16, "j", "printARI16Mem", MxARI>;
262def MxARI32       : MxMemOp<(ops AR32), MxSize32, "j", "printARI32Mem", MxARI>;
263
264def MxARI8_TC     : MxMemOp<(ops AR32_TC), MxSize8,  "j", "printARI8Mem", MxARI>;
265def MxARI16_TC    : MxMemOp<(ops AR32_TC), MxSize16, "j", "printARI16Mem", MxARI>;
266def MxARI32_TC    : MxMemOp<(ops AR32_TC), MxSize32, "j", "printARI32Mem", MxARI>;
267
268// ADDRESS REGISTER INDIRECT WITH POSTINCREMENT. The address of the operand is
269// in the address register specified by the register field. After the operand
270// address is used, it is incremented by one, two, or four depending upon whether
271// the size of the operand is byte, word, or long word. If the address register
272// is the stack pointer and the operand size is byte, the address is incremented
273// by two rather than one to keep the stack pointer on a word boundary.
274// The reference is classified as a data reference.
275def MxARIPI       : MxOpClass<"ARIPI">;
276def MxARIPI8      : MxMemOp<(ops AR32), MxSize8,  "o", "printARIPI8Mem", MxARIPI>;
277def MxARIPI16     : MxMemOp<(ops AR32), MxSize16, "o", "printARIPI16Mem", MxARIPI>;
278def MxARIPI32     : MxMemOp<(ops AR32), MxSize32, "o", "printARIPI32Mem", MxARIPI>;
279
280def MxARIPI8_TC   : MxMemOp<(ops AR32_TC), MxSize8,  "o", "printARIPI8Mem", MxARIPI>;
281def MxARIPI16_TC  : MxMemOp<(ops AR32_TC), MxSize16, "o", "printARIPI16Mem", MxARIPI>;
282def MxARIPI32_TC  : MxMemOp<(ops AR32_TC), MxSize32, "o", "printARIPI32Mem", MxARIPI>;
283
284// ADDRESS REGISTER INDIRECT WITH PREDECREMENT. The address of the operand is in
285// the address register specified by the register field. Before the operand
286// address is used, it is decremented by one, two, or four depending upon whether
287// the operand size is byte, word, or long word. If the address register is
288// the stack pointer and the operand size is byte, the address is decremented by
289// two rather than one to keep the stack pointer on a word boundary.
290// The reference is classified as a data reference.
291def MxARIPD       : MxOpClass<"ARIPD">;
292def MxARIPD8      : MxMemOp<(ops AR32), MxSize8,  "e", "printARIPD8Mem", MxARIPD>;
293def MxARIPD16     : MxMemOp<(ops AR32), MxSize16, "e", "printARIPD16Mem", MxARIPD>;
294def MxARIPD32     : MxMemOp<(ops AR32), MxSize32, "e", "printARIPD32Mem", MxARIPD>;
295
296def MxARIPD8_TC   : MxMemOp<(ops AR32_TC), MxSize8,  "e", "printARIPD8Mem", MxARIPD>;
297def MxARIPD16_TC  : MxMemOp<(ops AR32_TC), MxSize16, "e", "printARIPD16Mem", MxARIPD>;
298def MxARIPD32_TC  : MxMemOp<(ops AR32_TC), MxSize32, "e", "printARIPD32Mem", MxARIPD>;
299
300// ADDRESS REGISTER INDIRECT WITH DISPLACEMENT. This addressing mode requires one
301// word of extension. The address of the operand is the sum of the address in
302// the address register and the sign-extended 16-bit displacement integer in the
303// extension word. The reference is classified as a data reference with the
304// exception of the jump and jump-to-subroutine instructions.
305def MxARID        : MxOpClass<"ARID">;
306def MxARID8       : MxMemOp<(ops i16imm:$disp, AR32:$reg), MxSize8,  "p", "printARID8Mem", MxARID>;
307def MxARID16      : MxMemOp<(ops i16imm:$disp, AR32:$reg), MxSize16, "p", "printARID16Mem", MxARID>;
308def MxARID32      : MxMemOp<(ops i16imm:$disp, AR32:$reg), MxSize32, "p", "printARID32Mem", MxARID>;
309
310def MxARID8_TC    : MxMemOp<(ops i16imm:$disp, AR32_TC:$reg), MxSize8,  "p", "printARID8Mem", MxARID>;
311def MxARID16_TC   : MxMemOp<(ops i16imm:$disp, AR32_TC:$reg), MxSize16, "p", "printARID16Mem", MxARID>;
312def MxARID32_TC   : MxMemOp<(ops i16imm:$disp, AR32_TC:$reg), MxSize32, "p", "printARID32Mem", MxARID>;
313
314// ADDRESS REGISTER INDIRECT WITH INDEX. This addressing mode requires one word
315// of extension. The address of the operand is the sum of the address in the
316// address register, the signextended displacement integer in the low order eight
317// bits of the extension word, and the contents of the index register.
318// The reference is classified as a data reference with the exception of the
319// jump and jump-to-subroutine instructions
320def MxARII       : MxOpClass<"ARII">;
321def MxARII8      : MxMemOp<(ops i8imm:$disp, AR32:$reg, XR32:$index),
322                           MxSize8,  "f", "printARII8Mem", MxARII>;
323def MxARII16     : MxMemOp<(ops i8imm:$disp, AR32:$reg, XR32:$index),
324                           MxSize16, "f", "printARII16Mem", MxARII>;
325def MxARII32     : MxMemOp<(ops i8imm:$disp, AR32:$reg, XR32:$index),
326                           MxSize32, "f", "printARII32Mem", MxARII>;
327
328def MxARII8_TC   : MxMemOp<(ops i8imm:$disp, AR32_TC:$reg, XR32_TC:$index),
329                           MxSize8,  "f", "printARII8Mem", MxARII>;
330def MxARII16_TC  : MxMemOp<(ops i8imm:$disp, AR32_TC:$reg, XR32_TC:$index),
331                           MxSize16, "f", "printARII16Mem", MxARII>;
332def MxARII32_TC  : MxMemOp<(ops i8imm:$disp, AR32_TC:$reg, XR32_TC:$index),
333                           MxSize32, "f", "printARII32Mem", MxARII>;
334
335// ABSOLUTE SHORT ADDRESS. This addressing mode requires one word of extension.
336// The address of the operand is the extension word. The 16-bit address is sign
337// extended before it is used.  The reference is classified as a data reference
338// with the exception of the jump and jump-tosubroutine instructions.
339def MxAddr     : MxOpClass<"Addr">;
340let RenderMethod = "addAddrOperands" in {
341  // This hierarchy ensures Addr8 will always be parsed
342  // before other larger-width variants.
343  def MxAddr32   : MxOpClass<"Addr32", [MxAddr]>;
344  def MxAddr16   : MxOpClass<"Addr16", [MxAddr32]>;
345  def MxAddr8    : MxOpClass<"Addr8",  [MxAddr16]>;
346}
347
348def MxAS8      : MxMemOp<(ops OtherVT), MxSize8,  "B", "printAS8Mem",  MxAddr8>;
349def MxAS16     : MxMemOp<(ops OtherVT), MxSize16, "B", "printAS16Mem", MxAddr16>;
350def MxAS32     : MxMemOp<(ops OtherVT), MxSize32, "B", "printAS32Mem", MxAddr32>;
351
352// ABSOLUTE LONG ADDRESS. This addressing mode requires two words of extension.
353// The address of the operand is developed by the concatenation of the extension
354// words. The high order part of the address is the first extension word; the low
355// order part of the address is the second extension word. The reference is
356// classified as a data reference with the exception of the jump and jump
357// to-subroutine instructions.
358def MxAL8      : MxMemOp<(ops OtherVT), MxSize8,  "b", "printAL8Mem",  MxAddr8>;
359def MxAL16     : MxMemOp<(ops OtherVT), MxSize16, "b", "printAL16Mem", MxAddr16>;
360def MxAL32     : MxMemOp<(ops OtherVT), MxSize32, "b", "printAL32Mem", MxAddr32>;
361
362def MxPCD : MxOpClass<"PCD">;
363def MxPCI : MxOpClass<"PCI">;
364
365let OperandType = "OPERAND_PCREL" in {
366// PROGRAM COUNTER WITH DISPLACEMENT. This addressing mode requires one word of
367// extension. The address of the operand is the sum of the address in the program
368// counter and the Sign-extended 16-bit displacement integer in the extension
369// word. The value in the program counter is the address of the extension word.
370// The reference is classified as a program reference.
371def MxPCD8     : MxMemOp<(ops i16imm), MxSize8,  "q", "printPCD8Mem", MxPCD>;
372def MxPCD16    : MxMemOp<(ops i16imm), MxSize16, "q", "printPCD16Mem", MxPCD>;
373def MxPCD32    : MxMemOp<(ops i16imm), MxSize32, "q", "printPCD32Mem", MxPCD>;
374
375// PROGRAM COUNTER WITH INDEX. This addressing mode requires one word of
376// extension. The address is the sum of the address in the program counter, the
377// sign-extended displacement integer in the lower eight bits of the extension
378// word, and the contents of the index register.  The value in the program
379// counter is the address of the extension word. This reference is classified as
380// a program reference.
381def MxPCI8   : MxMemOp<(ops i8imm:$disp, XR32:$index), MxSize8,  "k", "printPCI8Mem", MxPCI>;
382def MxPCI16  : MxMemOp<(ops i8imm:$disp, XR32:$index), MxSize16, "k", "printPCI16Mem", MxPCI>;
383def MxPCI32  : MxMemOp<(ops i8imm:$disp, XR32:$index), MxSize32, "k", "printPCI32Mem", MxPCI>;
384} // OPERAND_PCREL
385
386def MxImm : AsmOperandClass {
387  let Name = "MxImm";
388  let PredicateMethod = "isImm";
389  let RenderMethod = "addImmOperands";
390  let ParserMethod = "parseImm";
391}
392
393class MxOp<ValueType vt, MxSize size, string letter>
394    : Operand<vt>,
395      MxOperand<vt, size, letter, ?> {
396  let ParserMatchClass = MxImm;
397}
398
399let OperandType = "OPERAND_IMMEDIATE",
400    PrintMethod = "printImmediate" in {
401// IMMEDIATE DATA. This addressing mode requires either one or two words of
402// extension depending on the size of the operation.
403//     Byte Operation - operand is low order byte of extension word
404//     Word Operation - operand is extension word
405//     Long Word Operation - operand is in the two extension words,
406//                           high order 16 bits are in the first
407//                           extension word, low order 16 bits are
408//                           in the second extension word.
409def Mxi8imm  : MxOp<i8,  MxSize8,  "i">;
410def Mxi16imm : MxOp<i16, MxSize16, "i">;
411def Mxi32imm : MxOp<i32, MxSize32, "i">;
412} // OPERAND_IMMEDIATE
413
414class MxBrTargetOperand<int N> : Operand<OtherVT> {
415  let OperandType = "OPERAND_PCREL";
416  let PrintMethod = "printPCRelImm";
417  let ParserMatchClass = !cast<AsmOperandClass>("MxAddr"#N);
418}
419// Branch targets have OtherVT type and print as pc-relative values.
420def MxBrTarget8  : MxBrTargetOperand<8>;
421def MxBrTarget16 : MxBrTargetOperand<16>;
422def MxBrTarget32 : MxBrTargetOperand<32>;
423
424// Used with MOVEM
425def MxMoveMaskClass : MxOpClass<"MoveMask">;
426def MxMoveMask : MxOp<i16, MxSize16, "m"> {
427  let OperandType = "OPERAND_IMMEDIATE";
428  let PrintMethod = "printMoveMask";
429  let ParserMatchClass = MxMoveMaskClass;
430}
431
432//===----------------------------------------------------------------------===//
433// Predicates
434//===----------------------------------------------------------------------===//
435
436def SmallCode    : Predicate<"TM.getCodeModel() == CodeModel::Small">;
437def KernelCode   : Predicate<"TM.getCodeModel() == CodeModel::Kernel">;
438def FarData      : Predicate<"TM.getCodeModel() != CodeModel::Small &&"
439                             "TM.getCodeModel() != CodeModel::Kernel">;
440def NearData     : Predicate<"TM.getCodeModel() == CodeModel::Small ||"
441                             "TM.getCodeModel() == CodeModel::Kernel">;
442def IsPIC        : Predicate<"TM.isPositionIndependent()">;
443def IsNotPIC     : Predicate<"!TM.isPositionIndependent()">;
444
445// ISA versions
446foreach i = [0,1,2,4,6] in
447def AtLeastM680 # i # "0" : Predicate<"Subtarget->atLeastM680"#i#"0()">,
448                            AssemblerPredicate<(all_of
449                                                !cast<SubtargetFeature>("FeatureISA"#i#"0"))>;
450def AtLeastM68881 : Predicate<"Subtarget->atLeastM68881()">,
451                    AssemblerPredicate<(all_of FeatureISA881)>;
452def AtLeastM68882 : Predicate<"Subtarget->atLeastM68882()">,
453                    AssemblerPredicate<(all_of FeatureISA882)>;
454
455//===----------------------------------------------------------------------===//
456// Condition Codes
457//
458// These MUST be kept in sync with codes enum in M68kInstrInfo.h
459//===----------------------------------------------------------------------===//
460
461def MxCONDt   : PatLeaf<(i8 0)>;  // True
462def MxCONDf   : PatLeaf<(i8 1)>;  // False
463def MxCONDhi  : PatLeaf<(i8 2)>;  // High
464def MxCONDls  : PatLeaf<(i8 3)>;  // Less or Same
465def MxCONDcc  : PatLeaf<(i8 4)>;  // Carry Clear
466def MxCONDcs  : PatLeaf<(i8 5)>;  // Carry Set
467def MxCONDne  : PatLeaf<(i8 6)>;  // Not Equal
468def MxCONDeq  : PatLeaf<(i8 7)>;  // Equal
469def MxCONDvc  : PatLeaf<(i8 8)>;  // Overflow Clear
470def MxCONDvs  : PatLeaf<(i8 9)>;  // Overflow Set
471def MxCONDpl  : PatLeaf<(i8 10)>; // Plus
472def MxCONDmi  : PatLeaf<(i8 11)>; // Minus
473def MxCONDge  : PatLeaf<(i8 12)>; // Greater or Equal
474def MxCONDlt  : PatLeaf<(i8 13)>; // Less Than
475def MxCONDgt  : PatLeaf<(i8 14)>; // Greater Than
476def MxCONDle  : PatLeaf<(i8 15)>; // Less or Equal
477
478
479//===----------------------------------------------------------------------===//
480// Complex Patterns
481//===----------------------------------------------------------------------===//
482
483// NOTE Though this CP is not strictly necessarily it will simplify instruciton
484// definitions
485def MxCP_ARI   : ComplexPattern<iPTR, 1, "SelectARI",
486                                [], [SDNPWantParent]>;
487
488def MxCP_ARIPI : ComplexPattern<iPTR, 1, "SelectARIPI",
489                                [], [SDNPWantParent]>;
490
491def MxCP_ARIPD : ComplexPattern<iPTR, 1, "SelectARIPD",
492                                [], [SDNPWantParent]>;
493
494def MxCP_ARID  : ComplexPattern<iPTR, 2, "SelectARID",
495                                [add, sub, mul, or, shl, frameindex],
496                                [SDNPWantParent]>;
497
498def MxCP_ARII  : ComplexPattern<iPTR, 3, "SelectARII",
499                                [add, sub, mul, or, shl, frameindex],
500                                [SDNPWantParent]>;
501
502def MxCP_AL    : ComplexPattern<iPTR, 1, "SelectAL",
503                                [add, sub, mul, or, shl],
504                                [SDNPWantParent]>;
505
506def MxCP_PCD   : ComplexPattern<iPTR, 1, "SelectPCD",
507                                [add, sub, mul, or, shl],
508                                [SDNPWantParent]>;
509
510def MxCP_PCI   : ComplexPattern<iPTR, 2, "SelectPCI",
511                                [add, sub, mul, or, shl], [SDNPWantParent]>;
512
513
514//===----------------------------------------------------------------------===//
515// Pattern Fragments
516//===----------------------------------------------------------------------===//
517
518def MximmSExt8  : PatLeaf<(i8  imm)>;
519def MximmSExt16 : PatLeaf<(i16 imm)>;
520def MximmSExt32 : PatLeaf<(i32 imm)>;
521
522// Used for Shifts and Rotations, since M68k immediates in these instructions
523// are 1 <= i <= 8. Generally, if immediate is bigger than 8 it will be moved
524// to a register and then an operation is performed.
525//
526// TODO Need to evaluate whether splitting one big shift(or rotate)
527// into a few smaller is faster than doing a move, if so do custom lowering
528def Mximm8_1to8   : ImmLeaf<i8,  [{ return Imm >= 1 && Imm <= 8; }]>;
529def Mximm16_1to8  : ImmLeaf<i16, [{ return Imm >= 1 && Imm <= 8; }]>;
530def Mximm32_1to8  : ImmLeaf<i32, [{ return Imm >= 1 && Imm <= 8; }]>;
531
532// Helper fragments for loads.
533// It's always safe to treat a anyext i16 load as a i32 load if the i16 is
534// known to be 32-bit aligned or better. Ditto for i8 to i16.
535def Mxloadi16 : PatFrag<(ops node:$ptr), (i16 (unindexedload node:$ptr)), [{
536  LoadSDNode *LD = cast<LoadSDNode>(N);
537  ISD::LoadExtType ExtType = LD->getExtensionType();
538  if (ExtType == ISD::NON_EXTLOAD)
539    return true;
540  if (ExtType == ISD::EXTLOAD)
541    return LD->getAlign() >= 2 && !LD->isSimple();
542  return false;
543}]>;
544
545def Mxloadi32 : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)), [{
546  LoadSDNode *LD = cast<LoadSDNode>(N);
547  ISD::LoadExtType ExtType = LD->getExtensionType();
548  if (ExtType == ISD::NON_EXTLOAD)
549    return true;
550  if (ExtType == ISD::EXTLOAD)
551    return LD->getAlign() >= 4 && !LD->isSimple();
552  return false;
553}]>;
554
555def Mxloadi8         : PatFrag<(ops node:$ptr), (i8  (load node:$ptr))>;
556
557def MxSExtLoadi16i8  : PatFrag<(ops node:$ptr), (i16 (sextloadi8 node:$ptr))>;
558def MxSExtLoadi32i8  : PatFrag<(ops node:$ptr), (i32 (sextloadi8 node:$ptr))>;
559def MxSExtLoadi32i16 : PatFrag<(ops node:$ptr), (i32 (sextloadi16 node:$ptr))>;
560
561def MxZExtLoadi8i1   : PatFrag<(ops node:$ptr), (i8  (zextloadi1 node:$ptr))>;
562def MxZExtLoadi16i1  : PatFrag<(ops node:$ptr), (i16 (zextloadi1 node:$ptr))>;
563def MxZExtLoadi32i1  : PatFrag<(ops node:$ptr), (i32 (zextloadi1 node:$ptr))>;
564def MxZExtLoadi16i8  : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>;
565def MxZExtLoadi32i8  : PatFrag<(ops node:$ptr), (i32 (zextloadi8 node:$ptr))>;
566def MxZExtLoadi32i16 : PatFrag<(ops node:$ptr), (i32 (zextloadi16 node:$ptr))>;
567
568def MxExtLoadi8i1    : PatFrag<(ops node:$ptr), (i8  (extloadi1 node:$ptr))>;
569def MxExtLoadi16i1   : PatFrag<(ops node:$ptr), (i16 (extloadi1 node:$ptr))>;
570def MxExtLoadi32i1   : PatFrag<(ops node:$ptr), (i32 (extloadi1 node:$ptr))>;
571def MxExtLoadi16i8   : PatFrag<(ops node:$ptr), (i16 (extloadi8 node:$ptr))>;
572def MxExtLoadi32i8   : PatFrag<(ops node:$ptr), (i32 (extloadi8 node:$ptr))>;
573def MxExtLoadi32i16  : PatFrag<(ops node:$ptr), (i32 (extloadi16 node:$ptr))>;
574
575
576//===----------------------------------------------------------------------===//
577// Type Fixtures
578//
579// Type Fixtures are ValueType related information sets that usually go together
580//===----------------------------------------------------------------------===//
581
582// TODO make it folded like MxType8.F.Op nad MxType8.F.Pat
583// TODO move strings into META subclass
584// vt: Type of data this fixture refers to
585// prefix: Prefix used to identify type
586// postfix: Prefix used to qualify type
587class MxType<ValueType vt, string prefix, string postfix,
588             // rLet: Register letter
589             // rOp:  Supported any register operand
590             string rLet, MxOperand rOp,
591             // jOp:  Supported ARI operand
592             // jPat: What ARI pattern to use
593             MxOperand jOp, ComplexPattern jPat,
594             // oOp:  Supported ARIPI operand
595             // oPat: What ARIPI pattern is used
596             MxOperand oOp, ComplexPattern oPat,
597             // eOp:  Supported ARIPD operand
598             // ePat: What ARIPD pattern is used
599             MxOperand eOp, ComplexPattern ePat,
600             // pOp:  Supported ARID operand
601             // pPat: What ARID pattern is used
602             MxOperand pOp, ComplexPattern pPat,
603             // fOp:  Supported ARII operand
604             // fPat: What ARII pattern is used
605             MxOperand fOp, ComplexPattern fPat,
606             // bOp:  Supported absolute operand
607             // bPat: What absolute pattern is used
608             MxOperand bOp, ComplexPattern bPat,
609             // qOp:  Supported PCD operand
610             // qPat: What PCD pattern is used
611             MxOperand qOp, ComplexPattern qPat,
612             // kOp:  Supported PCI operand
613             // kPat: What PCI pattern is used
614             MxOperand kOp, ComplexPattern kPat,
615             // iOp:  Supported immediate operand
616             // iPat: What immediate pattern is used
617             MxOperand iOp, PatFrag iPat,
618             // load: What load operation is used with MEM
619             PatFrag load> {
620  int Size = vt.Size;
621  ValueType VT = vt;
622  string Prefix = prefix;
623  string Postfix = postfix;
624
625  string RLet = rLet;
626  MxOperand ROp = rOp;
627
628  MxOperand JOp = jOp;
629  ComplexPattern JPat = jPat;
630
631  MxOperand OOp = oOp;
632  ComplexPattern OPat = oPat;
633
634  MxOperand EOp = eOp;
635  ComplexPattern EPat = ePat;
636
637  MxOperand POp = pOp;
638  ComplexPattern PPat = pPat;
639
640  MxOperand FOp = fOp;
641  ComplexPattern FPat = fPat;
642
643  MxOperand BOp = bOp;
644  ComplexPattern BPat = bPat;
645
646  MxOperand QOp = qOp;
647  ComplexPattern QPat = qPat;
648
649  MxOperand KOp = kOp;
650  ComplexPattern KPat = kPat;
651
652  MxOperand IOp = iOp;
653  PatFrag IPat = iPat;
654
655  PatFrag Load = load;
656}
657
658// Provides an alternative way to access the MxOperand and
659// patterns w.r.t a specific addressing mode.
660class MxOpBundle<int size, MxOperand op, ComplexPattern pat> {
661  int Size = size;
662  MxOperand Op = op;
663  ComplexPattern Pat = pat;
664}
665
666class MxImmOpBundle<int size, MxOperand op, PatFrag pat>
667  : MxOpBundle<size, op, ?> {
668  PatFrag ImmPat = pat;
669}
670
671// TODO: We can use MxOp<S>AddrMode_<AM> in more places to
672// replace MxType-based operand factoring.
673foreach size = [8, 16, 32] in {
674  // Dn
675  def MxOp#size#AddrMode_d
676    : MxOpBundle<size, !cast<MxOperand>("MxDRD"#size), ?>;
677
678  // (An)
679  def MxOp#size#AddrMode_j
680    : MxOpBundle<size, !cast<MxOperand>("MxARI"#size), MxCP_ARI>;
681
682  // (An)+
683  def MxOp#size#AddrMode_o
684    : MxOpBundle<size, !cast<MxOperand>("MxARIPI"#size), MxCP_ARIPI>;
685
686  // -(An)
687  def MxOp#size#AddrMode_e
688    : MxOpBundle<size, !cast<MxOperand>("MxARIPD"#size), MxCP_ARIPD>;
689
690  // (i,An)
691  def MxOp#size#AddrMode_p
692    : MxOpBundle<size, !cast<MxOperand>("MxARID"#size), MxCP_ARID>;
693
694  // (i,An,Xn)
695  def MxOp#size#AddrMode_f
696    : MxOpBundle<size, !cast<MxOperand>("MxARII"#size), MxCP_ARII>;
697
698  // (ABS).L
699  def MxOp#size#AddrMode_b
700    : MxOpBundle<size, !cast<MxOperand>("MxAL"#size), MxCP_AL>;
701
702  // (i,PC)
703  def MxOp#size#AddrMode_q
704    : MxOpBundle<size, !cast<MxOperand>("MxPCD"#size), MxCP_PCD>;
705
706  // (i,PC,Xn)
707  def MxOp#size#AddrMode_k
708    : MxOpBundle<size, !cast<MxOperand>("MxPCI"#size), MxCP_PCI>;
709
710  // #imm
711  def MxOp#size#AddrMode_i
712    : MxImmOpBundle<size, !cast<MxOperand>("Mxi"#size#"imm"),
713                    !cast<PatFrag>("MximmSExt"#size)>;
714} // foreach size = [8, 16, 32]
715
716foreach size = [16, 32] in {
717  // An
718  def MxOp#size#AddrMode_a
719    : MxOpBundle<size, !cast<MxOperand>("MxARD"#size), ?>;
720
721  // Xn
722  def MxOp#size#AddrMode_r
723    : MxOpBundle<size, !cast<MxOperand>("MxXRD"#size), ?>;
724} // foreach size = [16, 32]
725
726foreach size = [32, 64, 80] in
727def MxOp#size#AddrMode_fpr
728  : MxOpBundle<size, !cast<MxOperand>("MxFPR"#size), ?>;
729
730class MxType8Class<string rLet, MxOperand reg>
731    : MxType<i8, "b", "", rLet, reg,
732             MxARI8,   MxCP_ARI,
733             MxARIPI8, MxCP_ARIPI,
734             MxARIPD8, MxCP_ARIPD,
735             MxARID8,  MxCP_ARID,
736             MxARII8,  MxCP_ARII,
737             MxAL8,    MxCP_AL,
738             MxPCD8,   MxCP_PCD,
739             MxPCI8,   MxCP_PCI,
740             Mxi8imm,  MximmSExt8,
741             Mxloadi8>;
742
743def MxType8 : MxType8Class<?,?>;
744
745class MxType16Class<string rLet, MxOperand reg>
746    : MxType<i16, "w", "", rLet, reg,
747             MxARI16,   MxCP_ARI,
748             MxARIPI16, MxCP_ARIPI,
749             MxARIPD16, MxCP_ARIPD,
750             MxARID16,  MxCP_ARID,
751             MxARII16,  MxCP_ARII,
752             MxAL16,    MxCP_AL,
753             MxPCD16,   MxCP_PCD,
754             MxPCI16,   MxCP_PCI,
755             Mxi16imm,  MximmSExt16,
756             Mxloadi16>;
757
758def MxType16 : MxType16Class<?,?>;
759
760class MxType32Class<string rLet, MxOperand reg>
761    : MxType<i32, "l", "", rLet, reg,
762             MxARI32,   MxCP_ARI,
763             MxARIPI32, MxCP_ARIPI,
764             MxARIPD32, MxCP_ARIPD,
765             MxARID32,  MxCP_ARID,
766             MxARII32,  MxCP_ARII,
767             MxAL32,    MxCP_AL,
768             MxPCD32,   MxCP_PCD,
769             MxPCI32,   MxCP_PCI,
770             Mxi32imm,  MximmSExt32,
771             Mxloadi32>;
772
773def MxType32 : MxType32Class<?,?>;
774
775
776def MxType8d : MxType8Class<"d", MxDRD8>;
777
778def MxType16d : MxType16Class<"d", MxDRD16>;
779def MxType16a : MxType16Class<"a", MxARD16>;
780def MxType16r : MxType16Class<"r", MxXRD16>;
781def MxType32d : MxType32Class<"d", MxDRD32>;
782def MxType32a : MxType32Class<"a", MxARD32>;
783def MxType32r : MxType32Class<"r", MxXRD32>;
784
785let Postfix = "_TC" in {
786def MxType16d_TC : MxType16Class<"d", MxDRD16_TC>;
787def MxType16a_TC : MxType16Class<"a", MxARD16_TC>;
788def MxType16r_TC : MxType16Class<"r", MxXRD16_TC>;
789def MxType32d_TC : MxType32Class<"d", MxDRD32_TC>;
790def MxType32a_TC : MxType32Class<"a", MxARD32_TC>;
791def MxType32r_TC : MxType32Class<"r", MxXRD32_TC>;
792}
793
794
795//===----------------------------------------------------------------------===//
796// Subsystems
797//===----------------------------------------------------------------------===//
798
799include "M68kInstrData.td"
800include "M68kInstrShiftRotate.td"
801include "M68kInstrBits.td"
802include "M68kInstrArithmetic.td"
803include "M68kInstrControl.td"
804include "M68kInstrAtomics.td"
805
806include "M68kInstrCompiler.td"
807