1//===-- XCoreInstrInfo.td - Target Description for XCore ---*- tablegen -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// This file describes the XCore instructions in TableGen format. 10// 11//===----------------------------------------------------------------------===// 12 13// Uses of CP, DP are not currently reflected in the patterns, since 14// having a physical register as an operand prevents loop hoisting and 15// since the value of these registers never changes during the life of the 16// function. 17 18//===----------------------------------------------------------------------===// 19// Instruction format superclass. 20//===----------------------------------------------------------------------===// 21 22include "XCoreInstrFormats.td" 23 24//===----------------------------------------------------------------------===// 25// XCore specific DAG Nodes. 26// 27 28// Call 29def SDT_XCoreBranchLink : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>; 30def XCoreBranchLink : SDNode<"XCoreISD::BL",SDT_XCoreBranchLink, 31 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 32 SDNPVariadic]>; 33 34def XCoreRetsp : SDNode<"XCoreISD::RETSP", SDTBrind, 35 [SDNPHasChain, SDNPOptInGlue, SDNPMayLoad, SDNPVariadic]>; 36 37def SDT_XCoreEhRet : SDTypeProfile<0, 2, 38 [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>; 39def XCoreEhRet : SDNode<"XCoreISD::EH_RETURN", SDT_XCoreEhRet, 40 [SDNPHasChain, SDNPOptInGlue]>; 41 42def SDT_XCoreBR_JT : SDTypeProfile<0, 2, 43 [SDTCisVT<0, i32>, SDTCisVT<1, i32>]>; 44 45def XCoreBR_JT : SDNode<"XCoreISD::BR_JT", SDT_XCoreBR_JT, 46 [SDNPHasChain]>; 47 48def XCoreBR_JT32 : SDNode<"XCoreISD::BR_JT32", SDT_XCoreBR_JT, 49 [SDNPHasChain]>; 50 51def SDT_XCoreAddress : SDTypeProfile<1, 1, 52 [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>; 53 54def pcrelwrapper : SDNode<"XCoreISD::PCRelativeWrapper", SDT_XCoreAddress, 55 []>; 56 57def dprelwrapper : SDNode<"XCoreISD::DPRelativeWrapper", SDT_XCoreAddress, 58 []>; 59 60def cprelwrapper : SDNode<"XCoreISD::CPRelativeWrapper", SDT_XCoreAddress, 61 []>; 62 63def frametoargsoffset : SDNode<"XCoreISD::FRAME_TO_ARGS_OFFSET", SDTIntLeaf, 64 []>; 65 66def SDT_XCoreStwsp : SDTypeProfile<0, 2, [SDTCisInt<1>]>; 67def XCoreStwsp : SDNode<"XCoreISD::STWSP", SDT_XCoreStwsp, 68 [SDNPHasChain, SDNPMayStore]>; 69 70def SDT_XCoreLdwsp : SDTypeProfile<1, 1, [SDTCisInt<1>]>; 71def XCoreLdwsp : SDNode<"XCoreISD::LDWSP", SDT_XCoreLdwsp, 72 [SDNPHasChain, SDNPMayLoad]>; 73 74// These are target-independent nodes, but have target-specific formats. 75def SDT_XCoreCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32>, 76 SDTCisVT<1, i32> ]>; 77def SDT_XCoreCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, 78 SDTCisVT<1, i32> ]>; 79 80def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_XCoreCallSeqStart, 81 [SDNPHasChain, SDNPOutGlue]>; 82def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_XCoreCallSeqEnd, 83 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 84 85def SDT_XCoreMEMBARRIER : SDTypeProfile<0, 0, []>; 86 87def XCoreMemBarrier : SDNode<"XCoreISD::MEMBARRIER", SDT_XCoreMEMBARRIER, 88 [SDNPHasChain]>; 89 90//===----------------------------------------------------------------------===// 91// Instruction Pattern Stuff 92//===----------------------------------------------------------------------===// 93 94def div4_xform : SDNodeXForm<imm, [{ 95 // Transformation function: imm/4 96 assert(N->getZExtValue() % 4 == 0); 97 return getI32Imm(N->getZExtValue()/4, SDLoc(N)); 98}]>; 99 100def msksize_xform : SDNodeXForm<imm, [{ 101 // Transformation function: get the size of a mask 102 assert(isMask_32(N->getZExtValue())); 103 // look for the first non-zero bit 104 return getI32Imm(32 - countLeadingZeros((uint32_t)N->getZExtValue()), 105 SDLoc(N)); 106}]>; 107 108def neg_xform : SDNodeXForm<imm, [{ 109 // Transformation function: -imm 110 uint32_t value = N->getZExtValue(); 111 return getI32Imm(-value, SDLoc(N)); 112}]>; 113 114def bpwsub_xform : SDNodeXForm<imm, [{ 115 // Transformation function: 32-imm 116 uint32_t value = N->getZExtValue(); 117 return getI32Imm(32 - value, SDLoc(N)); 118}]>; 119 120def div4neg_xform : SDNodeXForm<imm, [{ 121 // Transformation function: -imm/4 122 uint32_t value = N->getZExtValue(); 123 assert(-value % 4 == 0); 124 return getI32Imm(-value/4, SDLoc(N)); 125}]>; 126 127def immUs4Neg : PatLeaf<(imm), [{ 128 uint32_t value = (uint32_t)N->getZExtValue(); 129 return (-value)%4 == 0 && (-value)/4 <= 11; 130}]>; 131 132def immUs4 : PatLeaf<(imm), [{ 133 uint32_t value = (uint32_t)N->getZExtValue(); 134 return value%4 == 0 && value/4 <= 11; 135}]>; 136 137def immUsNeg : PatLeaf<(imm), [{ 138 return -((uint32_t)N->getZExtValue()) <= 11; 139}]>; 140 141def immUs : PatLeaf<(imm), [{ 142 return (uint32_t)N->getZExtValue() <= 11; 143}]>; 144 145def immU6 : PatLeaf<(imm), [{ 146 return (uint32_t)N->getZExtValue() < (1 << 6); 147}]>; 148 149def immU16 : PatLeaf<(imm), [{ 150 return (uint32_t)N->getZExtValue() < (1 << 16); 151}]>; 152 153def immMskBitp : PatLeaf<(imm), [{ return immMskBitp(N); }]>; 154 155def immBitp : PatLeaf<(imm), [{ 156 uint32_t value = (uint32_t)N->getZExtValue(); 157 return (value >= 1 && value <= 8) 158 || value == 16 159 || value == 24 160 || value == 32; 161}]>; 162 163def immBpwSubBitp : PatLeaf<(imm), [{ 164 uint32_t value = (uint32_t)N->getZExtValue(); 165 return (value >= 24 && value <= 31) 166 || value == 16 167 || value == 8 168 || value == 0; 169}]>; 170 171def lda16f : PatFrag<(ops node:$addr, node:$offset), 172 (add node:$addr, (shl node:$offset, 1))>; 173def lda16b : PatFrag<(ops node:$addr, node:$offset), 174 (sub node:$addr, (shl node:$offset, 1))>; 175def ldawf : PatFrag<(ops node:$addr, node:$offset), 176 (add node:$addr, (shl node:$offset, 2))>; 177def ldawb : PatFrag<(ops node:$addr, node:$offset), 178 (sub node:$addr, (shl node:$offset, 2))>; 179 180// Instruction operand types 181def pcrel_imm : Operand<i32>; 182def pcrel_imm_neg : Operand<i32> { 183 let DecoderMethod = "DecodeNegImmOperand"; 184} 185def brtarget : Operand<OtherVT>; 186def brtarget_neg : Operand<OtherVT> { 187 let DecoderMethod = "DecodeNegImmOperand"; 188} 189 190// Addressing modes 191def ADDRspii : ComplexPattern<i32, 2, "SelectADDRspii", [add, frameindex], []>; 192 193// Address operands 194def MEMii : Operand<i32> { 195 let MIOperandInfo = (ops i32imm, i32imm); 196} 197 198// Jump tables. 199def InlineJT : Operand<i32> { 200 let PrintMethod = "printInlineJT"; 201} 202 203def InlineJT32 : Operand<i32> { 204 let PrintMethod = "printInlineJT32"; 205} 206 207//===----------------------------------------------------------------------===// 208// Instruction Class Templates 209//===----------------------------------------------------------------------===// 210 211// Three operand short 212 213multiclass F3R_2RUS<bits<5> opc1, bits<5> opc2, string OpcStr, SDNode OpNode> { 214 def _3r: _F3R<opc1, (outs GRRegs:$dst), (ins GRRegs:$b, GRRegs:$c), 215 !strconcat(OpcStr, " $dst, $b, $c"), 216 [(set GRRegs:$dst, (OpNode GRRegs:$b, GRRegs:$c))]>; 217 def _2rus : _F2RUS<opc2, (outs GRRegs:$dst), (ins GRRegs:$b, i32imm:$c), 218 !strconcat(OpcStr, " $dst, $b, $c"), 219 [(set GRRegs:$dst, (OpNode GRRegs:$b, immUs:$c))]>; 220} 221 222multiclass F3R_2RUS_np<bits<5> opc1, bits<5> opc2, string OpcStr> { 223 def _3r: _F3R<opc1, (outs GRRegs:$dst), (ins GRRegs:$b, GRRegs:$c), 224 !strconcat(OpcStr, " $dst, $b, $c"), []>; 225 def _2rus : _F2RUS<opc2, (outs GRRegs:$dst), (ins GRRegs:$b, i32imm:$c), 226 !strconcat(OpcStr, " $dst, $b, $c"), []>; 227} 228 229multiclass F3R_2RBITP<bits<5> opc1, bits<5> opc2, string OpcStr, 230 SDNode OpNode> { 231 def _3r: _F3R<opc1, (outs GRRegs:$dst), (ins GRRegs:$b, GRRegs:$c), 232 !strconcat(OpcStr, " $dst, $b, $c"), 233 [(set GRRegs:$dst, (OpNode GRRegs:$b, GRRegs:$c))]>; 234 def _2rus : _F2RUSBitp<opc2, (outs GRRegs:$dst), (ins GRRegs:$b, i32imm:$c), 235 !strconcat(OpcStr, " $dst, $b, $c"), 236 [(set GRRegs:$dst, (OpNode GRRegs:$b, immBitp:$c))]>; 237} 238 239class F3R<bits<5> opc, string OpcStr, SDNode OpNode> : 240 _F3R<opc, (outs GRRegs:$dst), (ins GRRegs:$b, GRRegs:$c), 241 !strconcat(OpcStr, " $dst, $b, $c"), 242 [(set GRRegs:$dst, (OpNode GRRegs:$b, GRRegs:$c))]>; 243 244class F3R_np<bits<5> opc, string OpcStr> : 245 _F3R<opc, (outs GRRegs:$dst), (ins GRRegs:$b, GRRegs:$c), 246 !strconcat(OpcStr, " $dst, $b, $c"), []>; 247// Three operand long 248 249/// FL3R_L2RUS multiclass - Define a normal FL3R/FL2RUS pattern in one shot. 250multiclass FL3R_L2RUS<bits<9> opc1, bits<9> opc2, string OpcStr, 251 SDNode OpNode> { 252 def _l3r: _FL3R<opc1, (outs GRRegs:$dst), (ins GRRegs:$b, GRRegs:$c), 253 !strconcat(OpcStr, " $dst, $b, $c"), 254 [(set GRRegs:$dst, (OpNode GRRegs:$b, GRRegs:$c))]>; 255 def _l2rus : _FL2RUS<opc2, (outs GRRegs:$dst), (ins GRRegs:$b, i32imm:$c), 256 !strconcat(OpcStr, " $dst, $b, $c"), 257 [(set GRRegs:$dst, (OpNode GRRegs:$b, immUs:$c))]>; 258} 259 260/// FL3R_L2RUS multiclass - Define a normal FL3R/FL2RUS pattern in one shot. 261multiclass FL3R_L2RBITP<bits<9> opc1, bits<9> opc2, string OpcStr, 262 SDNode OpNode> { 263 def _l3r: _FL3R<opc1, (outs GRRegs:$dst), (ins GRRegs:$b, GRRegs:$c), 264 !strconcat(OpcStr, " $dst, $b, $c"), 265 [(set GRRegs:$dst, (OpNode GRRegs:$b, GRRegs:$c))]>; 266 def _l2rus : _FL2RUSBitp<opc2, (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<bits<9> opc, string OpcStr, SDNode OpNode> : 272 _FL3R<opc, (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<bits<6> opc, string OpcStr> { 279 def _ru6: _FRU6<opc, (outs), (ins GRRegs:$a, brtarget:$b), 280 !strconcat(OpcStr, " $a, $b"), []>; 281 def _lru6: _FLRU6<opc, (outs), (ins GRRegs:$a, brtarget:$b), 282 !strconcat(OpcStr, " $a, $b"), []>; 283} 284 285multiclass FRU6_LRU6_backwards_branch<bits<6> opc, string OpcStr> { 286 def _ru6: _FRU6<opc, (outs), (ins GRRegs:$a, brtarget_neg:$b), 287 !strconcat(OpcStr, " $a, $b"), []>; 288 def _lru6: _FLRU6<opc, (outs), (ins GRRegs:$a, brtarget_neg:$b), 289 !strconcat(OpcStr, " $a, $b"), []>; 290} 291 292 293// U6 294multiclass FU6_LU6<bits<10> opc, string OpcStr, SDNode OpNode> { 295 def _u6: _FU6<opc, (outs), (ins i32imm:$a), !strconcat(OpcStr, " $a"), 296 [(OpNode immU6:$a)]>; 297 def _lu6: _FLU6<opc, (outs), (ins i32imm:$a), !strconcat(OpcStr, " $a"), 298 [(OpNode immU16:$a)]>; 299} 300 301multiclass FU6_LU6_int<bits<10> opc, string OpcStr, Intrinsic Int> { 302 def _u6: _FU6<opc, (outs), (ins i32imm:$a), !strconcat(OpcStr, " $a"), 303 [(Int immU6:$a)]>; 304 def _lu6: _FLU6<opc, (outs), (ins i32imm:$a), !strconcat(OpcStr, " $a"), 305 [(Int immU16:$a)]>; 306} 307 308multiclass FU6_LU6_np<bits<10> opc, string OpcStr> { 309 def _u6: _FU6<opc, (outs), (ins i32imm:$a), !strconcat(OpcStr, " $a"), []>; 310 def _lu6: _FLU6<opc, (outs), (ins i32imm:$a), !strconcat(OpcStr, " $a"), []>; 311} 312 313// Two operand short 314 315class F2R_np<bits<6> opc, string OpcStr> : 316 _F2R<opc, (outs GRRegs:$dst), (ins GRRegs:$b), 317 !strconcat(OpcStr, " $dst, $b"), []>; 318 319// Two operand long 320 321//===----------------------------------------------------------------------===// 322// Pseudo Instructions 323//===----------------------------------------------------------------------===// 324 325let Defs = [SP], Uses = [SP] in { 326def ADJCALLSTACKDOWN : PseudoInstXCore<(outs), (ins i32imm:$amt, i32imm:$amt2), 327 "# ADJCALLSTACKDOWN $amt, $amt2", 328 [(callseq_start timm:$amt, timm:$amt2)]>; 329def ADJCALLSTACKUP : PseudoInstXCore<(outs), (ins i32imm:$amt1, i32imm:$amt2), 330 "# ADJCALLSTACKUP $amt1", 331 [(callseq_end timm:$amt1, timm:$amt2)]>; 332} 333 334let isReMaterializable = 1 in 335def FRAME_TO_ARGS_OFFSET : PseudoInstXCore<(outs GRRegs:$dst), (ins), 336 "# FRAME_TO_ARGS_OFFSET $dst", 337 [(set GRRegs:$dst, (frametoargsoffset))]>; 338 339let isReturn = 1, isTerminator = 1, isBarrier = 1 in 340def EH_RETURN : PseudoInstXCore<(outs), (ins GRRegs:$s, GRRegs:$handler), 341 "# EH_RETURN $s, $handler", 342 [(XCoreEhRet GRRegs:$s, GRRegs:$handler)]>; 343 344def LDWFI : PseudoInstXCore<(outs GRRegs:$dst), (ins MEMii:$addr), 345 "# LDWFI $dst, $addr", 346 [(set GRRegs:$dst, (load ADDRspii:$addr))]>; 347 348def LDAWFI : PseudoInstXCore<(outs GRRegs:$dst), (ins MEMii:$addr), 349 "# LDAWFI $dst, $addr", 350 [(set GRRegs:$dst, ADDRspii:$addr)]>; 351 352def STWFI : PseudoInstXCore<(outs), (ins GRRegs:$src, MEMii:$addr), 353 "# STWFI $src, $addr", 354 [(store GRRegs:$src, ADDRspii:$addr)]>; 355 356// SELECT_CC_* - Used to implement the SELECT_CC DAG operation. Expanded after 357// instruction selection into a branch sequence. 358let usesCustomInserter = 1 in { 359 def SELECT_CC : PseudoInstXCore<(outs GRRegs:$dst), 360 (ins GRRegs:$cond, GRRegs:$T, GRRegs:$F), 361 "# SELECT_CC PSEUDO!", 362 [(set GRRegs:$dst, 363 (select GRRegs:$cond, GRRegs:$T, GRRegs:$F))]>; 364} 365 366let hasSideEffects = 1 in 367def Int_MemBarrier : PseudoInstXCore<(outs), (ins), "#MEMBARRIER", 368 [(XCoreMemBarrier)]>; 369 370//===----------------------------------------------------------------------===// 371// Instructions 372//===----------------------------------------------------------------------===// 373 374// Three operand short 375defm ADD : F3R_2RUS<0b00010, 0b10010, "add", add>; 376defm SUB : F3R_2RUS<0b00011, 0b10011, "sub", sub>; 377let hasSideEffects = 0 in { 378defm EQ : F3R_2RUS_np<0b00110, 0b10110, "eq">; 379def LSS_3r : F3R_np<0b11000, "lss">; 380def LSU_3r : F3R_np<0b11001, "lsu">; 381} 382def AND_3r : F3R<0b00111, "and", and>; 383def OR_3r : F3R<0b01000, "or", or>; 384 385let mayLoad=1 in { 386def LDW_3r : _F3R<0b01001, (outs GRRegs:$dst), 387 (ins GRRegs:$addr, GRRegs:$offset), 388 "ldw $dst, $addr[$offset]", []>; 389 390def LDW_2rus : _F2RUS<0b00001, (outs GRRegs:$dst), 391 (ins GRRegs:$addr, i32imm:$offset), 392 "ldw $dst, $addr[$offset]", []>; 393 394def LD16S_3r : _F3R<0b10000, (outs GRRegs:$dst), 395 (ins GRRegs:$addr, GRRegs:$offset), 396 "ld16s $dst, $addr[$offset]", []>; 397 398def LD8U_3r : _F3R<0b10001, (outs GRRegs:$dst), 399 (ins GRRegs:$addr, GRRegs:$offset), 400 "ld8u $dst, $addr[$offset]", []>; 401} 402 403let mayStore=1 in { 404def STW_l3r : _FL3R<0b000001100, (outs), 405 (ins GRRegs:$val, GRRegs:$addr, GRRegs:$offset), 406 "stw $val, $addr[$offset]", []>; 407 408def STW_2rus : _F2RUS<0b00000, (outs), 409 (ins GRRegs:$val, GRRegs:$addr, i32imm:$offset), 410 "stw $val, $addr[$offset]", []>; 411} 412 413defm SHL : F3R_2RBITP<0b00100, 0b10100, "shl", shl>; 414defm SHR : F3R_2RBITP<0b00101, 0b10101, "shr", srl>; 415 416// The first operand is treated as an immediate since it refers to a register 417// number in another thread. 418def TSETR_3r : _F3RImm<0b10111, (outs), (ins i32imm:$a, GRRegs:$b, GRRegs:$c), 419 "set t[$c]:r$a, $b", []>; 420 421// Three operand long 422def LDAWF_l3r : _FL3R<0b000111100, (outs GRRegs:$dst), 423 (ins GRRegs:$addr, GRRegs:$offset), 424 "ldaw $dst, $addr[$offset]", 425 [(set GRRegs:$dst, 426 (ldawf GRRegs:$addr, GRRegs:$offset))]>; 427 428let hasSideEffects = 0 in 429def LDAWF_l2rus : _FL2RUS<0b100111100, (outs GRRegs:$dst), 430 (ins GRRegs:$addr, i32imm:$offset), 431 "ldaw $dst, $addr[$offset]", []>; 432 433def LDAWB_l3r : _FL3R<0b001001100, (outs GRRegs:$dst), 434 (ins GRRegs:$addr, GRRegs:$offset), 435 "ldaw $dst, $addr[-$offset]", 436 [(set GRRegs:$dst, 437 (ldawb GRRegs:$addr, GRRegs:$offset))]>; 438 439let hasSideEffects = 0 in 440def LDAWB_l2rus : _FL2RUS<0b101001100, (outs GRRegs:$dst), 441 (ins GRRegs:$addr, i32imm:$offset), 442 "ldaw $dst, $addr[-$offset]", []>; 443 444def LDA16F_l3r : _FL3R<0b001011100, (outs GRRegs:$dst), 445 (ins GRRegs:$addr, GRRegs:$offset), 446 "lda16 $dst, $addr[$offset]", 447 [(set GRRegs:$dst, 448 (lda16f GRRegs:$addr, GRRegs:$offset))]>; 449 450def LDA16B_l3r : _FL3R<0b001101100, (outs GRRegs:$dst), 451 (ins GRRegs:$addr, GRRegs:$offset), 452 "lda16 $dst, $addr[-$offset]", 453 [(set GRRegs:$dst, 454 (lda16b GRRegs:$addr, GRRegs:$offset))]>; 455 456def MUL_l3r : FL3R<0b001111100, "mul", mul>; 457// Instructions which may trap are marked as side effecting. 458let hasSideEffects = 1 in { 459def DIVS_l3r : FL3R<0b010001100, "divs", sdiv>; 460def DIVU_l3r : FL3R<0b010011100, "divu", udiv>; 461def REMS_l3r : FL3R<0b110001100, "rems", srem>; 462def REMU_l3r : FL3R<0b110011100, "remu", urem>; 463} 464def XOR_l3r : FL3R<0b000011100, "xor", xor>; 465defm ASHR : FL3R_L2RBITP<0b000101100, 0b100101100, "ashr", sra>; 466 467let Constraints = "$src1 = $dst" in 468def CRC_l3r : _FL3RSrcDst<0b101011100, (outs GRRegs:$dst), 469 (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3), 470 "crc32 $dst, $src2, $src3", 471 [(set GRRegs:$dst, 472 (int_xcore_crc32 GRRegs:$src1, GRRegs:$src2, 473 GRRegs:$src3))]>; 474 475let mayStore=1 in { 476def ST16_l3r : _FL3R<0b100001100, (outs), 477 (ins GRRegs:$val, GRRegs:$addr, GRRegs:$offset), 478 "st16 $val, $addr[$offset]", []>; 479 480def ST8_l3r : _FL3R<0b100011100, (outs), 481 (ins GRRegs:$val, GRRegs:$addr, GRRegs:$offset), 482 "st8 $val, $addr[$offset]", []>; 483} 484 485def INPW_l2rus : _FL2RUSBitp<0b100101110, (outs GRRegs:$a), 486 (ins GRRegs:$b, i32imm:$c), "inpw $a, res[$b], $c", 487 []>; 488 489def OUTPW_l2rus : _FL2RUSBitp<0b100101101, (outs), 490 (ins GRRegs:$a, GRRegs:$b, i32imm:$c), 491 "outpw res[$b], $a, $c", []>; 492 493// Four operand long 494let Constraints = "$e = $a,$f = $b" in { 495def MACCU_l4r : _FL4RSrcDstSrcDst< 496 0b000001, (outs GRRegs:$a, GRRegs:$b), 497 (ins GRRegs:$e, GRRegs:$f, GRRegs:$c, GRRegs:$d), "maccu $a, $b, $c, $d", []>; 498 499def MACCS_l4r : _FL4RSrcDstSrcDst< 500 0b000010, (outs GRRegs:$a, GRRegs:$b), 501 (ins GRRegs:$e, GRRegs:$f, GRRegs:$c, GRRegs:$d), "maccs $a, $b, $c, $d", []>; 502} 503 504let Constraints = "$e = $b" in 505def CRC8_l4r : _FL4RSrcDst<0b000000, (outs GRRegs:$a, GRRegs:$b), 506 (ins GRRegs:$e, GRRegs:$c, GRRegs:$d), 507 "crc8 $b, $a, $c, $d", []>; 508 509// Five operand long 510 511def LADD_l5r : _FL5R<0b000001, (outs GRRegs:$dst1, GRRegs:$dst2), 512 (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3), 513 "ladd $dst2, $dst1, $src1, $src2, $src3", 514 []>; 515 516def LSUB_l5r : _FL5R<0b000010, (outs GRRegs:$dst1, GRRegs:$dst2), 517 (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3), 518 "lsub $dst2, $dst1, $src1, $src2, $src3", []>; 519 520def LDIVU_l5r : _FL5R<0b000000, (outs GRRegs:$dst1, GRRegs:$dst2), 521 (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3), 522 "ldivu $dst1, $dst2, $src3, $src1, $src2", []>; 523 524// Six operand long 525 526def LMUL_l6r : _FL6R< 527 0b00000, (outs GRRegs:$dst1, GRRegs:$dst2), 528 (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3, GRRegs:$src4), 529 "lmul $dst1, $dst2, $src1, $src2, $src3, $src4", []>; 530 531// Register - U6 532 533//let Uses = [DP] in ... 534let hasSideEffects = 0, isReMaterializable = 1 in 535def LDAWDP_ru6: _FRU6<0b011000, (outs RRegs:$a), (ins i32imm:$b), 536 "ldaw $a, dp[$b]", []>; 537 538let isReMaterializable = 1 in 539def LDAWDP_lru6: _FLRU6<0b011000, (outs RRegs:$a), (ins i32imm:$b), 540 "ldaw $a, dp[$b]", 541 [(set RRegs:$a, (dprelwrapper tglobaladdr:$b))]>; 542 543let mayLoad=1 in 544def LDWDP_ru6: _FRU6<0b010110, (outs RRegs:$a), (ins i32imm:$b), 545 "ldw $a, dp[$b]", []>; 546 547def LDWDP_lru6: _FLRU6<0b010110, (outs RRegs:$a), (ins i32imm:$b), 548 "ldw $a, dp[$b]", 549 [(set RRegs:$a, (load (dprelwrapper tglobaladdr:$b)))]>; 550 551let mayStore=1 in 552def STWDP_ru6 : _FRU6<0b010100, (outs), (ins RRegs:$a, i32imm:$b), 553 "stw $a, dp[$b]", []>; 554 555def STWDP_lru6 : _FLRU6<0b010100, (outs), (ins RRegs:$a, i32imm:$b), 556 "stw $a, dp[$b]", 557 [(store RRegs:$a, (dprelwrapper tglobaladdr:$b))]>; 558 559//let Uses = [CP] in .. 560let mayLoad = 1, isReMaterializable = 1, hasSideEffects = 0 in { 561def LDWCP_ru6 : _FRU6<0b011011, (outs RRegs:$a), (ins i32imm:$b), 562 "ldw $a, cp[$b]", []>; 563def LDWCP_lru6: _FLRU6<0b011011, (outs RRegs:$a), (ins i32imm:$b), 564 "ldw $a, cp[$b]", 565 [(set RRegs:$a, (load (cprelwrapper tglobaladdr:$b)))]>; 566} 567 568let Uses = [SP] in { 569let mayStore=1 in { 570def STWSP_ru6 : _FRU6<0b010101, (outs), (ins RRegs:$a, i32imm:$b), 571 "stw $a, sp[$b]", 572 [(XCoreStwsp RRegs:$a, immU6:$b)]>; 573 574def STWSP_lru6 : _FLRU6<0b010101, (outs), (ins RRegs:$a, i32imm:$b), 575 "stw $a, sp[$b]", 576 [(XCoreStwsp RRegs:$a, immU16:$b)]>; 577} 578 579let mayLoad=1 in { 580def LDWSP_ru6 : _FRU6<0b010111, (outs RRegs:$a), (ins i32imm:$b), 581 "ldw $a, sp[$b]", 582 [(set RRegs:$a, (XCoreLdwsp immU6:$b))]>; 583 584def LDWSP_lru6 : _FLRU6<0b010111, (outs RRegs:$a), (ins i32imm:$b), 585 "ldw $a, sp[$b]", 586 [(set RRegs:$a, (XCoreLdwsp immU16:$b))]>; 587} 588 589let hasSideEffects = 0 in { 590def LDAWSP_ru6 : _FRU6<0b011001, (outs RRegs:$a), (ins i32imm:$b), 591 "ldaw $a, sp[$b]", []>; 592 593def LDAWSP_lru6 : _FLRU6<0b011001, (outs RRegs:$a), (ins i32imm:$b), 594 "ldaw $a, sp[$b]", []>; 595} 596} 597 598let isReMaterializable = 1 in { 599def LDC_ru6 : _FRU6<0b011010, (outs RRegs:$a), (ins i32imm:$b), 600 "ldc $a, $b", [(set RRegs:$a, immU6:$b)]>; 601 602def LDC_lru6 : _FLRU6<0b011010, (outs RRegs:$a), (ins i32imm:$b), 603 "ldc $a, $b", [(set RRegs:$a, immU16:$b)]>; 604} 605 606def SETC_ru6 : _FRU6<0b111010, (outs), (ins GRRegs:$a, i32imm:$b), 607 "setc res[$a], $b", 608 [(int_xcore_setc GRRegs:$a, immU6:$b)]>; 609 610def SETC_lru6 : _FLRU6<0b111010, (outs), (ins GRRegs:$a, i32imm:$b), 611 "setc res[$a], $b", 612 [(int_xcore_setc GRRegs:$a, immU16:$b)]>; 613 614// Operand register - U6 615let isBranch = 1, isTerminator = 1 in { 616defm BRFT: FRU6_LRU6_branch<0b011100, "bt">; 617defm BRBT: FRU6_LRU6_backwards_branch<0b011101, "bt">; 618defm BRFF: FRU6_LRU6_branch<0b011110, "bf">; 619defm BRBF: FRU6_LRU6_backwards_branch<0b011111, "bf">; 620} 621 622// U6 623let Defs = [SP], Uses = [SP] in { 624let hasSideEffects = 0 in 625defm EXTSP : FU6_LU6_np<0b0111011110, "extsp">; 626 627let mayStore = 1 in 628defm ENTSP : FU6_LU6_np<0b0111011101, "entsp">; 629 630let isReturn = 1, isTerminator = 1, mayLoad = 1, isBarrier = 1 in { 631defm RETSP : FU6_LU6<0b0111011111, "retsp", XCoreRetsp>; 632} 633} 634 635let hasSideEffects = 0 in 636defm EXTDP : FU6_LU6_np<0b0111001110, "extdp">; 637 638let Uses = [R11], isCall=1 in 639defm BLAT : FU6_LU6_np<0b0111001101, "blat">; 640 641let isBranch = 1, isTerminator = 1, isBarrier = 1 in { 642def BRBU_u6 : _FU6<0b0111011100, (outs), (ins brtarget_neg:$a), "bu $a", []>; 643 644def BRBU_lu6 : _FLU6<0b0111011100, (outs), (ins brtarget_neg:$a), "bu $a", []>; 645 646def BRFU_u6 : _FU6<0b0111001100, (outs), (ins brtarget:$a), "bu $a", []>; 647 648def BRFU_lu6 : _FLU6<0b0111001100, (outs), (ins brtarget:$a), "bu $a", []>; 649} 650 651//let Uses = [CP] in ... 652let Defs = [R11], hasSideEffects = 0, isReMaterializable = 1 in 653def LDAWCP_u6: _FU6<0b0111111101, (outs), (ins i32imm:$a), "ldaw r11, cp[$a]", 654 []>; 655 656let Defs = [R11], isReMaterializable = 1 in 657def LDAWCP_lu6: _FLU6<0b0111111101, (outs), (ins i32imm:$a), "ldaw r11, cp[$a]", 658 [(set R11, (cprelwrapper tglobaladdr:$a))]>; 659 660let Defs = [R11] in 661defm GETSR : FU6_LU6_np<0b0111111100, "getsr r11,">; 662 663defm SETSR : FU6_LU6_int<0b0111101101, "setsr", int_xcore_setsr>; 664 665defm CLRSR : FU6_LU6_int<0b0111101100, "clrsr", int_xcore_clrsr>; 666 667// setsr may cause a branch if it is used to enable events. clrsr may 668// branch if it is executed while events are enabled. 669let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1, 670 isCodeGenOnly = 1 in { 671defm SETSR_branch : FU6_LU6_np<0b0111101101, "setsr">; 672defm CLRSR_branch : FU6_LU6_np<0b0111101100, "clrsr">; 673} 674 675defm KCALL : FU6_LU6_np<0b0111001111, "kcall">; 676 677let Uses = [SP], Defs = [SP], mayStore = 1 in 678defm KENTSP : FU6_LU6_np<0b0111101110, "kentsp">; 679 680let Uses = [SP], Defs = [SP], mayLoad = 1 in 681defm KRESTSP : FU6_LU6_np<0b0111101111, "krestsp">; 682 683// U10 684 685let Defs = [R11], isReMaterializable = 1 in { 686let hasSideEffects = 0 in 687def LDAPF_u10 : _FU10<0b110110, (outs), (ins pcrel_imm:$a), "ldap r11, $a", []>; 688 689def LDAPF_lu10 : _FLU10<0b110110, (outs), (ins pcrel_imm:$a), "ldap r11, $a", 690 [(set R11, (pcrelwrapper tglobaladdr:$a))]>; 691 692let hasSideEffects = 0 in 693def LDAPB_u10 : _FU10<0b110111, (outs), (ins pcrel_imm_neg:$a), "ldap r11, $a", 694 []>; 695 696let hasSideEffects = 0 in 697def LDAPB_lu10 : _FLU10<0b110111, (outs), (ins pcrel_imm_neg:$a), 698 "ldap r11, $a", 699 [(set R11, (pcrelwrapper tglobaladdr:$a))]>; 700 701let isCodeGenOnly = 1 in 702def LDAPF_lu10_ba : _FLU10<0b110110, (outs), (ins pcrel_imm:$a), "ldap r11, $a", 703 [(set R11, (pcrelwrapper tblockaddress:$a))]>; 704} 705 706let isCall=1, 707// All calls clobber the link register and the non-callee-saved registers: 708Defs = [R0, R1, R2, R3, R11, LR], Uses = [SP] in { 709def BLACP_u10 : _FU10<0b111000, (outs), (ins i32imm:$a), "bla cp[$a]", []>; 710 711def BLACP_lu10 : _FLU10<0b111000, (outs), (ins i32imm:$a), "bla cp[$a]", []>; 712 713def BLRF_u10 : _FU10<0b110100, (outs), (ins pcrel_imm:$a), "bl $a", 714 []>; 715 716def BLRF_lu10 : _FLU10<0b110100, (outs), (ins pcrel_imm:$a), "bl $a", 717 [(XCoreBranchLink tglobaladdr:$a)]>; 718 719def BLRB_u10 : _FU10<0b110101, (outs), (ins pcrel_imm_neg:$a), "bl $a", []>; 720 721def BLRB_lu10 : _FLU10<0b110101, (outs), (ins pcrel_imm_neg:$a), "bl $a", []>; 722} 723 724let Defs = [R11], mayLoad = 1, isReMaterializable = 1, 725 hasSideEffects = 0 in { 726def LDWCP_u10 : _FU10<0b111001, (outs), (ins i32imm:$a), "ldw r11, cp[$a]", []>; 727 728def LDWCP_lu10 : _FLU10<0b111001, (outs), (ins i32imm:$a), "ldw r11, cp[$a]", 729 []>; 730} 731 732// Two operand short 733def NOT : _F2R<0b100010, (outs GRRegs:$dst), (ins GRRegs:$b), 734 "not $dst, $b", [(set GRRegs:$dst, (not GRRegs:$b))]>; 735 736def NEG : _F2R<0b100100, (outs GRRegs:$dst), (ins GRRegs:$b), 737 "neg $dst, $b", [(set GRRegs:$dst, (ineg GRRegs:$b))]>; 738 739let Constraints = "$src1 = $dst" in { 740def SEXT_rus : 741 _FRUSSrcDstBitp<0b001101, (outs GRRegs:$dst), (ins GRRegs:$src1, i32imm:$src2), 742 "sext $dst, $src2", 743 [(set GRRegs:$dst, (int_xcore_sext GRRegs:$src1, 744 immBitp:$src2))]>; 745 746def SEXT_2r : 747 _F2RSrcDst<0b001100, (outs GRRegs:$dst), (ins GRRegs:$src1, GRRegs:$src2), 748 "sext $dst, $src2", 749 [(set GRRegs:$dst, (int_xcore_sext GRRegs:$src1, GRRegs:$src2))]>; 750 751def ZEXT_rus : 752 _FRUSSrcDstBitp<0b010001, (outs GRRegs:$dst), (ins GRRegs:$src1, i32imm:$src2), 753 "zext $dst, $src2", 754 [(set GRRegs:$dst, (int_xcore_zext GRRegs:$src1, 755 immBitp:$src2))]>; 756 757def ZEXT_2r : 758 _F2RSrcDst<0b010000, (outs GRRegs:$dst), (ins GRRegs:$src1, GRRegs:$src2), 759 "zext $dst, $src2", 760 [(set GRRegs:$dst, (int_xcore_zext GRRegs:$src1, GRRegs:$src2))]>; 761 762def ANDNOT_2r : 763 _F2RSrcDst<0b001010, (outs GRRegs:$dst), (ins GRRegs:$src1, GRRegs:$src2), 764 "andnot $dst, $src2", 765 [(set GRRegs:$dst, (and GRRegs:$src1, (not GRRegs:$src2)))]>; 766} 767 768let isReMaterializable = 1, hasSideEffects = 0 in 769def MKMSK_rus : _FRUSBitp<0b101001, (outs GRRegs:$dst), (ins i32imm:$size), 770 "mkmsk $dst, $size", []>; 771 772def MKMSK_2r : _F2R<0b101000, (outs GRRegs:$dst), (ins GRRegs:$size), 773 "mkmsk $dst, $size", 774 [(set GRRegs:$dst, (add (shl 1, GRRegs:$size), -1))]>; 775 776def GETR_rus : _FRUS<0b100000, (outs GRRegs:$dst), (ins i32imm:$type), 777 "getr $dst, $type", 778 [(set GRRegs:$dst, (int_xcore_getr immUs:$type))]>; 779 780def GETTS_2r : _F2R<0b001110, (outs GRRegs:$dst), (ins GRRegs:$r), 781 "getts $dst, res[$r]", 782 [(set GRRegs:$dst, (int_xcore_getts GRRegs:$r))]>; 783 784def SETPT_2r : _FR2R<0b001111, (outs), (ins GRRegs:$r, GRRegs:$val), 785 "setpt res[$r], $val", 786 [(int_xcore_setpt GRRegs:$r, GRRegs:$val)]>; 787 788def OUTCT_2r : _F2R<0b010010, (outs), (ins GRRegs:$r, GRRegs:$val), 789 "outct res[$r], $val", 790 [(int_xcore_outct GRRegs:$r, GRRegs:$val)]>; 791 792def OUTCT_rus : _FRUS<0b010011, (outs), (ins GRRegs:$r, i32imm:$val), 793 "outct res[$r], $val", 794 [(int_xcore_outct GRRegs:$r, immUs:$val)]>; 795 796def OUTT_2r : _FR2R<0b000011, (outs), (ins GRRegs:$r, GRRegs:$val), 797 "outt res[$r], $val", 798 [(int_xcore_outt GRRegs:$r, GRRegs:$val)]>; 799 800def OUT_2r : _FR2R<0b101010, (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 : 806 _F2RSrcDst<0b101011, (outs GRRegs:$dst), (ins GRRegs:$src, GRRegs:$r), 807 "outshr res[$r], $src", 808 [(set GRRegs:$dst, (int_xcore_outshr GRRegs:$r, GRRegs:$src))]>; 809 810def INCT_2r : _F2R<0b100001, (outs GRRegs:$dst), (ins GRRegs:$r), 811 "inct $dst, res[$r]", 812 [(set GRRegs:$dst, (int_xcore_inct GRRegs:$r))]>; 813 814def INT_2r : _F2R<0b100011, (outs GRRegs:$dst), (ins GRRegs:$r), 815 "int $dst, res[$r]", 816 [(set GRRegs:$dst, (int_xcore_int GRRegs:$r))]>; 817 818def IN_2r : _F2R<0b101100, (outs GRRegs:$dst), (ins GRRegs:$r), 819 "in $dst, res[$r]", 820 [(set GRRegs:$dst, (int_xcore_in GRRegs:$r))]>; 821 822let Constraints = "$src = $dst" in 823def INSHR_2r : 824 _F2RSrcDst<0b101101, (outs GRRegs:$dst), (ins GRRegs:$src, GRRegs:$r), 825 "inshr $dst, res[$r]", 826 [(set GRRegs:$dst, (int_xcore_inshr GRRegs:$r, GRRegs:$src))]>; 827 828def CHKCT_2r : _F2R<0b110010, (outs), (ins GRRegs:$r, GRRegs:$val), 829 "chkct res[$r], $val", 830 [(int_xcore_chkct GRRegs:$r, GRRegs:$val)]>; 831 832def CHKCT_rus : _FRUSBitp<0b110011, (outs), (ins GRRegs:$r, i32imm:$val), 833 "chkct res[$r], $val", 834 [(int_xcore_chkct GRRegs:$r, immUs:$val)]>; 835 836def TESTCT_2r : _F2R<0b101111, (outs GRRegs:$dst), (ins GRRegs:$src), 837 "testct $dst, res[$src]", 838 [(set GRRegs:$dst, (int_xcore_testct GRRegs:$src))]>; 839 840def TESTWCT_2r : _F2R<0b110001, (outs GRRegs:$dst), (ins GRRegs:$src), 841 "testwct $dst, res[$src]", 842 [(set GRRegs:$dst, (int_xcore_testwct GRRegs:$src))]>; 843 844def SETD_2r : _FR2R<0b000101, (outs), (ins GRRegs:$r, GRRegs:$val), 845 "setd res[$r], $val", 846 [(int_xcore_setd GRRegs:$r, GRRegs:$val)]>; 847 848def SETPSC_2r : _FR2R<0b110000, (outs), (ins GRRegs:$src1, GRRegs:$src2), 849 "setpsc res[$src1], $src2", 850 [(int_xcore_setpsc GRRegs:$src1, GRRegs:$src2)]>; 851 852def GETST_2r : _F2R<0b000001, (outs GRRegs:$dst), (ins GRRegs:$r), 853 "getst $dst, res[$r]", 854 [(set GRRegs:$dst, (int_xcore_getst GRRegs:$r))]>; 855 856def INITSP_2r : _F2R<0b000100, (outs), (ins GRRegs:$src, GRRegs:$t), 857 "init t[$t]:sp, $src", 858 [(int_xcore_initsp GRRegs:$t, GRRegs:$src)]>; 859 860def INITPC_2r : _F2R<0b000000, (outs), (ins GRRegs:$src, GRRegs:$t), 861 "init t[$t]:pc, $src", 862 [(int_xcore_initpc GRRegs:$t, GRRegs:$src)]>; 863 864def INITCP_2r : _F2R<0b000110, (outs), (ins GRRegs:$src, GRRegs:$t), 865 "init t[$t]:cp, $src", 866 [(int_xcore_initcp GRRegs:$t, GRRegs:$src)]>; 867 868def INITDP_2r : _F2R<0b000010, (outs), (ins GRRegs:$src, GRRegs:$t), 869 "init t[$t]:dp, $src", 870 [(int_xcore_initdp GRRegs:$t, GRRegs:$src)]>; 871 872def PEEK_2r : _F2R<0b101110, (outs GRRegs:$dst), (ins GRRegs:$src), 873 "peek $dst, res[$src]", 874 [(set GRRegs:$dst, (int_xcore_peek GRRegs:$src))]>; 875 876def ENDIN_2r : _F2R<0b100101, (outs GRRegs:$dst), (ins GRRegs:$src), 877 "endin $dst, res[$src]", 878 [(set GRRegs:$dst, (int_xcore_endin GRRegs:$src))]>; 879 880def EEF_2r : _F2R<0b001011, (outs), (ins GRRegs:$a, GRRegs:$b), 881 "eef $a, res[$b]", []>; 882 883def EET_2r : _F2R<0b001001, (outs), (ins GRRegs:$a, GRRegs:$b), 884 "eet $a, res[$b]", []>; 885 886def TSETMR_2r : _F2RImm<0b000111, (outs), (ins i32imm:$a, GRRegs:$b), 887 "tsetmr r$a, $b", []>; 888 889// Two operand long 890def BITREV_l2r : _FL2R<0b0000011000, (outs GRRegs:$dst), (ins GRRegs:$src), 891 "bitrev $dst, $src", 892 [(set GRRegs:$dst, (int_xcore_bitrev GRRegs:$src))]>; 893 894def BYTEREV_l2r : _FL2R<0b0000011001, (outs GRRegs:$dst), (ins GRRegs:$src), 895 "byterev $dst, $src", 896 [(set GRRegs:$dst, (bswap GRRegs:$src))]>; 897 898def CLZ_l2r : _FL2R<0b0000111000, (outs GRRegs:$dst), (ins GRRegs:$src), 899 "clz $dst, $src", 900 [(set GRRegs:$dst, (ctlz GRRegs:$src))]>; 901 902def GETD_l2r : _FL2R<0b0001111001, (outs GRRegs:$dst), (ins GRRegs:$src), 903 "getd $dst, res[$src]", []>; 904 905def GETN_l2r : _FL2R<0b0011011001, (outs GRRegs:$dst), (ins GRRegs:$src), 906 "getn $dst, res[$src]", []>; 907 908def SETC_l2r : _FL2R<0b0010111001, (outs), (ins GRRegs:$r, GRRegs:$val), 909 "setc res[$r], $val", 910 [(int_xcore_setc GRRegs:$r, GRRegs:$val)]>; 911 912def SETTW_l2r : _FLR2R<0b0010011001, (outs), (ins GRRegs:$r, GRRegs:$val), 913 "settw res[$r], $val", 914 [(int_xcore_settw GRRegs:$r, GRRegs:$val)]>; 915 916def GETPS_l2r : _FL2R<0b0001011001, (outs GRRegs:$dst), (ins GRRegs:$src), 917 "get $dst, ps[$src]", 918 [(set GRRegs:$dst, (int_xcore_getps GRRegs:$src))]>; 919 920def SETPS_l2r : _FLR2R<0b0001111000, (outs), (ins GRRegs:$src1, GRRegs:$src2), 921 "set ps[$src1], $src2", 922 [(int_xcore_setps GRRegs:$src1, GRRegs:$src2)]>; 923 924def INITLR_l2r : _FL2R<0b0001011000, (outs), (ins GRRegs:$src, GRRegs:$t), 925 "init t[$t]:lr, $src", 926 [(int_xcore_initlr GRRegs:$t, GRRegs:$src)]>; 927 928def SETCLK_l2r : _FLR2R<0b0000111001, (outs), (ins GRRegs:$src1, GRRegs:$src2), 929 "setclk res[$src1], $src2", 930 [(int_xcore_setclk GRRegs:$src1, GRRegs:$src2)]>; 931 932def SETN_l2r : _FLR2R<0b0011011000, (outs), (ins GRRegs:$src1, GRRegs:$src2), 933 "setn res[$src1], $src2", []>; 934 935def SETRDY_l2r : _FLR2R<0b0010111000, (outs), (ins GRRegs:$src1, GRRegs:$src2), 936 "setrdy res[$src1], $src2", 937 [(int_xcore_setrdy GRRegs:$src1, GRRegs:$src2)]>; 938 939def TESTLCL_l2r : _FL2R<0b0010011000, (outs GRRegs:$dst), (ins GRRegs:$src), 940 "testlcl $dst, res[$src]", []>; 941 942// One operand short 943def MSYNC_1r : _F1R<0b000111, (outs), (ins GRRegs:$a), 944 "msync res[$a]", 945 [(int_xcore_msync GRRegs:$a)]>; 946def MJOIN_1r : _F1R<0b000101, (outs), (ins GRRegs:$a), 947 "mjoin res[$a]", 948 [(int_xcore_mjoin GRRegs:$a)]>; 949 950let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1 in 951def BAU_1r : _F1R<0b001001, (outs), (ins GRRegs:$a), 952 "bau $a", 953 [(brind GRRegs:$a)]>; 954 955let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1 in 956def BR_JT : PseudoInstXCore<(outs), (ins InlineJT:$t, GRRegs:$i), 957 "bru $i\n$t", 958 [(XCoreBR_JT tjumptable:$t, GRRegs:$i)]>; 959 960let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1 in 961def BR_JT32 : PseudoInstXCore<(outs), (ins InlineJT32:$t, GRRegs:$i), 962 "bru $i\n$t", 963 [(XCoreBR_JT32 tjumptable:$t, GRRegs:$i)]>; 964 965let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1 in 966def BRU_1r : _F1R<0b001010, (outs), (ins GRRegs:$a), "bru $a", []>; 967 968let Defs=[SP], hasSideEffects=0 in 969def SETSP_1r : _F1R<0b001011, (outs), (ins GRRegs:$a), "set sp, $a", []>; 970 971let hasSideEffects=0 in 972def SETDP_1r : _F1R<0b001100, (outs), (ins GRRegs:$a), "set dp, $a", []>; 973 974let hasSideEffects=0 in 975def SETCP_1r : _F1R<0b001101, (outs), (ins GRRegs:$a), "set cp, $a", []>; 976 977let hasCtrlDep = 1 in 978def ECALLT_1r : _F1R<0b010011, (outs), (ins GRRegs:$a), 979 "ecallt $a", 980 []>; 981 982let hasCtrlDep = 1 in 983def ECALLF_1r : _F1R<0b010010, (outs), (ins GRRegs:$a), 984 "ecallf $a", 985 []>; 986 987let isCall=1, 988// All calls clobber the link register and the non-callee-saved registers: 989Defs = [R0, R1, R2, R3, R11, LR], Uses = [SP] in { 990def BLA_1r : _F1R<0b001000, (outs), (ins GRRegs:$a), 991 "bla $a", 992 [(XCoreBranchLink GRRegs:$a)]>; 993} 994 995def SYNCR_1r : _F1R<0b100001, (outs), (ins GRRegs:$a), 996 "syncr res[$a]", 997 [(int_xcore_syncr GRRegs:$a)]>; 998 999def FREER_1r : _F1R<0b000100, (outs), (ins GRRegs:$a), 1000 "freer res[$a]", 1001 [(int_xcore_freer GRRegs:$a)]>; 1002 1003let Uses=[R11] in { 1004def SETV_1r : _F1R<0b010001, (outs), (ins GRRegs:$a), 1005 "setv res[$a], r11", 1006 [(int_xcore_setv GRRegs:$a, R11)]>; 1007 1008def SETEV_1r : _F1R<0b001111, (outs), (ins GRRegs:$a), 1009 "setev res[$a], r11", 1010 [(int_xcore_setev GRRegs:$a, R11)]>; 1011} 1012 1013def DGETREG_1r : _F1R<0b001110, (outs GRRegs:$a), (ins), "dgetreg $a", []>; 1014 1015def EDU_1r : _F1R<0b000000, (outs), (ins GRRegs:$a), "edu res[$a]", 1016 [(int_xcore_edu GRRegs:$a)]>; 1017 1018def EEU_1r : _F1R<0b000001, (outs), (ins GRRegs:$a), 1019 "eeu res[$a]", 1020 [(int_xcore_eeu GRRegs:$a)]>; 1021 1022def KCALL_1r : _F1R<0b010000, (outs), (ins GRRegs:$a), "kcall $a", []>; 1023 1024def WAITEF_1R : _F1R<0b000011, (outs), (ins GRRegs:$a), "waitef $a", []>; 1025 1026def WAITET_1R : _F1R<0b000010, (outs), (ins GRRegs:$a), "waitet $a", []>; 1027 1028def TSTART_1R : _F1R<0b000110, (outs), (ins GRRegs:$a), "start t[$a]", []>; 1029 1030def CLRPT_1R : _F1R<0b100000, (outs), (ins GRRegs:$a), "clrpt res[$a]", 1031 [(int_xcore_clrpt GRRegs:$a)]>; 1032 1033// Zero operand short 1034 1035def CLRE_0R : _F0R<0b0000001101, (outs), (ins), "clre", [(int_xcore_clre)]>; 1036 1037def DCALL_0R : _F0R<0b0000011100, (outs), (ins), "dcall", []>; 1038 1039let Defs = [SP], Uses = [SP] in 1040def DENTSP_0R : _F0R<0b0001001100, (outs), (ins), "dentsp", []>; 1041 1042let Defs = [SP] in 1043def DRESTSP_0R : _F0R<0b0001001101, (outs), (ins), "drestsp", []>; 1044 1045def DRET_0R : _F0R<0b0000011110, (outs), (ins), "dret", []>; 1046 1047def FREET_0R : _F0R<0b0000001111, (outs), (ins), "freet", []>; 1048 1049let Defs = [R11] in { 1050def GETID_0R : _F0R<0b0001001110, (outs), (ins), 1051 "get r11, id", 1052 [(set R11, (int_xcore_getid))]>; 1053 1054def GETED_0R : _F0R<0b0000111110, (outs), (ins), 1055 "get r11, ed", 1056 [(set R11, (int_xcore_geted))]>; 1057 1058def GETET_0R : _F0R<0b0000111111, (outs), (ins), 1059 "get r11, et", 1060 [(set R11, (int_xcore_getet))]>; 1061 1062def GETKEP_0R : _F0R<0b0001001111, (outs), (ins), 1063 "get r11, kep", []>; 1064 1065def GETKSP_0R : _F0R<0b0001011100, (outs), (ins), 1066 "get r11, ksp", []>; 1067} 1068 1069let Defs = [SP] in 1070def KRET_0R : _F0R<0b0000011101, (outs), (ins), "kret", []>; 1071 1072let Uses = [SP], mayLoad = 1 in { 1073def LDET_0R : _F0R<0b0001011110, (outs), (ins), "ldw et, sp[4]", []>; 1074 1075def LDSED_0R : _F0R<0b0001011101, (outs), (ins), "ldw sed, sp[3]", []>; 1076 1077def LDSPC_0R : _F0R<0b0000101100, (outs), (ins), "ldw spc, sp[1]", []>; 1078 1079def LDSSR_0R : _F0R<0b0000101110, (outs), (ins), "ldw ssr, sp[2]", []>; 1080} 1081 1082let Uses=[R11] in 1083def SETKEP_0R : _F0R<0b0000011111, (outs), (ins), "set kep, r11", []>; 1084 1085def SSYNC_0r : _F0R<0b0000001110, (outs), (ins), 1086 "ssync", 1087 [(int_xcore_ssync)]>; 1088 1089let Uses = [SP], mayStore = 1 in { 1090def STET_0R : _F0R<0b0000111101, (outs), (ins), "stw et, sp[4]", []>; 1091 1092def STSED_0R : _F0R<0b0000111100, (outs), (ins), "stw sed, sp[3]", []>; 1093 1094def STSPC_0R : _F0R<0b0000101101, (outs), (ins), "stw spc, sp[1]", []>; 1095 1096def STSSR_0R : _F0R<0b0000101111, (outs), (ins), "stw ssr, sp[2]", []>; 1097} 1098 1099let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1, 1100 hasSideEffects = 1 in 1101def WAITEU_0R : _F0R<0b0000001100, (outs), (ins), 1102 "waiteu", 1103 [(brind (int_xcore_waitevent))]>; 1104 1105//===----------------------------------------------------------------------===// 1106// Non-Instruction Patterns 1107//===----------------------------------------------------------------------===// 1108 1109def : Pat<(XCoreBranchLink texternalsym:$addr), (BLRF_lu10 texternalsym:$addr)>; 1110 1111/// sext_inreg 1112def : Pat<(sext_inreg GRRegs:$b, i1), (SEXT_rus GRRegs:$b, 1)>; 1113def : Pat<(sext_inreg GRRegs:$b, i8), (SEXT_rus GRRegs:$b, 8)>; 1114def : Pat<(sext_inreg GRRegs:$b, i16), (SEXT_rus GRRegs:$b, 16)>; 1115 1116/// loads 1117def : Pat<(zextloadi8 (add GRRegs:$addr, GRRegs:$offset)), 1118 (LD8U_3r GRRegs:$addr, GRRegs:$offset)>; 1119def : Pat<(zextloadi8 GRRegs:$addr), (LD8U_3r GRRegs:$addr, (LDC_ru6 0))>; 1120 1121def : Pat<(sextloadi16 (lda16f GRRegs:$addr, GRRegs:$offset)), 1122 (LD16S_3r GRRegs:$addr, GRRegs:$offset)>; 1123def : Pat<(sextloadi16 GRRegs:$addr), (LD16S_3r GRRegs:$addr, (LDC_ru6 0))>; 1124 1125def : Pat<(load (ldawf GRRegs:$addr, GRRegs:$offset)), 1126 (LDW_3r GRRegs:$addr, GRRegs:$offset)>; 1127def : Pat<(load (add GRRegs:$addr, immUs4:$offset)), 1128 (LDW_2rus GRRegs:$addr, (div4_xform immUs4:$offset))>; 1129def : Pat<(load GRRegs:$addr), (LDW_2rus GRRegs:$addr, 0)>; 1130 1131/// anyext 1132def : Pat<(extloadi8 (add GRRegs:$addr, GRRegs:$offset)), 1133 (LD8U_3r GRRegs:$addr, GRRegs:$offset)>; 1134def : Pat<(extloadi8 GRRegs:$addr), (LD8U_3r GRRegs:$addr, (LDC_ru6 0))>; 1135def : Pat<(extloadi16 (lda16f GRRegs:$addr, GRRegs:$offset)), 1136 (LD16S_3r GRRegs:$addr, GRRegs:$offset)>; 1137def : Pat<(extloadi16 GRRegs:$addr), (LD16S_3r GRRegs:$addr, (LDC_ru6 0))>; 1138 1139/// stores 1140def : Pat<(truncstorei8 GRRegs:$val, (add GRRegs:$addr, GRRegs:$offset)), 1141 (ST8_l3r GRRegs:$val, GRRegs:$addr, GRRegs:$offset)>; 1142def : Pat<(truncstorei8 GRRegs:$val, GRRegs:$addr), 1143 (ST8_l3r GRRegs:$val, GRRegs:$addr, (LDC_ru6 0))>; 1144 1145def : Pat<(truncstorei16 GRRegs:$val, (lda16f GRRegs:$addr, GRRegs:$offset)), 1146 (ST16_l3r GRRegs:$val, GRRegs:$addr, GRRegs:$offset)>; 1147def : Pat<(truncstorei16 GRRegs:$val, GRRegs:$addr), 1148 (ST16_l3r GRRegs:$val, GRRegs:$addr, (LDC_ru6 0))>; 1149 1150def : Pat<(store GRRegs:$val, (ldawf GRRegs:$addr, GRRegs:$offset)), 1151 (STW_l3r GRRegs:$val, GRRegs:$addr, GRRegs:$offset)>; 1152def : Pat<(store GRRegs:$val, (add GRRegs:$addr, immUs4:$offset)), 1153 (STW_2rus GRRegs:$val, GRRegs:$addr, (div4_xform immUs4:$offset))>; 1154def : Pat<(store GRRegs:$val, GRRegs:$addr), 1155 (STW_2rus GRRegs:$val, GRRegs:$addr, 0)>; 1156 1157/// bitrev 1158def : Pat<(bitreverse GRRegs:$src), (BITREV_l2r GRRegs:$src)>; 1159 1160/// cttz 1161def : Pat<(cttz GRRegs:$src), (CLZ_l2r (BITREV_l2r GRRegs:$src))>; 1162 1163/// trap 1164def : Pat<(trap), (ECALLF_1r (LDC_ru6 0))>; 1165 1166/// 1167/// branch patterns 1168/// 1169 1170// unconditional branch 1171def : Pat<(br bb:$addr), (BRFU_lu6 bb:$addr)>; 1172 1173// direct match equal/notequal zero brcond 1174def : Pat<(brcond (setne GRRegs:$lhs, 0), bb:$dst), 1175 (BRFT_lru6 GRRegs:$lhs, bb:$dst)>; 1176def : Pat<(brcond (seteq GRRegs:$lhs, 0), bb:$dst), 1177 (BRFF_lru6 GRRegs:$lhs, bb:$dst)>; 1178 1179def : Pat<(brcond (setle GRRegs:$lhs, GRRegs:$rhs), bb:$dst), 1180 (BRFF_lru6 (LSS_3r GRRegs:$rhs, GRRegs:$lhs), bb:$dst)>; 1181def : Pat<(brcond (setule GRRegs:$lhs, GRRegs:$rhs), bb:$dst), 1182 (BRFF_lru6 (LSU_3r GRRegs:$rhs, GRRegs:$lhs), bb:$dst)>; 1183def : Pat<(brcond (setge GRRegs:$lhs, GRRegs:$rhs), bb:$dst), 1184 (BRFF_lru6 (LSS_3r GRRegs:$lhs, GRRegs:$rhs), bb:$dst)>; 1185def : Pat<(brcond (setuge GRRegs:$lhs, GRRegs:$rhs), bb:$dst), 1186 (BRFF_lru6 (LSU_3r GRRegs:$lhs, GRRegs:$rhs), bb:$dst)>; 1187def : Pat<(brcond (setne GRRegs:$lhs, GRRegs:$rhs), bb:$dst), 1188 (BRFF_lru6 (EQ_3r GRRegs:$lhs, GRRegs:$rhs), bb:$dst)>; 1189def : Pat<(brcond (setne GRRegs:$lhs, immUs:$rhs), bb:$dst), 1190 (BRFF_lru6 (EQ_2rus GRRegs:$lhs, immUs:$rhs), bb:$dst)>; 1191 1192// generic brcond pattern 1193def : Pat<(brcond GRRegs:$cond, bb:$addr), (BRFT_lru6 GRRegs:$cond, bb:$addr)>; 1194 1195 1196/// 1197/// Select patterns 1198/// 1199 1200// direct match equal/notequal zero select 1201def : Pat<(select (setne GRRegs:$lhs, 0), GRRegs:$T, GRRegs:$F), 1202 (SELECT_CC GRRegs:$lhs, GRRegs:$T, GRRegs:$F)>; 1203 1204def : Pat<(select (seteq GRRegs:$lhs, 0), GRRegs:$T, GRRegs:$F), 1205 (SELECT_CC GRRegs:$lhs, GRRegs:$F, GRRegs:$T)>; 1206 1207def : Pat<(select (setle GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F), 1208 (SELECT_CC (LSS_3r GRRegs:$rhs, GRRegs:$lhs), GRRegs:$F, GRRegs:$T)>; 1209def : Pat<(select (setule GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F), 1210 (SELECT_CC (LSU_3r GRRegs:$rhs, GRRegs:$lhs), GRRegs:$F, GRRegs:$T)>; 1211def : Pat<(select (setge GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F), 1212 (SELECT_CC (LSS_3r GRRegs:$lhs, GRRegs:$rhs), GRRegs:$F, GRRegs:$T)>; 1213def : Pat<(select (setuge GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F), 1214 (SELECT_CC (LSU_3r GRRegs:$lhs, GRRegs:$rhs), GRRegs:$F, GRRegs:$T)>; 1215def : Pat<(select (setne GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F), 1216 (SELECT_CC (EQ_3r GRRegs:$lhs, GRRegs:$rhs), GRRegs:$F, GRRegs:$T)>; 1217def : Pat<(select (setne GRRegs:$lhs, immUs:$rhs), GRRegs:$T, GRRegs:$F), 1218 (SELECT_CC (EQ_2rus GRRegs:$lhs, immUs:$rhs), GRRegs:$F, GRRegs:$T)>; 1219 1220/// 1221/// setcc patterns, only matched when none of the above brcond 1222/// patterns match 1223/// 1224 1225// setcc 2 register operands 1226def : Pat<(setle GRRegs:$lhs, GRRegs:$rhs), 1227 (EQ_2rus (LSS_3r GRRegs:$rhs, GRRegs:$lhs), 0)>; 1228def : Pat<(setule GRRegs:$lhs, GRRegs:$rhs), 1229 (EQ_2rus (LSU_3r GRRegs:$rhs, GRRegs:$lhs), 0)>; 1230 1231def : Pat<(setgt GRRegs:$lhs, GRRegs:$rhs), 1232 (LSS_3r GRRegs:$rhs, GRRegs:$lhs)>; 1233def : Pat<(setugt GRRegs:$lhs, GRRegs:$rhs), 1234 (LSU_3r GRRegs:$rhs, GRRegs:$lhs)>; 1235 1236def : Pat<(setge GRRegs:$lhs, GRRegs:$rhs), 1237 (EQ_2rus (LSS_3r GRRegs:$lhs, GRRegs:$rhs), 0)>; 1238def : Pat<(setuge GRRegs:$lhs, GRRegs:$rhs), 1239 (EQ_2rus (LSU_3r GRRegs:$lhs, GRRegs:$rhs), 0)>; 1240 1241def : Pat<(setlt GRRegs:$lhs, GRRegs:$rhs), 1242 (LSS_3r GRRegs:$lhs, GRRegs:$rhs)>; 1243def : Pat<(setult GRRegs:$lhs, GRRegs:$rhs), 1244 (LSU_3r GRRegs:$lhs, GRRegs:$rhs)>; 1245 1246def : Pat<(setne GRRegs:$lhs, GRRegs:$rhs), 1247 (EQ_2rus (EQ_3r GRRegs:$lhs, GRRegs:$rhs), 0)>; 1248 1249def : Pat<(seteq GRRegs:$lhs, GRRegs:$rhs), 1250 (EQ_3r GRRegs:$lhs, GRRegs:$rhs)>; 1251 1252// setcc reg/imm operands 1253def : Pat<(seteq GRRegs:$lhs, immUs:$rhs), 1254 (EQ_2rus GRRegs:$lhs, immUs:$rhs)>; 1255def : Pat<(setne GRRegs:$lhs, immUs:$rhs), 1256 (EQ_2rus (EQ_2rus GRRegs:$lhs, immUs:$rhs), 0)>; 1257 1258// misc 1259def : Pat<(add GRRegs:$addr, immUs4:$offset), 1260 (LDAWF_l2rus GRRegs:$addr, (div4_xform immUs4:$offset))>; 1261 1262def : Pat<(sub GRRegs:$addr, immUs4:$offset), 1263 (LDAWB_l2rus GRRegs:$addr, (div4_xform immUs4:$offset))>; 1264 1265def : Pat<(and GRRegs:$val, immMskBitp:$mask), 1266 (ZEXT_rus GRRegs:$val, (msksize_xform immMskBitp:$mask))>; 1267 1268// (sub X, imm) gets canonicalized to (add X, -imm). Match this form. 1269def : Pat<(add GRRegs:$src1, immUsNeg:$src2), 1270 (SUB_2rus GRRegs:$src1, (neg_xform immUsNeg:$src2))>; 1271 1272def : Pat<(add GRRegs:$src1, immUs4Neg:$src2), 1273 (LDAWB_l2rus GRRegs:$src1, (div4neg_xform immUs4Neg:$src2))>; 1274 1275/// 1276/// Some peepholes 1277/// 1278 1279def : Pat<(mul GRRegs:$src, 3), 1280 (LDA16F_l3r GRRegs:$src, GRRegs:$src)>; 1281 1282def : Pat<(mul GRRegs:$src, 5), 1283 (LDAWF_l3r GRRegs:$src, GRRegs:$src)>; 1284 1285def : Pat<(mul GRRegs:$src, -3), 1286 (LDAWB_l3r GRRegs:$src, GRRegs:$src)>; 1287 1288// ashr X, 32 is equivalent to ashr X, 31 on the XCore. 1289def : Pat<(sra GRRegs:$src, 31), 1290 (ASHR_l2rus GRRegs:$src, 32)>; 1291 1292def : Pat<(brcond (setlt GRRegs:$lhs, 0), bb:$dst), 1293 (BRFT_lru6 (ASHR_l2rus GRRegs:$lhs, 32), bb:$dst)>; 1294 1295// setge X, 0 is canonicalized to setgt X, -1 1296def : Pat<(brcond (setgt GRRegs:$lhs, -1), bb:$dst), 1297 (BRFF_lru6 (ASHR_l2rus GRRegs:$lhs, 32), bb:$dst)>; 1298 1299def : Pat<(select (setlt GRRegs:$lhs, 0), GRRegs:$T, GRRegs:$F), 1300 (SELECT_CC (ASHR_l2rus GRRegs:$lhs, 32), GRRegs:$T, GRRegs:$F)>; 1301 1302def : Pat<(select (setgt GRRegs:$lhs, -1), GRRegs:$T, GRRegs:$F), 1303 (SELECT_CC (ASHR_l2rus GRRegs:$lhs, 32), GRRegs:$F, GRRegs:$T)>; 1304 1305def : Pat<(setgt GRRegs:$lhs, -1), 1306 (EQ_2rus (ASHR_l2rus GRRegs:$lhs, 32), 0)>; 1307 1308def : Pat<(sra (shl GRRegs:$src, immBpwSubBitp:$imm), immBpwSubBitp:$imm), 1309 (SEXT_rus GRRegs:$src, (bpwsub_xform immBpwSubBitp:$imm))>; 1310 1311def : Pat<(load (cprelwrapper tconstpool:$b)), 1312 (LDWCP_lru6 tconstpool:$b)>; 1313 1314def : Pat<(cprelwrapper tconstpool:$b), 1315 (LDAWCP_lu6 tconstpool:$b)>; 1316