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 23 include "XCoreInstrFormats.td" 24 25 //===----------------------------------------------------------------------===// 26 // XCore specific DAG Nodes. 27 // 28 29 // Call 30 def SDT_XCoreBranchLink : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>; 31 def XCoreBranchLink : SDNode<"XCoreISD::BL",SDT_XCoreBranchLink, 32 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 33 SDNPVariadic]>; 34 35 def XCoreRetsp : SDNode<"XCoreISD::RETSP", SDTBrind, 36 [SDNPHasChain, SDNPOptInGlue]>; 37 38 def SDT_XCoreBR_JT : SDTypeProfile<0, 2, 39 [SDTCisVT<0, i32>, SDTCisVT<1, i32>]>; 40 41 def XCoreBR_JT : SDNode<"XCoreISD::BR_JT", SDT_XCoreBR_JT, 42 [SDNPHasChain]>; 43 44 def XCoreBR_JT32 : SDNode<"XCoreISD::BR_JT32", SDT_XCoreBR_JT, 45 [SDNPHasChain]>; 46 47 def SDT_XCoreAddress : SDTypeProfile<1, 1, 48 [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>; 49 50 def pcrelwrapper : SDNode<"XCoreISD::PCRelativeWrapper", SDT_XCoreAddress, 51 []>; 52 53 def dprelwrapper : SDNode<"XCoreISD::DPRelativeWrapper", SDT_XCoreAddress, 54 []>; 55 56 def cprelwrapper : SDNode<"XCoreISD::CPRelativeWrapper", SDT_XCoreAddress, 57 []>; 58 59 def SDT_XCoreStwsp : SDTypeProfile<0, 2, [SDTCisInt<1>]>; 60 def XCoreStwsp : SDNode<"XCoreISD::STWSP", SDT_XCoreStwsp, 61 [SDNPHasChain]>; 62 63 // These are target-independent nodes, but have target-specific formats. 64 def SDT_XCoreCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>; 65 def SDT_XCoreCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, 66 SDTCisVT<1, i32> ]>; 67 68 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_XCoreCallSeqStart, 69 [SDNPHasChain, SDNPOutGlue]>; 70 def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_XCoreCallSeqEnd, 71 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 72 73 //===----------------------------------------------------------------------===// 74 // Instruction Pattern Stuff 75 //===----------------------------------------------------------------------===// 76 77 def div4_xform : SDNodeXForm<imm, [{ 78 // Transformation function: imm/4 79 assert(N->getZExtValue() % 4 == 0); 80 return getI32Imm(N->getZExtValue()/4); 81 }]>; 82 83 def 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 90 def neg_xform : SDNodeXForm<imm, [{ 91 // Transformation function: -imm 92 uint32_t value = N->getZExtValue(); 93 return getI32Imm(-value); 94 }]>; 95 96 def bpwsub_xform : SDNodeXForm<imm, [{ 97 // Transformation function: 32-imm 98 uint32_t value = N->getZExtValue(); 99 return getI32Imm(32-value); 100 }]>; 101 102 def 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 109 def immUs4Neg : PatLeaf<(imm), [{ 110 uint32_t value = (uint32_t)N->getZExtValue(); 111 return (-value)%4 == 0 && (-value)/4 <= 11; 112 }]>; 113 114 def immUs4 : PatLeaf<(imm), [{ 115 uint32_t value = (uint32_t)N->getZExtValue(); 116 return value%4 == 0 && value/4 <= 11; 117 }]>; 118 119 def immUsNeg : PatLeaf<(imm), [{ 120 return -((uint32_t)N->getZExtValue()) <= 11; 121 }]>; 122 123 def immUs : PatLeaf<(imm), [{ 124 return (uint32_t)N->getZExtValue() <= 11; 125 }]>; 126 127 def immU6 : PatLeaf<(imm), [{ 128 return (uint32_t)N->getZExtValue() < (1 << 6); 129 }]>; 130 131 def immU10 : PatLeaf<(imm), [{ 132 return (uint32_t)N->getZExtValue() < (1 << 10); 133 }]>; 134 135 def immU16 : PatLeaf<(imm), [{ 136 return (uint32_t)N->getZExtValue() < (1 << 16); 137 }]>; 138 139 def immU20 : PatLeaf<(imm), [{ 140 return (uint32_t)N->getZExtValue() < (1 << 20); 141 }]>; 142 143 def immMskBitp : PatLeaf<(imm), [{ return immMskBitp(N); }]>; 144 145 def 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 153 def 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 161 def lda16f : PatFrag<(ops node:$addr, node:$offset), 162 (add node:$addr, (shl node:$offset, 1))>; 163 def lda16b : PatFrag<(ops node:$addr, node:$offset), 164 (sub node:$addr, (shl node:$offset, 1))>; 165 def ldawf : PatFrag<(ops node:$addr, node:$offset), 166 (add node:$addr, (shl node:$offset, 2))>; 167 def ldawb : PatFrag<(ops node:$addr, node:$offset), 168 (sub node:$addr, (shl node:$offset, 2))>; 169 170 // Instruction operand types 171 def calltarget : Operand<i32>; 172 def brtarget : Operand<OtherVT>; 173 def pclabel : Operand<i32>; 174 175 // Addressing modes 176 def ADDRspii : ComplexPattern<i32, 2, "SelectADDRspii", [add, frameindex], []>; 177 def ADDRdpii : ComplexPattern<i32, 2, "SelectADDRdpii", [add, dprelwrapper], 178 []>; 179 def ADDRcpii : ComplexPattern<i32, 2, "SelectADDRcpii", [add, cprelwrapper], 180 []>; 181 182 // Address operands 183 def MEMii : Operand<i32> { 184 let PrintMethod = "printMemOperand"; 185 let MIOperandInfo = (ops i32imm, i32imm); 186 } 187 188 // Jump tables. 189 def InlineJT : Operand<i32> { 190 let PrintMethod = "printInlineJT"; 191 } 192 193 def InlineJT32 : Operand<i32> { 194 let PrintMethod = "printInlineJT32"; 195 } 196 197 //===----------------------------------------------------------------------===// 198 // Instruction Class Templates 199 //===----------------------------------------------------------------------===// 200 201 // Three operand short 202 203 multiclass 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 214 multiclass 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 225 multiclass 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 236 class 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 241 class 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. 248 multiclass 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. 260 multiclass 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 271 class 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 278 multiclass 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 289 multiclass 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 301 multiclass 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 multiclass 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 322 multiclass 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 334 multiclass 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 347 class 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 358 let Defs = [SP], Uses = [SP] in { 359 def ADJCALLSTACKDOWN : PseudoInstXCore<(outs), (ins i32imm:$amt), 360 "${:comment} ADJCALLSTACKDOWN $amt", 361 [(callseq_start timm:$amt)]>; 362 def ADJCALLSTACKUP : PseudoInstXCore<(outs), (ins i32imm:$amt1, i32imm:$amt2), 363 "${:comment} ADJCALLSTACKUP $amt1", 364 [(callseq_end timm:$amt1, timm:$amt2)]>; 365 } 366 367 def LDWFI : PseudoInstXCore<(outs GRRegs:$dst), (ins MEMii:$addr), 368 "${:comment} LDWFI $dst, $addr", 369 [(set GRRegs:$dst, (load ADDRspii:$addr))]>; 370 371 def LDAWFI : PseudoInstXCore<(outs GRRegs:$dst), (ins MEMii:$addr), 372 "${:comment} LDAWFI $dst, $addr", 373 [(set GRRegs:$dst, ADDRspii:$addr)]>; 374 375 def 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. 381 let 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 394 defm ADD : F3R_2RUS<"add", add>; 395 defm SUB : F3R_2RUS<"sub", sub>; 396 let neverHasSideEffects = 1 in { 397 defm EQ : F3R_2RUS_np<"eq">; 398 def LSS_3r : F3R_np<"lss">; 399 def LSU_3r : F3R_np<"lsu">; 400 } 401 def AND_3r : F3R<"and", and>; 402 def OR_3r : F3R<"or", or>; 403 404 let mayLoad=1 in { 405 def LDW_3r : _F3R<(outs GRRegs:$dst), (ins GRRegs:$addr, GRRegs:$offset), 406 "ldw $dst, $addr[$offset]", 407 []>; 408 409 def LDW_2rus : _F2RUS<(outs GRRegs:$dst), (ins GRRegs:$addr, i32imm:$offset), 410 "ldw $dst, $addr[$offset]", 411 []>; 412 413 def LD16S_3r : _F3R<(outs GRRegs:$dst), (ins GRRegs:$addr, GRRegs:$offset), 414 "ld16s $dst, $addr[$offset]", 415 []>; 416 417 def LD8U_3r : _F3R<(outs GRRegs:$dst), (ins GRRegs:$addr, GRRegs:$offset), 418 "ld8u $dst, $addr[$offset]", 419 []>; 420 } 421 422 let mayStore=1 in { 423 def STW_3r : _F3R<(outs), (ins GRRegs:$val, GRRegs:$addr, GRRegs:$offset), 424 "stw $val, $addr[$offset]", 425 []>; 426 427 def STW_2rus : _F2RUS<(outs), (ins GRRegs:$val, GRRegs:$addr, i32imm:$offset), 428 "stw $val, $addr[$offset]", 429 []>; 430 } 431 432 defm SHL : F3R_2RBITP<"shl", shl>; 433 defm SHR : F3R_2RBITP<"shr", srl>; 434 // TODO tsetr 435 436 // Three operand long 437 def 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 441 let neverHasSideEffects = 1 in 442 def LDAWF_l2rus : _FL2RUS<(outs GRRegs:$dst), 443 (ins GRRegs:$addr, i32imm:$offset), 444 "ldaw $dst, $addr[$offset]", 445 []>; 446 447 def 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 451 let neverHasSideEffects = 1 in 452 def LDAWB_l2rus : _FL2RUS<(outs GRRegs:$dst), 453 (ins GRRegs:$addr, i32imm:$offset), 454 "ldaw $dst, $addr[-$offset]", 455 []>; 456 457 def 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 461 def 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 465 def MUL_l3r : FL3R<"mul", mul>; 466 // Instructions which may trap are marked as side effecting. 467 let hasSideEffects = 1 in { 468 def DIVS_l3r : FL3R<"divs", sdiv>; 469 def DIVU_l3r : FL3R<"divu", udiv>; 470 def REMS_l3r : FL3R<"rems", srem>; 471 def REMU_l3r : FL3R<"remu", urem>; 472 } 473 def XOR_l3r : FL3R<"xor", xor>; 474 defm ASHR : FL3R_L2RBITP<"ashr", sra>; 475 476 let Constraints = "$src1 = $dst" in 477 def CRC_l3r : _FL3R<(outs GRRegs:$dst), 478 (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3), 479 "crc32 $dst, $src2, $src3", 480 [(set GRRegs:$dst, 481 (int_xcore_crc32 GRRegs:$src1, GRRegs:$src2, 482 GRRegs:$src3))]>; 483 484 // TODO inpw, outpw 485 let mayStore=1 in { 486 def ST16_l3r : _FL3R<(outs), (ins GRRegs:$val, GRRegs:$addr, GRRegs:$offset), 487 "st16 $val, $addr[$offset]", 488 []>; 489 490 def ST8_l3r : _FL3R<(outs), (ins GRRegs:$val, GRRegs:$addr, GRRegs:$offset), 491 "st8 $val, $addr[$offset]", 492 []>; 493 } 494 495 // Four operand long 496 let Constraints = "$src1 = $dst1,$src2 = $dst2" in { 497 def MACCU_l4r : _L4R<(outs GRRegs:$dst1, GRRegs:$dst2), 498 (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3, 499 GRRegs:$src4), 500 "maccu $dst1, $dst2, $src3, $src4", 501 []>; 502 503 def MACCS_l4r : _L4R<(outs GRRegs:$dst1, GRRegs:$dst2), 504 (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3, 505 GRRegs:$src4), 506 "maccs $dst1, $dst2, $src3, $src4", 507 []>; 508 } 509 510 let Constraints = "$src1 = $dst1" in 511 def CRC8_l4r : _L4R<(outs GRRegs:$dst1, GRRegs:$dst2), 512 (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3), 513 "crc8 $dst1, $dst2, $src2, $src3", 514 []>; 515 516 // Five operand long 517 518 def LADD_l5r : _L5R<(outs GRRegs:$dst1, GRRegs:$dst2), 519 (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3), 520 "ladd $dst1, $dst2, $src1, $src2, $src3", 521 []>; 522 523 def LSUB_l5r : _L5R<(outs GRRegs:$dst1, GRRegs:$dst2), 524 (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3), 525 "lsub $dst1, $dst2, $src1, $src2, $src3", 526 []>; 527 528 def LDIV_l5r : _L5R<(outs GRRegs:$dst1, GRRegs:$dst2), 529 (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3), 530 "ldiv $dst1, $dst2, $src1, $src2, $src3", 531 []>; 532 533 // Six operand long 534 535 def LMUL_l6r : _L6R<(outs GRRegs:$dst1, GRRegs:$dst2), 536 (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3, 537 GRRegs:$src4), 538 "lmul $dst1, $dst2, $src1, $src2, $src3, $src4", 539 []>; 540 541 // Register - U6 542 543 //let Uses = [DP] in ... 544 let neverHasSideEffects = 1, isReMaterializable = 1 in 545 def LDAWDP_ru6: _FRU6<(outs GRRegs:$dst), (ins MEMii:$a), 546 "ldaw $dst, dp[$a]", 547 []>; 548 549 let isReMaterializable = 1 in 550 def LDAWDP_lru6: _FLRU6< 551 (outs GRRegs:$dst), (ins MEMii:$a), 552 "ldaw $dst, dp[$a]", 553 [(set GRRegs:$dst, ADDRdpii:$a)]>; 554 555 let mayLoad=1 in 556 def LDWDP_ru6: _FRU6<(outs GRRegs:$dst), (ins MEMii:$a), 557 "ldw $dst, dp[$a]", 558 []>; 559 560 def LDWDP_lru6: _FLRU6< 561 (outs GRRegs:$dst), (ins MEMii:$a), 562 "ldw $dst, dp[$a]", 563 [(set GRRegs:$dst, (load ADDRdpii:$a))]>; 564 565 let mayStore=1 in 566 def STWDP_ru6 : _FRU6<(outs), (ins GRRegs:$val, MEMii:$addr), 567 "stw $val, dp[$addr]", 568 []>; 569 570 def STWDP_lru6 : _FLRU6<(outs), (ins GRRegs:$val, MEMii:$addr), 571 "stw $val, dp[$addr]", 572 [(store GRRegs:$val, ADDRdpii:$addr)]>; 573 574 //let Uses = [CP] in .. 575 let mayLoad = 1, isReMaterializable = 1, neverHasSideEffects = 1 in 576 defm LDWCP : FRU6_LRU6_cp<"ldw">; 577 578 let Uses = [SP] in { 579 let mayStore=1 in { 580 def STWSP_ru6 : _FRU6< 581 (outs), (ins GRRegs:$val, i32imm:$index), 582 "stw $val, sp[$index]", 583 [(XCoreStwsp GRRegs:$val, immU6:$index)]>; 584 585 def STWSP_lru6 : _FLRU6< 586 (outs), (ins GRRegs:$val, i32imm:$index), 587 "stw $val, sp[$index]", 588 [(XCoreStwsp GRRegs:$val, immU16:$index)]>; 589 } 590 591 let mayLoad=1 in { 592 def LDWSP_ru6 : _FRU6< 593 (outs GRRegs:$dst), (ins i32imm:$b), 594 "ldw $dst, sp[$b]", 595 []>; 596 597 def LDWSP_lru6 : _FLRU6< 598 (outs GRRegs:$dst), (ins i32imm:$b), 599 "ldw $dst, sp[$b]", 600 []>; 601 } 602 603 let neverHasSideEffects = 1 in { 604 def LDAWSP_ru6 : _FRU6< 605 (outs GRRegs:$dst), (ins i32imm:$b), 606 "ldaw $dst, sp[$b]", 607 []>; 608 609 def LDAWSP_lru6 : _FLRU6< 610 (outs GRRegs:$dst), (ins i32imm:$b), 611 "ldaw $dst, sp[$b]", 612 []>; 613 614 def LDAWSP_ru6_RRegs : _FRU6< 615 (outs RRegs:$dst), (ins i32imm:$b), 616 "ldaw $dst, sp[$b]", 617 []>; 618 619 def LDAWSP_lru6_RRegs : _FLRU6< 620 (outs RRegs:$dst), (ins i32imm:$b), 621 "ldaw $dst, sp[$b]", 622 []>; 623 } 624 } 625 626 let isReMaterializable = 1 in { 627 def LDC_ru6 : _FRU6< 628 (outs GRRegs:$dst), (ins i32imm:$b), 629 "ldc $dst, $b", 630 [(set GRRegs:$dst, immU6:$b)]>; 631 632 def LDC_lru6 : _FLRU6< 633 (outs GRRegs:$dst), (ins i32imm:$b), 634 "ldc $dst, $b", 635 [(set GRRegs:$dst, immU16:$b)]>; 636 } 637 638 def SETC_ru6 : _FRU6<(outs), (ins GRRegs:$r, i32imm:$val), 639 "setc res[$r], $val", 640 [(int_xcore_setc GRRegs:$r, immU6:$val)]>; 641 642 def SETC_lru6 : _FLRU6<(outs), (ins GRRegs:$r, i32imm:$val), 643 "setc res[$r], $val", 644 [(int_xcore_setc GRRegs:$r, immU16:$val)]>; 645 646 // Operand register - U6 647 let isBranch = 1, isTerminator = 1 in { 648 defm BRFT: FRU6_LRU6_branch<"bt">; 649 defm BRBT: FRU6_LRU6_branch<"bt">; 650 defm BRFF: FRU6_LRU6_branch<"bf">; 651 defm BRBF: FRU6_LRU6_branch<"bf">; 652 } 653 654 // U6 655 let Defs = [SP], Uses = [SP] in { 656 let neverHasSideEffects = 1 in 657 defm EXTSP : FU6_LU6_np<"extsp">; 658 let mayStore = 1 in 659 defm ENTSP : FU6_LU6_np<"entsp">; 660 661 let isReturn = 1, isTerminator = 1, mayLoad = 1, isBarrier = 1 in { 662 defm RETSP : FU6_LU6<"retsp", XCoreRetsp>; 663 } 664 } 665 666 // TODO extdp, kentsp, krestsp, blat 667 // getsr, kalli 668 let isBranch = 1, isTerminator = 1, isBarrier = 1 in { 669 def BRBU_u6 : _FU6< 670 (outs), 671 (ins brtarget:$target), 672 "bu $target", 673 []>; 674 675 def BRBU_lu6 : _FLU6< 676 (outs), 677 (ins brtarget:$target), 678 "bu $target", 679 []>; 680 681 def BRFU_u6 : _FU6< 682 (outs), 683 (ins brtarget:$target), 684 "bu $target", 685 []>; 686 687 def BRFU_lu6 : _FLU6< 688 (outs), 689 (ins brtarget:$target), 690 "bu $target", 691 []>; 692 } 693 694 //let Uses = [CP] in ... 695 let Defs = [R11], neverHasSideEffects = 1, isReMaterializable = 1 in 696 def LDAWCP_u6: _FRU6<(outs), (ins MEMii:$a), 697 "ldaw r11, cp[$a]", 698 []>; 699 700 let Defs = [R11], isReMaterializable = 1 in 701 def LDAWCP_lu6: _FLRU6< 702 (outs), (ins MEMii:$a), 703 "ldaw r11, cp[$a]", 704 [(set R11, ADDRcpii:$a)]>; 705 706 defm SETSR : FU6_LU6_int<"setsr", int_xcore_setsr>; 707 708 defm CLRSR : FU6_LU6_int<"clrsr", int_xcore_clrsr>; 709 710 // setsr may cause a branch if it is used to enable events. clrsr may 711 // branch if it is executed while events are enabled. 712 let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1 in { 713 defm SETSR_branch : FU6_LU6_np<"setsr">; 714 defm CLRSR_branch : FU6_LU6_np<"clrsr">; 715 } 716 717 // U10 718 // TODO ldwcpl, blacp 719 720 let Defs = [R11], isReMaterializable = 1, neverHasSideEffects = 1 in 721 def LDAP_u10 : _FU10< 722 (outs), 723 (ins i32imm:$addr), 724 "ldap r11, $addr", 725 []>; 726 727 let Defs = [R11], isReMaterializable = 1 in 728 def LDAP_lu10 : _FLU10< 729 (outs), 730 (ins i32imm:$addr), 731 "ldap r11, $addr", 732 [(set R11, (pcrelwrapper tglobaladdr:$addr))]>; 733 734 let Defs = [R11], isReMaterializable = 1 in 735 def LDAP_lu10_ba : _FLU10<(outs), 736 (ins i32imm:$addr), 737 "ldap r11, $addr", 738 [(set R11, (pcrelwrapper tblockaddress:$addr))]>; 739 740 let isCall=1, 741 // All calls clobber the link register and the non-callee-saved registers: 742 Defs = [R0, R1, R2, R3, R11, LR], Uses = [SP] in { 743 def BL_u10 : _FU10< 744 (outs), 745 (ins calltarget:$target, variable_ops), 746 "bl $target", 747 [(XCoreBranchLink immU10:$target)]>; 748 749 def BL_lu10 : _FLU10< 750 (outs), 751 (ins calltarget:$target, variable_ops), 752 "bl $target", 753 [(XCoreBranchLink immU20:$target)]>; 754 } 755 756 // Two operand short 757 // TODO eet, eef, tsetmr 758 def NOT : _F2R<(outs GRRegs:$dst), (ins GRRegs:$b), 759 "not $dst, $b", 760 [(set GRRegs:$dst, (not GRRegs:$b))]>; 761 762 def NEG : _F2R<(outs GRRegs:$dst), (ins GRRegs:$b), 763 "neg $dst, $b", 764 [(set GRRegs:$dst, (ineg GRRegs:$b))]>; 765 766 let Constraints = "$src1 = $dst" in { 767 def SEXT_rus : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$src1, i32imm:$src2), 768 "sext $dst, $src2", 769 [(set GRRegs:$dst, (int_xcore_sext GRRegs:$src1, 770 immBitp:$src2))]>; 771 772 def SEXT_2r : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$src1, GRRegs:$src2), 773 "sext $dst, $src2", 774 [(set GRRegs:$dst, (int_xcore_sext GRRegs:$src1, 775 GRRegs:$src2))]>; 776 777 def ZEXT_rus : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$src1, i32imm:$src2), 778 "zext $dst, $src2", 779 [(set GRRegs:$dst, (int_xcore_zext GRRegs:$src1, 780 immBitp:$src2))]>; 781 782 def ZEXT_2r : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$src1, GRRegs:$src2), 783 "zext $dst, $src2", 784 [(set GRRegs:$dst, (int_xcore_zext GRRegs:$src1, 785 GRRegs:$src2))]>; 786 787 def ANDNOT_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$src1, GRRegs:$src2), 788 "andnot $dst, $src2", 789 [(set GRRegs:$dst, (and GRRegs:$src1, (not GRRegs:$src2)))]>; 790 } 791 792 let isReMaterializable = 1, neverHasSideEffects = 1 in 793 def MKMSK_rus : _FRUS<(outs GRRegs:$dst), (ins i32imm:$size), 794 "mkmsk $dst, $size", 795 []>; 796 797 def MKMSK_2r : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$size), 798 "mkmsk $dst, $size", 799 [(set GRRegs:$dst, (add (shl 1, GRRegs:$size), 0xffffffff))]>; 800 801 def GETR_rus : _FRUS<(outs GRRegs:$dst), (ins i32imm:$type), 802 "getr $dst, $type", 803 [(set GRRegs:$dst, (int_xcore_getr immUs:$type))]>; 804 805 def GETTS_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$r), 806 "getts $dst, res[$r]", 807 [(set GRRegs:$dst, (int_xcore_getts GRRegs:$r))]>; 808 809 def SETPT_2r : _F2R<(outs), (ins GRRegs:$r, GRRegs:$val), 810 "setpt res[$r], $val", 811 [(int_xcore_setpt GRRegs:$r, GRRegs:$val)]>; 812 813 def OUTCT_2r : _F2R<(outs), (ins GRRegs:$r, GRRegs:$val), 814 "outct res[$r], $val", 815 [(int_xcore_outct GRRegs:$r, GRRegs:$val)]>; 816 817 def OUTCT_rus : _F2R<(outs), (ins GRRegs:$r, i32imm:$val), 818 "outct res[$r], $val", 819 [(int_xcore_outct GRRegs:$r, immUs:$val)]>; 820 821 def OUTT_2r : _F2R<(outs), (ins GRRegs:$r, GRRegs:$val), 822 "outt res[$r], $val", 823 [(int_xcore_outt GRRegs:$r, GRRegs:$val)]>; 824 825 def OUT_2r : _F2R<(outs), (ins GRRegs:$r, GRRegs:$val), 826 "out res[$r], $val", 827 [(int_xcore_out GRRegs:$r, GRRegs:$val)]>; 828 829 let Constraints = "$src = $dst" in 830 def OUTSHR_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$r, GRRegs:$src), 831 "outshr res[$r], $src", 832 [(set GRRegs:$dst, (int_xcore_outshr GRRegs:$r, 833 GRRegs:$src))]>; 834 835 def INCT_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$r), 836 "inct $dst, res[$r]", 837 [(set GRRegs:$dst, (int_xcore_inct GRRegs:$r))]>; 838 839 def INT_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$r), 840 "int $dst, res[$r]", 841 [(set GRRegs:$dst, (int_xcore_int GRRegs:$r))]>; 842 843 def IN_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$r), 844 "in $dst, res[$r]", 845 [(set GRRegs:$dst, (int_xcore_in GRRegs:$r))]>; 846 847 let Constraints = "$src = $dst" in 848 def INSHR_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$r, GRRegs:$src), 849 "inshr $dst, res[$r]", 850 [(set GRRegs:$dst, (int_xcore_inshr GRRegs:$r, 851 GRRegs:$src))]>; 852 853 def CHKCT_2r : _F2R<(outs), (ins GRRegs:$r, GRRegs:$val), 854 "chkct res[$r], $val", 855 [(int_xcore_chkct GRRegs:$r, GRRegs:$val)]>; 856 857 def CHKCT_rus : _F2R<(outs), (ins GRRegs:$r, i32imm:$val), 858 "chkct res[$r], $val", 859 [(int_xcore_chkct GRRegs:$r, immUs:$val)]>; 860 861 def TESTCT_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$src), 862 "testct $dst, res[$src]", 863 [(set GRRegs:$dst, (int_xcore_testct GRRegs:$src))]>; 864 865 def TESTWCT_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$src), 866 "testwct $dst, res[$src]", 867 [(set GRRegs:$dst, (int_xcore_testwct GRRegs:$src))]>; 868 869 def SETD_2r : _F2R<(outs), (ins GRRegs:$r, GRRegs:$val), 870 "setd res[$r], $val", 871 [(int_xcore_setd GRRegs:$r, GRRegs:$val)]>; 872 873 def GETST_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$r), 874 "getst $dst, res[$r]", 875 [(set GRRegs:$dst, (int_xcore_getst GRRegs:$r))]>; 876 877 def INITSP_2r : _F2R<(outs), (ins GRRegs:$t, GRRegs:$src), 878 "init t[$t]:sp, $src", 879 [(int_xcore_initsp GRRegs:$t, GRRegs:$src)]>; 880 881 def INITPC_2r : _F2R<(outs), (ins GRRegs:$t, GRRegs:$src), 882 "init t[$t]:pc, $src", 883 [(int_xcore_initpc GRRegs:$t, GRRegs:$src)]>; 884 885 def INITCP_2r : _F2R<(outs), (ins GRRegs:$t, GRRegs:$src), 886 "init t[$t]:cp, $src", 887 [(int_xcore_initcp GRRegs:$t, GRRegs:$src)]>; 888 889 def INITDP_2r : _F2R<(outs), (ins GRRegs:$t, GRRegs:$src), 890 "init t[$t]:dp, $src", 891 [(int_xcore_initdp GRRegs:$t, GRRegs:$src)]>; 892 893 // Two operand long 894 // getd, testlcl 895 def BITREV_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src), 896 "bitrev $dst, $src", 897 [(set GRRegs:$dst, (int_xcore_bitrev GRRegs:$src))]>; 898 899 def BYTEREV_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src), 900 "byterev $dst, $src", 901 [(set GRRegs:$dst, (bswap GRRegs:$src))]>; 902 903 def CLZ_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src), 904 "clz $dst, $src", 905 [(set GRRegs:$dst, (ctlz GRRegs:$src))]>; 906 907 def SETC_l2r : _FL2R<(outs), (ins GRRegs:$r, GRRegs:$val), 908 "setc res[$r], $val", 909 [(int_xcore_setc GRRegs:$r, GRRegs:$val)]>; 910 911 def SETTW_l2r : _FL2R<(outs), (ins GRRegs:$r, GRRegs:$val), 912 "settw res[$r], $val", 913 [(int_xcore_settw GRRegs:$r, GRRegs:$val)]>; 914 915 def GETPS_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src), 916 "get $dst, ps[$src]", 917 [(set GRRegs:$dst, (int_xcore_getps GRRegs:$src))]>; 918 919 def SETPS_l2r : _FL2R<(outs), (ins GRRegs:$src1, GRRegs:$src2), 920 "set ps[$src1], $src2", 921 [(int_xcore_setps GRRegs:$src1, GRRegs:$src2)]>; 922 923 def INITLR_l2r : _FL2R<(outs), (ins GRRegs:$t, GRRegs:$src), 924 "init t[$t]:lr, $src", 925 [(int_xcore_initlr GRRegs:$t, GRRegs:$src)]>; 926 927 def SETCLK_l2r : _FL2R<(outs), (ins GRRegs:$src1, GRRegs:$src2), 928 "setclk res[$src1], $src2", 929 [(int_xcore_setclk GRRegs:$src1, GRRegs:$src2)]>; 930 931 def SETRDY_l2r : _FL2R<(outs), (ins GRRegs:$src1, GRRegs:$src2), 932 "setrdy res[$src1], $src2", 933 [(int_xcore_setrdy GRRegs:$src1, GRRegs:$src2)]>; 934 935 def SETPSC_l2r : _FL2R<(outs), (ins GRRegs:$src1, GRRegs:$src2), 936 "setpsc res[$src1], $src2", 937 [(int_xcore_setpsc GRRegs:$src1, GRRegs:$src2)]>; 938 939 def PEEK_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src), 940 "peek $dst, res[$src]", 941 [(set GRRegs:$dst, (int_xcore_peek GRRegs:$src))]>; 942 943 def ENDIN_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src), 944 "endin $dst, res[$src]", 945 [(set GRRegs:$dst, (int_xcore_endin GRRegs:$src))]>; 946 947 // One operand short 948 // TODO edu, eeu, waitet, waitef, tstart, clrtp 949 // setdp, setcp, setev, kcall 950 // dgetreg 951 def MSYNC_1r : _F1R<(outs), (ins GRRegs:$i), 952 "msync res[$i]", 953 [(int_xcore_msync GRRegs:$i)]>; 954 def MJOIN_1r : _F1R<(outs), (ins GRRegs:$i), 955 "mjoin res[$i]", 956 [(int_xcore_mjoin GRRegs:$i)]>; 957 958 let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1 in 959 def BAU_1r : _F1R<(outs), (ins GRRegs:$addr), 960 "bau $addr", 961 [(brind GRRegs:$addr)]>; 962 963 let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1 in 964 def BR_JT : PseudoInstXCore<(outs), (ins InlineJT:$t, GRRegs:$i), 965 "bru $i\n$t", 966 [(XCoreBR_JT tjumptable:$t, GRRegs:$i)]>; 967 968 let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1 in 969 def BR_JT32 : PseudoInstXCore<(outs), (ins InlineJT32:$t, GRRegs:$i), 970 "bru $i\n$t", 971 [(XCoreBR_JT32 tjumptable:$t, GRRegs:$i)]>; 972 973 let Defs=[SP], neverHasSideEffects=1 in 974 def SETSP_1r : _F1R<(outs), (ins GRRegs:$src), 975 "set sp, $src", 976 []>; 977 978 let hasCtrlDep = 1 in 979 def ECALLT_1r : _F1R<(outs), (ins GRRegs:$src), 980 "ecallt $src", 981 []>; 982 983 let hasCtrlDep = 1 in 984 def ECALLF_1r : _F1R<(outs), (ins GRRegs:$src), 985 "ecallf $src", 986 []>; 987 988 let isCall=1, 989 // All calls clobber the link register and the non-callee-saved registers: 990 Defs = [R0, R1, R2, R3, R11, LR], Uses = [SP] in { 991 def BLA_1r : _F1R<(outs), (ins GRRegs:$addr, variable_ops), 992 "bla $addr", 993 [(XCoreBranchLink GRRegs:$addr)]>; 994 } 995 996 def SYNCR_1r : _F1R<(outs), (ins GRRegs:$r), 997 "syncr res[$r]", 998 [(int_xcore_syncr GRRegs:$r)]>; 999 1000 def FREER_1r : _F1R<(outs), (ins GRRegs:$r), 1001 "freer res[$r]", 1002 [(int_xcore_freer GRRegs:$r)]>; 1003 1004 let Uses=[R11] in { 1005 def SETV_1r : _F1R<(outs), (ins GRRegs:$r), 1006 "setv res[$r], r11", 1007 [(int_xcore_setv GRRegs:$r, R11)]>; 1008 1009 def SETEV_1r : _F1R<(outs), (ins GRRegs:$r), 1010 "setev res[$r], r11", 1011 [(int_xcore_setev GRRegs:$r, R11)]>; 1012 } 1013 1014 def EEU_1r : _F1R<(outs), (ins GRRegs:$r), 1015 "eeu res[$r]", 1016 [(int_xcore_eeu GRRegs:$r)]>; 1017 1018 // Zero operand short 1019 // TODO freet, ldspc, stspc, ldssr, stssr, ldsed, stsed, 1020 // stet, getkep, getksp, setkep, getid, kret, dcall, dret, 1021 // dentsp, drestsp 1022 1023 def CLRE_0R : _F0R<(outs), (ins), "clre", [(int_xcore_clre)]>; 1024 1025 let Defs = [R11] in { 1026 def GETID_0R : _F0R<(outs), (ins), 1027 "get r11, id", 1028 [(set R11, (int_xcore_getid))]>; 1029 1030 def GETED_0R : _F0R<(outs), (ins), 1031 "get r11, ed", 1032 [(set R11, (int_xcore_geted))]>; 1033 1034 def GETET_0R : _F0R<(outs), (ins), 1035 "get r11, et", 1036 [(set R11, (int_xcore_getet))]>; 1037 } 1038 1039 def SSYNC_0r : _F0R<(outs), (ins), 1040 "ssync", 1041 [(int_xcore_ssync)]>; 1042 1043 let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1, 1044 hasSideEffects = 1 in 1045 def WAITEU_0R : _F0R<(outs), (ins), 1046 "waiteu", 1047 [(brind (int_xcore_waitevent))]>; 1048 1049 //===----------------------------------------------------------------------===// 1050 // Non-Instruction Patterns 1051 //===----------------------------------------------------------------------===// 1052 1053 def : Pat<(XCoreBranchLink tglobaladdr:$addr), (BL_lu10 tglobaladdr:$addr)>; 1054 def : Pat<(XCoreBranchLink texternalsym:$addr), (BL_lu10 texternalsym:$addr)>; 1055 1056 /// sext_inreg 1057 def : Pat<(sext_inreg GRRegs:$b, i1), (SEXT_rus GRRegs:$b, 1)>; 1058 def : Pat<(sext_inreg GRRegs:$b, i8), (SEXT_rus GRRegs:$b, 8)>; 1059 def : Pat<(sext_inreg GRRegs:$b, i16), (SEXT_rus GRRegs:$b, 16)>; 1060 1061 /// loads 1062 def : Pat<(zextloadi8 (add GRRegs:$addr, GRRegs:$offset)), 1063 (LD8U_3r GRRegs:$addr, GRRegs:$offset)>; 1064 def : Pat<(zextloadi8 GRRegs:$addr), (LD8U_3r GRRegs:$addr, (LDC_ru6 0))>; 1065 1066 def : Pat<(sextloadi16 (lda16f GRRegs:$addr, GRRegs:$offset)), 1067 (LD16S_3r GRRegs:$addr, GRRegs:$offset)>; 1068 def : Pat<(sextloadi16 GRRegs:$addr), (LD16S_3r GRRegs:$addr, (LDC_ru6 0))>; 1069 1070 def : Pat<(load (ldawf GRRegs:$addr, GRRegs:$offset)), 1071 (LDW_3r GRRegs:$addr, GRRegs:$offset)>; 1072 def : Pat<(load (add GRRegs:$addr, immUs4:$offset)), 1073 (LDW_2rus GRRegs:$addr, (div4_xform immUs4:$offset))>; 1074 def : Pat<(load GRRegs:$addr), (LDW_2rus GRRegs:$addr, 0)>; 1075 1076 /// anyext 1077 def : Pat<(extloadi8 (add GRRegs:$addr, GRRegs:$offset)), 1078 (LD8U_3r GRRegs:$addr, GRRegs:$offset)>; 1079 def : Pat<(extloadi8 GRRegs:$addr), (LD8U_3r GRRegs:$addr, (LDC_ru6 0))>; 1080 def : Pat<(extloadi16 (lda16f GRRegs:$addr, GRRegs:$offset)), 1081 (LD16S_3r GRRegs:$addr, GRRegs:$offset)>; 1082 def : Pat<(extloadi16 GRRegs:$addr), (LD16S_3r GRRegs:$addr, (LDC_ru6 0))>; 1083 1084 /// stores 1085 def : Pat<(truncstorei8 GRRegs:$val, (add GRRegs:$addr, GRRegs:$offset)), 1086 (ST8_l3r GRRegs:$val, GRRegs:$addr, GRRegs:$offset)>; 1087 def : Pat<(truncstorei8 GRRegs:$val, GRRegs:$addr), 1088 (ST8_l3r GRRegs:$val, GRRegs:$addr, (LDC_ru6 0))>; 1089 1090 def : Pat<(truncstorei16 GRRegs:$val, (lda16f GRRegs:$addr, GRRegs:$offset)), 1091 (ST16_l3r GRRegs:$val, GRRegs:$addr, GRRegs:$offset)>; 1092 def : Pat<(truncstorei16 GRRegs:$val, GRRegs:$addr), 1093 (ST16_l3r GRRegs:$val, GRRegs:$addr, (LDC_ru6 0))>; 1094 1095 def : Pat<(store GRRegs:$val, (ldawf GRRegs:$addr, GRRegs:$offset)), 1096 (STW_3r GRRegs:$val, GRRegs:$addr, GRRegs:$offset)>; 1097 def : Pat<(store GRRegs:$val, (add GRRegs:$addr, immUs4:$offset)), 1098 (STW_2rus GRRegs:$val, GRRegs:$addr, (div4_xform immUs4:$offset))>; 1099 def : Pat<(store GRRegs:$val, GRRegs:$addr), 1100 (STW_2rus GRRegs:$val, GRRegs:$addr, 0)>; 1101 1102 /// cttz 1103 def : Pat<(cttz GRRegs:$src), (CLZ_l2r (BITREV_l2r GRRegs:$src))>; 1104 1105 /// trap 1106 def : Pat<(trap), (ECALLF_1r (LDC_ru6 0))>; 1107 1108 /// 1109 /// branch patterns 1110 /// 1111 1112 // unconditional branch 1113 def : Pat<(br bb:$addr), (BRFU_lu6 bb:$addr)>; 1114 1115 // direct match equal/notequal zero brcond 1116 def : Pat<(brcond (setne GRRegs:$lhs, 0), bb:$dst), 1117 (BRFT_lru6 GRRegs:$lhs, bb:$dst)>; 1118 def : Pat<(brcond (seteq GRRegs:$lhs, 0), bb:$dst), 1119 (BRFF_lru6 GRRegs:$lhs, bb:$dst)>; 1120 1121 def : Pat<(brcond (setle GRRegs:$lhs, GRRegs:$rhs), bb:$dst), 1122 (BRFF_lru6 (LSS_3r GRRegs:$rhs, GRRegs:$lhs), bb:$dst)>; 1123 def : Pat<(brcond (setule GRRegs:$lhs, GRRegs:$rhs), bb:$dst), 1124 (BRFF_lru6 (LSU_3r GRRegs:$rhs, GRRegs:$lhs), bb:$dst)>; 1125 def : Pat<(brcond (setge GRRegs:$lhs, GRRegs:$rhs), bb:$dst), 1126 (BRFF_lru6 (LSS_3r GRRegs:$lhs, GRRegs:$rhs), bb:$dst)>; 1127 def : Pat<(brcond (setuge GRRegs:$lhs, GRRegs:$rhs), bb:$dst), 1128 (BRFF_lru6 (LSU_3r GRRegs:$lhs, GRRegs:$rhs), bb:$dst)>; 1129 def : Pat<(brcond (setne GRRegs:$lhs, GRRegs:$rhs), bb:$dst), 1130 (BRFF_lru6 (EQ_3r GRRegs:$lhs, GRRegs:$rhs), bb:$dst)>; 1131 def : Pat<(brcond (setne GRRegs:$lhs, immUs:$rhs), bb:$dst), 1132 (BRFF_lru6 (EQ_2rus GRRegs:$lhs, immUs:$rhs), bb:$dst)>; 1133 1134 // generic brcond pattern 1135 def : Pat<(brcond GRRegs:$cond, bb:$addr), (BRFT_lru6 GRRegs:$cond, bb:$addr)>; 1136 1137 1138 /// 1139 /// Select patterns 1140 /// 1141 1142 // direct match equal/notequal zero select 1143 def : Pat<(select (setne GRRegs:$lhs, 0), GRRegs:$T, GRRegs:$F), 1144 (SELECT_CC GRRegs:$lhs, GRRegs:$T, GRRegs:$F)>; 1145 1146 def : Pat<(select (seteq GRRegs:$lhs, 0), GRRegs:$T, GRRegs:$F), 1147 (SELECT_CC GRRegs:$lhs, GRRegs:$F, GRRegs:$T)>; 1148 1149 def : Pat<(select (setle GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F), 1150 (SELECT_CC (LSS_3r GRRegs:$rhs, GRRegs:$lhs), GRRegs:$F, GRRegs:$T)>; 1151 def : Pat<(select (setule GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F), 1152 (SELECT_CC (LSU_3r GRRegs:$rhs, GRRegs:$lhs), GRRegs:$F, GRRegs:$T)>; 1153 def : Pat<(select (setge GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F), 1154 (SELECT_CC (LSS_3r GRRegs:$lhs, GRRegs:$rhs), GRRegs:$F, GRRegs:$T)>; 1155 def : Pat<(select (setuge GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F), 1156 (SELECT_CC (LSU_3r GRRegs:$lhs, GRRegs:$rhs), GRRegs:$F, GRRegs:$T)>; 1157 def : Pat<(select (setne GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F), 1158 (SELECT_CC (EQ_3r GRRegs:$lhs, GRRegs:$rhs), GRRegs:$F, GRRegs:$T)>; 1159 def : Pat<(select (setne GRRegs:$lhs, immUs:$rhs), GRRegs:$T, GRRegs:$F), 1160 (SELECT_CC (EQ_2rus GRRegs:$lhs, immUs:$rhs), GRRegs:$F, GRRegs:$T)>; 1161 1162 /// 1163 /// setcc patterns, only matched when none of the above brcond 1164 /// patterns match 1165 /// 1166 1167 // setcc 2 register operands 1168 def : Pat<(setle GRRegs:$lhs, GRRegs:$rhs), 1169 (EQ_2rus (LSS_3r GRRegs:$rhs, GRRegs:$lhs), 0)>; 1170 def : Pat<(setule GRRegs:$lhs, GRRegs:$rhs), 1171 (EQ_2rus (LSU_3r GRRegs:$rhs, GRRegs:$lhs), 0)>; 1172 1173 def : Pat<(setgt GRRegs:$lhs, GRRegs:$rhs), 1174 (LSS_3r GRRegs:$rhs, GRRegs:$lhs)>; 1175 def : Pat<(setugt GRRegs:$lhs, GRRegs:$rhs), 1176 (LSU_3r GRRegs:$rhs, GRRegs:$lhs)>; 1177 1178 def : Pat<(setge GRRegs:$lhs, GRRegs:$rhs), 1179 (EQ_2rus (LSS_3r GRRegs:$lhs, GRRegs:$rhs), 0)>; 1180 def : Pat<(setuge GRRegs:$lhs, GRRegs:$rhs), 1181 (EQ_2rus (LSU_3r GRRegs:$lhs, GRRegs:$rhs), 0)>; 1182 1183 def : Pat<(setlt GRRegs:$lhs, GRRegs:$rhs), 1184 (LSS_3r GRRegs:$lhs, GRRegs:$rhs)>; 1185 def : Pat<(setult GRRegs:$lhs, GRRegs:$rhs), 1186 (LSU_3r GRRegs:$lhs, GRRegs:$rhs)>; 1187 1188 def : Pat<(setne GRRegs:$lhs, GRRegs:$rhs), 1189 (EQ_2rus (EQ_3r GRRegs:$lhs, GRRegs:$rhs), 0)>; 1190 1191 def : Pat<(seteq GRRegs:$lhs, GRRegs:$rhs), 1192 (EQ_3r GRRegs:$lhs, GRRegs:$rhs)>; 1193 1194 // setcc reg/imm operands 1195 def : Pat<(seteq GRRegs:$lhs, immUs:$rhs), 1196 (EQ_2rus GRRegs:$lhs, immUs:$rhs)>; 1197 def : Pat<(setne GRRegs:$lhs, immUs:$rhs), 1198 (EQ_2rus (EQ_2rus GRRegs:$lhs, immUs:$rhs), 0)>; 1199 1200 // misc 1201 def : Pat<(add GRRegs:$addr, immUs4:$offset), 1202 (LDAWF_l2rus GRRegs:$addr, (div4_xform immUs4:$offset))>; 1203 1204 def : Pat<(sub GRRegs:$addr, immUs4:$offset), 1205 (LDAWB_l2rus GRRegs:$addr, (div4_xform immUs4:$offset))>; 1206 1207 def : Pat<(and GRRegs:$val, immMskBitp:$mask), 1208 (ZEXT_rus GRRegs:$val, (msksize_xform immMskBitp:$mask))>; 1209 1210 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form. 1211 def : Pat<(add GRRegs:$src1, immUsNeg:$src2), 1212 (SUB_2rus GRRegs:$src1, (neg_xform immUsNeg:$src2))>; 1213 1214 def : Pat<(add GRRegs:$src1, immUs4Neg:$src2), 1215 (LDAWB_l2rus GRRegs:$src1, (div4neg_xform immUs4Neg:$src2))>; 1216 1217 /// 1218 /// Some peepholes 1219 /// 1220 1221 def : Pat<(mul GRRegs:$src, 3), 1222 (LDA16F_l3r GRRegs:$src, GRRegs:$src)>; 1223 1224 def : Pat<(mul GRRegs:$src, 5), 1225 (LDAWF_l3r GRRegs:$src, GRRegs:$src)>; 1226 1227 def : Pat<(mul GRRegs:$src, -3), 1228 (LDAWB_l3r GRRegs:$src, GRRegs:$src)>; 1229 1230 // ashr X, 32 is equivalent to ashr X, 31 on the XCore. 1231 def : Pat<(sra GRRegs:$src, 31), 1232 (ASHR_l2rus GRRegs:$src, 32)>; 1233 1234 def : Pat<(brcond (setlt GRRegs:$lhs, 0), bb:$dst), 1235 (BRFT_lru6 (ASHR_l2rus GRRegs:$lhs, 32), bb:$dst)>; 1236 1237 // setge X, 0 is canonicalized to setgt X, -1 1238 def : Pat<(brcond (setgt GRRegs:$lhs, -1), bb:$dst), 1239 (BRFF_lru6 (ASHR_l2rus GRRegs:$lhs, 32), bb:$dst)>; 1240 1241 def : Pat<(select (setlt GRRegs:$lhs, 0), GRRegs:$T, GRRegs:$F), 1242 (SELECT_CC (ASHR_l2rus GRRegs:$lhs, 32), GRRegs:$T, GRRegs:$F)>; 1243 1244 def : Pat<(select (setgt GRRegs:$lhs, -1), GRRegs:$T, GRRegs:$F), 1245 (SELECT_CC (ASHR_l2rus GRRegs:$lhs, 32), GRRegs:$F, GRRegs:$T)>; 1246 1247 def : Pat<(setgt GRRegs:$lhs, -1), 1248 (EQ_2rus (ASHR_l2rus GRRegs:$lhs, 32), 0)>; 1249 1250 def : Pat<(sra (shl GRRegs:$src, immBpwSubBitp:$imm), immBpwSubBitp:$imm), 1251 (SEXT_rus GRRegs:$src, (bpwsub_xform immBpwSubBitp:$imm))>; 1252