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