1//===-- LanaiInstrInfo.td - Target Description for Lanai Target -----------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file describes the Lanai instructions in TableGen format. 11// 12//===----------------------------------------------------------------------===// 13 14//===----------------------------------------------------------------------===// 15// Instruction format superclass 16//===----------------------------------------------------------------------===// 17 18include "LanaiInstrFormats.td" 19 20// -------------------------------------------------- // 21// Instruction Operands and Patterns 22// -------------------------------------------------- // 23 24// These are target-independent nodes, but have target-specific formats. 25def SDT_LanaiCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>]>; 26def SDT_LanaiCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, 27 SDTCisVT<1, i32>]>; 28def SDT_LanaiCall : SDTypeProfile<0, -1, [SDTCisVT<0, i32>]>; 29def SDT_LanaiSetFlag : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>; 30def SDT_LanaiSelectCC : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, 31 SDTCisSameAs<1, 2>]>; 32def SDT_LanaiSetCC : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, 33 SDTCisVT<1, i32>]>; 34def SDT_LanaiBrCC : SDTypeProfile<0, 2, [SDTCisVT<0, OtherVT>, 35 SDTCisVT<1, i32>]>; 36def SDT_LanaiAdjDynAlloc : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, 37 SDTCisVT<1, i32>]>; 38 39def Call : SDNode<"LanaiISD::CALL", SDT_LanaiCall, 40 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 41 SDNPVariadic]>; 42def RetFlag : SDNode<"LanaiISD::RET_FLAG", SDTNone, 43 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 44def CallSeqStart : SDNode<"ISD::CALLSEQ_START", SDT_LanaiCallSeqStart, 45 [SDNPHasChain, SDNPOutGlue]>; 46def CallSeqEnd : SDNode<"ISD::CALLSEQ_END", SDT_LanaiCallSeqEnd, 47 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 48def LanaiSetFlag : SDNode<"LanaiISD::SET_FLAG", SDT_LanaiSetFlag, 49 [SDNPOutGlue]>; 50def LanaiSubbF : SDNode<"LanaiISD::SUBBF", SDT_LanaiSetFlag, 51 [SDNPOutGlue, SDNPInGlue]>; 52def LanaiBrCC : SDNode<"LanaiISD::BR_CC", SDT_LanaiBrCC, 53 [SDNPHasChain, SDNPInGlue]>; 54def LanaiSelectCC : SDNode<"LanaiISD::SELECT_CC", SDT_LanaiSelectCC, 55 [SDNPInGlue]>; 56def LanaiSetCC : SDNode<"LanaiISD::SETCC", SDT_LanaiSetCC, 57 [SDNPInGlue]>; 58def LanaiHi : SDNode<"LanaiISD::HI", SDTIntUnaryOp>; 59def LanaiLo : SDNode<"LanaiISD::LO", SDTIntUnaryOp>; 60def LanaiSmall : SDNode<"LanaiISD::SMALL", SDTIntUnaryOp>; 61def LanaiAdjDynAlloc : SDNode<"LanaiISD::ADJDYNALLOC", SDT_LanaiAdjDynAlloc>; 62 63// Extract bits 0-15 (low-end) of an immediate value. 64def LO16 : SDNodeXForm<imm, [{ 65 return CurDAG->getTargetConstant((uint64_t)N->getZExtValue() & 0xffff, 66 SDLoc(N), MVT::i32); 67}]>; 68 69// Extract bits 16-31 (high-end) of an immediate value. 70// Transformation function: shift the immediate value down into the low bits. 71def HI16 : SDNodeXForm<imm, [{ 72 return CurDAG->getTargetConstant((uint64_t)N->getZExtValue() >> 16, SDLoc(N), 73 MVT::i32); 74}]>; 75 76def NEG : SDNodeXForm<imm, [{ 77 return CurDAG->getTargetConstant(-N->getSExtValue(), SDLoc(N), MVT::i32); 78}]>; 79 80def LO21 : SDNodeXForm<imm, [{ 81 return CurDAG->getTargetConstant((uint64_t)N->getZExtValue() & 0x1fffff, 82 SDLoc(N), MVT::i32); 83}]>; 84 85// Branch targets 86def BrTargetAsmOperand : AsmOperandClass { 87 let Name = "BrTarget"; 88} 89def BrTarget : Operand<OtherVT> { 90 let ParserMatchClass = BrTargetAsmOperand; 91 let EncoderMethod = "getBranchTargetOpValue"; 92 let DecoderMethod = "decodeBranch"; 93} 94 95def CallTargetAsmOperand : AsmOperandClass { 96 let Name = "CallTarget"; 97} 98def CallTarget : Operand<i32> { 99 let ParserMatchClass = CallTargetAsmOperand; 100 let EncoderMethod = "getBranchTargetOpValue"; 101 let DecoderMethod = "decodeBranch"; 102} 103 104def ImmShiftAsmOperand : AsmOperandClass { let Name = "ImmShift"; } 105def immShift : Operand<i32>, PatLeaf<(imm), [{ 106 int Imm = N->getSExtValue(); 107 return Imm >= -31 && Imm <= 31;}]> { 108 let ParserMatchClass = ImmShiftAsmOperand; 109 let DecoderMethod = "decodeShiftImm"; 110} 111 112def Imm10AsmOperand : AsmOperandClass { let Name = "Imm10"; } 113def imm10 : Operand<i32>, PatLeaf<(imm), [{ 114 return isInt<10>(N->getSExtValue()); }]> { 115 let ParserMatchClass = Imm10AsmOperand; 116} 117 118def immZExt21 : PatLeaf<(imm), 119 [{return isUInt<21>(N->getZExtValue()); }], LO21>; 120 121def LoImm16AsmOperand : AsmOperandClass { let Name = "LoImm16"; } 122def i32lo16z : Operand<i32>, PatLeaf<(i32 imm), [{ 123 // i32lo16 predicate - true if the 32-bit immediate has only rightmost 16 124 // bits set. 125 return ((N->getZExtValue() & 0xFFFFUL) == N->getZExtValue());}], LO16> { 126 let ParserMatchClass = LoImm16AsmOperand; 127} 128def i32neg16 : Operand<i32>, PatLeaf<(i32 imm), [{ 129 // i32neg16 predicate - true if the 32-bit immediate is negative and can 130 // be represented by a 16 bit integer. 131 int Imm = N->getSExtValue(); 132 return (Imm < 0) && (isInt<16>(Imm));}], LO16> { 133 let ParserMatchClass = LoImm16AsmOperand; 134} 135def i32lo16s : Operand<i32>, PatLeaf<(i32 imm), [{ 136 // i32lo16 predicate - true if the 32-bit immediate has only rightmost 16 137 // bits set. 138 return ((int64_t)(N->getSExtValue() & 0xFFFFUL) == N->getSExtValue());}], LO16> { 139 let ParserMatchClass = LoImm16AsmOperand; 140} 141 142def LoImm16AndAsmOperand : AsmOperandClass { let Name = "LoImm16And"; } 143def i32lo16and : Operand<i32>, PatLeaf<(i32 imm), [{ 144 // i32lo16 predicate - true if the 32-bit immediate has the rightmost 16 145 // bits set and the leftmost 16 bits 1's. 146 return (N->getZExtValue() >= 0xFFFF0000UL);}], LO16> { 147 let ParserMatchClass = LoImm16AndAsmOperand; 148 let PrintMethod = "printLo16AndImmOperand"; 149} 150 151def HiImm16AsmOperand : AsmOperandClass { let Name = "HiImm16"; } 152def i32hi16 : Operand<i32>, PatLeaf<(i32 imm), [{ 153 // i32hi16 predicate - true if the 32-bit immediate has only leftmost 16 154 // bits set. 155 return ((N->getZExtValue() & 0xFFFF0000UL) == N->getZExtValue());}], HI16> { 156 let ParserMatchClass = HiImm16AsmOperand; 157 let PrintMethod = "printHi16ImmOperand"; 158} 159 160def HiImm16AndAsmOperand : AsmOperandClass { let Name = "HiImm16And"; } 161def i32hi16and : Operand<i32>, PatLeaf<(i32 imm), [{ 162 // i32lo16 predicate - true if the 32-bit immediate has the leftmost 16 163 // bits set and the rightmost 16 bits 1's. 164 return ((N->getZExtValue() & 0xFFFFUL) == 0xFFFFUL);}], HI16> { 165 let ParserMatchClass = HiImm16AndAsmOperand; 166 let PrintMethod = "printHi16AndImmOperand"; 167} 168 169def LoImm21AsmOperand : AsmOperandClass { let Name = "LoImm21"; } 170def i32lo21 : Operand<i32>, PatLeaf<(i32 imm), [{ 171 // i32lo21 predicate - true if the 32-bit immediate has only rightmost 21 172 // bits set. 173 return ((N->getZExtValue() & 0x1FFFFFUL) == N->getZExtValue());}], LO21> { 174 let ParserMatchClass = LoImm21AsmOperand; 175} 176 177def AluOp : Operand<i32> { 178 let PrintMethod = "printAluOperand"; 179} 180 181// Addressing modes. 182def ADDRrr : ComplexPattern<i32, 3, "selectAddrRr", [], []>; 183def ADDRri : ComplexPattern<i32, 3, "selectAddrRi", [frameindex], []>; 184def ADDRsls : ComplexPattern<i32, 1, "selectAddrSls", [frameindex], []>; 185def ADDRspls : ComplexPattern<i32, 3, "selectAddrSpls", [frameindex], []>; 186 187// Address operands 188def MemRegImmAsmOperand : AsmOperandClass { 189 let Name = "MemRegImm"; 190 let ParserMethod = "parseMemoryOperand"; 191} 192def MEMri : Operand<i32> { 193 let DecoderMethod = "decodeRiMemoryValue"; 194 let EncoderMethod = "getRiMemoryOpValue"; 195 let MIOperandInfo = (ops GPR:$base, i32lo16s:$offset, AluOp:$Opcode); 196 let ParserMatchClass = MemRegImmAsmOperand; 197 let PrintMethod = "printMemRiOperand"; 198} 199 200def MemRegRegAsmOperand : AsmOperandClass { 201 let Name = "MemRegReg"; 202 let ParserMethod = "parseMemoryOperand"; 203} 204def MEMrr : Operand<i32> { 205 let DecoderMethod = "decodeRrMemoryValue"; 206 let EncoderMethod = "getRrMemoryOpValue"; 207 let MIOperandInfo = (ops GPR:$Op1, GPR:$Op2, AluOp:$Opcode); 208 let ParserMatchClass = MemRegRegAsmOperand; 209 let PrintMethod = "printMemRrOperand"; 210} 211 212def MemImmAsmOperand : AsmOperandClass { 213 let Name = "MemImm"; 214 let ParserMethod = "parseMemoryOperand"; 215} 216def MEMi : Operand<i32> { 217 let MIOperandInfo = (ops i32lo21:$offset); 218 let ParserMatchClass = MemImmAsmOperand; 219 let PrintMethod = "printMemImmOperand"; 220} 221 222def MemSplsAsmOperand : AsmOperandClass { 223 let Name = "MemSpls"; 224 let ParserMethod = "parseMemoryOperand"; 225} 226def MEMspls : Operand<i32> { 227 let DecoderMethod = "decodeSplsValue"; 228 let EncoderMethod = "getSplsOpValue"; 229 let MIOperandInfo = (ops GPR:$base, imm10:$offset, AluOp:$Opcode); 230 let ParserMatchClass = MemSplsAsmOperand; 231 let PrintMethod = "printMemSplsOperand"; 232} 233 234def CCOp : Operand<i32> { 235 let PrintMethod = "printCCOperand"; 236} 237 238// Predicate operand. Default to 0 = true. 239def CondCodeOperand : AsmOperandClass { let Name = "CondCode"; } 240 241def pred : PredicateOperand<i32, (ops i32imm), (ops (i32 0))> { 242 let PrintMethod = "printPredicateOperand"; 243 let ParserMatchClass = CondCodeOperand; 244 let DecoderMethod = "decodePredicateOperand"; 245} 246 247let hasSideEffects = 0, Inst = 0x00000001 in 248 def NOP : InstLanai<(outs), (ins), "nop", []>; 249 250// Special NOPs to change logging level in vlanai. 251let hasSideEffects = 0, Inst = 0x00000002 in 252 def LOG0 : InstLanai<(outs), (ins), "log_0", []>; 253let hasSideEffects = 0, Inst = 0x00000003 in 254 def LOG1 : InstLanai<(outs), (ins), "log_1", []>; 255let hasSideEffects = 0, Inst = 0x00000004 in 256 def LOG2 : InstLanai<(outs), (ins), "log_2", []>; 257let hasSideEffects = 0, Inst = 0x00000005 in 258 def LOG3 : InstLanai<(outs), (ins), "log_3", []>; 259let hasSideEffects = 0, Inst = 0x00000006 in 260 def LOG4 : InstLanai<(outs), (ins), "log_4", []>; 261 262// Map an SPLS instruction onto itself. All other instructions will be mapped 263// onto -1. Used to identify SPLS instructions. 264def splsIdempotent : InstrMapping { 265 let FilterClass = "InstSPLS"; 266 let RowFields = ["AsmString"]; 267 let ColFields = ["PostEncoderMethod"]; 268 let KeyCol = ["adjustPqBitsSpls"]; 269 let ValueCols = [["adjustPqBitsSpls"]]; 270} 271 272// -------------------------------------------------- // 273// ALU instructions 274// -------------------------------------------------- // 275multiclass ALUbase<bits<3> subOp, string AsmStr, SDNode OpNode, 276 PatLeaf LoExt, PatLeaf HiExt, 277 list<dag> loPattern, list<dag> hiPattern> { 278 // Register Immediate 279 let H = 0 in 280 def LO : InstRI<subOp, (outs GPR:$Rd), (ins GPR:$Rs1, LoExt:$imm16), 281 !strconcat(AsmStr, "\t$Rs1, $imm16, $Rd"), 282 loPattern>; 283 let H = 1 in 284 def HI : InstRI<subOp, (outs GPR:$Rd), (ins GPR:$Rs1, HiExt:$imm16), 285 !strconcat(AsmStr, "\t$Rs1, $imm16, $Rd"), 286 hiPattern>; 287 288} 289 290multiclass ALUarith<bits<3> subOp, string AsmStr, SDNode OpNode, 291 PatLeaf LoExt, PatLeaf HiExt> { 292 defm I_ : ALUbase<subOp, AsmStr, OpNode, LoExt, HiExt, [], []>; 293 294 // Register Register 295 let JJJJJ = 0 in 296 def R : InstRR<subOp, (outs GPR:$Rd), (ins GPR:$Rs1, GPR:$Rs2, pred:$DDDI), 297 !strconcat(AsmStr, "$DDDI\t$Rs1, $Rs2, $Rd"), 298 [(set GPR:$Rd, (OpNode GPR:$Rs1, GPR:$Rs2))]>; 299} 300 301multiclass ALUlogic<bits<3> subOp, string AsmStr, SDNode OpNode, 302 PatLeaf LoExt, PatLeaf HiExt> { 303 defm I_ : ALUbase<subOp, AsmStr, OpNode, LoExt, HiExt, 304 [(set GPR:$Rd, (OpNode GPR:$Rs1, LoExt:$imm16))], 305 [(set GPR:$Rd, (OpNode GPR:$Rs1, HiExt:$imm16))]>; 306 307 // Register Register 308 let JJJJJ = 0 in 309 def R : InstRR<subOp, (outs GPR:$Rd), (ins GPR:$Rs1, GPR:$Rs2, pred:$DDDI), 310 !strconcat(AsmStr, "$DDDI\t$Rs1, $Rs2, $Rd"), 311 [(set GPR:$Rd, (OpNode GPR:$Rs1, GPR:$Rs2))]>; 312} 313 314// Non flag setting ALU operations 315let isAsCheapAsAMove = 1, F = 0 in { 316 let isCommutable = 1 in { 317 defm ADD_ : ALUarith<0b000, "add", add, i32lo16z, i32hi16>; 318 } 319 defm SUB_ : ALUarith<0b010, "sub", sub, i32lo16z, i32hi16>; 320 let isCommutable = 1 in { 321 defm AND_ : ALUlogic<0b100, "and", and, i32lo16and, i32hi16and>; 322 defm OR_ : ALUlogic<0b101, "or", or, i32lo16z, i32hi16>; 323 defm XOR_ : ALUlogic<0b110, "xor", xor, i32lo16z, i32hi16>; 324 } 325} 326 327def : Pat<(add GPR:$Rs1, i32lo16z:$imm), 328 (ADD_I_LO GPR:$Rs1, i32lo16z:$imm)>; 329 330def : Pat<(sub GPR:$Rs1, i32lo16z:$imm), 331 (SUB_I_LO GPR:$Rs1, i32lo16z:$imm)>; 332 333def : Pat<(add GPR:$Rs1, i32hi16:$imm), 334 (ADD_I_HI GPR:$Rs1, i32hi16:$imm)>; 335 336def : Pat<(sub GPR:$Rs1, i32hi16:$imm), 337 (SUB_I_HI GPR:$Rs1, i32hi16:$imm)>; 338 339def : Pat<(i32 i32lo16and:$imm), (AND_I_LO (i32 R1), i32lo16and:$imm)>; 340def : Pat<(i32 i32hi16and:$imm), (AND_I_HI (i32 R1), i32hi16and:$imm)>; 341 342// Change add/sub with negative number to sub/add 343def : Pat<(add GPR:$Rs1, i32neg16:$imm), 344 (SUB_I_LO GPR:$Rs1, (NEG $imm))>; 345def : Pat<(sub GPR:$Rs1, i32neg16:$imm), 346 (ADD_I_LO GPR:$Rs1, (NEG $imm))>; 347 348// Flag (incl. carry) setting addition and subtraction 349let F = 1, Defs = [SR] in { 350 defm ADD_F_ : ALUarith<0b000, "add.f", addc, i32lo16z, i32hi16>; 351 defm SUB_F_ : ALUarith<0b010, "sub.f", subc, i32lo16z, i32hi16>; 352} 353 354def : Pat<(addc GPR:$Rs1, i32lo16z:$imm), 355 (ADD_F_I_LO GPR:$Rs1, i32lo16z:$imm)>; 356 357def : Pat<(subc GPR:$Rs1, i32lo16z:$imm), 358 (SUB_F_I_LO GPR:$Rs1, i32lo16z:$imm)>; 359 360def : Pat<(addc GPR:$Rs1, i32hi16:$imm), 361 (ADD_F_I_HI GPR:$Rs1, i32hi16:$imm)>; 362 363def : Pat<(subc GPR:$Rs1, i32hi16:$imm), 364 (SUB_F_I_HI GPR:$Rs1, i32hi16:$imm)>; 365 366// Carry using addition and subtraction 367let F = 0, Uses = [SR] in { 368 defm ADDC_ : ALUarith<0b001, "addc", adde, i32lo16z, i32hi16>; 369 defm SUBB_ : ALUarith<0b011, "subb", sube, i32lo16z, i32hi16>; 370} 371 372def : Pat<(adde GPR:$Rs1, i32lo16z:$imm), 373 (ADDC_I_LO GPR:$Rs1, i32lo16z:$imm)>; 374 375def : Pat<(sube GPR:$Rs1, i32lo16z:$imm), 376 (SUBB_I_LO GPR:$Rs1, i32lo16z:$imm)>; 377 378def : Pat<(adde GPR:$Rs1, i32hi16:$imm), 379 (ADDC_I_HI GPR:$Rs1, i32hi16:$imm)>; 380 381def : Pat<(sube GPR:$Rs1, i32hi16:$imm), 382 (SUBB_I_HI GPR:$Rs1, i32hi16:$imm)>; 383 384// Flag setting ALU operations 385let isAsCheapAsAMove = 1, F = 1, Defs = [SR] in { 386 let isCommutable = 1 in { 387 defm AND_F_ : ALUlogic<0b100, "and.f", and, i32lo16and, i32hi16and>; 388 defm OR_F_ : ALUlogic<0b101, "or.f", or, i32lo16z, i32hi16>; 389 defm XOR_F_ : ALUlogic<0b110, "xor.f", xor, i32lo16z, i32hi16>; 390 } 391} 392 393let isAsCheapAsAMove = 1, F = 1, Defs = [SR], Uses = [SR] in { 394 defm ADDC_F_ : ALUarith<0b001, "addc.f", adde, i32lo16z, i32hi16>; 395 defm SUBB_F_ : ALUarith<0b011, "subb.f", sube, i32lo16z, i32hi16>; 396} 397 398def : Pat<(LanaiSubbF GPR:$Rs1, GPR:$Rs2), 399 (SUBB_F_R GPR:$Rs1, GPR:$Rs2)>; 400 401def : Pat<(LanaiSubbF GPR:$Rs1, i32lo16z:$imm), 402 (SUBB_F_I_LO GPR:$Rs1, i32lo16z:$imm)>; 403 404def : Pat<(LanaiSubbF GPR:$Rs1, i32hi16:$imm), 405 (SUBB_F_I_HI GPR:$Rs1, i32hi16:$imm)>; 406 407def : InstAlias<"mov $src, $dst", (ADD_R GPR:$dst, GPR:$src, R0, 0)>; 408 409let isAsCheapAsAMove = 1, Rs1 = R0.Num, isCodeGenOnly = 1, H = 1, F = 0, 410 isReMaterializable = 1 in 411 def MOVHI : InstRI<0b000, (outs GPR:$Rd), (ins i32hi16:$imm16), 412 "mov\t$imm16, $Rd", 413 [(set GPR:$Rd, i32hi16:$imm16)]>; 414 415def : InstAlias<"mov $imm16, $dst", (ADD_I_LO GPR:$dst, R0, i32lo16z:$imm16)>; 416def : InstAlias<"mov $imm16, $dst", (ADD_I_HI GPR:$dst, R0, i32hi16:$imm16)>; 417def : InstAlias<"mov $imm16, $dst", 418 (AND_I_LO GPR:$dst, R1, i32lo16and:$imm16)>; 419def : InstAlias<"mov $imm16, $dst", 420 (AND_I_HI GPR:$dst, R1, i32hi16and:$imm16)>; 421 422// Shift instructions 423class ShiftRI<string AsmStr, list<dag> Pattern> 424 : InstRI<0b111, (outs GPR:$Rd), (ins GPR:$Rs1, immShift:$imm16), 425 !strconcat(AsmStr, "\t$Rs1, $imm16, $Rd"), Pattern> { 426 let isReMaterializable = 1; 427} 428 429let F = 0 in { 430 let H = 0 in 431 def SL_I : ShiftRI<"sh", [(set GPR:$Rd, (shl GPR:$Rs1, immShift:$imm16))]>; 432 let H = 1 in 433 def SA_I : ShiftRI<"sha", []>; 434} 435def : Pat<(srl GPR:$Rs1, immShift:$imm), (SL_I GPR:$Rs1, (NEG $imm))>; 436def : Pat<(sra GPR:$Rs1, immShift:$imm), (SA_I GPR:$Rs1, (NEG $imm))>; 437 438let F = 1, Defs = [SR] in { 439 let H = 0 in 440 def SL_F_I : ShiftRI<"sh.f", []>; 441 let H = 1 in 442 def SA_F_I : ShiftRI<"sha.f", []>; 443} 444 445class ShiftRR<string AsmStr, list<dag> Pattern> 446 : InstRR<0b111, (outs GPR:$Rd), (ins GPR:$Rs1, GPR:$Rs2, pred:$DDDI), AsmStr, 447 Pattern>; 448 449let F = 0 in { 450 let JJJJJ = 0b10000 in 451 def SHL_R : ShiftRR<"sh$DDDI\t$Rs1, $Rs2, $Rd", 452 [(set GPR:$Rd, (shl GPR:$Rs1, GPR:$Rs2))]>; 453 let isCodeGenOnly = 1 in { 454 let JJJJJ = 0b10000 in 455 def SRL_R : ShiftRR<"sh$DDDI\t$Rs1, $Rs2, $Rd", []>; 456 } 457 let JJJJJ = 0b11000 in 458 def SRA_R : ShiftRR<"sha$DDDI\t$Rs1, $Rs2, $Rd", []>; 459} 460 461let F = 1, Defs = [SR] in { 462 let JJJJJ = 0b10000 in 463 def SHL_F_R : ShiftRR<"sh.f$DDDI\t$Rs1, $Rs2, $Rd", []>; 464 let isCodeGenOnly = 1 in { 465 let JJJJJ = 0b10000 in 466 def SRL_F_R : ShiftRR<"sh.f$DDDI\t$Rs1, $Rs2, $Rd", []>; 467 } 468 let JJJJJ = 0b11000 in 469 def SRA_F_R : ShiftRR<"sha.f$DDDI\t$Rs1, $Rs2, $Rd", []>; 470} 471 472// Expand shift-right operations 473def : Pat<(srl GPR:$Rs1, GPR:$Rs2), 474 (SRL_R GPR:$Rs1, (SUB_R R0, GPR:$Rs2))>; 475def : Pat<(sra GPR:$Rs1, GPR:$Rs2), 476 (SRA_R GPR:$Rs1, (SUB_R R0, GPR:$Rs2))>; 477 478// -------------------------------------------------- // 479// LOAD instructions 480// -------------------------------------------------- // 481 482class LoadRR<string OpcString, PatFrag OpNode, ValueType Ty> 483 : InstRRM<0b0, (outs GPR:$Rd), (ins MEMrr:$src), 484 !strconcat(OpcString, "\t$src, $Rd"), 485 [(set (Ty GPR:$Rd), (OpNode ADDRrr:$src))]>, 486 Sched<[WriteLD]> { 487 bits<20> src; 488 489 let Rs1 = src{19-15}; 490 let Rs2 = src{14-10}; 491 let P = src{9}; 492 let Q = src{8}; 493 let BBB = src{7-5}; 494 let JJJJJ = src{4-0}; 495 let mayLoad = 1; 496} 497 498class LoadRI<string OpcString, PatFrag OpNode, ValueType Ty> 499 : InstRM<0b0, (outs GPR:$Rd), (ins MEMri:$src), 500 !strconcat(OpcString, "\t$src, $Rd"), 501 [(set (Ty GPR:$Rd), (OpNode ADDRri:$src))]>, 502 Sched<[WriteLD]> { 503 bits<23> src; 504 505 let Itinerary = IIC_LD; 506 let Rs1 = src{22-18}; 507 let P = src{17}; 508 let Q = src{16}; 509 let imm16 = src{15-0}; 510 let isReMaterializable = 1; 511 let mayLoad = 1; 512} 513 514let E = 0 in { 515 let YL = 0b01 in { 516 // uld is used here and ld in the alias as the alias is printed out first if 517 // an alias exist 518 def LDW_RI : LoadRI<"uld", load, i32>; 519 def LDW_RR : LoadRR<"ld", load, i32>; 520 } 521} 522 523def : InstAlias<"ld $src, $dst", (LDW_RI GPR:$dst, MEMri:$src)>; 524 525let E = 1 in { 526 let YL = 0b01 in { 527 def LDWz_RR : LoadRR<"uld", zextloadi32, i32>; 528 } 529} 530 531let E = 1 in { 532 let YL = 0b00 in 533 def LDHz_RR : LoadRR<"uld.h", zextloadi16, i32>; 534 let YL = 0b10 in 535 def LDBz_RR : LoadRR<"uld.b", zextloadi8, i32>; 536} 537 538let E = 0 in { 539 let YL = 0b00 in 540 def LDHs_RR : LoadRR<"ld.h", sextloadi16, i32>; 541 let YL = 0b10 in 542 def LDBs_RR : LoadRR<"ld.b", sextloadi8, i32>; 543} 544 545def LDADDR : InstSLS<0x0, (outs GPR:$Rd), (ins MEMi:$src), 546 "ld\t$src, $Rd", 547 [(set (i32 GPR:$Rd), (load ADDRsls:$src))]>, 548 Sched<[WriteLD]> { 549 bits<21> src; 550 551 let Itinerary = IIC_LD; 552 let msb = src{20-16}; 553 let lsb = src{15-0}; 554 let isReMaterializable = 1; 555 let mayLoad = 1; 556} 557 558class LoadSPLS<string asmstring, PatFrag opNode> 559 : InstSPLS<(outs GPR:$Rd), (ins MEMspls:$src), 560 !strconcat(asmstring, "\t$src, $Rd"), 561 [(set (i32 GPR:$Rd), (opNode ADDRspls:$src))]>, 562 Sched<[WriteLDSW]> { 563 bits<17> src; 564 let Itinerary = IIC_LDSW; 565 let Rs1 = src{16-12}; 566 let P = src{11}; 567 let Q = src{10}; 568 let imm10 = src{9-0}; 569 let mayLoad = 1; 570 let isReMaterializable = 1; 571} 572 573let Y = 0, S = 0, E = 1 in 574 def LDHz_RI : LoadSPLS<"uld.h", zextloadi16>; 575 576let Y = 0, S = 0, E = 0 in 577 def LDHs_RI : LoadSPLS<"ld.h", sextloadi16>; 578 579let Y = 1, S = 0, E = 1 in 580 def LDBz_RI : LoadSPLS<"uld.b", zextloadi8>; 581 582let Y = 1, S = 0, E = 0 in 583 def LDBs_RI : LoadSPLS<"ld.b", sextloadi8>; 584 585def SLI : InstSLI<(outs GPR:$Rd), (ins i32lo21:$imm), 586 "mov\t$imm, $Rd", 587 [(set GPR:$Rd, i32lo21:$imm)]> { 588 bits<21> imm; 589 590 let msb = imm{20-16}; 591 let lsb = imm{15-0}; 592 let isReMaterializable = 1; 593 let isAsCheapAsAMove = 1; 594} 595 596// -------------------------------------------------- // 597// STORE instructions 598// -------------------------------------------------- // 599 600class StoreRR<string OpcString, PatFrag OpNode, ValueType Ty> 601 : InstRRM<0b1, (outs), (ins GPR:$Rd, MEMrr:$dst), 602 !strconcat(OpcString, "\t$Rd, $dst"), 603 [(OpNode (Ty GPR:$Rd), ADDRrr:$dst)]>, 604 Sched<[WriteST]> { 605 bits<20> dst; 606 607 let Itinerary = IIC_ST; 608 let Rs1 = dst{19-15}; 609 let Rs2 = dst{14-10}; 610 let P = dst{9}; 611 let Q = dst{8}; 612 let BBB = dst{7-5}; 613 let JJJJJ = dst{4-0}; 614 let mayStore = 1; 615} 616 617class StoreRI<string OpcString, PatFrag OpNode, ValueType Ty> 618 : InstRM<0b1, (outs), (ins GPR:$Rd, MEMri:$dst), 619 !strconcat(OpcString, "\t$Rd, $dst"), 620 [(OpNode (Ty GPR:$Rd), ADDRri:$dst)]>, 621 Sched<[WriteST]> { 622 bits<23> dst; 623 624 let Itinerary = IIC_ST; 625 let Rs1 = dst{22-18}; 626 let P = dst{17}; 627 let Q = dst{16}; 628 let imm16 = dst{15-0}; 629 let mayStore = 1; 630} 631 632let YL = 0b01, E = 0 in { 633 def SW_RR : StoreRR<"st", store, i32>; 634 def SW_RI : StoreRI<"st", store, i32>; 635} 636 637let E = 0 in { 638 let YL = 0b00 in 639 def STH_RR : StoreRR<"st.h", truncstorei16, i32>; 640 let YL = 0b10 in 641 def STB_RR : StoreRR<"st.b", truncstorei8, i32>; 642} 643 644def STADDR : InstSLS<0x1, (outs), (ins GPR:$Rd, MEMi:$dst), 645 "st\t$Rd, $dst", 646 [(store (i32 GPR:$Rd), ADDRsls:$dst)]>, 647 Sched<[WriteST]> { 648 bits<21> dst; 649 650 let Itinerary = IIC_ST; 651 let msb = dst{20-16}; 652 let lsb = dst{15-0}; 653 let mayStore = 1; 654} 655 656class StoreSPLS<string asmstring, PatFrag opNode> 657 : InstSPLS<(outs), (ins GPR:$Rd, MEMspls:$dst), 658 !strconcat(asmstring, "\t$Rd, $dst"), 659 [(opNode (i32 GPR:$Rd), ADDRspls:$dst)]>, 660 Sched<[WriteSTSW]> { 661 bits<17> dst; 662 663 let Itinerary = IIC_STSW; 664 let Rs1 = dst{16-12}; 665 let P = dst{11}; 666 let Q = dst{10}; 667 let imm10 = dst{9-0}; 668 let mayStore = 1; 669} 670 671let Y = 0, S = 1, E = 0 in 672 def STH_RI : StoreSPLS<"st.h", truncstorei16>; 673 674let Y = 1, S = 1, E = 0 in 675 def STB_RI : StoreSPLS<"st.b", truncstorei8>; 676 677// -------------------------------------------------- // 678// BRANCH instructions 679// -------------------------------------------------- // 680 681let isBranch = 1, isBarrier = 1, isTerminator = 1, hasDelaySlot = 1 in { 682 def BT : InstBR<(outs), (ins BrTarget:$addr), 683 "bt\t$addr", 684 [(br bb:$addr)]> { 685 let DDDI = 0b0000; 686 } 687 let Uses = [SR] in 688 def BRCC : InstBR<(outs), (ins BrTarget:$addr, CCOp:$DDDI), 689 "b$DDDI\t$addr", 690 [(LanaiBrCC bb:$addr, imm:$DDDI)]>; 691 692 let isIndirectBranch = 1 in { 693 def JR : InstRR<0b101, (outs), (ins GPR:$Rs2), "bt\t$Rs2", 694 [(brind GPR:$Rs2)]> { 695 let Rs1 = R0.Num; 696 let Rd = R2.Num; 697 let F = 0; 698 let JJJJJ = 0; 699 let DDDI = 0; 700 } 701 } 702} 703 704// -------------------------------------------------- // 705// Condition/SF instructions 706// -------------------------------------------------- // 707 708// Instructions to set flags used in lowering comparisons. 709multiclass SF<bits<3> op2Val, string AsmStr> { 710 let F = 1, Rd = R0.Num, JJJJJ = 0, Defs = [SR], DDDI = 0 in 711 def _RR : InstRR<op2Val, (outs), (ins GPR:$Rs1, GPR:$Rs2), 712 !strconcat(AsmStr, "\t$Rs1, $Rs2, %r0"), 713 [(LanaiSetFlag (i32 GPR:$Rs1), (i32 GPR:$Rs2))]>; 714 let F = 1, Rd = R0.Num, H = 0, Defs = [SR] in 715 def _RI_LO : InstRI<op2Val, (outs), (ins GPR:$Rs1, i32lo16z:$imm16), 716 !strconcat(AsmStr, "\t$Rs1, $imm16, %r0"), 717 [(LanaiSetFlag (i32 GPR:$Rs1), i32lo16z:$imm16)]>; 718 let F = 1, Rd = R0.Num, H = 1, Defs = [SR] in 719 def _RI_HI : InstRI<op2Val, (outs), (ins GPR:$Rs1, i32hi16:$imm16), 720 !strconcat(AsmStr, "\t$Rs1, $imm16, %r0"), 721 [(LanaiSetFlag (i32 GPR:$Rs1), i32hi16:$imm16)]>; 722} 723let isCodeGenOnly = 1, isCompare = 1 in { 724 defm SFSUB_F : SF<0b010, "sub.f">; 725} 726 727// Jump and link 728let isCall = 1, hasDelaySlot = 1, isCodeGenOnly = 1, Uses = [SP], 729 Defs = [RCA] in { 730 def CALL : Pseudo<(outs), (ins CallTarget:$addr), "", []>; 731 def CALLR : Pseudo<(outs), (ins GPR:$Rs1), "", [(Call GPR:$Rs1)]>; 732} 733 734let isReturn = 1, isTerminator = 1, hasDelaySlot = 1, isBarrier = 1, 735 Uses = [RCA] in { 736 def RET : InstRM<0b0, (outs), (ins), 737 "ld\t-4[%fp], %pc ! return", 738 [(RetFlag)]> { 739 let Rd = PC.Num; 740 let Rs1 = FP.Num; 741 let P = 1; 742 let Q = 0; 743 let imm16 = -4; 744 745 // Post encoding is not needed for RET. 746 let PostEncoderMethod = ""; 747 } 748} 749 750// ADJCALLSTACKDOWN/UP implicitly use/def SP because they may be expanded into 751// a stack adjustment and the codegen must know that they may modify the stack 752// pointer before prolog-epilog rewriting occurs. 753// Pessimistically assume ADJCALLSTACKDOWN / ADJCALLSTACKUP will become 754// sub / add which can clobber SP. 755let Defs = [SP], Uses = [SP] in { 756 def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt), 757 "#ADJCALLSTACKDOWN $amt", 758 [(CallSeqStart timm:$amt)]>; 759 def ADJCALLSTACKUP : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), 760 "#ADJCALLSTACKUP $amt1 $amt2", 761 [(CallSeqEnd timm:$amt1, timm:$amt2)]>; 762} 763 764let Defs = [SP], Uses = [SP] in { 765 def ADJDYNALLOC : Pseudo<(outs GPR:$dst), (ins GPR:$src), 766 "#ADJDYNALLOC $dst $src", 767 [(set GPR:$dst, (LanaiAdjDynAlloc GPR:$src))]>; 768} 769 770let Uses = [SR] in { 771 def SCC : InstSCC<(outs GPR:$Rs1), (ins CCOp:$DDDI), 772 "s$DDDI\t$Rs1", 773 [(set (i32 GPR:$Rs1), (LanaiSetCC imm:$DDDI))]>; 774} 775 776// SCC's output is already 1-bit so and'ing with 1 is redundant. 777def : Pat<(and (LanaiSetCC imm:$DDDI), 1), (SCC imm:$DDDI)>; 778 779// Select with hardware support 780let Uses = [SR], isSelect = 1 in { 781 def SELECT : InstRR<0b111, (outs GPR:$Rd), 782 (ins GPR:$Rs1, GPR:$Rs2, CCOp:$DDDI), 783 "sel.$DDDI $Rs1, $Rs2, $Rd", 784 [(set (i32 GPR:$Rd), 785 (LanaiSelectCC (i32 GPR:$Rs1), (i32 GPR:$Rs2), 786 (imm:$DDDI)))]> { 787 let JJJJJ = 0; 788 let F = 0; 789 } 790} 791 792let isBranch = 1, isBarrier = 1, isTerminator = 1, hasDelaySlot = 1, 793 isIndirectBranch = 1, Uses = [SR] in { 794 def BRIND_CC : InstRR<0b101, (outs), (ins GPR:$Rs1, CCOp:$DDDI), 795 "b$DDDI\t$Rs1", []> { 796 let F = 0; 797 let JJJJJ = 0; 798 let Rd = PC.Num; 799 let Rs2 = R0.Num; 800 } 801 802 def BRIND_CCA : InstRR<0b101, (outs), (ins GPR:$Rs1, GPR:$Rs2, CCOp:$DDDI), 803 "b${DDDI}\t$Rs1 add $Rs2", []> { 804 let F = 0; 805 let Rd = PC.Num; 806 let JJJJJ = 0; 807 } 808} 809 810// TODO: This only considers the case where BROFF is an immediate and not where 811// it is a register. Add support for register relative branching. 812let isBranch = 1, isBarrier = 1, isTerminator = 1, hasDelaySlot = 1, Rs1 = 0, 813 Uses = [SR] in 814 def BRR : InstBRR<(outs), (ins i16imm:$imm16, CCOp:$DDDI), 815 "b${DDDI}.r\t$imm16", []>; 816 817let F = 0 in { 818// Population Count (POPC) 819def POPC: InstSpecial<0b001, (outs GPR:$Rd), (ins GPR:$Rs1), 820 "popc\t$Rs1, $Rd", 821 [(set GPR:$Rd, (ctpop GPR:$Rs1))]>; 822 823// Count Leading Zeros (LEADZ) 824def LEADZ: InstSpecial<0b010, (outs GPR:$Rd), (ins GPR:$Rs1), 825 "leadz\t$Rs1, $Rd", [(set GPR:$Rd, (ctlz GPR:$Rs1))]>; 826 827// Count Trailing Zeros (TRAILZ) 828def TRAILZ : InstSpecial<0b011, (outs GPR:$Rd), (ins GPR:$Rs1), 829 "trailz\t$Rs1, $Rd", 830 [(set GPR:$Rd, (cttz GPR:$Rs1))]>; 831} 832 833//===----------------------------------------------------------------------===// 834// Non-Instruction Patterns 835//===----------------------------------------------------------------------===// 836 837// i32 0 and R0 can be used interchangeably. 838def : Pat<(i32 0), (i32 R0)>; 839// i32 -1 and R1 can be used interchangeably. 840def : Pat<(i32 -1), (i32 R1)>; 841 842// unsigned 16-bit immediate 843def : Pat<(i32 i32lo16z:$imm), (OR_I_LO (i32 R0), imm:$imm)>; 844 845// arbitrary immediate 846def : Pat<(i32 imm:$imm), (OR_I_LO (MOVHI (HI16 imm:$imm)), (LO16 imm:$imm))>; 847 848// Calls 849def : Pat<(Call tglobaladdr:$dst), (CALL tglobaladdr:$dst)>; 850def : Pat<(Call texternalsym:$dst), (CALL texternalsym:$dst)>; 851 852// Loads 853def : Pat<(extloadi8 ADDRspls:$src), (i32 (LDBz_RI ADDRspls:$src))>; 854def : Pat<(extloadi16 ADDRspls:$src), (i32 (LDHz_RI ADDRspls:$src))>; 855 856// GlobalAddress, ExternalSymbol, Jumptable, ConstantPool 857def : Pat<(LanaiHi tglobaladdr:$dst), (MOVHI tglobaladdr:$dst)>; 858def : Pat<(LanaiLo tglobaladdr:$dst), (OR_I_LO (i32 R0), tglobaladdr:$dst)>; 859def : Pat<(LanaiSmall tglobaladdr:$dst), (SLI tglobaladdr:$dst)>; 860def : Pat<(LanaiHi texternalsym:$dst), (MOVHI texternalsym:$dst)>; 861def : Pat<(LanaiLo texternalsym:$dst), (OR_I_LO (i32 R0), texternalsym:$dst)>; 862def : Pat<(LanaiSmall texternalsym:$dst), (SLI texternalsym:$dst)>; 863def : Pat<(LanaiHi tblockaddress:$dst), (MOVHI tblockaddress:$dst)>; 864def : Pat<(LanaiLo tblockaddress:$dst), (OR_I_LO (i32 R0), tblockaddress:$dst)>; 865def : Pat<(LanaiSmall tblockaddress:$dst), (SLI tblockaddress:$dst)>; 866def : Pat<(LanaiHi tjumptable:$dst), (MOVHI tjumptable:$dst)>; 867def : Pat<(LanaiLo tjumptable:$dst), (OR_I_LO (i32 R0), tjumptable:$dst)>; 868def : Pat<(LanaiSmall tjumptable:$dst), (SLI tjumptable:$dst)>; 869def : Pat<(LanaiHi tconstpool:$dst), (MOVHI tconstpool:$dst)>; 870def : Pat<(LanaiLo tconstpool:$dst), (OR_I_LO (i32 R0), tconstpool:$dst)>; 871def : Pat<(LanaiSmall tconstpool:$dst), (SLI tconstpool:$dst)>; 872 873def : Pat<(or GPR:$hi, (LanaiLo tglobaladdr:$lo)), 874 (OR_I_LO GPR:$hi, tglobaladdr:$lo)>; 875def : Pat<(or R0, (LanaiSmall tglobaladdr:$small)), 876 (SLI tglobaladdr:$small)>; 877def : Pat<(or GPR:$hi, (LanaiLo texternalsym:$lo)), 878 (OR_I_LO GPR:$hi, texternalsym:$lo)>; 879def : Pat<(or R0, (LanaiSmall texternalsym:$small)), 880 (SLI texternalsym:$small)>; 881def : Pat<(or GPR:$hi, (LanaiLo tblockaddress:$lo)), 882 (OR_I_LO GPR:$hi, tblockaddress:$lo)>; 883def : Pat<(or R0, (LanaiSmall tblockaddress:$small)), 884 (SLI tblockaddress:$small)>; 885def : Pat<(or GPR:$hi, (LanaiLo tjumptable:$lo)), 886 (OR_I_LO GPR:$hi, tjumptable:$lo)>; 887def : Pat<(or R0, (LanaiSmall tjumptable:$small)), 888 (SLI tjumptable:$small)>; 889def : Pat<(or GPR:$hi, (LanaiLo tconstpool:$lo)), 890 (OR_I_LO GPR:$hi, tconstpool:$lo)>; 891def : Pat<(or R0, (LanaiSmall tconstpool:$small)), 892 (SLI tconstpool:$small)>; 893