XCoreInstrInfo.td revision 212904
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 SDNPVariadic]>; 34 35def XCoreRetsp : SDNode<"XCoreISD::RETSP", SDTBrind, 36 [SDNPHasChain, SDNPOptInFlag]>; 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, SDNPOutFlag]>; 70def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_XCoreCallSeqEnd, 71 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; 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 613// Operand register - U6 614// TODO setc 615let isBranch = 1, isTerminator = 1 in { 616defm BRFT: FRU6_LRU6_branch<"bt">; 617defm BRBT: FRU6_LRU6_branch<"bt">; 618defm BRFF: FRU6_LRU6_branch<"bf">; 619defm BRBF: FRU6_LRU6_branch<"bf">; 620} 621 622// U6 623let Defs = [SP], Uses = [SP] in { 624let neverHasSideEffects = 1 in 625defm EXTSP : FU6_LU6_np<"extsp">; 626let mayStore = 1 in 627defm ENTSP : FU6_LU6_np<"entsp">; 628 629let isReturn = 1, isTerminator = 1, mayLoad = 1, isBarrier = 1 in { 630defm RETSP : FU6_LU6<"retsp", XCoreRetsp>; 631} 632} 633 634// TODO extdp, kentsp, krestsp, blat, setsr 635// clrsr, getsr, kalli 636let isBranch = 1, isTerminator = 1, isBarrier = 1 in { 637def BRBU_u6 : _FU6< 638 (outs), 639 (ins brtarget:$target), 640 "bu $target", 641 []>; 642 643def BRBU_lu6 : _FLU6< 644 (outs), 645 (ins brtarget:$target), 646 "bu $target", 647 []>; 648 649def BRFU_u6 : _FU6< 650 (outs), 651 (ins brtarget:$target), 652 "bu $target", 653 []>; 654 655def BRFU_lu6 : _FLU6< 656 (outs), 657 (ins brtarget:$target), 658 "bu $target", 659 []>; 660} 661 662//let Uses = [CP] in ... 663let Defs = [R11], neverHasSideEffects = 1, isReMaterializable = 1 in 664def LDAWCP_u6: _FRU6<(outs), (ins MEMii:$a), 665 "ldaw r11, cp[$a]", 666 []>; 667 668let Defs = [R11], isReMaterializable = 1 in 669def LDAWCP_lu6: _FLRU6< 670 (outs), (ins MEMii:$a), 671 "ldaw r11, cp[$a]", 672 [(set R11, ADDRcpii:$a)]>; 673 674// U10 675// TODO ldwcpl, blacp 676 677let Defs = [R11], isReMaterializable = 1, neverHasSideEffects = 1 in 678def LDAP_u10 : _FU10< 679 (outs), 680 (ins i32imm:$addr), 681 "ldap r11, $addr", 682 []>; 683 684let Defs = [R11], isReMaterializable = 1 in 685def LDAP_lu10 : _FLU10< 686 (outs), 687 (ins i32imm:$addr), 688 "ldap r11, $addr", 689 [(set R11, (pcrelwrapper tglobaladdr:$addr))]>; 690 691let Defs = [R11], isReMaterializable = 1 in 692def LDAP_lu10_ba : _FLU10<(outs), 693 (ins i32imm:$addr), 694 "ldap r11, $addr", 695 [(set R11, (pcrelwrapper tblockaddress:$addr))]>; 696 697let isCall=1, 698// All calls clobber the link register and the non-callee-saved registers: 699Defs = [R0, R1, R2, R3, R11, LR] in { 700def BL_u10 : _FU10< 701 (outs), 702 (ins calltarget:$target, variable_ops), 703 "bl $target", 704 [(XCoreBranchLink immU10:$target)]>; 705 706def BL_lu10 : _FLU10< 707 (outs), 708 (ins calltarget:$target, variable_ops), 709 "bl $target", 710 [(XCoreBranchLink immU20:$target)]>; 711} 712 713// Two operand short 714// TODO getr, getst 715def NOT : _F2R<(outs GRRegs:$dst), (ins GRRegs:$b), 716 "not $dst, $b", 717 [(set GRRegs:$dst, (not GRRegs:$b))]>; 718 719def NEG : _F2R<(outs GRRegs:$dst), (ins GRRegs:$b), 720 "neg $dst, $b", 721 [(set GRRegs:$dst, (ineg GRRegs:$b))]>; 722 723// TODO setd, eet, eef, getts, setpt, outct, inct, chkct, outt, intt, out, 724// in, outshr, inshr, testct, testwct, tinitpc, tinitdp, tinitsp, tinitcp, 725// tsetmr, sext (reg), zext (reg) 726let Constraints = "$src1 = $dst" in { 727let neverHasSideEffects = 1 in 728def SEXT_rus : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$src1, i32imm:$src2), 729 "sext $dst, $src2", 730 []>; 731 732let neverHasSideEffects = 1 in 733def ZEXT_rus : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$src1, i32imm:$src2), 734 "zext $dst, $src2", 735 []>; 736 737def ANDNOT_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$src1, GRRegs:$src2), 738 "andnot $dst, $src2", 739 [(set GRRegs:$dst, (and GRRegs:$src1, (not GRRegs:$src2)))]>; 740} 741 742let isReMaterializable = 1, neverHasSideEffects = 1 in 743def MKMSK_rus : _FRUS<(outs GRRegs:$dst), (ins i32imm:$size), 744 "mkmsk $dst, $size", 745 []>; 746 747def MKMSK_2r : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$size), 748 "mkmsk $dst, $size", 749 [(set GRRegs:$dst, (add (shl 1, GRRegs:$size), 0xffffffff))]>; 750 751// Two operand long 752// TODO settw, setclk, setrdy, setpsc, endin, peek, 753// getd, testlcl, tinitlr, getps, setps 754def BITREV_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src), 755 "bitrev $dst, $src", 756 [(set GRRegs:$dst, (int_xcore_bitrev GRRegs:$src))]>; 757 758def BYTEREV_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src), 759 "byterev $dst, $src", 760 [(set GRRegs:$dst, (bswap GRRegs:$src))]>; 761 762def CLZ_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src), 763 "clz $dst, $src", 764 [(set GRRegs:$dst, (ctlz GRRegs:$src))]>; 765 766// One operand short 767// TODO edu, eeu, waitet, waitef, freer, tstart, msync, mjoin, syncr, clrtp 768// setdp, setcp, setv, setev, kcall 769// dgetreg 770let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1 in 771def BAU_1r : _F1R<(outs), (ins GRRegs:$addr), 772 "bau $addr", 773 [(brind GRRegs:$addr)]>; 774 775let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1 in 776def BR_JT : PseudoInstXCore<(outs), (ins InlineJT:$t, GRRegs:$i), 777 "bru $i\n$t", 778 [(XCoreBR_JT tjumptable:$t, GRRegs:$i)]>; 779 780let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1 in 781def BR_JT32 : PseudoInstXCore<(outs), (ins InlineJT32:$t, GRRegs:$i), 782 "bru $i\n$t", 783 [(XCoreBR_JT32 tjumptable:$t, GRRegs:$i)]>; 784 785let Defs=[SP], neverHasSideEffects=1 in 786def SETSP_1r : _F1R<(outs), (ins GRRegs:$src), 787 "set sp, $src", 788 []>; 789 790let hasCtrlDep = 1 in 791def ECALLT_1r : _F1R<(outs), (ins GRRegs:$src), 792 "ecallt $src", 793 []>; 794 795let hasCtrlDep = 1 in 796def ECALLF_1r : _F1R<(outs), (ins GRRegs:$src), 797 "ecallf $src", 798 []>; 799 800let isCall=1, 801// All calls clobber the link register and the non-callee-saved registers: 802Defs = [R0, R1, R2, R3, R11, LR] in { 803def BLA_1r : _F1R<(outs), (ins GRRegs:$addr, variable_ops), 804 "bla $addr", 805 [(XCoreBranchLink GRRegs:$addr)]>; 806} 807 808// Zero operand short 809// TODO waiteu, clre, ssync, freet, ldspc, stspc, ldssr, stssr, ldsed, stsed, 810// stet, geted, getet, getkep, getksp, setkep, getid, kret, dcall, dret, 811// dentsp, drestsp 812 813let Defs = [R11] in 814def GETID_0R : _F0R<(outs), (ins), 815 "get r11, id", 816 [(set R11, (int_xcore_getid))]>; 817 818//===----------------------------------------------------------------------===// 819// Non-Instruction Patterns 820//===----------------------------------------------------------------------===// 821 822def : Pat<(XCoreBranchLink tglobaladdr:$addr), (BL_lu10 tglobaladdr:$addr)>; 823def : Pat<(XCoreBranchLink texternalsym:$addr), (BL_lu10 texternalsym:$addr)>; 824 825/// sext_inreg 826def : Pat<(sext_inreg GRRegs:$b, i1), (SEXT_rus GRRegs:$b, 1)>; 827def : Pat<(sext_inreg GRRegs:$b, i8), (SEXT_rus GRRegs:$b, 8)>; 828def : Pat<(sext_inreg GRRegs:$b, i16), (SEXT_rus GRRegs:$b, 16)>; 829 830/// loads 831def : Pat<(zextloadi8 (add GRRegs:$addr, GRRegs:$offset)), 832 (LD8U_3r GRRegs:$addr, GRRegs:$offset)>; 833def : Pat<(zextloadi8 GRRegs:$addr), (LD8U_3r GRRegs:$addr, (LDC_ru6 0))>; 834 835def : Pat<(sextloadi16 (lda16f GRRegs:$addr, GRRegs:$offset)), 836 (LD16S_3r GRRegs:$addr, GRRegs:$offset)>; 837def : Pat<(sextloadi16 GRRegs:$addr), (LD16S_3r GRRegs:$addr, (LDC_ru6 0))>; 838 839def : Pat<(load (ldawf GRRegs:$addr, GRRegs:$offset)), 840 (LDW_3r GRRegs:$addr, GRRegs:$offset)>; 841def : Pat<(load (add GRRegs:$addr, immUs4:$offset)), 842 (LDW_2rus GRRegs:$addr, (div4_xform immUs4:$offset))>; 843def : Pat<(load GRRegs:$addr), (LDW_2rus GRRegs:$addr, 0)>; 844 845/// anyext 846def : Pat<(extloadi8 (add GRRegs:$addr, GRRegs:$offset)), 847 (LD8U_3r GRRegs:$addr, GRRegs:$offset)>; 848def : Pat<(extloadi8 GRRegs:$addr), (LD8U_3r GRRegs:$addr, (LDC_ru6 0))>; 849def : Pat<(extloadi16 (lda16f GRRegs:$addr, GRRegs:$offset)), 850 (LD16S_3r GRRegs:$addr, GRRegs:$offset)>; 851def : Pat<(extloadi16 GRRegs:$addr), (LD16S_3r GRRegs:$addr, (LDC_ru6 0))>; 852 853/// stores 854def : Pat<(truncstorei8 GRRegs:$val, (add GRRegs:$addr, GRRegs:$offset)), 855 (ST8_l3r GRRegs:$val, GRRegs:$addr, GRRegs:$offset)>; 856def : Pat<(truncstorei8 GRRegs:$val, GRRegs:$addr), 857 (ST8_l3r GRRegs:$val, GRRegs:$addr, (LDC_ru6 0))>; 858 859def : Pat<(truncstorei16 GRRegs:$val, (lda16f GRRegs:$addr, GRRegs:$offset)), 860 (ST16_l3r GRRegs:$val, GRRegs:$addr, GRRegs:$offset)>; 861def : Pat<(truncstorei16 GRRegs:$val, GRRegs:$addr), 862 (ST16_l3r GRRegs:$val, GRRegs:$addr, (LDC_ru6 0))>; 863 864def : Pat<(store GRRegs:$val, (ldawf GRRegs:$addr, GRRegs:$offset)), 865 (STW_3r GRRegs:$val, GRRegs:$addr, GRRegs:$offset)>; 866def : Pat<(store GRRegs:$val, (add GRRegs:$addr, immUs4:$offset)), 867 (STW_2rus GRRegs:$val, GRRegs:$addr, (div4_xform immUs4:$offset))>; 868def : Pat<(store GRRegs:$val, GRRegs:$addr), 869 (STW_2rus GRRegs:$val, GRRegs:$addr, 0)>; 870 871/// cttz 872def : Pat<(cttz GRRegs:$src), (CLZ_l2r (BITREV_l2r GRRegs:$src))>; 873 874/// trap 875def : Pat<(trap), (ECALLF_1r (LDC_ru6 0))>; 876 877/// 878/// branch patterns 879/// 880 881// unconditional branch 882def : Pat<(br bb:$addr), (BRFU_lu6 bb:$addr)>; 883 884// direct match equal/notequal zero brcond 885def : Pat<(brcond (setne GRRegs:$lhs, 0), bb:$dst), 886 (BRFT_lru6 GRRegs:$lhs, bb:$dst)>; 887def : Pat<(brcond (seteq GRRegs:$lhs, 0), bb:$dst), 888 (BRFF_lru6 GRRegs:$lhs, bb:$dst)>; 889 890def : Pat<(brcond (setle GRRegs:$lhs, GRRegs:$rhs), bb:$dst), 891 (BRFF_lru6 (LSS_3r GRRegs:$rhs, GRRegs:$lhs), bb:$dst)>; 892def : Pat<(brcond (setule GRRegs:$lhs, GRRegs:$rhs), bb:$dst), 893 (BRFF_lru6 (LSU_3r GRRegs:$rhs, GRRegs:$lhs), bb:$dst)>; 894def : Pat<(brcond (setge GRRegs:$lhs, GRRegs:$rhs), bb:$dst), 895 (BRFF_lru6 (LSS_3r GRRegs:$lhs, GRRegs:$rhs), bb:$dst)>; 896def : Pat<(brcond (setuge GRRegs:$lhs, GRRegs:$rhs), bb:$dst), 897 (BRFF_lru6 (LSU_3r GRRegs:$lhs, GRRegs:$rhs), bb:$dst)>; 898def : Pat<(brcond (setne GRRegs:$lhs, GRRegs:$rhs), bb:$dst), 899 (BRFF_lru6 (EQ_3r GRRegs:$lhs, GRRegs:$rhs), bb:$dst)>; 900def : Pat<(brcond (setne GRRegs:$lhs, immUs:$rhs), bb:$dst), 901 (BRFF_lru6 (EQ_2rus GRRegs:$lhs, immUs:$rhs), bb:$dst)>; 902 903// generic brcond pattern 904def : Pat<(brcond GRRegs:$cond, bb:$addr), (BRFT_lru6 GRRegs:$cond, bb:$addr)>; 905 906 907/// 908/// Select patterns 909/// 910 911// direct match equal/notequal zero select 912def : Pat<(select (setne GRRegs:$lhs, 0), GRRegs:$T, GRRegs:$F), 913 (SELECT_CC GRRegs:$lhs, GRRegs:$T, GRRegs:$F)>; 914 915def : Pat<(select (seteq GRRegs:$lhs, 0), GRRegs:$T, GRRegs:$F), 916 (SELECT_CC GRRegs:$lhs, GRRegs:$F, GRRegs:$T)>; 917 918def : Pat<(select (setle GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F), 919 (SELECT_CC (LSS_3r GRRegs:$rhs, GRRegs:$lhs), GRRegs:$F, GRRegs:$T)>; 920def : Pat<(select (setule GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F), 921 (SELECT_CC (LSU_3r GRRegs:$rhs, GRRegs:$lhs), GRRegs:$F, GRRegs:$T)>; 922def : Pat<(select (setge GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F), 923 (SELECT_CC (LSS_3r GRRegs:$lhs, GRRegs:$rhs), GRRegs:$F, GRRegs:$T)>; 924def : Pat<(select (setuge GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F), 925 (SELECT_CC (LSU_3r GRRegs:$lhs, GRRegs:$rhs), GRRegs:$F, GRRegs:$T)>; 926def : Pat<(select (setne GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F), 927 (SELECT_CC (EQ_3r GRRegs:$lhs, GRRegs:$rhs), GRRegs:$F, GRRegs:$T)>; 928def : Pat<(select (setne GRRegs:$lhs, immUs:$rhs), GRRegs:$T, GRRegs:$F), 929 (SELECT_CC (EQ_2rus GRRegs:$lhs, immUs:$rhs), GRRegs:$F, GRRegs:$T)>; 930 931/// 932/// setcc patterns, only matched when none of the above brcond 933/// patterns match 934/// 935 936// setcc 2 register operands 937def : Pat<(setle GRRegs:$lhs, GRRegs:$rhs), 938 (EQ_2rus (LSS_3r GRRegs:$rhs, GRRegs:$lhs), 0)>; 939def : Pat<(setule GRRegs:$lhs, GRRegs:$rhs), 940 (EQ_2rus (LSU_3r GRRegs:$rhs, GRRegs:$lhs), 0)>; 941 942def : Pat<(setgt GRRegs:$lhs, GRRegs:$rhs), 943 (LSS_3r GRRegs:$rhs, GRRegs:$lhs)>; 944def : Pat<(setugt GRRegs:$lhs, GRRegs:$rhs), 945 (LSU_3r GRRegs:$rhs, GRRegs:$lhs)>; 946 947def : Pat<(setge GRRegs:$lhs, GRRegs:$rhs), 948 (EQ_2rus (LSS_3r GRRegs:$lhs, GRRegs:$rhs), 0)>; 949def : Pat<(setuge GRRegs:$lhs, GRRegs:$rhs), 950 (EQ_2rus (LSU_3r GRRegs:$lhs, GRRegs:$rhs), 0)>; 951 952def : Pat<(setlt GRRegs:$lhs, GRRegs:$rhs), 953 (LSS_3r GRRegs:$lhs, GRRegs:$rhs)>; 954def : Pat<(setult GRRegs:$lhs, GRRegs:$rhs), 955 (LSU_3r GRRegs:$lhs, GRRegs:$rhs)>; 956 957def : Pat<(setne GRRegs:$lhs, GRRegs:$rhs), 958 (EQ_2rus (EQ_3r GRRegs:$lhs, GRRegs:$rhs), 0)>; 959 960def : Pat<(seteq GRRegs:$lhs, GRRegs:$rhs), 961 (EQ_3r GRRegs:$lhs, GRRegs:$rhs)>; 962 963// setcc reg/imm operands 964def : Pat<(seteq GRRegs:$lhs, immUs:$rhs), 965 (EQ_2rus GRRegs:$lhs, immUs:$rhs)>; 966def : Pat<(setne GRRegs:$lhs, immUs:$rhs), 967 (EQ_2rus (EQ_2rus GRRegs:$lhs, immUs:$rhs), 0)>; 968 969// misc 970def : Pat<(add GRRegs:$addr, immUs4:$offset), 971 (LDAWF_l2rus GRRegs:$addr, (div4_xform immUs4:$offset))>; 972 973def : Pat<(sub GRRegs:$addr, immUs4:$offset), 974 (LDAWB_l2rus GRRegs:$addr, (div4_xform immUs4:$offset))>; 975 976def : Pat<(and GRRegs:$val, immMskBitp:$mask), 977 (ZEXT_rus GRRegs:$val, (msksize_xform immMskBitp:$mask))>; 978 979// (sub X, imm) gets canonicalized to (add X, -imm). Match this form. 980def : Pat<(add GRRegs:$src1, immUsNeg:$src2), 981 (SUB_2rus GRRegs:$src1, (neg_xform immUsNeg:$src2))>; 982 983def : Pat<(add GRRegs:$src1, immUs4Neg:$src2), 984 (LDAWB_l2rus GRRegs:$src1, (div4neg_xform immUs4Neg:$src2))>; 985 986/// 987/// Some peepholes 988/// 989 990def : Pat<(mul GRRegs:$src, 3), 991 (LDA16F_l3r GRRegs:$src, GRRegs:$src)>; 992 993def : Pat<(mul GRRegs:$src, 5), 994 (LDAWF_l3r GRRegs:$src, GRRegs:$src)>; 995 996def : Pat<(mul GRRegs:$src, -3), 997 (LDAWB_l3r GRRegs:$src, GRRegs:$src)>; 998 999// ashr X, 32 is equivalent to ashr X, 31 on the XCore. 1000def : Pat<(sra GRRegs:$src, 31), 1001 (ASHR_l2rus GRRegs:$src, 32)>; 1002 1003def : Pat<(brcond (setlt GRRegs:$lhs, 0), bb:$dst), 1004 (BRFT_lru6 (ASHR_l2rus GRRegs:$lhs, 32), bb:$dst)>; 1005 1006// setge X, 0 is canonicalized to setgt X, -1 1007def : Pat<(brcond (setgt GRRegs:$lhs, -1), bb:$dst), 1008 (BRFF_lru6 (ASHR_l2rus GRRegs:$lhs, 32), bb:$dst)>; 1009 1010def : Pat<(select (setlt GRRegs:$lhs, 0), GRRegs:$T, GRRegs:$F), 1011 (SELECT_CC (ASHR_l2rus GRRegs:$lhs, 32), GRRegs:$T, GRRegs:$F)>; 1012 1013def : Pat<(select (setgt GRRegs:$lhs, -1), GRRegs:$T, GRRegs:$F), 1014 (SELECT_CC (ASHR_l2rus GRRegs:$lhs, 32), GRRegs:$F, GRRegs:$T)>; 1015 1016def : Pat<(setgt GRRegs:$lhs, -1), 1017 (EQ_2rus (ASHR_l2rus GRRegs:$lhs, 32), 0)>; 1018 1019def : Pat<(sra (shl GRRegs:$src, immBpwSubBitp:$imm), immBpwSubBitp:$imm), 1020 (SEXT_rus GRRegs:$src, (bpwsub_xform immBpwSubBitp:$imm))>; 1021