XCoreInstrInfo.td revision 221345
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} 311multiclass FU6_LU6_int<string OpcStr, Intrinsic Int> { 312 def _u6: _FU6< 313 (outs), (ins i32imm:$b), 314 !strconcat(OpcStr, " $b"), 315 [(Int immU6:$b)]>; 316 def _lu6: _FLU6< 317 (outs), (ins i32imm:$b), 318 !strconcat(OpcStr, " $b"), 319 [(Int immU16:$b)]>; 320} 321 322multiclass FU6_LU6_np<string OpcStr> { 323 def _u6: _FU6< 324 (outs), (ins i32imm:$b), 325 !strconcat(OpcStr, " $b"), 326 []>; 327 def _lu6: _FLU6< 328 (outs), (ins i32imm:$b), 329 !strconcat(OpcStr, " $b"), 330 []>; 331} 332 333// U10 334multiclass FU10_LU10_np<string OpcStr> { 335 def _u10: _FU10< 336 (outs), (ins i32imm:$b), 337 !strconcat(OpcStr, " $b"), 338 []>; 339 def _lu10: _FLU10< 340 (outs), (ins i32imm:$b), 341 !strconcat(OpcStr, " $b"), 342 []>; 343} 344 345// Two operand short 346 347class F2R_np<string OpcStr> : _F2R< 348 (outs GRRegs:$dst), (ins GRRegs:$b), 349 !strconcat(OpcStr, " $dst, $b"), 350 []>; 351 352// Two operand long 353 354//===----------------------------------------------------------------------===// 355// Pseudo Instructions 356//===----------------------------------------------------------------------===// 357 358let Defs = [SP], Uses = [SP] in { 359def ADJCALLSTACKDOWN : PseudoInstXCore<(outs), (ins i32imm:$amt), 360 "${:comment} ADJCALLSTACKDOWN $amt", 361 [(callseq_start timm:$amt)]>; 362def ADJCALLSTACKUP : PseudoInstXCore<(outs), (ins i32imm:$amt1, i32imm:$amt2), 363 "${:comment} ADJCALLSTACKUP $amt1", 364 [(callseq_end timm:$amt1, timm:$amt2)]>; 365} 366 367def LDWFI : PseudoInstXCore<(outs GRRegs:$dst), (ins MEMii:$addr), 368 "${:comment} LDWFI $dst, $addr", 369 [(set GRRegs:$dst, (load ADDRspii:$addr))]>; 370 371def LDAWFI : PseudoInstXCore<(outs GRRegs:$dst), (ins MEMii:$addr), 372 "${:comment} LDAWFI $dst, $addr", 373 [(set GRRegs:$dst, ADDRspii:$addr)]>; 374 375def STWFI : PseudoInstXCore<(outs), (ins GRRegs:$src, MEMii:$addr), 376 "${:comment} STWFI $src, $addr", 377 [(store GRRegs:$src, ADDRspii:$addr)]>; 378 379// SELECT_CC_* - Used to implement the SELECT_CC DAG operation. Expanded after 380// instruction selection into a branch sequence. 381let usesCustomInserter = 1 in { 382 def SELECT_CC : PseudoInstXCore<(outs GRRegs:$dst), 383 (ins GRRegs:$cond, GRRegs:$T, GRRegs:$F), 384 "${:comment} SELECT_CC PSEUDO!", 385 [(set GRRegs:$dst, 386 (select GRRegs:$cond, GRRegs:$T, GRRegs:$F))]>; 387} 388 389//===----------------------------------------------------------------------===// 390// Instructions 391//===----------------------------------------------------------------------===// 392 393// Three operand short 394defm ADD : F3R_2RUS<"add", add>; 395defm SUB : F3R_2RUS<"sub", sub>; 396let neverHasSideEffects = 1 in { 397defm EQ : F3R_2RUS_np<"eq">; 398def LSS_3r : F3R_np<"lss">; 399def LSU_3r : F3R_np<"lsu">; 400} 401def AND_3r : F3R<"and", and>; 402def OR_3r : F3R<"or", or>; 403 404let mayLoad=1 in { 405def LDW_3r : _F3R<(outs GRRegs:$dst), (ins GRRegs:$addr, GRRegs:$offset), 406 "ldw $dst, $addr[$offset]", 407 []>; 408 409def LDW_2rus : _F2RUS<(outs GRRegs:$dst), (ins GRRegs:$addr, i32imm:$offset), 410 "ldw $dst, $addr[$offset]", 411 []>; 412 413def LD16S_3r : _F3R<(outs GRRegs:$dst), (ins GRRegs:$addr, GRRegs:$offset), 414 "ld16s $dst, $addr[$offset]", 415 []>; 416 417def LD8U_3r : _F3R<(outs GRRegs:$dst), (ins GRRegs:$addr, GRRegs:$offset), 418 "ld8u $dst, $addr[$offset]", 419 []>; 420} 421 422let mayStore=1 in { 423def STW_3r : _F3R<(outs), (ins GRRegs:$val, GRRegs:$addr, GRRegs:$offset), 424 "stw $val, $addr[$offset]", 425 []>; 426 427def STW_2rus : _F2RUS<(outs), (ins GRRegs:$val, GRRegs:$addr, i32imm:$offset), 428 "stw $val, $addr[$offset]", 429 []>; 430} 431 432defm SHL : F3R_2RBITP<"shl", shl>; 433defm SHR : F3R_2RBITP<"shr", srl>; 434// TODO tsetr 435 436// Three operand long 437def LDAWF_l3r : _FL3R<(outs GRRegs:$dst), (ins GRRegs:$addr, GRRegs:$offset), 438 "ldaw $dst, $addr[$offset]", 439 [(set GRRegs:$dst, (ldawf GRRegs:$addr, GRRegs:$offset))]>; 440 441let neverHasSideEffects = 1 in 442def LDAWF_l2rus : _FL2RUS<(outs GRRegs:$dst), 443 (ins GRRegs:$addr, i32imm:$offset), 444 "ldaw $dst, $addr[$offset]", 445 []>; 446 447def LDAWB_l3r : _FL3R<(outs GRRegs:$dst), (ins GRRegs:$addr, GRRegs:$offset), 448 "ldaw $dst, $addr[-$offset]", 449 [(set GRRegs:$dst, (ldawb GRRegs:$addr, GRRegs:$offset))]>; 450 451let neverHasSideEffects = 1 in 452def LDAWB_l2rus : _FL2RUS<(outs GRRegs:$dst), 453 (ins GRRegs:$addr, i32imm:$offset), 454 "ldaw $dst, $addr[-$offset]", 455 []>; 456 457def LDA16F_l3r : _FL3R<(outs GRRegs:$dst), (ins GRRegs:$addr, GRRegs:$offset), 458 "lda16 $dst, $addr[$offset]", 459 [(set GRRegs:$dst, (lda16f GRRegs:$addr, GRRegs:$offset))]>; 460 461def LDA16B_l3r : _FL3R<(outs GRRegs:$dst), (ins GRRegs:$addr, GRRegs:$offset), 462 "lda16 $dst, $addr[-$offset]", 463 [(set GRRegs:$dst, (lda16b GRRegs:$addr, GRRegs:$offset))]>; 464 465def MUL_l3r : FL3R<"mul", mul>; 466// Instructions which may trap are marked as side effecting. 467let hasSideEffects = 1 in { 468def DIVS_l3r : FL3R<"divs", sdiv>; 469def DIVU_l3r : FL3R<"divu", udiv>; 470def REMS_l3r : FL3R<"rems", srem>; 471def REMU_l3r : FL3R<"remu", urem>; 472} 473def XOR_l3r : FL3R<"xor", xor>; 474defm ASHR : FL3R_L2RBITP<"ashr", sra>; 475// TODO crc32, crc8, inpw, outpw 476let mayStore=1 in { 477def ST16_l3r : _FL3R<(outs), (ins GRRegs:$val, GRRegs:$addr, GRRegs:$offset), 478 "st16 $val, $addr[$offset]", 479 []>; 480 481def ST8_l3r : _FL3R<(outs), (ins GRRegs:$val, GRRegs:$addr, GRRegs:$offset), 482 "st8 $val, $addr[$offset]", 483 []>; 484} 485 486// Four operand long 487let Constraints = "$src1 = $dst1,$src2 = $dst2" in { 488def MACCU_l4r : _L4R<(outs GRRegs:$dst1, GRRegs:$dst2), 489 (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3, 490 GRRegs:$src4), 491 "maccu $dst1, $dst2, $src3, $src4", 492 []>; 493 494def MACCS_l4r : _L4R<(outs GRRegs:$dst1, GRRegs:$dst2), 495 (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3, 496 GRRegs:$src4), 497 "maccs $dst1, $dst2, $src3, $src4", 498 []>; 499} 500 501// Five operand long 502 503def LADD_l5r : _L5R<(outs GRRegs:$dst1, GRRegs:$dst2), 504 (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3), 505 "ladd $dst1, $dst2, $src1, $src2, $src3", 506 []>; 507 508def LSUB_l5r : _L5R<(outs GRRegs:$dst1, GRRegs:$dst2), 509 (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3), 510 "lsub $dst1, $dst2, $src1, $src2, $src3", 511 []>; 512 513def LDIV_l5r : _L5R<(outs GRRegs:$dst1, GRRegs:$dst2), 514 (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3), 515 "ldiv $dst1, $dst2, $src1, $src2, $src3", 516 []>; 517 518// Six operand long 519 520def LMUL_l6r : _L6R<(outs GRRegs:$dst1, GRRegs:$dst2), 521 (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3, 522 GRRegs:$src4), 523 "lmul $dst1, $dst2, $src1, $src2, $src3, $src4", 524 []>; 525 526// Register - U6 527 528//let Uses = [DP] in ... 529let neverHasSideEffects = 1, isReMaterializable = 1 in 530def LDAWDP_ru6: _FRU6<(outs GRRegs:$dst), (ins MEMii:$a), 531 "ldaw $dst, dp[$a]", 532 []>; 533 534let isReMaterializable = 1 in 535def LDAWDP_lru6: _FLRU6< 536 (outs GRRegs:$dst), (ins MEMii:$a), 537 "ldaw $dst, dp[$a]", 538 [(set GRRegs:$dst, ADDRdpii:$a)]>; 539 540let mayLoad=1 in 541def LDWDP_ru6: _FRU6<(outs GRRegs:$dst), (ins MEMii:$a), 542 "ldw $dst, dp[$a]", 543 []>; 544 545def LDWDP_lru6: _FLRU6< 546 (outs GRRegs:$dst), (ins MEMii:$a), 547 "ldw $dst, dp[$a]", 548 [(set GRRegs:$dst, (load ADDRdpii:$a))]>; 549 550let mayStore=1 in 551def STWDP_ru6 : _FRU6<(outs), (ins GRRegs:$val, MEMii:$addr), 552 "stw $val, dp[$addr]", 553 []>; 554 555def STWDP_lru6 : _FLRU6<(outs), (ins GRRegs:$val, MEMii:$addr), 556 "stw $val, dp[$addr]", 557 [(store GRRegs:$val, ADDRdpii:$addr)]>; 558 559//let Uses = [CP] in .. 560let mayLoad = 1, isReMaterializable = 1 in 561defm LDWCP : FRU6_LRU6_cp<"ldw">; 562 563let Uses = [SP] in { 564let mayStore=1 in { 565def STWSP_ru6 : _FRU6< 566 (outs), (ins GRRegs:$val, i32imm:$index), 567 "stw $val, sp[$index]", 568 [(XCoreStwsp GRRegs:$val, immU6:$index)]>; 569 570def STWSP_lru6 : _FLRU6< 571 (outs), (ins GRRegs:$val, i32imm:$index), 572 "stw $val, sp[$index]", 573 [(XCoreStwsp GRRegs:$val, immU16:$index)]>; 574} 575 576let mayLoad=1 in { 577def LDWSP_ru6 : _FRU6< 578 (outs GRRegs:$dst), (ins i32imm:$b), 579 "ldw $dst, sp[$b]", 580 []>; 581 582def LDWSP_lru6 : _FLRU6< 583 (outs GRRegs:$dst), (ins i32imm:$b), 584 "ldw $dst, sp[$b]", 585 []>; 586} 587 588let neverHasSideEffects = 1 in { 589def LDAWSP_ru6 : _FRU6< 590 (outs GRRegs:$dst), (ins i32imm:$b), 591 "ldaw $dst, sp[$b]", 592 []>; 593 594def LDAWSP_lru6 : _FLRU6< 595 (outs GRRegs:$dst), (ins i32imm:$b), 596 "ldaw $dst, sp[$b]", 597 []>; 598 599def LDAWSP_ru6_RRegs : _FRU6< 600 (outs RRegs:$dst), (ins i32imm:$b), 601 "ldaw $dst, sp[$b]", 602 []>; 603 604def LDAWSP_lru6_RRegs : _FLRU6< 605 (outs RRegs:$dst), (ins i32imm:$b), 606 "ldaw $dst, sp[$b]", 607 []>; 608} 609} 610 611let isReMaterializable = 1 in { 612def LDC_ru6 : _FRU6< 613 (outs GRRegs:$dst), (ins i32imm:$b), 614 "ldc $dst, $b", 615 [(set GRRegs:$dst, immU6:$b)]>; 616 617def LDC_lru6 : _FLRU6< 618 (outs GRRegs:$dst), (ins i32imm:$b), 619 "ldc $dst, $b", 620 [(set GRRegs:$dst, immU16:$b)]>; 621} 622 623def SETC_ru6 : _FRU6<(outs), (ins GRRegs:$r, i32imm:$val), 624 "setc res[$r], $val", 625 [(int_xcore_setc GRRegs:$r, immU6:$val)]>; 626 627def SETC_lru6 : _FLRU6<(outs), (ins GRRegs:$r, i32imm:$val), 628 "setc res[$r], $val", 629 [(int_xcore_setc GRRegs:$r, immU16:$val)]>; 630 631// Operand register - U6 632let isBranch = 1, isTerminator = 1 in { 633defm BRFT: FRU6_LRU6_branch<"bt">; 634defm BRBT: FRU6_LRU6_branch<"bt">; 635defm BRFF: FRU6_LRU6_branch<"bf">; 636defm BRBF: FRU6_LRU6_branch<"bf">; 637} 638 639// U6 640let Defs = [SP], Uses = [SP] in { 641let neverHasSideEffects = 1 in 642defm EXTSP : FU6_LU6_np<"extsp">; 643let mayStore = 1 in 644defm ENTSP : FU6_LU6_np<"entsp">; 645 646let isReturn = 1, isTerminator = 1, mayLoad = 1, isBarrier = 1 in { 647defm RETSP : FU6_LU6<"retsp", XCoreRetsp>; 648} 649} 650 651// TODO extdp, kentsp, krestsp, blat 652// getsr, kalli 653let isBranch = 1, isTerminator = 1, isBarrier = 1 in { 654def BRBU_u6 : _FU6< 655 (outs), 656 (ins brtarget:$target), 657 "bu $target", 658 []>; 659 660def BRBU_lu6 : _FLU6< 661 (outs), 662 (ins brtarget:$target), 663 "bu $target", 664 []>; 665 666def BRFU_u6 : _FU6< 667 (outs), 668 (ins brtarget:$target), 669 "bu $target", 670 []>; 671 672def BRFU_lu6 : _FLU6< 673 (outs), 674 (ins brtarget:$target), 675 "bu $target", 676 []>; 677} 678 679//let Uses = [CP] in ... 680let Defs = [R11], neverHasSideEffects = 1, isReMaterializable = 1 in 681def LDAWCP_u6: _FRU6<(outs), (ins MEMii:$a), 682 "ldaw r11, cp[$a]", 683 []>; 684 685let Defs = [R11], isReMaterializable = 1 in 686def LDAWCP_lu6: _FLRU6< 687 (outs), (ins MEMii:$a), 688 "ldaw r11, cp[$a]", 689 [(set R11, ADDRcpii:$a)]>; 690 691defm SETSR : FU6_LU6_int<"setsr", int_xcore_setsr>; 692 693defm CLRSR : FU6_LU6_int<"clrsr", int_xcore_clrsr>; 694 695// setsr may cause a branch if it is used to enable events. clrsr may 696// branch if it is executed while events are enabled. 697let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1 in { 698defm SETSR_branch : FU6_LU6_np<"setsr">; 699defm CLRSR_branch : FU6_LU6_np<"clrsr">; 700} 701 702// U10 703// TODO ldwcpl, blacp 704 705let Defs = [R11], isReMaterializable = 1, neverHasSideEffects = 1 in 706def LDAP_u10 : _FU10< 707 (outs), 708 (ins i32imm:$addr), 709 "ldap r11, $addr", 710 []>; 711 712let Defs = [R11], isReMaterializable = 1 in 713def LDAP_lu10 : _FLU10< 714 (outs), 715 (ins i32imm:$addr), 716 "ldap r11, $addr", 717 [(set R11, (pcrelwrapper tglobaladdr:$addr))]>; 718 719let Defs = [R11], isReMaterializable = 1 in 720def LDAP_lu10_ba : _FLU10<(outs), 721 (ins i32imm:$addr), 722 "ldap r11, $addr", 723 [(set R11, (pcrelwrapper tblockaddress:$addr))]>; 724 725let isCall=1, 726// All calls clobber the link register and the non-callee-saved registers: 727Defs = [R0, R1, R2, R3, R11, LR] in { 728def BL_u10 : _FU10< 729 (outs), 730 (ins calltarget:$target, variable_ops), 731 "bl $target", 732 [(XCoreBranchLink immU10:$target)]>; 733 734def BL_lu10 : _FLU10< 735 (outs), 736 (ins calltarget:$target, variable_ops), 737 "bl $target", 738 [(XCoreBranchLink immU20:$target)]>; 739} 740 741// Two operand short 742// TODO eet, eef, testwct, tsetmr, sext (reg), zext (reg) 743def NOT : _F2R<(outs GRRegs:$dst), (ins GRRegs:$b), 744 "not $dst, $b", 745 [(set GRRegs:$dst, (not GRRegs:$b))]>; 746 747def NEG : _F2R<(outs GRRegs:$dst), (ins GRRegs:$b), 748 "neg $dst, $b", 749 [(set GRRegs:$dst, (ineg GRRegs:$b))]>; 750 751let Constraints = "$src1 = $dst" in { 752let neverHasSideEffects = 1 in 753def SEXT_rus : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$src1, i32imm:$src2), 754 "sext $dst, $src2", 755 []>; 756 757let neverHasSideEffects = 1 in 758def ZEXT_rus : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$src1, i32imm:$src2), 759 "zext $dst, $src2", 760 []>; 761 762def ANDNOT_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$src1, GRRegs:$src2), 763 "andnot $dst, $src2", 764 [(set GRRegs:$dst, (and GRRegs:$src1, (not GRRegs:$src2)))]>; 765} 766 767let isReMaterializable = 1, neverHasSideEffects = 1 in 768def MKMSK_rus : _FRUS<(outs GRRegs:$dst), (ins i32imm:$size), 769 "mkmsk $dst, $size", 770 []>; 771 772def MKMSK_2r : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$size), 773 "mkmsk $dst, $size", 774 [(set GRRegs:$dst, (add (shl 1, GRRegs:$size), 0xffffffff))]>; 775 776def GETR_rus : _FRUS<(outs GRRegs:$dst), (ins i32imm:$type), 777 "getr $dst, $type", 778 [(set GRRegs:$dst, (int_xcore_getr immUs:$type))]>; 779 780def GETTS_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$r), 781 "getts $dst, res[$r]", 782 [(set GRRegs:$dst, (int_xcore_getts GRRegs:$r))]>; 783 784def SETPT_2r : _F2R<(outs), (ins GRRegs:$r, GRRegs:$val), 785 "setpt res[$r], $val", 786 [(int_xcore_setpt GRRegs:$r, GRRegs:$val)]>; 787 788def OUTCT_2r : _F2R<(outs), (ins GRRegs:$r, GRRegs:$val), 789 "outct res[$r], $val", 790 [(int_xcore_outct GRRegs:$r, GRRegs:$val)]>; 791 792def OUTCT_rus : _F2R<(outs), (ins GRRegs:$r, i32imm:$val), 793 "outct res[$r], $val", 794 [(int_xcore_outct GRRegs:$r, immUs:$val)]>; 795 796def OUTT_2r : _F2R<(outs), (ins GRRegs:$r, GRRegs:$val), 797 "outt res[$r], $val", 798 [(int_xcore_outt GRRegs:$r, GRRegs:$val)]>; 799 800def OUT_2r : _F2R<(outs), (ins GRRegs:$r, GRRegs:$val), 801 "out res[$r], $val", 802 [(int_xcore_out GRRegs:$r, GRRegs:$val)]>; 803 804let Constraints = "$src = $dst" in 805def OUTSHR_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$r, GRRegs:$src), 806 "outshr res[$r], $src", 807 [(set GRRegs:$dst, (int_xcore_outshr GRRegs:$r, GRRegs:$src))]>; 808 809def INCT_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$r), 810 "inct $dst, res[$r]", 811 [(set GRRegs:$dst, (int_xcore_inct GRRegs:$r))]>; 812 813def INT_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$r), 814 "int $dst, res[$r]", 815 [(set GRRegs:$dst, (int_xcore_int GRRegs:$r))]>; 816 817def IN_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$r), 818 "in $dst, res[$r]", 819 [(set GRRegs:$dst, (int_xcore_in GRRegs:$r))]>; 820 821let Constraints = "$src = $dst" in 822def INSHR_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$r, GRRegs:$src), 823 "inshr $dst, res[$r]", 824 [(set GRRegs:$dst, (int_xcore_inshr GRRegs:$r, GRRegs:$src))]>; 825 826def CHKCT_2r : _F2R<(outs), (ins GRRegs:$r, GRRegs:$val), 827 "chkct res[$r], $val", 828 [(int_xcore_chkct GRRegs:$r, GRRegs:$val)]>; 829 830def CHKCT_rus : _F2R<(outs), (ins GRRegs:$r, i32imm:$val), 831 "chkct res[$r], $val", 832 [(int_xcore_chkct GRRegs:$r, immUs:$val)]>; 833 834def SETD_2r : _F2R<(outs), (ins GRRegs:$r, GRRegs:$val), 835 "setd res[$r], $val", 836 [(int_xcore_setd GRRegs:$r, GRRegs:$val)]>; 837 838def GETST_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$r), 839 "getst $dst, res[$r]", 840 [(set GRRegs:$dst, (int_xcore_getst GRRegs:$r))]>; 841 842def INITSP_2r : _F2R<(outs), (ins GRRegs:$t, GRRegs:$src), 843 "init t[$t]:sp, $src", 844 [(int_xcore_initsp GRRegs:$t, GRRegs:$src)]>; 845 846def INITPC_2r : _F2R<(outs), (ins GRRegs:$t, GRRegs:$src), 847 "init t[$t]:pc, $src", 848 [(int_xcore_initpc GRRegs:$t, GRRegs:$src)]>; 849 850def INITCP_2r : _F2R<(outs), (ins GRRegs:$t, GRRegs:$src), 851 "init t[$t]:cp, $src", 852 [(int_xcore_initcp GRRegs:$t, GRRegs:$src)]>; 853 854def INITDP_2r : _F2R<(outs), (ins GRRegs:$t, GRRegs:$src), 855 "init t[$t]:dp, $src", 856 [(int_xcore_initdp GRRegs:$t, GRRegs:$src)]>; 857 858// Two operand long 859// TODO endin, peek, 860// getd, testlcl 861def BITREV_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src), 862 "bitrev $dst, $src", 863 [(set GRRegs:$dst, (int_xcore_bitrev GRRegs:$src))]>; 864 865def BYTEREV_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src), 866 "byterev $dst, $src", 867 [(set GRRegs:$dst, (bswap GRRegs:$src))]>; 868 869def CLZ_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src), 870 "clz $dst, $src", 871 [(set GRRegs:$dst, (ctlz GRRegs:$src))]>; 872 873def SETC_l2r : _FL2R<(outs), (ins GRRegs:$r, GRRegs:$val), 874 "setc res[$r], $val", 875 [(int_xcore_setc GRRegs:$r, GRRegs:$val)]>; 876 877def SETTW_l2r : _FL2R<(outs), (ins GRRegs:$r, GRRegs:$val), 878 "settw res[$r], $val", 879 [(int_xcore_settw GRRegs:$r, GRRegs:$val)]>; 880 881def GETPS_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src), 882 "get $dst, ps[$src]", 883 [(set GRRegs:$dst, (int_xcore_getps GRRegs:$src))]>; 884 885def SETPS_l2r : _FL2R<(outs), (ins GRRegs:$src1, GRRegs:$src2), 886 "set ps[$src1], $src2", 887 [(int_xcore_setps GRRegs:$src1, GRRegs:$src2)]>; 888 889def INITLR_l2r : _FL2R<(outs), (ins GRRegs:$t, GRRegs:$src), 890 "init t[$t]:lr, $src", 891 [(int_xcore_initlr GRRegs:$t, GRRegs:$src)]>; 892 893def SETCLK_l2r : _FL2R<(outs), (ins GRRegs:$src1, GRRegs:$src2), 894 "setclk res[$src1], $src2", 895 [(int_xcore_setclk GRRegs:$src1, GRRegs:$src2)]>; 896 897def SETRDY_l2r : _FL2R<(outs), (ins GRRegs:$src1, GRRegs:$src2), 898 "setrdy res[$src1], $src2", 899 [(int_xcore_setrdy GRRegs:$src1, GRRegs:$src2)]>; 900 901def SETPSC_l2r : _FL2R<(outs), (ins GRRegs:$src1, GRRegs:$src2), 902 "setpsc res[$src1], $src2", 903 [(int_xcore_setpsc GRRegs:$src1, GRRegs:$src2)]>; 904 905// One operand short 906// TODO edu, eeu, waitet, waitef, tstart, clrtp 907// setdp, setcp, setev, kcall 908// dgetreg 909def MSYNC_1r : _F1R<(outs), (ins GRRegs:$i), 910 "msync res[$i]", 911 [(int_xcore_msync GRRegs:$i)]>; 912def MJOIN_1r : _F1R<(outs), (ins GRRegs:$i), 913 "mjoin res[$i]", 914 [(int_xcore_mjoin GRRegs:$i)]>; 915 916let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1 in 917def BAU_1r : _F1R<(outs), (ins GRRegs:$addr), 918 "bau $addr", 919 [(brind GRRegs:$addr)]>; 920 921let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1 in 922def BR_JT : PseudoInstXCore<(outs), (ins InlineJT:$t, GRRegs:$i), 923 "bru $i\n$t", 924 [(XCoreBR_JT tjumptable:$t, GRRegs:$i)]>; 925 926let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1 in 927def BR_JT32 : PseudoInstXCore<(outs), (ins InlineJT32:$t, GRRegs:$i), 928 "bru $i\n$t", 929 [(XCoreBR_JT32 tjumptable:$t, GRRegs:$i)]>; 930 931let Defs=[SP], neverHasSideEffects=1 in 932def SETSP_1r : _F1R<(outs), (ins GRRegs:$src), 933 "set sp, $src", 934 []>; 935 936let hasCtrlDep = 1 in 937def ECALLT_1r : _F1R<(outs), (ins GRRegs:$src), 938 "ecallt $src", 939 []>; 940 941let hasCtrlDep = 1 in 942def ECALLF_1r : _F1R<(outs), (ins GRRegs:$src), 943 "ecallf $src", 944 []>; 945 946let isCall=1, 947// All calls clobber the link register and the non-callee-saved registers: 948Defs = [R0, R1, R2, R3, R11, LR] in { 949def BLA_1r : _F1R<(outs), (ins GRRegs:$addr, variable_ops), 950 "bla $addr", 951 [(XCoreBranchLink GRRegs:$addr)]>; 952} 953 954def SYNCR_1r : _F1R<(outs), (ins GRRegs:$r), 955 "syncr res[$r]", 956 [(int_xcore_syncr GRRegs:$r)]>; 957 958def FREER_1r : _F1R<(outs), (ins GRRegs:$r), 959 "freer res[$r]", 960 [(int_xcore_freer GRRegs:$r)]>; 961 962let Uses=[R11] in 963def SETV_1r : _F1R<(outs), (ins GRRegs:$r), 964 "setv res[$r], r11", 965 [(int_xcore_setv GRRegs:$r, R11)]>; 966 967def EEU_1r : _F1R<(outs), (ins GRRegs:$r), 968 "eeu res[$r]", 969 [(int_xcore_eeu GRRegs:$r)]>; 970 971// Zero operand short 972// TODO freet, ldspc, stspc, ldssr, stssr, ldsed, stsed, 973// stet, geted, getet, getkep, getksp, setkep, getid, kret, dcall, dret, 974// dentsp, drestsp 975 976def CLRE_0R : _F0R<(outs), (ins), "clre", [(int_xcore_clre)]>; 977 978let Defs = [R11] in 979def GETID_0R : _F0R<(outs), (ins), 980 "get r11, id", 981 [(set R11, (int_xcore_getid))]>; 982 983def SSYNC_0r : _F0R<(outs), (ins), 984 "ssync", 985 [(int_xcore_ssync)]>; 986 987let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1, 988 hasSideEffects = 1 in 989def WAITEU_0R : _F0R<(outs), (ins), 990 "waiteu", 991 [(brind (int_xcore_waitevent))]>; 992 993//===----------------------------------------------------------------------===// 994// Non-Instruction Patterns 995//===----------------------------------------------------------------------===// 996 997def : Pat<(XCoreBranchLink tglobaladdr:$addr), (BL_lu10 tglobaladdr:$addr)>; 998def : Pat<(XCoreBranchLink texternalsym:$addr), (BL_lu10 texternalsym:$addr)>; 999 1000/// sext_inreg 1001def : Pat<(sext_inreg GRRegs:$b, i1), (SEXT_rus GRRegs:$b, 1)>; 1002def : Pat<(sext_inreg GRRegs:$b, i8), (SEXT_rus GRRegs:$b, 8)>; 1003def : Pat<(sext_inreg GRRegs:$b, i16), (SEXT_rus GRRegs:$b, 16)>; 1004 1005/// loads 1006def : Pat<(zextloadi8 (add GRRegs:$addr, GRRegs:$offset)), 1007 (LD8U_3r GRRegs:$addr, GRRegs:$offset)>; 1008def : Pat<(zextloadi8 GRRegs:$addr), (LD8U_3r GRRegs:$addr, (LDC_ru6 0))>; 1009 1010def : Pat<(sextloadi16 (lda16f GRRegs:$addr, GRRegs:$offset)), 1011 (LD16S_3r GRRegs:$addr, GRRegs:$offset)>; 1012def : Pat<(sextloadi16 GRRegs:$addr), (LD16S_3r GRRegs:$addr, (LDC_ru6 0))>; 1013 1014def : Pat<(load (ldawf GRRegs:$addr, GRRegs:$offset)), 1015 (LDW_3r GRRegs:$addr, GRRegs:$offset)>; 1016def : Pat<(load (add GRRegs:$addr, immUs4:$offset)), 1017 (LDW_2rus GRRegs:$addr, (div4_xform immUs4:$offset))>; 1018def : Pat<(load GRRegs:$addr), (LDW_2rus GRRegs:$addr, 0)>; 1019 1020/// anyext 1021def : Pat<(extloadi8 (add GRRegs:$addr, GRRegs:$offset)), 1022 (LD8U_3r GRRegs:$addr, GRRegs:$offset)>; 1023def : Pat<(extloadi8 GRRegs:$addr), (LD8U_3r GRRegs:$addr, (LDC_ru6 0))>; 1024def : Pat<(extloadi16 (lda16f GRRegs:$addr, GRRegs:$offset)), 1025 (LD16S_3r GRRegs:$addr, GRRegs:$offset)>; 1026def : Pat<(extloadi16 GRRegs:$addr), (LD16S_3r GRRegs:$addr, (LDC_ru6 0))>; 1027 1028/// stores 1029def : Pat<(truncstorei8 GRRegs:$val, (add GRRegs:$addr, GRRegs:$offset)), 1030 (ST8_l3r GRRegs:$val, GRRegs:$addr, GRRegs:$offset)>; 1031def : Pat<(truncstorei8 GRRegs:$val, GRRegs:$addr), 1032 (ST8_l3r GRRegs:$val, GRRegs:$addr, (LDC_ru6 0))>; 1033 1034def : Pat<(truncstorei16 GRRegs:$val, (lda16f GRRegs:$addr, GRRegs:$offset)), 1035 (ST16_l3r GRRegs:$val, GRRegs:$addr, GRRegs:$offset)>; 1036def : Pat<(truncstorei16 GRRegs:$val, GRRegs:$addr), 1037 (ST16_l3r GRRegs:$val, GRRegs:$addr, (LDC_ru6 0))>; 1038 1039def : Pat<(store GRRegs:$val, (ldawf GRRegs:$addr, GRRegs:$offset)), 1040 (STW_3r GRRegs:$val, GRRegs:$addr, GRRegs:$offset)>; 1041def : Pat<(store GRRegs:$val, (add GRRegs:$addr, immUs4:$offset)), 1042 (STW_2rus GRRegs:$val, GRRegs:$addr, (div4_xform immUs4:$offset))>; 1043def : Pat<(store GRRegs:$val, GRRegs:$addr), 1044 (STW_2rus GRRegs:$val, GRRegs:$addr, 0)>; 1045 1046/// cttz 1047def : Pat<(cttz GRRegs:$src), (CLZ_l2r (BITREV_l2r GRRegs:$src))>; 1048 1049/// trap 1050def : Pat<(trap), (ECALLF_1r (LDC_ru6 0))>; 1051 1052/// 1053/// branch patterns 1054/// 1055 1056// unconditional branch 1057def : Pat<(br bb:$addr), (BRFU_lu6 bb:$addr)>; 1058 1059// direct match equal/notequal zero brcond 1060def : Pat<(brcond (setne GRRegs:$lhs, 0), bb:$dst), 1061 (BRFT_lru6 GRRegs:$lhs, bb:$dst)>; 1062def : Pat<(brcond (seteq GRRegs:$lhs, 0), bb:$dst), 1063 (BRFF_lru6 GRRegs:$lhs, bb:$dst)>; 1064 1065def : Pat<(brcond (setle GRRegs:$lhs, GRRegs:$rhs), bb:$dst), 1066 (BRFF_lru6 (LSS_3r GRRegs:$rhs, GRRegs:$lhs), bb:$dst)>; 1067def : Pat<(brcond (setule GRRegs:$lhs, GRRegs:$rhs), bb:$dst), 1068 (BRFF_lru6 (LSU_3r GRRegs:$rhs, GRRegs:$lhs), bb:$dst)>; 1069def : Pat<(brcond (setge GRRegs:$lhs, GRRegs:$rhs), bb:$dst), 1070 (BRFF_lru6 (LSS_3r GRRegs:$lhs, GRRegs:$rhs), bb:$dst)>; 1071def : Pat<(brcond (setuge GRRegs:$lhs, GRRegs:$rhs), bb:$dst), 1072 (BRFF_lru6 (LSU_3r GRRegs:$lhs, GRRegs:$rhs), bb:$dst)>; 1073def : Pat<(brcond (setne GRRegs:$lhs, GRRegs:$rhs), bb:$dst), 1074 (BRFF_lru6 (EQ_3r GRRegs:$lhs, GRRegs:$rhs), bb:$dst)>; 1075def : Pat<(brcond (setne GRRegs:$lhs, immUs:$rhs), bb:$dst), 1076 (BRFF_lru6 (EQ_2rus GRRegs:$lhs, immUs:$rhs), bb:$dst)>; 1077 1078// generic brcond pattern 1079def : Pat<(brcond GRRegs:$cond, bb:$addr), (BRFT_lru6 GRRegs:$cond, bb:$addr)>; 1080 1081 1082/// 1083/// Select patterns 1084/// 1085 1086// direct match equal/notequal zero select 1087def : Pat<(select (setne GRRegs:$lhs, 0), GRRegs:$T, GRRegs:$F), 1088 (SELECT_CC GRRegs:$lhs, GRRegs:$T, GRRegs:$F)>; 1089 1090def : Pat<(select (seteq GRRegs:$lhs, 0), GRRegs:$T, GRRegs:$F), 1091 (SELECT_CC GRRegs:$lhs, GRRegs:$F, GRRegs:$T)>; 1092 1093def : Pat<(select (setle GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F), 1094 (SELECT_CC (LSS_3r GRRegs:$rhs, GRRegs:$lhs), GRRegs:$F, GRRegs:$T)>; 1095def : Pat<(select (setule GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F), 1096 (SELECT_CC (LSU_3r GRRegs:$rhs, GRRegs:$lhs), GRRegs:$F, GRRegs:$T)>; 1097def : Pat<(select (setge GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F), 1098 (SELECT_CC (LSS_3r GRRegs:$lhs, GRRegs:$rhs), GRRegs:$F, GRRegs:$T)>; 1099def : Pat<(select (setuge GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F), 1100 (SELECT_CC (LSU_3r GRRegs:$lhs, GRRegs:$rhs), GRRegs:$F, GRRegs:$T)>; 1101def : Pat<(select (setne GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F), 1102 (SELECT_CC (EQ_3r GRRegs:$lhs, GRRegs:$rhs), GRRegs:$F, GRRegs:$T)>; 1103def : Pat<(select (setne GRRegs:$lhs, immUs:$rhs), GRRegs:$T, GRRegs:$F), 1104 (SELECT_CC (EQ_2rus GRRegs:$lhs, immUs:$rhs), GRRegs:$F, GRRegs:$T)>; 1105 1106/// 1107/// setcc patterns, only matched when none of the above brcond 1108/// patterns match 1109/// 1110 1111// setcc 2 register operands 1112def : Pat<(setle GRRegs:$lhs, GRRegs:$rhs), 1113 (EQ_2rus (LSS_3r GRRegs:$rhs, GRRegs:$lhs), 0)>; 1114def : Pat<(setule GRRegs:$lhs, GRRegs:$rhs), 1115 (EQ_2rus (LSU_3r GRRegs:$rhs, GRRegs:$lhs), 0)>; 1116 1117def : Pat<(setgt GRRegs:$lhs, GRRegs:$rhs), 1118 (LSS_3r GRRegs:$rhs, GRRegs:$lhs)>; 1119def : Pat<(setugt GRRegs:$lhs, GRRegs:$rhs), 1120 (LSU_3r GRRegs:$rhs, GRRegs:$lhs)>; 1121 1122def : Pat<(setge GRRegs:$lhs, GRRegs:$rhs), 1123 (EQ_2rus (LSS_3r GRRegs:$lhs, GRRegs:$rhs), 0)>; 1124def : Pat<(setuge GRRegs:$lhs, GRRegs:$rhs), 1125 (EQ_2rus (LSU_3r GRRegs:$lhs, GRRegs:$rhs), 0)>; 1126 1127def : Pat<(setlt GRRegs:$lhs, GRRegs:$rhs), 1128 (LSS_3r GRRegs:$lhs, GRRegs:$rhs)>; 1129def : Pat<(setult GRRegs:$lhs, GRRegs:$rhs), 1130 (LSU_3r GRRegs:$lhs, GRRegs:$rhs)>; 1131 1132def : Pat<(setne GRRegs:$lhs, GRRegs:$rhs), 1133 (EQ_2rus (EQ_3r GRRegs:$lhs, GRRegs:$rhs), 0)>; 1134 1135def : Pat<(seteq GRRegs:$lhs, GRRegs:$rhs), 1136 (EQ_3r GRRegs:$lhs, GRRegs:$rhs)>; 1137 1138// setcc reg/imm operands 1139def : Pat<(seteq GRRegs:$lhs, immUs:$rhs), 1140 (EQ_2rus GRRegs:$lhs, immUs:$rhs)>; 1141def : Pat<(setne GRRegs:$lhs, immUs:$rhs), 1142 (EQ_2rus (EQ_2rus GRRegs:$lhs, immUs:$rhs), 0)>; 1143 1144// misc 1145def : Pat<(add GRRegs:$addr, immUs4:$offset), 1146 (LDAWF_l2rus GRRegs:$addr, (div4_xform immUs4:$offset))>; 1147 1148def : Pat<(sub GRRegs:$addr, immUs4:$offset), 1149 (LDAWB_l2rus GRRegs:$addr, (div4_xform immUs4:$offset))>; 1150 1151def : Pat<(and GRRegs:$val, immMskBitp:$mask), 1152 (ZEXT_rus GRRegs:$val, (msksize_xform immMskBitp:$mask))>; 1153 1154// (sub X, imm) gets canonicalized to (add X, -imm). Match this form. 1155def : Pat<(add GRRegs:$src1, immUsNeg:$src2), 1156 (SUB_2rus GRRegs:$src1, (neg_xform immUsNeg:$src2))>; 1157 1158def : Pat<(add GRRegs:$src1, immUs4Neg:$src2), 1159 (LDAWB_l2rus GRRegs:$src1, (div4neg_xform immUs4Neg:$src2))>; 1160 1161/// 1162/// Some peepholes 1163/// 1164 1165def : Pat<(mul GRRegs:$src, 3), 1166 (LDA16F_l3r GRRegs:$src, GRRegs:$src)>; 1167 1168def : Pat<(mul GRRegs:$src, 5), 1169 (LDAWF_l3r GRRegs:$src, GRRegs:$src)>; 1170 1171def : Pat<(mul GRRegs:$src, -3), 1172 (LDAWB_l3r GRRegs:$src, GRRegs:$src)>; 1173 1174// ashr X, 32 is equivalent to ashr X, 31 on the XCore. 1175def : Pat<(sra GRRegs:$src, 31), 1176 (ASHR_l2rus GRRegs:$src, 32)>; 1177 1178def : Pat<(brcond (setlt GRRegs:$lhs, 0), bb:$dst), 1179 (BRFT_lru6 (ASHR_l2rus GRRegs:$lhs, 32), bb:$dst)>; 1180 1181// setge X, 0 is canonicalized to setgt X, -1 1182def : Pat<(brcond (setgt GRRegs:$lhs, -1), bb:$dst), 1183 (BRFF_lru6 (ASHR_l2rus GRRegs:$lhs, 32), bb:$dst)>; 1184 1185def : Pat<(select (setlt GRRegs:$lhs, 0), GRRegs:$T, GRRegs:$F), 1186 (SELECT_CC (ASHR_l2rus GRRegs:$lhs, 32), GRRegs:$T, GRRegs:$F)>; 1187 1188def : Pat<(select (setgt GRRegs:$lhs, -1), GRRegs:$T, GRRegs:$F), 1189 (SELECT_CC (ASHR_l2rus GRRegs:$lhs, 32), GRRegs:$F, GRRegs:$T)>; 1190 1191def : Pat<(setgt GRRegs:$lhs, -1), 1192 (EQ_2rus (ASHR_l2rus GRRegs:$lhs, 32), 0)>; 1193 1194def : Pat<(sra (shl GRRegs:$src, immBpwSubBitp:$imm), immBpwSubBitp:$imm), 1195 (SEXT_rus GRRegs:$src, (bpwsub_xform immBpwSubBitp:$imm))>; 1196