1//===- XCoreInstrInfo.td - Target Description for XCore ----*- tablegen -*-===// 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 XCore instructions in TableGen format. 11// 12//===----------------------------------------------------------------------===// 13 14// Uses of CP, DP are not currently reflected in the patterns, since 15// having a physical register as an operand prevents loop hoisting and 16// since the value of these registers never changes during the life of the 17// function. 18 19//===----------------------------------------------------------------------===// 20// Instruction format superclass. 21//===----------------------------------------------------------------------===// 22 23include "XCoreInstrFormats.td" 24 25//===----------------------------------------------------------------------===// 26// Feature predicates. 27//===----------------------------------------------------------------------===// 28 29// HasXS1A - This predicate is true when the target processor supports XS1A 30// instructions. 31def HasXS1A : Predicate<"Subtarget.isXS1A()">; 32 33// HasXS1B - This predicate is true when the target processor supports XS1B 34// instructions. 35def HasXS1B : Predicate<"Subtarget.isXS1B()">; 36 37//===----------------------------------------------------------------------===// 38// XCore specific DAG Nodes. 39// 40 41// Call 42def SDT_XCoreBranchLink : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>; 43def XCoreBranchLink : SDNode<"XCoreISD::BL",SDT_XCoreBranchLink, 44 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; 45 46def XCoreRetsp : SDNode<"XCoreISD::RETSP", SDTNone, 47 [SDNPHasChain, SDNPOptInFlag]>; 48 49def SDT_XCoreAddress : SDTypeProfile<1, 1, 50 [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>; 51 52def pcrelwrapper : SDNode<"XCoreISD::PCRelativeWrapper", SDT_XCoreAddress, 53 []>; 54 55def dprelwrapper : SDNode<"XCoreISD::DPRelativeWrapper", SDT_XCoreAddress, 56 []>; 57 58def cprelwrapper : SDNode<"XCoreISD::CPRelativeWrapper", SDT_XCoreAddress, 59 []>; 60 61def SDT_XCoreStwsp : SDTypeProfile<0, 2, [SDTCisInt<1>]>; 62def XCoreStwsp : SDNode<"XCoreISD::STWSP", SDT_XCoreStwsp, 63 [SDNPHasChain]>; 64 65// These are target-independent nodes, but have target-specific formats. 66def SDT_XCoreCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>; 67def SDT_XCoreCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, 68 SDTCisVT<1, i32> ]>; 69 70def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_XCoreCallSeqStart, 71 [SDNPHasChain, SDNPOutFlag]>; 72def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_XCoreCallSeqEnd, 73 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; 74 75//===----------------------------------------------------------------------===// 76// Instruction Pattern Stuff 77//===----------------------------------------------------------------------===// 78 79def div4_xform : SDNodeXForm<imm, [{ 80 // Transformation function: imm/4 81 assert(N->getZExtValue() % 4 == 0); 82 return getI32Imm(N->getZExtValue()/4); 83}]>; 84 85def msksize_xform : SDNodeXForm<imm, [{ 86 // Transformation function: get the size of a mask 87 assert(isMask_32(N->getZExtValue())); 88 // look for the first non-zero bit 89 return getI32Imm(32 - CountLeadingZeros_32(N->getZExtValue())); 90}]>; 91 92def neg_xform : SDNodeXForm<imm, [{ 93 // Transformation function: -imm 94 uint32_t value = N->getZExtValue(); 95 return getI32Imm(-value); 96}]>; 97 98def bpwsub_xform : SDNodeXForm<imm, [{ 99 // Transformation function: 32-imm 100 uint32_t value = N->getZExtValue(); 101 return getI32Imm(32-value); 102}]>; 103 104def div4neg_xform : SDNodeXForm<imm, [{ 105 // Transformation function: -imm/4 106 uint32_t value = N->getZExtValue(); 107 assert(-value % 4 == 0); 108 return getI32Imm(-value/4); 109}]>; 110 111def immUs4Neg : PatLeaf<(imm), [{ 112 uint32_t value = (uint32_t)N->getZExtValue(); 113 return (-value)%4 == 0 && (-value)/4 <= 11; 114}]>; 115 116def immUs4 : PatLeaf<(imm), [{ 117 uint32_t value = (uint32_t)N->getZExtValue(); 118 return value%4 == 0 && value/4 <= 11; 119}]>; 120 121def immUsNeg : PatLeaf<(imm), [{ 122 return -((uint32_t)N->getZExtValue()) <= 11; 123}]>; 124 125def immUs : PatLeaf<(imm), [{ 126 return (uint32_t)N->getZExtValue() <= 11; 127}]>; 128 129def immU6 : PatLeaf<(imm), [{ 130 return (uint32_t)N->getZExtValue() < (1 << 6); 131}]>; 132 133def immU10 : PatLeaf<(imm), [{ 134 return (uint32_t)N->getZExtValue() < (1 << 10); 135}]>; 136 137def immU16 : PatLeaf<(imm), [{ 138 return (uint32_t)N->getZExtValue() < (1 << 16); 139}]>; 140 141def immU20 : PatLeaf<(imm), [{ 142 return (uint32_t)N->getZExtValue() < (1 << 20); 143}]>; 144 145// FIXME check subtarget. Currently we check if the immediate 146// is in the common subset of legal immediate values for both 147// XS1A and XS1B. 148def immMskBitp : PatLeaf<(imm), [{ 149 uint32_t value = (uint32_t)N->getZExtValue(); 150 if (!isMask_32(value)) { 151 return false; 152 } 153 int msksize = 32 - CountLeadingZeros_32(value); 154 return (msksize >= 1 && msksize <= 8) 155 || msksize == 16 156 || msksize == 24 157 || msksize == 32; 158}]>; 159 160// FIXME check subtarget. Currently we check if the immediate 161// is in the common subset of legal immediate values for both 162// XS1A and XS1B. 163def immBitp : PatLeaf<(imm), [{ 164 uint32_t value = (uint32_t)N->getZExtValue(); 165 return (value >= 1 && value <= 8) 166 || value == 16 167 || value == 24 168 || value == 32; 169}]>; 170 171def immBpwSubBitp : PatLeaf<(imm), [{ 172 uint32_t value = (uint32_t)N->getZExtValue(); 173 return (value >= 24 && value <= 31) 174 || value == 16 175 || value == 8 176 || value == 0; 177}]>; 178 179def lda16f : PatFrag<(ops node:$addr, node:$offset), 180 (add node:$addr, (shl node:$offset, 1))>; 181def lda16b : PatFrag<(ops node:$addr, node:$offset), 182 (sub node:$addr, (shl node:$offset, 1))>; 183def ldawf : PatFrag<(ops node:$addr, node:$offset), 184 (add node:$addr, (shl node:$offset, 2))>; 185def ldawb : PatFrag<(ops node:$addr, node:$offset), 186 (sub node:$addr, (shl node:$offset, 2))>; 187 188// Instruction operand types 189def calltarget : Operand<i32>; 190def brtarget : Operand<OtherVT>; 191def pclabel : Operand<i32>; 192 193// Addressing modes 194def ADDRspii : ComplexPattern<i32, 2, "SelectADDRspii", [add, frameindex], []>; 195def ADDRdpii : ComplexPattern<i32, 2, "SelectADDRdpii", [add, dprelwrapper], 196 []>; 197def ADDRcpii : ComplexPattern<i32, 2, "SelectADDRcpii", [add, cprelwrapper], 198 []>; 199 200// Address operands 201def MEMii : Operand<i32> { 202 let PrintMethod = "printMemOperand"; 203 let MIOperandInfo = (ops i32imm, i32imm); 204} 205 206//===----------------------------------------------------------------------===// 207// Instruction Class Templates 208//===----------------------------------------------------------------------===// 209 210// Three operand short 211 212multiclass F3R_2RUS<string OpcStr, SDNode OpNode> { 213 def _3r: _F3R< 214 (outs GRRegs:$dst), (ins GRRegs:$b, GRRegs:$c), 215 !strconcat(OpcStr, " $dst, $b, $c"), 216 [(set GRRegs:$dst, (OpNode GRRegs:$b, GRRegs:$c))]>; 217 def _2rus : _F2RUS< 218 (outs GRRegs:$dst), (ins GRRegs:$b, i32imm:$c), 219 !strconcat(OpcStr, " $dst, $b, $c"), 220 [(set GRRegs:$dst, (OpNode GRRegs:$b, immUs:$c))]>; 221} 222 223multiclass F3R_2RUS_np<string OpcStr> { 224 def _3r: _F3R< 225 (outs GRRegs:$dst), (ins GRRegs:$b, GRRegs:$c), 226 !strconcat(OpcStr, " $dst, $b, $c"), 227 []>; 228 def _2rus : _F2RUS< 229 (outs GRRegs:$dst), (ins GRRegs:$b, i32imm:$c), 230 !strconcat(OpcStr, " $dst, $b, $c"), 231 []>; 232} 233 234multiclass F3R_2RBITP<string OpcStr, SDNode OpNode> { 235 def _3r: _F3R< 236 (outs GRRegs:$dst), (ins GRRegs:$b, GRRegs:$c), 237 !strconcat(OpcStr, " $dst, $b, $c"), 238 [(set GRRegs:$dst, (OpNode GRRegs:$b, GRRegs:$c))]>; 239 def _2rus : _F2RUS< 240 (outs GRRegs:$dst), (ins GRRegs:$b, i32imm:$c), 241 !strconcat(OpcStr, " $dst, $b, $c"), 242 [(set GRRegs:$dst, (OpNode GRRegs:$b, immBitp:$c))]>; 243} 244 245class F3R<string OpcStr, SDNode OpNode> : _F3R< 246 (outs GRRegs:$dst), (ins GRRegs:$b, GRRegs:$c), 247 !strconcat(OpcStr, " $dst, $b, $c"), 248 [(set GRRegs:$dst, (OpNode GRRegs:$b, GRRegs:$c))]>; 249 250class F3R_np<string OpcStr> : _F3R< 251 (outs GRRegs:$dst), (ins GRRegs:$b, GRRegs:$c), 252 !strconcat(OpcStr, " $dst, $b, $c"), 253 []>; 254// Three operand long 255 256/// FL3R_L2RUS multiclass - Define a normal FL3R/FL2RUS pattern in one shot. 257multiclass FL3R_L2RUS<string OpcStr, SDNode OpNode> { 258 def _l3r: _FL3R< 259 (outs GRRegs:$dst), (ins GRRegs:$b, GRRegs:$c), 260 !strconcat(OpcStr, " $dst, $b, $c"), 261 [(set GRRegs:$dst, (OpNode GRRegs:$b, GRRegs:$c))]>; 262 def _l2rus : _FL2RUS< 263 (outs GRRegs:$dst), (ins GRRegs:$b, i32imm:$c), 264 !strconcat(OpcStr, " $dst, $b, $c"), 265 [(set GRRegs:$dst, (OpNode GRRegs:$b, immUs:$c))]>; 266} 267 268/// FL3R_L2RUS multiclass - Define a normal FL3R/FL2RUS pattern in one shot. 269multiclass FL3R_L2RBITP<string OpcStr, SDNode OpNode> { 270 def _l3r: _FL3R< 271 (outs GRRegs:$dst), (ins GRRegs:$b, GRRegs:$c), 272 !strconcat(OpcStr, " $dst, $b, $c"), 273 [(set GRRegs:$dst, (OpNode GRRegs:$b, GRRegs:$c))]>; 274 def _l2rus : _FL2RUS< 275 (outs GRRegs:$dst), (ins GRRegs:$b, i32imm:$c), 276 !strconcat(OpcStr, " $dst, $b, $c"), 277 [(set GRRegs:$dst, (OpNode GRRegs:$b, immBitp:$c))]>; 278} 279 280class FL3R<string OpcStr, SDNode OpNode> : _FL3R< 281 (outs GRRegs:$dst), (ins GRRegs:$b, GRRegs:$c), 282 !strconcat(OpcStr, " $dst, $b, $c"), 283 [(set GRRegs:$dst, (OpNode GRRegs:$b, GRRegs:$c))]>; 284 285// Register - U6 286// Operand register - U6 287multiclass FRU6_LRU6_branch<string OpcStr> { 288 def _ru6: _FRU6< 289 (outs), (ins GRRegs:$cond, brtarget:$dest), 290 !strconcat(OpcStr, " $cond, $dest"), 291 []>; 292 def _lru6: _FLRU6< 293 (outs), (ins GRRegs:$cond, brtarget:$dest), 294 !strconcat(OpcStr, " $cond, $dest"), 295 []>; 296} 297 298multiclass FRU6_LRU6_cp<string OpcStr> { 299 def _ru6: _FRU6< 300 (outs GRRegs:$dst), (ins i32imm:$a), 301 !strconcat(OpcStr, " $dst, cp[$a]"), 302 []>; 303 def _lru6: _FLRU6< 304 (outs GRRegs:$dst), (ins i32imm:$a), 305 !strconcat(OpcStr, " $dst, cp[$a]"), 306 []>; 307} 308 309// U6 310multiclass FU6_LU6<string OpcStr, SDNode OpNode> { 311 def _u6: _FU6< 312 (outs), (ins i32imm:$b), 313 !strconcat(OpcStr, " $b"), 314 [(OpNode immU6:$b)]>; 315 def _lu6: _FLU6< 316 (outs), (ins i32imm:$b), 317 !strconcat(OpcStr, " $b"), 318 [(OpNode immU16:$b)]>; 319} 320 321multiclass FU6_LU6_np<string OpcStr> { 322 def _u6: _FU6< 323 (outs), (ins i32imm:$b), 324 !strconcat(OpcStr, " $b"), 325 []>; 326 def _lu6: _FLU6< 327 (outs), (ins i32imm:$b), 328 !strconcat(OpcStr, " $b"), 329 []>; 330} 331 332// U10 333multiclass FU10_LU10_np<string OpcStr> { 334 def _u10: _FU10< 335 (outs), (ins i32imm:$b), 336 !strconcat(OpcStr, " $b"), 337 []>; 338 def _lu10: _FLU10< 339 (outs), (ins i32imm:$b), 340 !strconcat(OpcStr, " $b"), 341 []>; 342} 343 344// Two operand short 345 346class F2R_np<string OpcStr> : _F2R< 347 (outs GRRegs:$dst), (ins GRRegs:$b), 348 !strconcat(OpcStr, " $dst, $b"), 349 []>; 350 351// Two operand long 352 353//===----------------------------------------------------------------------===// 354// Pseudo Instructions 355//===----------------------------------------------------------------------===// 356 357let Defs = [SP], Uses = [SP] in { 358def ADJCALLSTACKDOWN : PseudoInstXCore<(outs), (ins i32imm:$amt), 359 "${:comment} ADJCALLSTACKDOWN $amt", 360 [(callseq_start timm:$amt)]>; 361def ADJCALLSTACKUP : PseudoInstXCore<(outs), (ins i32imm:$amt1, i32imm:$amt2), 362 "${:comment} ADJCALLSTACKUP $amt1", 363 [(callseq_end timm:$amt1, timm:$amt2)]>; 364} 365 366def LDWFI : PseudoInstXCore<(outs GRRegs:$dst), (ins MEMii:$addr), 367 "${:comment} LDWFI $dst, $addr", 368 [(set GRRegs:$dst, (load ADDRspii:$addr))]>; 369 370def LDAWFI : PseudoInstXCore<(outs GRRegs:$dst), (ins MEMii:$addr), 371 "${:comment} LDAWFI $dst, $addr", 372 [(set GRRegs:$dst, ADDRspii:$addr)]>; 373 374def STWFI : PseudoInstXCore<(outs), (ins GRRegs:$src, MEMii:$addr), 375 "${:comment} STWFI $src, $addr", 376 [(store GRRegs:$src, ADDRspii:$addr)]>; 377 378// SELECT_CC_* - Used to implement the SELECT_CC DAG operation. Expanded by the 379// scheduler into a branch sequence. 380let usesCustomDAGSchedInserter = 1 in { 381 def SELECT_CC : PseudoInstXCore<(outs GRRegs:$dst), 382 (ins GRRegs:$cond, GRRegs:$T, GRRegs:$F), 383 "${:comment} SELECT_CC PSEUDO!", 384 [(set GRRegs:$dst, 385 (select GRRegs:$cond, GRRegs:$T, GRRegs:$F))]>; 386} 387 388//===----------------------------------------------------------------------===// 389// Instructions 390//===----------------------------------------------------------------------===// 391 392// Three operand short 393defm ADD : F3R_2RUS<"add", add>; 394defm SUB : F3R_2RUS<"sub", sub>; 395let neverHasSideEffects = 1 in { 396defm EQ : F3R_2RUS_np<"eq">; 397def LSS_3r : F3R_np<"lss">; 398def LSU_3r : F3R_np<"lsu">; 399} 400def AND_3r : F3R<"and", and>; 401def OR_3r : F3R<"or", or>; 402 403let mayLoad=1 in { 404def LDW_3r : _F3R<(outs GRRegs:$dst), (ins GRRegs:$addr, GRRegs:$offset), 405 "ldw $dst, $addr[$offset]", 406 []>; 407 408def LDW_2rus : _F2RUS<(outs GRRegs:$dst), (ins GRRegs:$addr, i32imm:$offset), 409 "ldw $dst, $addr[$offset]", 410 []>; 411 412def LD16S_3r : _F3R<(outs GRRegs:$dst), (ins GRRegs:$addr, GRRegs:$offset), 413 "ld16s $dst, $addr[$offset]", 414 []>; 415 416def LD8U_3r : _F3R<(outs GRRegs:$dst), (ins GRRegs:$addr, GRRegs:$offset), 417 "ld8u $dst, $addr[$offset]", 418 []>; 419} 420 421let mayStore=1 in { 422def STW_3r : _F3R<(outs), (ins GRRegs:$val, GRRegs:$addr, GRRegs:$offset), 423 "stw $val, $addr[$offset]", 424 []>; 425 426def STW_2rus : _F2RUS<(outs), (ins GRRegs:$val, GRRegs:$addr, i32imm:$offset), 427 "stw $val, $addr[$offset]", 428 []>; 429} 430 431defm SHL : F3R_2RBITP<"shl", shl>; 432defm SHR : F3R_2RBITP<"shr", srl>; 433// TODO tsetr 434 435// Three operand long 436def LDAWF_l3r : _FL3R<(outs GRRegs:$dst), (ins GRRegs:$addr, GRRegs:$offset), 437 "ldaw $dst, $addr[$offset]", 438 [(set GRRegs:$dst, (ldawf GRRegs:$addr, GRRegs:$offset))]>; 439 440let neverHasSideEffects = 1 in 441def LDAWF_l2rus : _FL2RUS<(outs GRRegs:$dst), 442 (ins GRRegs:$addr, i32imm:$offset), 443 "ldaw $dst, $addr[$offset]", 444 []>; 445 446def LDAWB_l3r : _FL3R<(outs GRRegs:$dst), (ins GRRegs:$addr, GRRegs:$offset), 447 "ldaw $dst, $addr[-$offset]", 448 [(set GRRegs:$dst, (ldawb GRRegs:$addr, GRRegs:$offset))]>; 449 450let neverHasSideEffects = 1 in 451def LDAWB_l2rus : _FL2RUS<(outs GRRegs:$dst), 452 (ins GRRegs:$addr, i32imm:$offset), 453 "ldaw $dst, $addr[-$offset]", 454 []>; 455 456def LDA16F_l3r : _FL3R<(outs GRRegs:$dst), (ins GRRegs:$addr, GRRegs:$offset), 457 "lda16 $dst, $addr[$offset]", 458 [(set GRRegs:$dst, (lda16f GRRegs:$addr, GRRegs:$offset))]>; 459 460def LDA16B_l3r : _FL3R<(outs GRRegs:$dst), (ins GRRegs:$addr, GRRegs:$offset), 461 "lda16 $dst, $addr[-$offset]", 462 [(set GRRegs:$dst, (lda16b GRRegs:$addr, GRRegs:$offset))]>; 463 464def MUL_l3r : FL3R<"mul", mul>; 465// Instructions which may trap are marked as side effecting. 466let hasSideEffects = 1 in { 467def DIVS_l3r : FL3R<"divs", sdiv>; 468def DIVU_l3r : FL3R<"divu", udiv>; 469def REMS_l3r : FL3R<"rems", srem>; 470def REMU_l3r : FL3R<"remu", urem>; 471} 472def XOR_l3r : FL3R<"xor", xor>; 473defm ASHR : FL3R_L2RBITP<"ashr", sra>; 474// TODO crc32, crc8, inpw, outpw 475let mayStore=1 in { 476def ST16_l3r : _FL3R<(outs), (ins GRRegs:$val, GRRegs:$addr, GRRegs:$offset), 477 "st16 $val, $addr[$offset]", 478 []>; 479 480def ST8_l3r : _FL3R<(outs), (ins GRRegs:$val, GRRegs:$addr, GRRegs:$offset), 481 "st8 $val, $addr[$offset]", 482 []>; 483} 484 485// Four operand long 486let Predicates = [HasXS1B], Constraints = "$src1 = $dst1,$src2 = $dst2" in { 487def MACCU_l4r : _L4R<(outs GRRegs:$dst1, GRRegs:$dst2), 488 (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3, 489 GRRegs:$src4), 490 "maccu $dst1, $dst2, $src3, $src4", 491 []>; 492 493def MACCS_l4r : _L4R<(outs GRRegs:$dst1, GRRegs:$dst2), 494 (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3, 495 GRRegs:$src4), 496 "maccs $dst1, $dst2, $src3, $src4", 497 []>; 498} 499 500// Five operand long 501 502let Predicates = [HasXS1B] in { 503def LADD_l5r : _L5R<(outs GRRegs:$dst1, GRRegs:$dst2), 504 (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3), 505 "ladd $dst1, $dst2, $src1, $src2, $src3", 506 []>; 507 508def LSUB_l5r : _L5R<(outs GRRegs:$dst1, GRRegs:$dst2), 509 (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3), 510 "lsub $dst1, $dst2, $src1, $src2, $src3", 511 []>; 512 513def LDIV_l5r : _L5R<(outs GRRegs:$dst1, GRRegs:$dst2), 514 (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3), 515 "ldiv $dst1, $dst2, $src1, $src2, $src3", 516 []>; 517} 518 519// Six operand long 520 521def LMUL_l6r : _L6R<(outs GRRegs:$dst1, GRRegs:$dst2), 522 (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3, 523 GRRegs:$src4), 524 "lmul $dst1, $dst2, $src1, $src2, $src3, $src4", 525 []>; 526 527let Predicates = [HasXS1A] in 528def MACC_l6r : _L6R<(outs GRRegs:$dst1, GRRegs:$dst2), 529 (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3, 530 GRRegs:$src4), 531 "macc $dst1, $dst2, $src1, $src2, $src3, $src4", 532 []>; 533 534// Register - U6 535 536//let Uses = [DP] in ... 537let neverHasSideEffects = 1, isReMaterializable = 1 in 538def LDAWDP_ru6: _FRU6<(outs GRRegs:$dst), (ins MEMii:$a), 539 "ldaw $dst, dp[$a]", 540 []>; 541 542let isReMaterializable = 1 in 543def LDAWDP_lru6: _FLRU6< 544 (outs GRRegs:$dst), (ins MEMii:$a), 545 "ldaw $dst, dp[$a]", 546 [(set GRRegs:$dst, ADDRdpii:$a)]>; 547 548let mayLoad=1 in 549def LDWDP_ru6: _FRU6<(outs GRRegs:$dst), (ins MEMii:$a), 550 "ldw $dst, dp[$a]", 551 []>; 552 553def LDWDP_lru6: _FLRU6< 554 (outs GRRegs:$dst), (ins MEMii:$a), 555 "ldw $dst, dp[$a]", 556 [(set GRRegs:$dst, (load ADDRdpii:$a))]>; 557 558let mayStore=1 in 559def STWDP_ru6 : _FRU6<(outs), (ins GRRegs:$val, MEMii:$addr), 560 "stw $val, dp[$addr]", 561 []>; 562 563def STWDP_lru6 : _FLRU6<(outs), (ins GRRegs:$val, MEMii:$addr), 564 "stw $val, dp[$addr]", 565 [(store GRRegs:$val, ADDRdpii:$addr)]>; 566 567//let Uses = [CP] in .. 568let mayLoad = 1, isReMaterializable = 1 in 569defm LDWCP : FRU6_LRU6_cp<"ldw">; 570 571let Uses = [SP] in { 572let mayStore=1 in { 573def STWSP_ru6 : _FRU6< 574 (outs), (ins GRRegs:$val, i32imm:$index), 575 "stw $val, sp[$index]", 576 [(XCoreStwsp GRRegs:$val, immU6:$index)]>; 577 578def STWSP_lru6 : _FLRU6< 579 (outs), (ins GRRegs:$val, i32imm:$index), 580 "stw $val, sp[$index]", 581 [(XCoreStwsp GRRegs:$val, immU16:$index)]>; 582} 583 584let mayLoad=1 in { 585def LDWSP_ru6 : _FRU6< 586 (outs GRRegs:$dst), (ins i32imm:$b), 587 "ldw $dst, sp[$b]", 588 []>; 589 590def LDWSP_lru6 : _FLRU6< 591 (outs GRRegs:$dst), (ins i32imm:$b), 592 "ldw $dst, sp[$b]", 593 []>; 594} 595 596let neverHasSideEffects = 1 in { 597def LDAWSP_ru6 : _FRU6< 598 (outs GRRegs:$dst), (ins i32imm:$b), 599 "ldaw $dst, sp[$b]", 600 []>; 601 602def LDAWSP_lru6 : _FLRU6< 603 (outs GRRegs:$dst), (ins i32imm:$b), 604 "ldaw $dst, sp[$b]", 605 []>; 606 607def LDAWSP_ru6_RRegs : _FRU6< 608 (outs RRegs:$dst), (ins i32imm:$b), 609 "ldaw $dst, sp[$b]", 610 []>; 611 612def LDAWSP_lru6_RRegs : _FLRU6< 613 (outs RRegs:$dst), (ins i32imm:$b), 614 "ldaw $dst, sp[$b]", 615 []>; 616} 617} 618 619let isReMaterializable = 1 in { 620def LDC_ru6 : _FRU6< 621 (outs GRRegs:$dst), (ins i32imm:$b), 622 "ldc $dst, $b", 623 [(set GRRegs:$dst, immU6:$b)]>; 624 625def LDC_lru6 : _FLRU6< 626 (outs GRRegs:$dst), (ins i32imm:$b), 627 "ldc $dst, $b", 628 [(set GRRegs:$dst, immU16:$b)]>; 629} 630 631// Operand register - U6 632// TODO setc 633let isBranch = 1, isTerminator = 1 in { 634defm BRFT: FRU6_LRU6_branch<"bt">; 635defm BRBT: FRU6_LRU6_branch<"bt">; 636defm BRFF: FRU6_LRU6_branch<"bf">; 637defm BRBF: FRU6_LRU6_branch<"bf">; 638} 639 640// U6 641let Defs = [SP], Uses = [SP] in { 642let neverHasSideEffects = 1 in 643defm EXTSP : FU6_LU6_np<"extsp">; 644let mayStore = 1 in 645defm ENTSP : FU6_LU6_np<"entsp">; 646 647let isReturn = 1, isTerminator = 1, mayLoad = 1 in { 648defm RETSP : FU6_LU6<"retsp", XCoreRetsp>; 649} 650} 651 652// TODO extdp, kentsp, krestsp, blat, setsr 653// clrsr, getsr, kalli 654let isBranch = 1, isTerminator = 1 in { 655def BRBU_u6 : _FU6< 656 (outs), 657 (ins brtarget:$target), 658 "bu $target", 659 []>; 660 661def BRBU_lu6 : _FLU6< 662 (outs), 663 (ins brtarget:$target), 664 "bu $target", 665 []>; 666 667def BRFU_u6 : _FU6< 668 (outs), 669 (ins brtarget:$target), 670 "bu $target", 671 []>; 672 673def BRFU_lu6 : _FLU6< 674 (outs), 675 (ins brtarget:$target), 676 "bu $target", 677 []>; 678} 679 680//let Uses = [CP] in ... 681let Predicates = [HasXS1B], Defs = [R11], neverHasSideEffects = 1, 682 isReMaterializable = 1 in 683def LDAWCP_u6: _FRU6<(outs), (ins MEMii:$a), 684 "ldaw r11, cp[$a]", 685 []>; 686 687let Predicates = [HasXS1B], Defs = [R11], isReMaterializable = 1 in 688def LDAWCP_lu6: _FLRU6< 689 (outs), (ins MEMii:$a), 690 "ldaw r11, cp[$a]", 691 [(set R11, ADDRcpii:$a)]>; 692 693// U10 694// TODO ldwcpl, blacp 695 696let Defs = [R11], isReMaterializable = 1, neverHasSideEffects = 1 in 697def LDAP_u10 : _FU10< 698 (outs), 699 (ins i32imm:$addr), 700 "ldap r11, $addr", 701 []>; 702 703let Defs = [R11], isReMaterializable = 1 in 704def LDAP_lu10 : _FLU10< 705 (outs), 706 (ins i32imm:$addr), 707 "ldap r11, $addr", 708 [(set R11, (pcrelwrapper tglobaladdr:$addr))]>; 709 710let isCall=1, 711// All calls clobber the the link register and the non-callee-saved registers: 712Defs = [R0, R1, R2, R3, R11, LR] in { 713def BL_u10 : _FU10< 714 (outs), 715 (ins calltarget:$target, variable_ops), 716 "bl $target", 717 [(XCoreBranchLink immU10:$target)]>; 718 719def BL_lu10 : _FLU10< 720 (outs), 721 (ins calltarget:$target, variable_ops), 722 "bl $target", 723 [(XCoreBranchLink immU20:$target)]>; 724} 725 726// Two operand short 727// TODO getr, getst 728def NOT : _F2R<(outs GRRegs:$dst), (ins GRRegs:$b), 729 "not $dst, $b", 730 [(set GRRegs:$dst, (not GRRegs:$b))]>; 731 732def NEG : _F2R<(outs GRRegs:$dst), (ins GRRegs:$b), 733 "neg $dst, $b", 734 [(set GRRegs:$dst, (ineg GRRegs:$b))]>; 735 736// TODO setd, eet, eef, getts, setpt, outct, inct, chkct, outt, intt, out, 737// in, outshr, inshr, testct, testwct, tinitpc, tinitdp, tinitsp, tinitcp, 738// tsetmr, sext (reg), zext (reg) 739let isTwoAddress = 1 in { 740let neverHasSideEffects = 1 in 741def SEXT_rus : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$src1, i32imm:$src2), 742 "sext $dst, $src2", 743 []>; 744 745let neverHasSideEffects = 1 in 746def ZEXT_rus : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$src1, i32imm:$src2), 747 "zext $dst, $src2", 748 []>; 749 750def ANDNOT_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$src1, GRRegs:$src2), 751 "andnot $dst, $src2", 752 [(set GRRegs:$dst, (and GRRegs:$src1, (not GRRegs:$src2)))]>; 753} 754 755let isReMaterializable = 1, neverHasSideEffects = 1 in 756def MKMSK_rus : _FRUS<(outs GRRegs:$dst), (ins i32imm:$size), 757 "mkmsk $dst, $size", 758 []>; 759 760def MKMSK_2r : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$size), 761 "mkmsk $dst, $size", 762 [(set GRRegs:$dst, (add (shl 1, GRRegs:$size), 0xffffffff))]>; 763 764// Two operand long 765// TODO settw, setclk, setrdy, setpsc, endin, peek, 766// getd, testlcl, tinitlr, getps, setps 767def BITREV_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src), 768 "bitrev $dst, $src", 769 [(set GRRegs:$dst, (int_xcore_bitrev GRRegs:$src))]>; 770 771def BYTEREV_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src), 772 "byterev $dst, $src", 773 [(set GRRegs:$dst, (bswap GRRegs:$src))]>; 774 775def CLZ_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src), 776 "clz $dst, $src", 777 [(set GRRegs:$dst, (ctlz GRRegs:$src))]>; 778 779// One operand short 780// TODO edu, eeu, waitet, waitef, freer, tstart, msync, mjoin, syncr, clrtp 781// bru, setdp, setcp, setv, setev, kcall 782// dgetreg 783let isBranch=1, isIndirectBranch=1, isTerminator=1 in 784def BAU_1r : _F1R<(outs), (ins GRRegs:$addr), 785 "bau $addr", 786 [(brind GRRegs:$addr)]>; 787 788let Defs=[SP], neverHasSideEffects=1 in 789def SETSP_1r : _F1R<(outs), (ins GRRegs:$src), 790 "set sp, $src", 791 []>; 792 793let isBarrier = 1, hasCtrlDep = 1 in 794def ECALLT_1r : _F1R<(outs), (ins GRRegs:$src), 795 "ecallt $src", 796 []>; 797 798let isBarrier = 1, hasCtrlDep = 1 in 799def ECALLF_1r : _F1R<(outs), (ins GRRegs:$src), 800 "ecallf $src", 801 []>; 802 803let isCall=1, 804// All calls clobber the the link register and the non-callee-saved registers: 805Defs = [R0, R1, R2, R3, R11, LR] in { 806def BLA_1r : _F1R<(outs), (ins GRRegs:$addr, variable_ops), 807 "bla $addr", 808 [(XCoreBranchLink GRRegs:$addr)]>; 809} 810 811// Zero operand short 812// TODO waiteu, clre, ssync, freet, ldspc, stspc, ldssr, stssr, ldsed, stsed, 813// stet, geted, getet, getkep, getksp, setkep, getid, kret, dcall, dret, 814// dentsp, drestsp 815 816let Defs = [R11] in 817def GETID_0R : _F0R<(outs), (ins), 818 "get r11, id", 819 [(set R11, (int_xcore_getid))]>; 820 821//===----------------------------------------------------------------------===// 822// Non-Instruction Patterns 823//===----------------------------------------------------------------------===// 824 825def : Pat<(XCoreBranchLink tglobaladdr:$addr), (BL_lu10 tglobaladdr:$addr)>; 826def : Pat<(XCoreBranchLink texternalsym:$addr), (BL_lu10 texternalsym:$addr)>; 827 828/// sext_inreg 829def : Pat<(sext_inreg GRRegs:$b, i1), (SEXT_rus GRRegs:$b, 1)>; 830def : Pat<(sext_inreg GRRegs:$b, i8), (SEXT_rus GRRegs:$b, 8)>; 831def : Pat<(sext_inreg GRRegs:$b, i16), (SEXT_rus GRRegs:$b, 16)>; 832 833/// loads 834def : Pat<(zextloadi8 (add GRRegs:$addr, GRRegs:$offset)), 835 (LD8U_3r GRRegs:$addr, GRRegs:$offset)>; 836def : Pat<(zextloadi8 GRRegs:$addr), (LD8U_3r GRRegs:$addr, (LDC_ru6 0))>; 837 838def : Pat<(sextloadi16 (lda16f GRRegs:$addr, GRRegs:$offset)), 839 (LD16S_3r GRRegs:$addr, GRRegs:$offset)>; 840def : Pat<(sextloadi16 GRRegs:$addr), (LD16S_3r GRRegs:$addr, (LDC_ru6 0))>; 841 842def : Pat<(load (ldawf GRRegs:$addr, GRRegs:$offset)), 843 (LDW_3r GRRegs:$addr, GRRegs:$offset)>; 844def : Pat<(load (add GRRegs:$addr, immUs4:$offset)), 845 (LDW_2rus GRRegs:$addr, (div4_xform immUs4:$offset))>; 846def : Pat<(load GRRegs:$addr), (LDW_2rus GRRegs:$addr, 0)>; 847 848/// anyext 849def : Pat<(extloadi8 (add GRRegs:$addr, GRRegs:$offset)), 850 (LD8U_3r GRRegs:$addr, GRRegs:$offset)>; 851def : Pat<(extloadi8 GRRegs:$addr), (LD8U_3r GRRegs:$addr, (LDC_ru6 0))>; 852def : Pat<(extloadi16 (lda16f GRRegs:$addr, GRRegs:$offset)), 853 (LD16S_3r GRRegs:$addr, GRRegs:$offset)>; 854def : Pat<(extloadi16 GRRegs:$addr), (LD16S_3r GRRegs:$addr, (LDC_ru6 0))>; 855 856/// stores 857def : Pat<(truncstorei8 GRRegs:$val, (add GRRegs:$addr, GRRegs:$offset)), 858 (ST8_l3r GRRegs:$val, GRRegs:$addr, GRRegs:$offset)>; 859def : Pat<(truncstorei8 GRRegs:$val, GRRegs:$addr), 860 (ST8_l3r GRRegs:$val, GRRegs:$addr, (LDC_ru6 0))>; 861 862def : Pat<(truncstorei16 GRRegs:$val, (lda16f GRRegs:$addr, GRRegs:$offset)), 863 (ST16_l3r GRRegs:$val, GRRegs:$addr, GRRegs:$offset)>; 864def : Pat<(truncstorei16 GRRegs:$val, GRRegs:$addr), 865 (ST16_l3r GRRegs:$val, GRRegs:$addr, (LDC_ru6 0))>; 866 867def : Pat<(store GRRegs:$val, (ldawf GRRegs:$addr, GRRegs:$offset)), 868 (STW_3r GRRegs:$val, GRRegs:$addr, GRRegs:$offset)>; 869def : Pat<(store GRRegs:$val, (add GRRegs:$addr, immUs4:$offset)), 870 (STW_2rus GRRegs:$val, GRRegs:$addr, (div4_xform immUs4:$offset))>; 871def : Pat<(store GRRegs:$val, GRRegs:$addr), 872 (STW_2rus GRRegs:$val, GRRegs:$addr, 0)>; 873 874/// cttz 875def : Pat<(cttz GRRegs:$src), (CLZ_l2r (BITREV_l2r GRRegs:$src))>; 876 877/// trap 878def : Pat<(trap), (ECALLF_1r (LDC_ru6 0))>; 879 880/// 881/// branch patterns 882/// 883 884// unconditional branch 885def : Pat<(br bb:$addr), (BRFU_lu6 bb:$addr)>; 886 887// direct match equal/notequal zero brcond 888def : Pat<(brcond (setne GRRegs:$lhs, 0), bb:$dst), 889 (BRFT_lru6 GRRegs:$lhs, bb:$dst)>; 890def : Pat<(brcond (seteq GRRegs:$lhs, 0), bb:$dst), 891 (BRFF_lru6 GRRegs:$lhs, bb:$dst)>; 892 893def : Pat<(brcond (setle GRRegs:$lhs, GRRegs:$rhs), bb:$dst), 894 (BRFF_lru6 (LSS_3r GRRegs:$rhs, GRRegs:$lhs), bb:$dst)>; 895def : Pat<(brcond (setule GRRegs:$lhs, GRRegs:$rhs), bb:$dst), 896 (BRFF_lru6 (LSU_3r GRRegs:$rhs, GRRegs:$lhs), bb:$dst)>; 897def : Pat<(brcond (setge GRRegs:$lhs, GRRegs:$rhs), bb:$dst), 898 (BRFF_lru6 (LSS_3r GRRegs:$lhs, GRRegs:$rhs), bb:$dst)>; 899def : Pat<(brcond (setuge GRRegs:$lhs, GRRegs:$rhs), bb:$dst), 900 (BRFF_lru6 (LSU_3r GRRegs:$lhs, GRRegs:$rhs), bb:$dst)>; 901def : Pat<(brcond (setne GRRegs:$lhs, GRRegs:$rhs), bb:$dst), 902 (BRFF_lru6 (EQ_3r GRRegs:$lhs, GRRegs:$rhs), bb:$dst)>; 903def : Pat<(brcond (setne GRRegs:$lhs, immUs:$rhs), bb:$dst), 904 (BRFF_lru6 (EQ_2rus GRRegs:$lhs, immUs:$rhs), bb:$dst)>; 905 906// generic brcond pattern 907def : Pat<(brcond GRRegs:$cond, bb:$addr), (BRFT_lru6 GRRegs:$cond, bb:$addr)>; 908 909 910/// 911/// Select patterns 912/// 913 914// direct match equal/notequal zero select 915def : Pat<(select (setne GRRegs:$lhs, 0), GRRegs:$T, GRRegs:$F), 916 (SELECT_CC GRRegs:$lhs, GRRegs:$T, GRRegs:$F)>; 917 918def : Pat<(select (seteq GRRegs:$lhs, 0), GRRegs:$T, GRRegs:$F), 919 (SELECT_CC GRRegs:$lhs, GRRegs:$F, GRRegs:$T)>; 920 921def : Pat<(select (setle GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F), 922 (SELECT_CC (LSS_3r GRRegs:$rhs, GRRegs:$lhs), GRRegs:$F, GRRegs:$T)>; 923def : Pat<(select (setule GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F), 924 (SELECT_CC (LSU_3r GRRegs:$rhs, GRRegs:$lhs), GRRegs:$F, GRRegs:$T)>; 925def : Pat<(select (setge GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F), 926 (SELECT_CC (LSS_3r GRRegs:$lhs, GRRegs:$rhs), GRRegs:$F, GRRegs:$T)>; 927def : Pat<(select (setuge GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F), 928 (SELECT_CC (LSU_3r GRRegs:$lhs, GRRegs:$rhs), GRRegs:$F, GRRegs:$T)>; 929def : Pat<(select (setne GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F), 930 (SELECT_CC (EQ_3r GRRegs:$lhs, GRRegs:$rhs), GRRegs:$F, GRRegs:$T)>; 931def : Pat<(select (setne GRRegs:$lhs, immUs:$rhs), GRRegs:$T, GRRegs:$F), 932 (SELECT_CC (EQ_2rus GRRegs:$lhs, immUs:$rhs), GRRegs:$F, GRRegs:$T)>; 933 934/// 935/// setcc patterns, only matched when none of the above brcond 936/// patterns match 937/// 938 939// setcc 2 register operands 940def : Pat<(setle GRRegs:$lhs, GRRegs:$rhs), 941 (EQ_2rus (LSS_3r GRRegs:$rhs, GRRegs:$lhs), 0)>; 942def : Pat<(setule GRRegs:$lhs, GRRegs:$rhs), 943 (EQ_2rus (LSU_3r GRRegs:$rhs, GRRegs:$lhs), 0)>; 944 945def : Pat<(setgt GRRegs:$lhs, GRRegs:$rhs), 946 (LSS_3r GRRegs:$rhs, GRRegs:$lhs)>; 947def : Pat<(setugt GRRegs:$lhs, GRRegs:$rhs), 948 (LSU_3r GRRegs:$rhs, GRRegs:$lhs)>; 949 950def : Pat<(setge GRRegs:$lhs, GRRegs:$rhs), 951 (EQ_2rus (LSS_3r GRRegs:$lhs, GRRegs:$rhs), 0)>; 952def : Pat<(setuge GRRegs:$lhs, GRRegs:$rhs), 953 (EQ_2rus (LSU_3r GRRegs:$lhs, GRRegs:$rhs), 0)>; 954 955def : Pat<(setlt GRRegs:$lhs, GRRegs:$rhs), 956 (LSS_3r GRRegs:$lhs, GRRegs:$rhs)>; 957def : Pat<(setult GRRegs:$lhs, GRRegs:$rhs), 958 (LSU_3r GRRegs:$lhs, GRRegs:$rhs)>; 959 960def : Pat<(setne GRRegs:$lhs, GRRegs:$rhs), 961 (EQ_2rus (EQ_3r GRRegs:$lhs, GRRegs:$rhs), 0)>; 962 963def : Pat<(seteq GRRegs:$lhs, GRRegs:$rhs), 964 (EQ_3r GRRegs:$lhs, GRRegs:$rhs)>; 965 966// setcc reg/imm operands 967def : Pat<(seteq GRRegs:$lhs, immUs:$rhs), 968 (EQ_2rus GRRegs:$lhs, immUs:$rhs)>; 969def : Pat<(setne GRRegs:$lhs, immUs:$rhs), 970 (EQ_2rus (EQ_2rus GRRegs:$lhs, immUs:$rhs), 0)>; 971 972// misc 973def : Pat<(add GRRegs:$addr, immUs4:$offset), 974 (LDAWF_l2rus GRRegs:$addr, (div4_xform immUs4:$offset))>; 975 976def : Pat<(sub GRRegs:$addr, immUs4:$offset), 977 (LDAWB_l2rus GRRegs:$addr, (div4_xform immUs4:$offset))>; 978 979def : Pat<(and GRRegs:$val, immMskBitp:$mask), 980 (ZEXT_rus GRRegs:$val, (msksize_xform immMskBitp:$mask))>; 981 982// (sub X, imm) gets canonicalized to (add X, -imm). Match this form. 983def : Pat<(add GRRegs:$src1, immUsNeg:$src2), 984 (SUB_2rus GRRegs:$src1, (neg_xform immUsNeg:$src2))>; 985 986def : Pat<(add GRRegs:$src1, immUs4Neg:$src2), 987 (LDAWB_l2rus GRRegs:$src1, (div4neg_xform immUs4Neg:$src2))>; 988 989/// 990/// Some peepholes 991/// 992 993def : Pat<(mul GRRegs:$src, 3), 994 (LDA16F_l3r GRRegs:$src, GRRegs:$src)>; 995 996def : Pat<(mul GRRegs:$src, 5), 997 (LDAWF_l3r GRRegs:$src, GRRegs:$src)>; 998 999def : Pat<(mul GRRegs:$src, -3), 1000 (LDAWB_l3r GRRegs:$src, GRRegs:$src)>; 1001 1002// ashr X, 32 is equivalent to ashr X, 31 on the XCore. 1003def : Pat<(sra GRRegs:$src, 31), 1004 (ASHR_l2rus GRRegs:$src, 32)>; 1005 1006def : Pat<(sra (shl GRRegs:$src, immBpwSubBitp:$imm), immBpwSubBitp:$imm), 1007 (SEXT_rus GRRegs:$src, (bpwsub_xform immBpwSubBitp:$imm))>; 1008