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