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