XCoreInstrInfo.td revision 198892
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 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 isCall=1, 683// All calls clobber the the link register and the non-callee-saved registers: 684Defs = [R0, R1, R2, R3, R11, LR] in { 685def BL_u10 : _FU10< 686 (outs), 687 (ins calltarget:$target, variable_ops), 688 "bl $target", 689 [(XCoreBranchLink immU10:$target)]>; 690 691def BL_lu10 : _FLU10< 692 (outs), 693 (ins calltarget:$target, variable_ops), 694 "bl $target", 695 [(XCoreBranchLink immU20:$target)]>; 696} 697 698// Two operand short 699// TODO getr, getst 700def NOT : _F2R<(outs GRRegs:$dst), (ins GRRegs:$b), 701 "not $dst, $b", 702 [(set GRRegs:$dst, (not GRRegs:$b))]>; 703 704def NEG : _F2R<(outs GRRegs:$dst), (ins GRRegs:$b), 705 "neg $dst, $b", 706 [(set GRRegs:$dst, (ineg GRRegs:$b))]>; 707 708// TODO setd, eet, eef, getts, setpt, outct, inct, chkct, outt, intt, out, 709// in, outshr, inshr, testct, testwct, tinitpc, tinitdp, tinitsp, tinitcp, 710// tsetmr, sext (reg), zext (reg) 711let isTwoAddress = 1 in { 712let neverHasSideEffects = 1 in 713def SEXT_rus : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$src1, i32imm:$src2), 714 "sext $dst, $src2", 715 []>; 716 717let neverHasSideEffects = 1 in 718def ZEXT_rus : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$src1, i32imm:$src2), 719 "zext $dst, $src2", 720 []>; 721 722def ANDNOT_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$src1, GRRegs:$src2), 723 "andnot $dst, $src2", 724 [(set GRRegs:$dst, (and GRRegs:$src1, (not GRRegs:$src2)))]>; 725} 726 727let isReMaterializable = 1, neverHasSideEffects = 1 in 728def MKMSK_rus : _FRUS<(outs GRRegs:$dst), (ins i32imm:$size), 729 "mkmsk $dst, $size", 730 []>; 731 732def MKMSK_2r : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$size), 733 "mkmsk $dst, $size", 734 [(set GRRegs:$dst, (add (shl 1, GRRegs:$size), 0xffffffff))]>; 735 736// Two operand long 737// TODO settw, setclk, setrdy, setpsc, endin, peek, 738// getd, testlcl, tinitlr, getps, setps 739def BITREV_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src), 740 "bitrev $dst, $src", 741 [(set GRRegs:$dst, (int_xcore_bitrev GRRegs:$src))]>; 742 743def BYTEREV_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src), 744 "byterev $dst, $src", 745 [(set GRRegs:$dst, (bswap GRRegs:$src))]>; 746 747def CLZ_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src), 748 "clz $dst, $src", 749 [(set GRRegs:$dst, (ctlz GRRegs:$src))]>; 750 751// One operand short 752// TODO edu, eeu, waitet, waitef, freer, tstart, msync, mjoin, syncr, clrtp 753// bru, setdp, setcp, setv, setev, kcall 754// dgetreg 755let isBranch=1, isIndirectBranch=1, isTerminator=1 in 756def BAU_1r : _F1R<(outs), (ins GRRegs:$addr), 757 "bau $addr", 758 [(brind GRRegs:$addr)]>; 759 760let Defs=[SP], neverHasSideEffects=1 in 761def SETSP_1r : _F1R<(outs), (ins GRRegs:$src), 762 "set sp, $src", 763 []>; 764 765let isBarrier = 1, hasCtrlDep = 1 in 766def ECALLT_1r : _F1R<(outs), (ins GRRegs:$src), 767 "ecallt $src", 768 []>; 769 770let isBarrier = 1, hasCtrlDep = 1 in 771def ECALLF_1r : _F1R<(outs), (ins GRRegs:$src), 772 "ecallf $src", 773 []>; 774 775let isCall=1, 776// All calls clobber the the link register and the non-callee-saved registers: 777Defs = [R0, R1, R2, R3, R11, LR] in { 778def BLA_1r : _F1R<(outs), (ins GRRegs:$addr, variable_ops), 779 "bla $addr", 780 [(XCoreBranchLink GRRegs:$addr)]>; 781} 782 783// Zero operand short 784// TODO waiteu, clre, ssync, freet, ldspc, stspc, ldssr, stssr, ldsed, stsed, 785// stet, geted, getet, getkep, getksp, setkep, getid, kret, dcall, dret, 786// dentsp, drestsp 787 788let Defs = [R11] in 789def GETID_0R : _F0R<(outs), (ins), 790 "get r11, id", 791 [(set R11, (int_xcore_getid))]>; 792 793//===----------------------------------------------------------------------===// 794// Non-Instruction Patterns 795//===----------------------------------------------------------------------===// 796 797def : Pat<(XCoreBranchLink tglobaladdr:$addr), (BL_lu10 tglobaladdr:$addr)>; 798def : Pat<(XCoreBranchLink texternalsym:$addr), (BL_lu10 texternalsym:$addr)>; 799 800/// sext_inreg 801def : Pat<(sext_inreg GRRegs:$b, i1), (SEXT_rus GRRegs:$b, 1)>; 802def : Pat<(sext_inreg GRRegs:$b, i8), (SEXT_rus GRRegs:$b, 8)>; 803def : Pat<(sext_inreg GRRegs:$b, i16), (SEXT_rus GRRegs:$b, 16)>; 804 805/// loads 806def : Pat<(zextloadi8 (add GRRegs:$addr, GRRegs:$offset)), 807 (LD8U_3r GRRegs:$addr, GRRegs:$offset)>; 808def : Pat<(zextloadi8 GRRegs:$addr), (LD8U_3r GRRegs:$addr, (LDC_ru6 0))>; 809 810def : Pat<(sextloadi16 (lda16f GRRegs:$addr, GRRegs:$offset)), 811 (LD16S_3r GRRegs:$addr, GRRegs:$offset)>; 812def : Pat<(sextloadi16 GRRegs:$addr), (LD16S_3r GRRegs:$addr, (LDC_ru6 0))>; 813 814def : Pat<(load (ldawf GRRegs:$addr, GRRegs:$offset)), 815 (LDW_3r GRRegs:$addr, GRRegs:$offset)>; 816def : Pat<(load (add GRRegs:$addr, immUs4:$offset)), 817 (LDW_2rus GRRegs:$addr, (div4_xform immUs4:$offset))>; 818def : Pat<(load GRRegs:$addr), (LDW_2rus GRRegs:$addr, 0)>; 819 820/// anyext 821def : Pat<(extloadi8 (add GRRegs:$addr, GRRegs:$offset)), 822 (LD8U_3r GRRegs:$addr, GRRegs:$offset)>; 823def : Pat<(extloadi8 GRRegs:$addr), (LD8U_3r GRRegs:$addr, (LDC_ru6 0))>; 824def : Pat<(extloadi16 (lda16f GRRegs:$addr, GRRegs:$offset)), 825 (LD16S_3r GRRegs:$addr, GRRegs:$offset)>; 826def : Pat<(extloadi16 GRRegs:$addr), (LD16S_3r GRRegs:$addr, (LDC_ru6 0))>; 827 828/// stores 829def : Pat<(truncstorei8 GRRegs:$val, (add GRRegs:$addr, GRRegs:$offset)), 830 (ST8_l3r GRRegs:$val, GRRegs:$addr, GRRegs:$offset)>; 831def : Pat<(truncstorei8 GRRegs:$val, GRRegs:$addr), 832 (ST8_l3r GRRegs:$val, GRRegs:$addr, (LDC_ru6 0))>; 833 834def : Pat<(truncstorei16 GRRegs:$val, (lda16f GRRegs:$addr, GRRegs:$offset)), 835 (ST16_l3r GRRegs:$val, GRRegs:$addr, GRRegs:$offset)>; 836def : Pat<(truncstorei16 GRRegs:$val, GRRegs:$addr), 837 (ST16_l3r GRRegs:$val, GRRegs:$addr, (LDC_ru6 0))>; 838 839def : Pat<(store GRRegs:$val, (ldawf GRRegs:$addr, GRRegs:$offset)), 840 (STW_3r GRRegs:$val, GRRegs:$addr, GRRegs:$offset)>; 841def : Pat<(store GRRegs:$val, (add GRRegs:$addr, immUs4:$offset)), 842 (STW_2rus GRRegs:$val, GRRegs:$addr, (div4_xform immUs4:$offset))>; 843def : Pat<(store GRRegs:$val, GRRegs:$addr), 844 (STW_2rus GRRegs:$val, GRRegs:$addr, 0)>; 845 846/// cttz 847def : Pat<(cttz GRRegs:$src), (CLZ_l2r (BITREV_l2r GRRegs:$src))>; 848 849/// trap 850def : Pat<(trap), (ECALLF_1r (LDC_ru6 0))>; 851 852/// 853/// branch patterns 854/// 855 856// unconditional branch 857def : Pat<(br bb:$addr), (BRFU_lu6 bb:$addr)>; 858 859// direct match equal/notequal zero brcond 860def : Pat<(brcond (setne GRRegs:$lhs, 0), bb:$dst), 861 (BRFT_lru6 GRRegs:$lhs, bb:$dst)>; 862def : Pat<(brcond (seteq GRRegs:$lhs, 0), bb:$dst), 863 (BRFF_lru6 GRRegs:$lhs, bb:$dst)>; 864 865def : Pat<(brcond (setle GRRegs:$lhs, GRRegs:$rhs), bb:$dst), 866 (BRFF_lru6 (LSS_3r GRRegs:$rhs, GRRegs:$lhs), bb:$dst)>; 867def : Pat<(brcond (setule GRRegs:$lhs, GRRegs:$rhs), bb:$dst), 868 (BRFF_lru6 (LSU_3r GRRegs:$rhs, GRRegs:$lhs), bb:$dst)>; 869def : Pat<(brcond (setge GRRegs:$lhs, GRRegs:$rhs), bb:$dst), 870 (BRFF_lru6 (LSS_3r GRRegs:$lhs, GRRegs:$rhs), bb:$dst)>; 871def : Pat<(brcond (setuge GRRegs:$lhs, GRRegs:$rhs), bb:$dst), 872 (BRFF_lru6 (LSU_3r GRRegs:$lhs, GRRegs:$rhs), bb:$dst)>; 873def : Pat<(brcond (setne GRRegs:$lhs, GRRegs:$rhs), bb:$dst), 874 (BRFF_lru6 (EQ_3r GRRegs:$lhs, GRRegs:$rhs), bb:$dst)>; 875def : Pat<(brcond (setne GRRegs:$lhs, immUs:$rhs), bb:$dst), 876 (BRFF_lru6 (EQ_2rus GRRegs:$lhs, immUs:$rhs), bb:$dst)>; 877 878// generic brcond pattern 879def : Pat<(brcond GRRegs:$cond, bb:$addr), (BRFT_lru6 GRRegs:$cond, bb:$addr)>; 880 881 882/// 883/// Select patterns 884/// 885 886// direct match equal/notequal zero select 887def : Pat<(select (setne GRRegs:$lhs, 0), GRRegs:$T, GRRegs:$F), 888 (SELECT_CC GRRegs:$lhs, GRRegs:$T, GRRegs:$F)>; 889 890def : Pat<(select (seteq GRRegs:$lhs, 0), GRRegs:$T, GRRegs:$F), 891 (SELECT_CC GRRegs:$lhs, GRRegs:$F, GRRegs:$T)>; 892 893def : Pat<(select (setle GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F), 894 (SELECT_CC (LSS_3r GRRegs:$rhs, GRRegs:$lhs), GRRegs:$F, GRRegs:$T)>; 895def : Pat<(select (setule GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F), 896 (SELECT_CC (LSU_3r GRRegs:$rhs, GRRegs:$lhs), GRRegs:$F, GRRegs:$T)>; 897def : Pat<(select (setge GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F), 898 (SELECT_CC (LSS_3r GRRegs:$lhs, GRRegs:$rhs), GRRegs:$F, GRRegs:$T)>; 899def : Pat<(select (setuge GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F), 900 (SELECT_CC (LSU_3r GRRegs:$lhs, GRRegs:$rhs), GRRegs:$F, GRRegs:$T)>; 901def : Pat<(select (setne GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F), 902 (SELECT_CC (EQ_3r GRRegs:$lhs, GRRegs:$rhs), GRRegs:$F, GRRegs:$T)>; 903def : Pat<(select (setne GRRegs:$lhs, immUs:$rhs), GRRegs:$T, GRRegs:$F), 904 (SELECT_CC (EQ_2rus GRRegs:$lhs, immUs:$rhs), GRRegs:$F, GRRegs:$T)>; 905 906/// 907/// setcc patterns, only matched when none of the above brcond 908/// patterns match 909/// 910 911// setcc 2 register operands 912def : Pat<(setle GRRegs:$lhs, GRRegs:$rhs), 913 (EQ_2rus (LSS_3r GRRegs:$rhs, GRRegs:$lhs), 0)>; 914def : Pat<(setule GRRegs:$lhs, GRRegs:$rhs), 915 (EQ_2rus (LSU_3r GRRegs:$rhs, GRRegs:$lhs), 0)>; 916 917def : Pat<(setgt GRRegs:$lhs, GRRegs:$rhs), 918 (LSS_3r GRRegs:$rhs, GRRegs:$lhs)>; 919def : Pat<(setugt GRRegs:$lhs, GRRegs:$rhs), 920 (LSU_3r GRRegs:$rhs, GRRegs:$lhs)>; 921 922def : Pat<(setge GRRegs:$lhs, GRRegs:$rhs), 923 (EQ_2rus (LSS_3r GRRegs:$lhs, GRRegs:$rhs), 0)>; 924def : Pat<(setuge GRRegs:$lhs, GRRegs:$rhs), 925 (EQ_2rus (LSU_3r GRRegs:$lhs, GRRegs:$rhs), 0)>; 926 927def : Pat<(setlt GRRegs:$lhs, GRRegs:$rhs), 928 (LSS_3r GRRegs:$lhs, GRRegs:$rhs)>; 929def : Pat<(setult GRRegs:$lhs, GRRegs:$rhs), 930 (LSU_3r GRRegs:$lhs, GRRegs:$rhs)>; 931 932def : Pat<(setne GRRegs:$lhs, GRRegs:$rhs), 933 (EQ_2rus (EQ_3r GRRegs:$lhs, GRRegs:$rhs), 0)>; 934 935def : Pat<(seteq GRRegs:$lhs, GRRegs:$rhs), 936 (EQ_3r GRRegs:$lhs, GRRegs:$rhs)>; 937 938// setcc reg/imm operands 939def : Pat<(seteq GRRegs:$lhs, immUs:$rhs), 940 (EQ_2rus GRRegs:$lhs, immUs:$rhs)>; 941def : Pat<(setne GRRegs:$lhs, immUs:$rhs), 942 (EQ_2rus (EQ_2rus GRRegs:$lhs, immUs:$rhs), 0)>; 943 944// misc 945def : Pat<(add GRRegs:$addr, immUs4:$offset), 946 (LDAWF_l2rus GRRegs:$addr, (div4_xform immUs4:$offset))>; 947 948def : Pat<(sub GRRegs:$addr, immUs4:$offset), 949 (LDAWB_l2rus GRRegs:$addr, (div4_xform immUs4:$offset))>; 950 951def : Pat<(and GRRegs:$val, immMskBitp:$mask), 952 (ZEXT_rus GRRegs:$val, (msksize_xform immMskBitp:$mask))>; 953 954// (sub X, imm) gets canonicalized to (add X, -imm). Match this form. 955def : Pat<(add GRRegs:$src1, immUsNeg:$src2), 956 (SUB_2rus GRRegs:$src1, (neg_xform immUsNeg:$src2))>; 957 958def : Pat<(add GRRegs:$src1, immUs4Neg:$src2), 959 (LDAWB_l2rus GRRegs:$src1, (div4neg_xform immUs4Neg:$src2))>; 960 961/// 962/// Some peepholes 963/// 964 965def : Pat<(mul GRRegs:$src, 3), 966 (LDA16F_l3r GRRegs:$src, GRRegs:$src)>; 967 968def : Pat<(mul GRRegs:$src, 5), 969 (LDAWF_l3r GRRegs:$src, GRRegs:$src)>; 970 971def : Pat<(mul GRRegs:$src, -3), 972 (LDAWB_l3r GRRegs:$src, GRRegs:$src)>; 973 974// ashr X, 32 is equivalent to ashr X, 31 on the XCore. 975def : Pat<(sra GRRegs:$src, 31), 976 (ASHR_l2rus GRRegs:$src, 32)>; 977 978def : Pat<(brcond (setlt GRRegs:$lhs, 0), bb:$dst), 979 (BRFT_lru6 (ASHR_l2rus GRRegs:$lhs, 32), bb:$dst)>; 980 981// setge X, 0 is canonicalized to setgt X, -1 982def : Pat<(brcond (setgt GRRegs:$lhs, -1), bb:$dst), 983 (BRFF_lru6 (ASHR_l2rus GRRegs:$lhs, 32), bb:$dst)>; 984 985def : Pat<(select (setlt GRRegs:$lhs, 0), GRRegs:$T, GRRegs:$F), 986 (SELECT_CC (ASHR_l2rus GRRegs:$lhs, 32), GRRegs:$T, GRRegs:$F)>; 987 988def : Pat<(select (setgt GRRegs:$lhs, -1), GRRegs:$T, GRRegs:$F), 989 (SELECT_CC (ASHR_l2rus GRRegs:$lhs, 32), GRRegs:$F, GRRegs:$T)>; 990 991def : Pat<(setgt GRRegs:$lhs, -1), 992 (EQ_2rus (ASHR_l2rus GRRegs:$lhs, 32), 0)>; 993 994def : Pat<(sra (shl GRRegs:$src, immBpwSubBitp:$imm), immBpwSubBitp:$imm), 995 (SEXT_rus GRRegs:$src, (bpwsub_xform immBpwSubBitp:$imm))>; 996