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