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