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