831 lines · plain
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-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// This file describes the M68k instruction set, defining the instructions11/// 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// Profiles20//===----------------------------------------------------------------------===//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, RHS42def 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, CCR50def 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// Nodes97//===----------------------------------------------------------------------===//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 MxGlobalBaseReg : SDNode<"M68kISD::GLOBAL_BASE_REG",116 SDTypeProfile<1, 0, [SDTCisVT<0, iPTR>]>>;117 118// A wrapper node for TargetConstantPool,119// TargetExternalSymbol, and TargetGlobalAddress.120def MxWrapper : SDNode<"M68kISD::Wrapper", MxSDT_Wrapper>;121 122// Special wrapper used under M68k PIC mode for PC123// relative displacements.124def MxWrapperPC : SDNode<"M68kISD::WrapperPC", MxSDT_Wrapper>;125 126// Arithmetic operations with CCR results.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_BiArithCCROut, [SDNPCommutative]>;138 139// M68k compare and logical compare instructions. Subtracts the source140// operand from the destination data register and sets the condition141// codes according to the result. Immediate always goes first.142def MxCmp : SDNode<"M68kISD::CMP", MxSDT_CmpTest>;143 144// M68k bit-test instructions.145def MxBtst : SDNode<"M68kISD::BTST", MxSDT_CmpTest>;146 147// M68k conditional moves. Operand 0 and operand 1 are the two values148// to select from. Operand 2 is the condition code, and operand 3 is the149// flag operand produced by a CMP or TEST instruction. It also writes a150// flag result.151def MxCmov : SDNode<"M68kISD::CMOV", MxSDT_Cmov>;152 153// M68k conditional branches. Operand 0 is the chain operand, operand 1154// is the block to branch if condition is true, operand 2 is the155// condition code, and operand 3 is the flag operand produced by a CMP156// or TEST instruction.157def MxBrCond : SDNode<"M68kISD::BRCOND", MxSDT_BrCond, [SDNPHasChain]>;158 159// M68k SetCC. Operand 0 is condition code, and operand 1 is the CCR160// operand, usually produced by a CMP instruction.161def MxSetCC : SDNode<"M68kISD::SETCC", MxSDT_SetCC>;162 163// Same as SETCC except it's materialized with a subx and the value is all164// one's or all zero's.165def MxSetCC_C : SDNode<"M68kISD::SETCC_CARRY", MxSDT_SetCC_C>;166 167// For allocating variable amounts of stack space when using168// segmented stacks. Check if the current stacklet has enough space, and169// falls back to heap allocation if not.170def MxSegAlloca : SDNode<"M68kISD::SEG_ALLOCA", MxSDT_SEG_ALLOCA,171 [SDNPHasChain]>;172 173 174//===----------------------------------------------------------------------===//175// Operands176//===----------------------------------------------------------------------===//177 178/// Size is the size of the data, either bits of a register or number of bits179/// addressed in memory. Size id is a letter that identifies size.180class MxSize<int num, string id, string full> {181 int Num = num;182 string Id = id;183 string Full = full;184}185 186def MxSize8 : MxSize<8, "b", "byte">;187def MxSize16 : MxSize<16, "w", "word">;188def MxSize32 : MxSize<32, "l", "long">;189def MxSizeF32 : MxSize<32, "s", "f32">;190def MxSizeF64 : MxSize<64, "d", "f64">;191def MxSizeF80 : MxSize<80, "x", "f80">;192 193class MxOpClass<string name,194 list<AsmOperandClass> superClasses = []> : AsmOperandClass {195 let Name = name;196 let ParserMethod = "parseMemOp";197 let SuperClasses = superClasses;198}199 200def MxRegClass : MxOpClass<"Reg">;201// Splitting asm register class to avoid ambiguous on operands'202// MatchClassKind. For instance, without this separation,203// both ADD32dd and ADD32dr has {MCK_RegClass, MCK_RegClass} for204// their operands, which makes AsmParser unable to pick the correct205// one in a deterministic way.206let RenderMethod = "addRegOperands", SuperClasses = [MxRegClass]in {207 def MxARegClass : MxOpClass<"AReg">;208 def MxDRegClass : MxOpClass<"DReg">;209 210 def MxFPDRegClass : MxOpClass<"FPDReg">;211 def MxFPCRegClass : MxOpClass<"FPCReg">;212}213 214class MxOperand<ValueType vt, MxSize size, string letter, RegisterClass rc, dag pat = (null_frag)> {215 ValueType VT = vt;216 string Letter = letter;217 MxSize Size = size;218 RegisterClass RC = rc;219 dag Pat = pat;220}221 222class MxRegOp<ValueType vt,223 RegisterClass rc,224 MxSize size,225 string letter,226 string pm = "printOperand">227 : RegisterOperand<rc, pm>,228 MxOperand<vt, size, letter, rc> {229 let ParserMatchClass = MxRegClass;230}231 232// REGISTER DIRECT. The operand is in the data register specified by233// the effective address register field.234foreach size = [16, 32] in {235 def MxXRD # size : MxRegOp<!cast<ValueType>("i"#size), !cast<MxRegClass>("XR"#size),236 !cast<MxSize>("MxSize"#size), "r">;237 def MxXRD # size # _TC : MxRegOp<!cast<ValueType>("i"#size), !cast<MxRegClass>("XR"#size#"_TC"),238 !cast<MxSize>("MxSize"#size), "r">;239} // foreach size240 241// DATA REGISTER DIRECT. The operand is in the data register specified by242// the effective address register field.243let ParserMatchClass = MxDRegClass in {244foreach size = [8, 16, 32] in {245 def MxDRD # size : MxRegOp<!cast<ValueType>("i"#size), !cast<MxRegClass>("DR"#size),246 !cast<MxSize>("MxSize"#size), "d">;247 if !gt(size, 8) then248 def MxDRD # size # _TC : MxRegOp<!cast<ValueType>("i"#size), !cast<MxRegClass>("DR"#size#"_TC"),249 !cast<MxSize>("MxSize"#size), "d">;250} // foreach size251} // let ParserMatchClass252 253// ADDRESS REGISTER DIRECT. The operand is in the address register specified by254// the effective address register field.255let ParserMatchClass = MxARegClass in {256foreach size = [16, 32] in {257 def MxARD # size : MxRegOp<!cast<ValueType>("i"#size), !cast<MxRegClass>("AR"#size),258 !cast<MxSize>("MxSize"#size), "a">;259 def MxARD # size # _TC : MxRegOp<!cast<ValueType>("i"#size), !cast<MxRegClass>("AR"#size#"_TC"),260 !cast<MxSize>("MxSize"#size), "a">;261} // foreach size262} // let ParserMatchClass263 264// FLOATING POINT DATA REGISTER.265let ParserMatchClass = MxFPDRegClass in {266 def MxFPR32 : MxRegOp<f32, FPDR32, MxSizeF32, "fp">;267 def MxFPR64 : MxRegOp<f64, FPDR64, MxSizeF64, "fp">;268 def MxFPR80 : MxRegOp<f80, FPDR80, MxSizeF80, "fp">;269}270 271// FLOATING POINT SYSTEM CONTROL REGISTER272let ParserMatchClass = MxFPCRegClass in {273 def MxFPCSR : MxRegOp<i32, FPCSC, MxSize32, "fpcs">;274 def MxFPIR : MxRegOp<i32, FPIC, MxSize32, "fpi">;275}276 277class MxMemOp<dag ops, MxSize size, string letter,278 string printMethod = "printOperand",279 AsmOperandClass parserMatchClass = ImmAsmOperand>280 : Operand<iPTR>, MxOperand<iPTR, size, letter, ?> {281 let PrintMethod = printMethod;282 let MIOperandInfo = ops;283 let ParserMatchClass = parserMatchClass;284 let OperandType = "OPERAND_MEMORY";285}286 287// ADDRESS REGISTER INDIRECT. The address of the operand is in the address288// register specified by the register field. The reference is classified as289// a data reference with the exception of the jump and jump-to-subroutine290// instructions.291def MxARI : MxOpClass<"ARI">;292foreach size = ["8", "16", "32"] in {293 defvar ResSize = !cast<MxSize>("MxSize"#size);294 def MxARI # size : MxMemOp<(ops AR32), ResSize, "j", "printARI"#size#"Mem", MxARI>;295 def MxARI # size # _TC : MxMemOp<(ops AR32_TC), ResSize, "j", "printARI"#size#"Mem", MxARI>;296} // foreach size297 298// ADDRESS REGISTER INDIRECT WITH POSTINCREMENT. The address of the operand is299// in the address register specified by the register field. After the operand300// address is used, it is incremented by one, two, or four depending upon whether301// the size of the operand is byte, word, or long word. If the address register302// is the stack pointer and the operand size is byte, the address is incremented303// by two rather than one to keep the stack pointer on a word boundary.304// The reference is classified as a data reference.305def MxARIPI : MxOpClass<"ARIPI">;306foreach size = ["8", "16", "32"] in {307 defvar ResSize = !cast<MxSize>("MxSize"#size);308 def MxARIPI # size : MxMemOp<(ops AR32), ResSize, "o", "printARIPI"#size#"Mem", MxARIPI>;309 def MxARIPI # size # _TC : MxMemOp<(ops AR32_TC), ResSize, "o", "printARIPI"#size#"Mem", MxARIPI>;310} // foreach size311 312// ADDRESS REGISTER INDIRECT WITH PREDECREMENT. The address of the operand is in313// the address register specified by the register field. Before the operand314// address is used, it is decremented by one, two, or four depending upon whether315// the operand size is byte, word, or long word. If the address register is316// the stack pointer and the operand size is byte, the address is decremented by317// two rather than one to keep the stack pointer on a word boundary.318// The reference is classified as a data reference.319def MxARIPD : MxOpClass<"ARIPD">;320foreach size = ["8", "16", "32"] in {321 defvar ResSize = !cast<MxSize>("MxSize"#size);322 def MxARIPD # size : MxMemOp<(ops AR32), ResSize, "e", "printARIPD"#size#"Mem", MxARIPD>;323 def MxARIPD # size # _TC : MxMemOp<(ops AR32_TC), ResSize, "e", "printARIPD"#size#"Mem", MxARIPD>;324} // foreach size325 326// ADDRESS REGISTER INDIRECT WITH DISPLACEMENT. This addressing mode requires one327// word of extension. The address of the operand is the sum of the address in328// the address register and the sign-extended 16-bit displacement integer in the329// extension word. The reference is classified as a data reference with the330// exception of the jump and jump-to-subroutine instructions.331def MxARID : MxOpClass<"ARID">;332foreach size = ["8", "16", "32"] in {333 defvar ResSize = !cast<MxSize>("MxSize"#size);334 def MxARID # size : MxMemOp<(ops i16imm:$disp, AR32:$reg), ResSize, "p", "printARID"#size#"Mem", MxARID>;335 def MxARID # size # _TC : MxMemOp<(ops i16imm:$disp, AR32_TC:$reg), ResSize, "p", "printARID"#size#"Mem", MxARID>;336} // foreach size337 338// ADDRESS REGISTER INDIRECT WITH INDEX. This addressing mode requires one word339// of extension. The address of the operand is the sum of the address in the340// address register, the signextended displacement integer in the low order eight341// bits of the extension word, and the contents of the index register.342// The reference is classified as a data reference with the exception of the343// jump and jump-to-subroutine instructions344def MxARII : MxOpClass<"ARII">;345foreach size = ["8", "16", "32"] in {346 defvar ResSize = !cast<MxSize>("MxSize"#size);347 def MxARII # size : MxMemOp<(ops i8imm:$disp, AR32:$reg, XR32:$index), ResSize, "f", "printARII"#size#"Mem", MxARII>;348 def MxARII # size # _TC : MxMemOp<(ops i8imm:$disp, AR32_TC:$reg, XR32:$index), ResSize, "f", "printARII"#size#"Mem", MxARII>;349} // foreach size350 351// ABSOLUTE SHORT ADDRESS. This addressing mode requires one word of extension.352// The address of the operand is the extension word. The 16-bit address is sign353// extended before it is used. The reference is classified as a data reference354// with the exception of the jump and jump-tosubroutine instructions.355def MxAddr : MxOpClass<"Addr">;356let RenderMethod = "addAddrOperands" in {357 // This hierarchy ensures Addr8 will always be parsed358 // before other larger-width variants.359 def MxAddr32 : MxOpClass<"Addr32", [MxAddr]>;360 def MxAddr16 : MxOpClass<"Addr16", [MxAddr32]>;361 def MxAddr8 : MxOpClass<"Addr8", [MxAddr16]>;362}363 364def MxAS8 : MxMemOp<(ops OtherVT), MxSize8, "B", "printAS8Mem", MxAddr8>;365def MxAS16 : MxMemOp<(ops OtherVT), MxSize16, "B", "printAS16Mem", MxAddr16>;366def MxAS32 : MxMemOp<(ops OtherVT), MxSize32, "B", "printAS32Mem", MxAddr32>;367 368// ABSOLUTE LONG ADDRESS. This addressing mode requires two words of extension.369// The address of the operand is developed by the concatenation of the extension370// words. The high order part of the address is the first extension word; the low371// order part of the address is the second extension word. The reference is372// classified as a data reference with the exception of the jump and jump373// to-subroutine instructions.374def MxAL8 : MxMemOp<(ops OtherVT), MxSize8, "b", "printAL8Mem", MxAddr8>;375def MxAL16 : MxMemOp<(ops OtherVT), MxSize16, "b", "printAL16Mem", MxAddr16>;376def MxAL32 : MxMemOp<(ops OtherVT), MxSize32, "b", "printAL32Mem", MxAddr32>;377 378def MxPCD : MxOpClass<"PCD">;379def MxPCI : MxOpClass<"PCI">;380 381let OperandType = "OPERAND_PCREL" in {382foreach size = ["8", "16", "32"] in {383defvar ResSize = !cast<MxSize>("MxSize"#size);384// PROGRAM COUNTER WITH DISPLACEMENT. This addressing mode requires one word of385// extension. The address of the operand is the sum of the address in the program386// counter and the Sign-extended 16-bit displacement integer in the extension387// word. The value in the program counter is the address of the extension word.388// The reference is classified as a program reference.389def MxPCD # size : MxMemOp<(ops i16imm), ResSize, "q", "printPCD"#size#"Mem", MxPCD>;390 391// PROGRAM COUNTER WITH INDEX. This addressing mode requires one word of392// extension. The address is the sum of the address in the program counter, the393// sign-extended displacement integer in the lower eight bits of the extension394// word, and the contents of the index register. The value in the program395// counter is the address of the extension word. This reference is classified as396// a program reference.397def MxPCI # size : MxMemOp<(ops i8imm:$disp, XR32:$index), ResSize, "k", "printPCI"#size#"Mem", MxPCI>;398} // foreach size399} // OPERAND_PCREL400 401def MxImm : AsmOperandClass {402 let Name = "MxImm";403 let PredicateMethod = "isImm";404 let RenderMethod = "addImmOperands";405 let ParserMethod = "parseImm";406}407 408class MxOp<ValueType vt, MxSize size, string letter>409 : Operand<vt>,410 MxOperand<vt, size, letter, ?> {411 let ParserMatchClass = MxImm;412}413 414let OperandType = "OPERAND_IMMEDIATE",415 PrintMethod = "printImmediate" in {416// IMMEDIATE DATA. This addressing mode requires either one or two words of417// extension depending on the size of the operation.418// Byte Operation - operand is low order byte of extension word419// Word Operation - operand is extension word420// Long Word Operation - operand is in the two extension words,421// high order 16 bits are in the first422// extension word, low order 16 bits are423// in the second extension word.424def Mxi8imm : MxOp<i8, MxSize8, "i">;425def Mxi16imm : MxOp<i16, MxSize16, "i">;426def Mxi32imm : MxOp<i32, MxSize32, "i">;427} // OPERAND_IMMEDIATE428 429class MxBrTargetOperand<int N> : Operand<OtherVT> {430 let OperandType = "OPERAND_PCREL";431 let PrintMethod = "printPCRelImm";432 let ParserMatchClass = !cast<AsmOperandClass>("MxAddr"#N);433}434// Branch targets have OtherVT type and print as pc-relative values.435def MxBrTarget8 : MxBrTargetOperand<8>;436def MxBrTarget16 : MxBrTargetOperand<16>;437def MxBrTarget32 : MxBrTargetOperand<32>;438 439// Used with MOVEM440def MxMoveMaskClass : MxOpClass<"MoveMask">;441class MxMoveMaskOp : MxOp<i16, MxSize16, "m"> {442 let OperandType = "OPERAND_IMMEDIATE";443 let PrintMethod = "printMoveMask";444 let ParserMatchClass = MxMoveMaskClass;445}446 447def MxMoveMask : MxMoveMaskOp;448// The encoding of mask is reversed when the memory operand has an addressing449// mode of 'e', that is, pre-decrement.450def MxInverseMoveMask : MxMoveMaskOp {451 let EncoderMethod = "encodeInverseMoveMask";452}453 454//===----------------------------------------------------------------------===//455// Predicates456//===----------------------------------------------------------------------===//457 458def SmallCode : Predicate<"TM.getCodeModel() == CodeModel::Small">;459def KernelCode : Predicate<"TM.getCodeModel() == CodeModel::Kernel">;460def FarData : Predicate<"TM.getCodeModel() != CodeModel::Small &&"461 "TM.getCodeModel() != CodeModel::Kernel">;462def NearData : Predicate<"TM.getCodeModel() == CodeModel::Small ||"463 "TM.getCodeModel() == CodeModel::Kernel">;464def IsPIC : Predicate<"TM.isPositionIndependent()">;465def IsNotPIC : Predicate<"!TM.isPositionIndependent()">;466 467// ISA versions468foreach i = [0,1,2,4,6] in469def AtLeastM680 # i # "0" : Predicate<"Subtarget->atLeastM680"#i#"0()">,470 AssemblerPredicate<(all_of471 !cast<SubtargetFeature>("FeatureISA"#i#"0"))>;472def AtLeastM68881 : Predicate<"Subtarget->atLeastM68881()">,473 AssemblerPredicate<(all_of FeatureISA881)>;474def AtLeastM68882 : Predicate<"Subtarget->atLeastM68882()">,475 AssemblerPredicate<(all_of FeatureISA882)>;476 477//===----------------------------------------------------------------------===//478// Condition Codes479//480// These MUST be kept in sync with codes enum in M68kInstrInfo.h481//===----------------------------------------------------------------------===//482 483def MxCONDt : PatLeaf<(i8 0)>; // True484def MxCONDf : PatLeaf<(i8 1)>; // False485def MxCONDhi : PatLeaf<(i8 2)>; // High486def MxCONDls : PatLeaf<(i8 3)>; // Less or Same487def MxCONDcc : PatLeaf<(i8 4)>; // Carry Clear488def MxCONDcs : PatLeaf<(i8 5)>; // Carry Set489def MxCONDne : PatLeaf<(i8 6)>; // Not Equal490def MxCONDeq : PatLeaf<(i8 7)>; // Equal491def MxCONDvc : PatLeaf<(i8 8)>; // Overflow Clear492def MxCONDvs : PatLeaf<(i8 9)>; // Overflow Set493def MxCONDpl : PatLeaf<(i8 10)>; // Plus494def MxCONDmi : PatLeaf<(i8 11)>; // Minus495def MxCONDge : PatLeaf<(i8 12)>; // Greater or Equal496def MxCONDlt : PatLeaf<(i8 13)>; // Less Than497def MxCONDgt : PatLeaf<(i8 14)>; // Greater Than498def MxCONDle : PatLeaf<(i8 15)>; // Less or Equal499 500 501//===----------------------------------------------------------------------===//502// Complex Patterns503//===----------------------------------------------------------------------===//504 505// NOTE Though this CP is not strictly necessarily it will simplify instruciton506// definitions507let WantsParent = true in {508 def MxCP_ARI : ComplexPattern<iPTR, 1, "SelectARI">;509 510 def MxCP_ARIPI : ComplexPattern<iPTR, 1, "SelectARIPI">;511 512 def MxCP_ARIPD : ComplexPattern<iPTR, 1, "SelectARIPD">;513 514 def MxCP_ARID : ComplexPattern<iPTR, 2, "SelectARID",515 [add, sub, mul, or, shl, frameindex]>;516 517 def MxCP_ARII : ComplexPattern<iPTR, 3, "SelectARII",518 [add, sub, mul, or, shl, frameindex]>;519 520 def MxCP_AL : ComplexPattern<iPTR, 1, "SelectAL",521 [add, sub, mul, or, shl]>;522 523 def MxCP_PCD : ComplexPattern<iPTR, 1, "SelectPCD",524 [add, sub, mul, or, shl]>;525 526 def MxCP_PCI : ComplexPattern<iPTR, 2, "SelectPCI",527 [add, sub, mul, or, shl]>;528}529 530//===----------------------------------------------------------------------===//531// Pattern Fragments532//===----------------------------------------------------------------------===//533 534def Mxi8immSExt8 : PatLeaf<(i8 imm)>;535def MximmSExt8 : PatLeaf<(imm), [{ return isInt<8>(N->getSExtValue()); }]>;536 537def Mxi16immSExt16 : PatLeaf<(i16 imm)>;538def MximmSExt16 : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>;539 540def Mxi32immSExt32 : PatLeaf<(i32 imm)>;541def MximmSExt32 : PatLeaf<(imm), [{ return isInt<32>(N->getSExtValue()); }]>;542 543// Used for Shifts and Rotations, since M68k immediates in these instructions544// are 1 <= i <= 8. Generally, if immediate is bigger than 8 it will be moved545// to a register and then an operation is performed.546//547// TODO Need to evaluate whether splitting one big shift(or rotate)548// into a few smaller is faster than doing a move, if so do custom lowering549def Mximm8_1to8 : ImmLeaf<i8, [{ return Imm >= 1 && Imm <= 8; }]>;550def Mximm16_1to8 : ImmLeaf<i16, [{ return Imm >= 1 && Imm <= 8; }]>;551def Mximm32_1to8 : ImmLeaf<i32, [{ return Imm >= 1 && Imm <= 8; }]>;552 553// Helper fragments for loads.554// It's always safe to treat a anyext i16 load as a i32 load if the i16 is555// known to be 32-bit aligned or better. Ditto for i8 to i16.556def Mxloadi16 : PatFrag<(ops node:$ptr), (i16 (unindexedload node:$ptr)), [{557 LoadSDNode *LD = cast<LoadSDNode>(N);558 ISD::LoadExtType ExtType = LD->getExtensionType();559 if (ExtType == ISD::NON_EXTLOAD)560 return true;561 if (ExtType == ISD::EXTLOAD)562 return LD->getAlign() >= 2 && !LD->isSimple();563 return false;564}]>;565 566def Mxloadi32 : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)), [{567 LoadSDNode *LD = cast<LoadSDNode>(N);568 ISD::LoadExtType ExtType = LD->getExtensionType();569 if (ExtType == ISD::NON_EXTLOAD)570 return true;571 if (ExtType == ISD::EXTLOAD)572 return LD->getAlign() >= 4 && !LD->isSimple();573 return false;574}]>;575 576def Mxloadi8 : PatFrag<(ops node:$ptr), (i8 (load node:$ptr))>;577 578def MxSExtLoadi16i8 : PatFrag<(ops node:$ptr), (i16 (sextloadi8 node:$ptr))>;579def MxSExtLoadi32i8 : PatFrag<(ops node:$ptr), (i32 (sextloadi8 node:$ptr))>;580def MxSExtLoadi32i16 : PatFrag<(ops node:$ptr), (i32 (sextloadi16 node:$ptr))>;581 582def MxZExtLoadi8i1 : PatFrag<(ops node:$ptr), (i8 (zextloadi1 node:$ptr))>;583def MxZExtLoadi16i1 : PatFrag<(ops node:$ptr), (i16 (zextloadi1 node:$ptr))>;584def MxZExtLoadi32i1 : PatFrag<(ops node:$ptr), (i32 (zextloadi1 node:$ptr))>;585def MxZExtLoadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>;586def MxZExtLoadi32i8 : PatFrag<(ops node:$ptr), (i32 (zextloadi8 node:$ptr))>;587def MxZExtLoadi32i16 : PatFrag<(ops node:$ptr), (i32 (zextloadi16 node:$ptr))>;588 589def MxExtLoadi8i1 : PatFrag<(ops node:$ptr), (i8 (extloadi1 node:$ptr))>;590def MxExtLoadi16i1 : PatFrag<(ops node:$ptr), (i16 (extloadi1 node:$ptr))>;591def MxExtLoadi32i1 : PatFrag<(ops node:$ptr), (i32 (extloadi1 node:$ptr))>;592def MxExtLoadi16i8 : PatFrag<(ops node:$ptr), (i16 (extloadi8 node:$ptr))>;593def MxExtLoadi32i8 : PatFrag<(ops node:$ptr), (i32 (extloadi8 node:$ptr))>;594def MxExtLoadi32i16 : PatFrag<(ops node:$ptr), (i32 (extloadi16 node:$ptr))>;595 596 597//===----------------------------------------------------------------------===//598// Type Fixtures599//600// Type Fixtures are ValueType related information sets that usually go together601//===----------------------------------------------------------------------===//602 603// TODO make it folded like MxType8.F.Op nad MxType8.F.Pat604// TODO move strings into META subclass605// vt: Type of data this fixture refers to606// prefix: Prefix used to identify type607// postfix: Prefix used to qualify type608class MxType<ValueType vt, string prefix, string postfix,609 // rLet: Register letter610 // rOp: Supported any register operand611 string rLet, MxOperand rOp,612 // jOp: Supported ARI operand613 // jPat: What ARI pattern to use614 MxOperand jOp, ComplexPattern jPat,615 // oOp: Supported ARIPI operand616 // oPat: What ARIPI pattern is used617 MxOperand oOp, ComplexPattern oPat,618 // eOp: Supported ARIPD operand619 // ePat: What ARIPD pattern is used620 MxOperand eOp, ComplexPattern ePat,621 // pOp: Supported ARID operand622 // pPat: What ARID pattern is used623 MxOperand pOp, ComplexPattern pPat,624 // fOp: Supported ARII operand625 // fPat: What ARII pattern is used626 MxOperand fOp, ComplexPattern fPat,627 // bOp: Supported absolute operand628 // bPat: What absolute pattern is used629 MxOperand bOp, ComplexPattern bPat,630 // qOp: Supported PCD operand631 // qPat: What PCD pattern is used632 MxOperand qOp, ComplexPattern qPat,633 // kOp: Supported PCI operand634 // kPat: What PCI pattern is used635 MxOperand kOp, ComplexPattern kPat,636 // iOp: Supported immediate operand637 // iPat: What immediate pattern is used638 MxOperand iOp, PatFrag iPat,639 // load: What load operation is used with MEM640 PatFrag load> {641 int Size = vt.Size;642 ValueType VT = vt;643 string Prefix = prefix;644 string Postfix = postfix;645 646 string RLet = rLet;647 MxOperand ROp = rOp;648 649 MxOperand JOp = jOp;650 ComplexPattern JPat = jPat;651 652 MxOperand OOp = oOp;653 ComplexPattern OPat = oPat;654 655 MxOperand EOp = eOp;656 ComplexPattern EPat = ePat;657 658 MxOperand POp = pOp;659 ComplexPattern PPat = pPat;660 661 MxOperand FOp = fOp;662 ComplexPattern FPat = fPat;663 664 MxOperand BOp = bOp;665 ComplexPattern BPat = bPat;666 667 MxOperand QOp = qOp;668 ComplexPattern QPat = qPat;669 670 MxOperand KOp = kOp;671 ComplexPattern KPat = kPat;672 673 MxOperand IOp = iOp;674 PatFrag IPat = iPat;675 676 PatFrag Load = load;677}678 679// Provides an alternative way to access the MxOperand and680// patterns w.r.t a specific addressing mode.681class MxOpBundle<int size, MxOperand op, ComplexPattern pat> {682 int Size = size;683 MxOperand Op = op;684 ComplexPattern Pat = pat;685}686 687class MxImmOpBundle<int size, MxOperand op, PatFrag pat>688 : MxOpBundle<size, op, ?> {689 PatFrag ImmPat = pat;690}691 692// TODO: We can use MxOp<S>AddrMode_<AM> in more places to693// replace MxType-based operand factoring.694foreach size = [8, 16, 32] in {695 // Dn696 def MxOp#size#AddrMode_d697 : MxOpBundle<size, !cast<MxOperand>("MxDRD"#size), ?>;698 699 // (An)700 def MxOp#size#AddrMode_j701 : MxOpBundle<size, !cast<MxOperand>("MxARI"#size), MxCP_ARI>;702 703 // (An)+704 def MxOp#size#AddrMode_o705 : MxOpBundle<size, !cast<MxOperand>("MxARIPI"#size), MxCP_ARIPI>;706 707 // -(An)708 def MxOp#size#AddrMode_e709 : MxOpBundle<size, !cast<MxOperand>("MxARIPD"#size), MxCP_ARIPD>;710 711 // (i,An)712 def MxOp#size#AddrMode_p713 : MxOpBundle<size, !cast<MxOperand>("MxARID"#size), MxCP_ARID>;714 715 // (i,An,Xn)716 def MxOp#size#AddrMode_f717 : MxOpBundle<size, !cast<MxOperand>("MxARII"#size), MxCP_ARII>;718 719 // (ABS).L720 def MxOp#size#AddrMode_b721 : MxOpBundle<size, !cast<MxOperand>("MxAL"#size), MxCP_AL>;722 723 // (i,PC)724 def MxOp#size#AddrMode_q725 : MxOpBundle<size, !cast<MxOperand>("MxPCD"#size), MxCP_PCD>;726 727 // (i,PC,Xn)728 def MxOp#size#AddrMode_k729 : MxOpBundle<size, !cast<MxOperand>("MxPCI"#size), MxCP_PCI>;730 731 // #imm732 def MxOp#size#AddrMode_i733 : MxImmOpBundle<size, !cast<MxOperand>("Mxi"#size#"imm"),734 !cast<PatFrag>("Mxi"#size#"immSExt"#size)>;735} // foreach size = [8, 16, 32]736 737foreach size = [16, 32] in {738 // An739 def MxOp#size#AddrMode_a740 : MxOpBundle<size, !cast<MxOperand>("MxARD"#size), ?>;741 742 // Xn743 def MxOp#size#AddrMode_r744 : MxOpBundle<size, !cast<MxOperand>("MxXRD"#size), ?>;745} // foreach size = [16, 32]746 747foreach size = [32, 64, 80] in748def MxOp#size#AddrMode_fpr749 : MxOpBundle<size, !cast<MxOperand>("MxFPR"#size), ?>;750 751def MxOp32AddrMode_fpcs : MxOpBundle<32, MxFPCSR, ?>;752def MxOp32AddrMode_fpi : MxOpBundle<32, MxFPIR, ?>;753 754class MxType8Class<string rLet, MxOperand reg>755 : MxType<i8, "b", "", rLet, reg,756 MxARI8, MxCP_ARI,757 MxARIPI8, MxCP_ARIPI,758 MxARIPD8, MxCP_ARIPD,759 MxARID8, MxCP_ARID,760 MxARII8, MxCP_ARII,761 MxAL8, MxCP_AL,762 MxPCD8, MxCP_PCD,763 MxPCI8, MxCP_PCI,764 Mxi8imm, Mxi8immSExt8,765 Mxloadi8>;766 767def MxType8 : MxType8Class<?,?>;768 769class MxType16Class<string rLet, MxOperand reg>770 : MxType<i16, "w", "", rLet, reg,771 MxARI16, MxCP_ARI,772 MxARIPI16, MxCP_ARIPI,773 MxARIPD16, MxCP_ARIPD,774 MxARID16, MxCP_ARID,775 MxARII16, MxCP_ARII,776 MxAL16, MxCP_AL,777 MxPCD16, MxCP_PCD,778 MxPCI16, MxCP_PCI,779 Mxi16imm, Mxi16immSExt16,780 Mxloadi16>;781 782def MxType16 : MxType16Class<?,?>;783 784class MxType32Class<string rLet, MxOperand reg>785 : MxType<i32, "l", "", rLet, reg,786 MxARI32, MxCP_ARI,787 MxARIPI32, MxCP_ARIPI,788 MxARIPD32, MxCP_ARIPD,789 MxARID32, MxCP_ARID,790 MxARII32, MxCP_ARII,791 MxAL32, MxCP_AL,792 MxPCD32, MxCP_PCD,793 MxPCI32, MxCP_PCI,794 Mxi32imm, Mxi32immSExt32,795 Mxloadi32>;796 797def MxType32 : MxType32Class<?,?>;798 799 800def MxType8d : MxType8Class<"d", MxDRD8>;801 802def MxType16d : MxType16Class<"d", MxDRD16>;803def MxType16a : MxType16Class<"a", MxARD16>;804def MxType16r : MxType16Class<"r", MxXRD16>;805def MxType32d : MxType32Class<"d", MxDRD32>;806def MxType32a : MxType32Class<"a", MxARD32>;807def MxType32r : MxType32Class<"r", MxXRD32>;808 809let Postfix = "_TC" in {810def MxType16d_TC : MxType16Class<"d", MxDRD16_TC>;811def MxType16a_TC : MxType16Class<"a", MxARD16_TC>;812def MxType16r_TC : MxType16Class<"r", MxXRD16_TC>;813def MxType32d_TC : MxType32Class<"d", MxDRD32_TC>;814def MxType32a_TC : MxType32Class<"a", MxARD32_TC>;815def MxType32r_TC : MxType32Class<"r", MxXRD32_TC>;816}817 818 819//===----------------------------------------------------------------------===//820// Subsystems821//===----------------------------------------------------------------------===//822 823include "M68kInstrData.td"824include "M68kInstrShiftRotate.td"825include "M68kInstrBits.td"826include "M68kInstrArithmetic.td"827include "M68kInstrControl.td"828include "M68kInstrAtomics.td"829 830include "M68kInstrCompiler.td"831