1//===- BlackfinInstrInfo.td - Target Description for Blackfin Target ------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file describes the Blackfin instructions in TableGen format. 11// 12//===----------------------------------------------------------------------===// 13 14//===----------------------------------------------------------------------===// 15// Instruction format superclass 16//===----------------------------------------------------------------------===// 17 18include "BlackfinInstrFormats.td" 19 20// These are target-independent nodes, but have target-specific formats. 21def SDT_BfinCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>; 22def SDT_BfinCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, 23 SDTCisVT<1, i32> ]>; 24 25def BfinCallseqStart : SDNode<"ISD::CALLSEQ_START", SDT_BfinCallSeqStart, 26 [SDNPHasChain, SDNPOutGlue]>; 27def BfinCallseqEnd : SDNode<"ISD::CALLSEQ_END", SDT_BfinCallSeqEnd, 28 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 29 30def SDT_BfinCall : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>; 31def BfinCall : SDNode<"BFISD::CALL", SDT_BfinCall, 32 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 33 SDNPVariadic]>; 34 35def BfinRet: SDNode<"BFISD::RET_FLAG", SDTNone, 36 [SDNPHasChain, SDNPOptInGlue]>; 37 38def BfinWrapper: SDNode<"BFISD::Wrapper", SDTIntUnaryOp>; 39 40//===----------------------------------------------------------------------===// 41// Transformations 42//===----------------------------------------------------------------------===// 43 44def trailingZeros_xform : SDNodeXForm<imm, [{ 45 return CurDAG->getTargetConstant(N->getAPIntValue().countTrailingZeros(), 46 MVT::i32); 47}]>; 48 49def trailingOnes_xform : SDNodeXForm<imm, [{ 50 return CurDAG->getTargetConstant(N->getAPIntValue().countTrailingOnes(), 51 MVT::i32); 52}]>; 53 54def LO16 : SDNodeXForm<imm, [{ 55 return CurDAG->getTargetConstant((unsigned short)N->getZExtValue(), MVT::i16); 56}]>; 57 58def HI16 : SDNodeXForm<imm, [{ 59 // Transformation function: shift the immediate value down into the low bits. 60 return CurDAG->getTargetConstant((unsigned)N->getZExtValue() >> 16, MVT::i16); 61}]>; 62 63//===----------------------------------------------------------------------===// 64// Immediates 65//===----------------------------------------------------------------------===// 66 67def imm3 : PatLeaf<(imm), [{return isInt<3>(N->getSExtValue());}]>; 68def uimm3 : PatLeaf<(imm), [{return isUInt<3>(N->getZExtValue());}]>; 69def uimm4 : PatLeaf<(imm), [{return isUInt<4>(N->getZExtValue());}]>; 70def uimm5 : PatLeaf<(imm), [{return isUInt<5>(N->getZExtValue());}]>; 71 72def uimm5m2 : PatLeaf<(imm), [{ 73 uint64_t value = N->getZExtValue(); 74 return value % 2 == 0 && isUInt<5>(value); 75}]>; 76 77def uimm6m4 : PatLeaf<(imm), [{ 78 uint64_t value = N->getZExtValue(); 79 return value % 4 == 0 && isUInt<6>(value); 80}]>; 81 82def imm7 : PatLeaf<(imm), [{return isInt<7>(N->getSExtValue());}]>; 83def imm16 : PatLeaf<(imm), [{return isInt<16>(N->getSExtValue());}]>; 84def uimm16 : PatLeaf<(imm), [{return isUInt<16>(N->getZExtValue());}]>; 85 86def ximm16 : PatLeaf<(imm), [{ 87 int64_t value = N->getSExtValue(); 88 return value < (1<<16) && value >= -(1<<15); 89}]>; 90 91def imm17m2 : PatLeaf<(imm), [{ 92 int64_t value = N->getSExtValue(); 93 return value % 2 == 0 && isInt<17>(value); 94}]>; 95 96def imm18m4 : PatLeaf<(imm), [{ 97 int64_t value = N->getSExtValue(); 98 return value % 4 == 0 && isInt<18>(value); 99}]>; 100 101// 32-bit bitmask transformed to a bit number 102def uimm5mask : Operand<i32>, PatLeaf<(imm), [{ 103 return isPowerOf2_32(N->getZExtValue()); 104}], trailingZeros_xform>; 105 106// 32-bit inverse bitmask transformed to a bit number 107def uimm5imask : Operand<i32>, PatLeaf<(imm), [{ 108 return isPowerOf2_32(~N->getZExtValue()); 109}], trailingOnes_xform>; 110 111//===----------------------------------------------------------------------===// 112// Operands 113//===----------------------------------------------------------------------===// 114 115def calltarget : Operand<iPTR>; 116 117def brtarget : Operand<OtherVT>; 118 119// Addressing modes 120def ADDRspii : ComplexPattern<i32, 2, "SelectADDRspii", [add, frameindex], []>; 121 122// Address operands 123def MEMii : Operand<i32> { 124 let PrintMethod = "printMemoryOperand"; 125 let MIOperandInfo = (ops i32imm, i32imm); 126} 127 128//===----------------------------------------------------------------------===// 129// Instructions 130//===----------------------------------------------------------------------===// 131 132// Pseudo instructions. 133class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern> 134 : InstBfin<outs, ins, asmstr, pattern>; 135 136let Defs = [SP], Uses = [SP] in { 137def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt), 138 "${:comment}ADJCALLSTACKDOWN $amt", 139 [(BfinCallseqStart timm:$amt)]>; 140def ADJCALLSTACKUP : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), 141 "${:comment}ADJCALLSTACKUP $amt1 $amt2", 142 [(BfinCallseqEnd timm:$amt1, timm:$amt2)]>; 143} 144 145//===----------------------------------------------------------------------===// 146// Table C-9. Program Flow Control Instructions 147//===----------------------------------------------------------------------===// 148 149let isBranch = 1, isTerminator = 1 in { 150 151let isIndirectBranch = 1 in 152def JUMPp : F1<(outs), (ins P:$target), 153 "JUMP ($target);", 154 [(brind P:$target)]>; 155 156// TODO JUMP (PC-P) 157 158// NOTE: assembler chooses between JUMP.S and JUMP.L 159def JUMPa : F1<(outs), (ins brtarget:$target), 160 "jump $target;", 161 [(br bb:$target)]>; 162 163def JUMPcc : F1<(outs), (ins AnyCC:$cc, brtarget:$target), 164 "if $cc jump $target;", 165 [(brcond AnyCC:$cc, bb:$target)]>; 166} 167 168let isCall = 1, 169 Defs = [R0, R1, R2, R3, P0, P1, P2, LB0, LB1, LC0, LC1, RETS, ASTAT] in { 170def CALLa: F1<(outs), (ins calltarget:$func, variable_ops), 171 "call $func;", []>; 172def CALLp: F1<(outs), (ins P:$func, variable_ops), 173 "call ($func);", [(BfinCall P:$func)]>; 174} 175 176let isReturn = 1, 177 isTerminator = 1, 178 isBarrier = 1, 179 Uses = [RETS] in 180def RTS: F1<(outs), (ins), "rts;", [(BfinRet)]>; 181 182//===----------------------------------------------------------------------===// 183// Table C-10. Load / Store Instructions 184//===----------------------------------------------------------------------===// 185 186// Immediate constant loads 187 188// sext immediate, i32 D/P regs 189def LOADimm7: F1<(outs DP:$dst), (ins i32imm:$src), 190 "$dst = $src (x);", 191 [(set DP:$dst, imm7:$src)]>; 192 193// zext immediate, i32 reg groups 0-3 194def LOADuimm16: F2<(outs GR:$dst), (ins i32imm:$src), 195 "$dst = $src (z);", 196 [(set GR:$dst, uimm16:$src)]>; 197 198// sext immediate, i32 reg groups 0-3 199def LOADimm16: F2<(outs GR:$dst), (ins i32imm:$src), 200 "$dst = $src (x);", 201 [(set GR:$dst, imm16:$src)]>; 202 203// Pseudo-instruction for loading a general 32-bit constant. 204def LOAD32imm: Pseudo<(outs GR:$dst), (ins i32imm:$src), 205 "$dst.h = ($src >> 16); $dst.l = ($src & 0xffff);", 206 [(set GR:$dst, imm:$src)]>; 207 208def LOAD32sym: Pseudo<(outs GR:$dst), (ins i32imm:$src), 209 "$dst.h = $src; $dst.l = $src;", []>; 210 211 212// 16-bit immediate, i16 reg groups 0-3 213def LOAD16i: F2<(outs GR16:$dst), (ins i16imm:$src), 214 "$dst = $src;", []>; 215 216def : Pat<(BfinWrapper (i32 tglobaladdr:$addr)), 217 (LOAD32sym tglobaladdr:$addr)>; 218 219def : Pat<(BfinWrapper (i32 tjumptable:$addr)), 220 (LOAD32sym tjumptable:$addr)>; 221 222// We cannot copy from GR16 to D16, and codegen wants to insert copies if we 223// emit GR16 instructions. As a hack, we use this fake instruction instead. 224def LOAD16i_d16: F2<(outs D16:$dst), (ins i16imm:$src), 225 "$dst = $src;", 226 [(set D16:$dst, ximm16:$src)]>; 227 228// Memory loads with patterns 229 230def LOAD32p: F1<(outs DP:$dst), (ins P:$ptr), 231 "$dst = [$ptr];", 232 [(set DP:$dst, (load P:$ptr))]>; 233 234// Pseudo-instruction for loading a stack slot 235def LOAD32fi: Pseudo<(outs DP:$dst), (ins MEMii:$mem), 236 "${:comment}FI $dst = [$mem];", 237 [(set DP:$dst, (load ADDRspii:$mem))]>; 238 239// Note: Expands to multiple insns 240def LOAD16fi: Pseudo<(outs D16:$dst), (ins MEMii:$mem), 241 "${:comment}FI $dst = [$mem];", 242 [(set D16:$dst, (load ADDRspii:$mem))]>; 243 244// Pseudo-instruction for loading a stack slot, used for AnyCC regs. 245// Replaced with Load D + CC=D 246def LOAD8fi: Pseudo<(outs AnyCC:$dst), (ins MEMii:$mem), 247 "${:comment}FI $dst = B[$mem];", 248 [(set AnyCC:$dst, (load ADDRspii:$mem))]>; 249 250def LOAD32p_uimm6m4: F1<(outs DP:$dst), (ins P:$ptr, i32imm:$off), 251 "$dst = [$ptr + $off];", 252 [(set DP:$dst, (load (add P:$ptr, uimm6m4:$off)))]>; 253 254def LOAD32p_imm18m4: F2<(outs DP:$dst), (ins P:$ptr, i32imm:$off), 255 "$dst = [$ptr + $off];", 256 [(set DP:$dst, (load (add P:$ptr, imm18m4:$off)))]>; 257 258def LOAD32p_16z: F1<(outs D:$dst), (ins P:$ptr), 259 "$dst = W[$ptr] (z);", 260 [(set D:$dst, (zextloadi16 P:$ptr))]>; 261 262def : Pat<(i32 (extloadi16 P:$ptr)),(LOAD32p_16z P:$ptr)>; 263 264def LOAD32p_uimm5m2_16z: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off), 265 "$dst = w[$ptr + $off] (z);", 266 [(set D:$dst, (zextloadi16 (add P:$ptr, 267 uimm5m2:$off)))]>; 268 269def : Pat<(i32 (extloadi16 (add P:$ptr, uimm5m2:$off))), 270 (LOAD32p_uimm5m2_16z P:$ptr, imm:$off)>; 271 272def LOAD32p_imm17m2_16z: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off), 273 "$dst = w[$ptr + $off] (z);", 274 [(set D:$dst, 275 (zextloadi16 (add P:$ptr, imm17m2:$off)))]>; 276 277def : Pat<(i32 (extloadi16 (add P:$ptr, imm17m2:$off))), 278 (LOAD32p_imm17m2_16z P:$ptr, imm:$off)>; 279 280def LOAD32p_16s: F1<(outs D:$dst), (ins P:$ptr), 281 "$dst = w[$ptr] (x);", 282 [(set D:$dst, (sextloadi16 P:$ptr))]>; 283 284def LOAD32p_uimm5m2_16s: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off), 285 "$dst = w[$ptr + $off] (x);", 286 [(set D:$dst, 287 (sextloadi16 (add P:$ptr, uimm5m2:$off)))]>; 288 289def LOAD32p_imm17m2_16s: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off), 290 "$dst = w[$ptr + $off] (x);", 291 [(set D:$dst, 292 (sextloadi16 (add P:$ptr, imm17m2:$off)))]>; 293 294def LOAD16pi: F1<(outs D16:$dst), (ins PI:$ptr), 295 "$dst = w[$ptr];", 296 [(set D16:$dst, (load PI:$ptr))]>; 297 298def LOAD32p_8z: F1<(outs D:$dst), (ins P:$ptr), 299 "$dst = B[$ptr] (z);", 300 [(set D:$dst, (zextloadi8 P:$ptr))]>; 301 302def : Pat<(i32 (extloadi8 P:$ptr)), (LOAD32p_8z P:$ptr)>; 303def : Pat<(i16 (extloadi8 P:$ptr)), 304 (EXTRACT_SUBREG (LOAD32p_8z P:$ptr), lo16)>; 305def : Pat<(i16 (zextloadi8 P:$ptr)), 306 (EXTRACT_SUBREG (LOAD32p_8z P:$ptr), lo16)>; 307 308def LOAD32p_imm16_8z: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off), 309 "$dst = b[$ptr + $off] (z);", 310 [(set D:$dst, (zextloadi8 (add P:$ptr, imm16:$off)))]>; 311 312def : Pat<(i32 (extloadi8 (add P:$ptr, imm16:$off))), 313 (LOAD32p_imm16_8z P:$ptr, imm:$off)>; 314def : Pat<(i16 (extloadi8 (add P:$ptr, imm16:$off))), 315 (EXTRACT_SUBREG (LOAD32p_imm16_8z P:$ptr, imm:$off), 316 lo16)>; 317def : Pat<(i16 (zextloadi8 (add P:$ptr, imm16:$off))), 318 (EXTRACT_SUBREG (LOAD32p_imm16_8z P:$ptr, imm:$off), 319 lo16)>; 320 321def LOAD32p_8s: F1<(outs D:$dst), (ins P:$ptr), 322 "$dst = b[$ptr] (x);", 323 [(set D:$dst, (sextloadi8 P:$ptr))]>; 324 325def : Pat<(i16 (sextloadi8 P:$ptr)), 326 (EXTRACT_SUBREG (LOAD32p_8s P:$ptr), lo16)>; 327 328def LOAD32p_imm16_8s: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off), 329 "$dst = b[$ptr + $off] (x);", 330 [(set D:$dst, (sextloadi8 (add P:$ptr, imm16:$off)))]>; 331 332def : Pat<(i16 (sextloadi8 (add P:$ptr, imm16:$off))), 333 (EXTRACT_SUBREG (LOAD32p_imm16_8s P:$ptr, imm:$off), 334 lo16)>; 335// Memory loads without patterns 336 337let mayLoad = 1 in { 338 339multiclass LOAD_incdec<RegisterClass drc, RegisterClass prc, 340 string mem="", string suf=";"> { 341 def _inc : F1<(outs drc:$dst, prc:$ptr_wb), (ins prc:$ptr), 342 !strconcat(!subst("M", mem, "$dst = M[$ptr++]"), suf), []>; 343 def _dec : F1<(outs drc:$dst, prc:$ptr_wb), (ins prc:$ptr), 344 !strconcat(!subst("M", mem, "$dst = M[$ptr--]"), suf), []>; 345} 346multiclass LOAD_incdecpost<RegisterClass drc, RegisterClass prc, 347 string mem="", string suf=";"> 348 : LOAD_incdec<drc, prc, mem, suf> { 349 def _post : F1<(outs drc:$dst, prc:$ptr_wb), (ins prc:$ptr, prc:$off), 350 !strconcat(!subst("M", mem, "$dst = M[$ptr++$off]"), suf), []>; 351} 352 353defm LOAD32p: LOAD_incdec<DP, P>; 354defm LOAD32i: LOAD_incdec<D, I>; 355defm LOAD8z32p: LOAD_incdec<D, P, "b", " (z);">; 356defm LOAD8s32p: LOAD_incdec<D, P, "b", " (x);">; 357defm LOADhi: LOAD_incdec<D16, I, "w">; 358defm LOAD16z32p: LOAD_incdecpost<D, P, "w", " (z);">; 359defm LOAD16s32p: LOAD_incdecpost<D, P, "w", " (x);">; 360 361def LOAD32p_post: F1<(outs D:$dst, P:$ptr_wb), (ins P:$ptr, P:$off), 362 "$dst = [$ptr ++ $off];", []>; 363 364// Note: $fp MUST be FP 365def LOAD32fp_nimm7m4: F1<(outs DP:$dst), (ins P:$fp, i32imm:$off), 366 "$dst = [$fp - $off];", []>; 367 368def LOAD32i: F1<(outs D:$dst), (ins I:$ptr), 369 "$dst = [$ptr];", []>; 370def LOAD32i_post: F1<(outs D:$dst, I:$ptr_wb), (ins I:$ptr, M:$off), 371 "$dst = [$ptr ++ $off];", []>; 372 373 374 375def LOADhp_post: F1<(outs D16:$dst, P:$ptr_wb), (ins P:$ptr, P:$off), 376 "$dst = w[$ptr ++ $off];", []>; 377 378 379} 380 381// Memory stores with patterns 382def STORE32p: F1<(outs), (ins DP:$val, P:$ptr), 383 "[$ptr] = $val;", 384 [(store DP:$val, P:$ptr)]>; 385 386// Pseudo-instructions for storing to a stack slot 387def STORE32fi: Pseudo<(outs), (ins DP:$val, MEMii:$mem), 388 "${:comment}FI [$mem] = $val;", 389 [(store DP:$val, ADDRspii:$mem)]>; 390 391// Note: This stack-storing pseudo-instruction is expanded to multiple insns 392def STORE16fi: Pseudo<(outs), (ins D16:$val, MEMii:$mem), 393 "${:comment}FI [$mem] = $val;", 394 [(store D16:$val, ADDRspii:$mem)]>; 395 396// Pseudo-instructions for storing AnyCC register to a stack slot. 397// Replaced with D=CC + STORE byte 398def STORE8fi: Pseudo<(outs), (ins AnyCC:$val, MEMii:$mem), 399 "${:comment}FI b[$mem] = $val;", 400 [(store AnyCC:$val, ADDRspii:$mem)]>; 401 402def STORE32p_uimm6m4: F1<(outs), (ins DP:$val, P:$ptr, i32imm:$off), 403 "[$ptr + $off] = $val;", 404 [(store DP:$val, (add P:$ptr, uimm6m4:$off))]>; 405 406def STORE32p_imm18m4: F1<(outs), (ins DP:$val, P:$ptr, i32imm:$off), 407 "[$ptr + $off] = $val;", 408 [(store DP:$val, (add P:$ptr, imm18m4:$off))]>; 409 410def STORE16pi: F1<(outs), (ins D16:$val, PI:$ptr), 411 "w[$ptr] = $val;", 412 [(store D16:$val, PI:$ptr)]>; 413 414def STORE8p: F1<(outs), (ins D:$val, P:$ptr), 415 "b[$ptr] = $val;", 416 [(truncstorei8 D:$val, P:$ptr)]>; 417 418def STORE8p_imm16: F1<(outs), (ins D:$val, P:$ptr, i32imm:$off), 419 "b[$ptr + $off] = $val;", 420 [(truncstorei8 D:$val, (add P:$ptr, imm16:$off))]>; 421 422let Constraints = "$ptr = $ptr_wb" in { 423 424multiclass STORE_incdec<RegisterClass drc, RegisterClass prc, 425 int off=4, string pre=""> { 426 def _inc : F1<(outs prc:$ptr_wb), (ins drc:$val, prc:$ptr), 427 !strconcat(pre, "[$ptr++] = $val;"), 428 [(set prc:$ptr_wb, (post_store drc:$val, prc:$ptr, off))]>; 429 def _dec : F1<(outs prc:$ptr_wb), (ins drc:$val, prc:$ptr), 430 !strconcat(pre, "[$ptr--] = $val;"), 431 [(set prc:$ptr_wb, (post_store drc:$val, prc:$ptr, 432 (ineg off)))]>; 433} 434 435defm STORE32p: STORE_incdec<DP, P>; 436defm STORE16i: STORE_incdec<D16, I, 2, "w">; 437defm STORE8p: STORE_incdec<D, P, 1, "b">; 438 439def STORE32p_post: F1<(outs P:$ptr_wb), (ins D:$val, P:$ptr, P:$off), 440 "[$ptr ++ $off] = $val;", 441 [(set P:$ptr_wb, (post_store D:$val, P:$ptr, P:$off))]>; 442 443def STORE16p_post: F1<(outs P:$ptr_wb), (ins D16:$val, P:$ptr, P:$off), 444 "w[$ptr ++ $off] = $val;", 445 [(set P:$ptr_wb, (post_store D16:$val, P:$ptr, P:$off))]>; 446} 447 448// Memory stores without patterns 449 450let mayStore = 1 in { 451 452// Note: only works for $fp == FP 453def STORE32fp_nimm7m4: F1<(outs), (ins DP:$val, P:$fp, i32imm:$off), 454 "[$fp - $off] = $val;", []>; 455 456def STORE32i: F1<(outs), (ins D:$val, I:$ptr), 457 "[$ptr] = $val;", []>; 458 459def STORE32i_inc: F1<(outs I:$ptr_wb), (ins D:$val, I:$ptr), 460 "[$ptr++] = $val;", []>; 461 462def STORE32i_dec: F1<(outs I:$ptr_wb), (ins D:$val, I:$ptr), 463 "[$ptr--] = $val;", []>; 464 465def STORE32i_post: F1<(outs I:$ptr_wb), (ins D:$val, I:$ptr, M:$off), 466 "[$ptr ++ $off] = $val;", []>; 467} 468 469def : Pat<(truncstorei16 D:$val, PI:$ptr), 470 (STORE16pi (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS D:$val, D)), 471 lo16), PI:$ptr)>; 472 473def : Pat<(truncstorei16 (srl D:$val, (i16 16)), PI:$ptr), 474 (STORE16pi (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS D:$val, D)), 475 hi16), PI:$ptr)>; 476 477def : Pat<(truncstorei8 D16L:$val, P:$ptr), 478 (STORE8p (INSERT_SUBREG (i32 (IMPLICIT_DEF)), 479 (i16 (COPY_TO_REGCLASS D16L:$val, D16L)), 480 lo16), 481 P:$ptr)>; 482 483//===----------------------------------------------------------------------===// 484// Table C-11. Move Instructions. 485//===----------------------------------------------------------------------===// 486 487def MOVE: F1<(outs ALL:$dst), (ins ALL:$src), 488 "$dst = $src;", 489 []>; 490 491let Constraints = "$src1 = $dst" in 492def MOVEcc: F1<(outs DP:$dst), (ins DP:$src1, DP:$src2, AnyCC:$cc), 493 "if $cc $dst = $src2;", 494 [(set DP:$dst, (select AnyCC:$cc, DP:$src2, DP:$src1))]>; 495 496let Defs = [AZ, AN, AC0, V] in { 497def MOVEzext: F1<(outs D:$dst), (ins D16L:$src), 498 "$dst = $src (z);", 499 [(set D:$dst, (zext D16L:$src))]>; 500 501def MOVEsext: F1<(outs D:$dst), (ins D16L:$src), 502 "$dst = $src (x);", 503 [(set D:$dst, (sext D16L:$src))]>; 504 505def MOVEzext8: F1<(outs D:$dst), (ins D:$src), 506 "$dst = $src.b (z);", 507 [(set D:$dst, (and D:$src, 0xff))]>; 508 509def MOVEsext8: F1<(outs D:$dst), (ins D:$src), 510 "$dst = $src.b (x);", 511 [(set D:$dst, (sext_inreg D:$src, i8))]>; 512 513} 514 515def : Pat<(sext_inreg D16L:$src, i8), 516 (EXTRACT_SUBREG (MOVEsext8 517 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), 518 D16L:$src, 519 lo16)), 520 lo16)>; 521 522def : Pat<(sext_inreg D:$src, i16), 523 (MOVEsext (EXTRACT_SUBREG D:$src, lo16))>; 524 525def : Pat<(and D:$src, 0xffff), 526 (MOVEzext (EXTRACT_SUBREG D:$src, lo16))>; 527 528def : Pat<(i32 (anyext D16L:$src)), 529 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), 530 (i16 (COPY_TO_REGCLASS D16L:$src, D16L)), 531 lo16)>; 532 533// TODO Dreg = Dreg_byte (X/Z) 534 535// TODO Accumulator moves 536 537//===----------------------------------------------------------------------===// 538// Table C-12. Stack Control Instructions 539//===----------------------------------------------------------------------===// 540 541let Uses = [SP], Defs = [SP] in { 542def PUSH: F1<(outs), (ins ALL:$src), 543 "[--sp] = $src;", []> { let mayStore = 1; } 544 545// NOTE: POP does not work for DP regs, use LOAD instead 546def POP: F1<(outs ALL:$dst), (ins), 547 "$dst = [sp++];", []> { let mayLoad = 1; } 548} 549 550// TODO: push/pop multiple 551 552def LINK: F2<(outs), (ins i32imm:$amount), 553 "link $amount;", []>; 554 555def UNLINK: F2<(outs), (ins), 556 "unlink;", []>; 557 558//===----------------------------------------------------------------------===// 559// Table C-13. Control Code Bit Management Instructions 560//===----------------------------------------------------------------------===// 561 562multiclass SETCC<PatFrag opnode, PatFrag invnode, string cond, string suf=";"> { 563 def dd : F1<(outs JustCC:$cc), (ins D:$a, D:$b), 564 !strconcat(!subst("XX", cond, "cc = $a XX $b"), suf), 565 [(set JustCC:$cc, (opnode D:$a, D:$b))]>; 566 567 def ri : F1<(outs JustCC:$cc), (ins DP:$a, i32imm:$b), 568 !strconcat(!subst("XX", cond, "cc = $a XX $b"), suf), 569 [(set JustCC:$cc, (opnode DP:$a, imm3:$b))]>; 570 571 def pp : F1<(outs JustCC:$cc), (ins P:$a, P:$b), 572 !strconcat(!subst("XX", cond, "cc = $a XX $b"), suf), 573 []>; 574 575 def ri_not : F1<(outs NotCC:$cc), (ins DP:$a, i32imm:$b), 576 !strconcat(!subst("XX", cond, "cc = $a XX $b"), suf), 577 [(set NotCC:$cc, (invnode DP:$a, imm3:$b))]>; 578} 579 580defm SETEQ : SETCC<seteq, setne, "==">; 581defm SETLT : SETCC<setlt, setge, "<">; 582defm SETLE : SETCC<setle, setgt, "<=">; 583defm SETULT : SETCC<setult, setuge, "<", " (iu);">; 584defm SETULE : SETCC<setule, setugt, "<=", " (iu);">; 585 586def SETNEdd : F1<(outs NotCC:$cc), (ins D:$a, D:$b), 587 "cc = $a == $b;", 588 [(set NotCC:$cc, (setne D:$a, D:$b))]>; 589 590def : Pat<(setgt D:$a, D:$b), (SETLTdd D:$b, D:$a)>; 591def : Pat<(setge D:$a, D:$b), (SETLEdd D:$b, D:$a)>; 592def : Pat<(setugt D:$a, D:$b), (SETULTdd D:$b, D:$a)>; 593def : Pat<(setuge D:$a, D:$b), (SETULEdd D:$b, D:$a)>; 594 595// TODO: compare pointer for P-P comparisons 596// TODO: compare accumulator 597 598let Defs = [AC0] in 599def OR_ac0_cc : F1<(outs), (ins JustCC:$cc), 600 "ac0 \\|= cc;", []>; 601 602let Uses = [AC0] in 603def MOVE_cc_ac0 : F1<(outs JustCC:$cc), (ins), 604 "cc = ac0;", []>; 605 606def MOVE_ccncc : F1<(outs JustCC:$cc), (ins NotCC:$sb), 607 "cc = !cc;", []>; 608 609def MOVE_ncccc : F1<(outs NotCC:$cc), (ins JustCC:$sb), 610 "cc = !cc;", []>; 611 612def MOVECC_zext : F1<(outs D:$dst), (ins JustCC:$cc), 613 "$dst = $cc;", []>; 614 615def MOVENCC_z : F1<(outs D:$dst), (ins NotCC:$cc), 616 "$dst = cc;", []>; 617 618def MOVECC_nz : F1<(outs AnyCC:$cc), (ins D:$src), 619 "cc = $src;", 620 [(set AnyCC:$cc, (setne D:$src, 0))]>; 621 622//===----------------------------------------------------------------------===// 623// Table C-14. Logical Operations Instructions 624//===----------------------------------------------------------------------===// 625 626def AND: F1<(outs D:$dst), (ins D:$src1, D:$src2), 627 "$dst = $src1 & $src2;", 628 [(set D:$dst, (and D:$src1, D:$src2))]>; 629 630def NOT: F1<(outs D:$dst), (ins D:$src), 631 "$dst = ~$src;", 632 [(set D:$dst, (not D:$src))]>; 633 634def OR: F1<(outs D:$dst), (ins D:$src1, D:$src2), 635 "$dst = $src1 \\| $src2;", 636 [(set D:$dst, (or D:$src1, D:$src2))]>; 637 638def XOR: F1<(outs D:$dst), (ins D:$src1, D:$src2), 639 "$dst = $src1 ^ $src2;", 640 [(set D:$dst, (xor D:$src1, D:$src2))]>; 641 642// missing: BXOR, BXORSHIFT 643 644//===----------------------------------------------------------------------===// 645// Table C-15. Bit Operations Instructions 646//===----------------------------------------------------------------------===// 647 648let Constraints = "$src1 = $dst" in { 649def BITCLR: F1<(outs D:$dst), (ins D:$src1, uimm5imask:$src2), 650 "bitclr($dst, $src2);", 651 [(set D:$dst, (and D:$src1, uimm5imask:$src2))]>; 652 653def BITSET: F1<(outs D:$dst), (ins D:$src1, uimm5mask:$src2), 654 "bitset($dst, $src2);", 655 [(set D:$dst, (or D:$src1, uimm5mask:$src2))]>; 656 657def BITTGL: F1<(outs D:$dst), (ins D:$src1, uimm5mask:$src2), 658 "bittgl($dst, $src2);", 659 [(set D:$dst, (xor D:$src1, uimm5mask:$src2))]>; 660} 661 662def BITTST: F1<(outs JustCC:$cc), (ins D:$src1, uimm5mask:$src2), 663 "cc = bittst($src1, $src2);", 664 [(set JustCC:$cc, (setne (and D:$src1, uimm5mask:$src2), 665 (i32 0)))]>; 666 667def NBITTST: F1<(outs JustCC:$cc), (ins D:$src1, uimm5mask:$src2), 668 "cc = !bittst($src1, $src2);", 669 [(set JustCC:$cc, (seteq (and D:$src1, uimm5mask:$src2), 670 (i32 0)))]>; 671 672// TODO: DEPOSIT, EXTRACT, BITMUX 673 674def ONES: F2<(outs D16L:$dst), (ins D:$src), 675 "$dst = ones $src;", 676 [(set D16L:$dst, (trunc (ctpop D:$src)))]>; 677 678def : Pat<(ctpop D:$src), (MOVEzext (ONES D:$src))>; 679 680//===----------------------------------------------------------------------===// 681// Table C-16. Shift / Rotate Instructions 682//===----------------------------------------------------------------------===// 683 684multiclass SHIFT32<SDNode opnode, string ops> { 685 def i : F1<(outs D:$dst), (ins D:$src, i16imm:$amount), 686 !subst("XX", ops, "$dst XX= $amount;"), 687 [(set D:$dst, (opnode D:$src, (i16 uimm5:$amount)))]>; 688 def r : F1<(outs D:$dst), (ins D:$src, D:$amount), 689 !subst("XX", ops, "$dst XX= $amount;"), 690 [(set D:$dst, (opnode D:$src, D:$amount))]>; 691} 692 693let Defs = [AZ, AN, V, VS], 694 Constraints = "$src = $dst" in { 695defm SRA : SHIFT32<sra, ">>>">; 696defm SRL : SHIFT32<srl, ">>">; 697defm SLL : SHIFT32<shl, "<<">; 698} 699 700// TODO: automatic switching between 2-addr and 3-addr (?) 701 702let Defs = [AZ, AN, V, VS] in { 703def SLLr16: F2<(outs D:$dst), (ins D:$src, D16L:$amount), 704 "$dst = lshift $src by $amount;", 705 [(set D:$dst, (shl D:$src, D16L:$amount))]>; 706 707// Arithmetic left-shift = saturing overflow. 708def SLAr16: F2<(outs D:$dst), (ins D:$src, D16L:$amount), 709 "$dst = ashift $src by $amount;", 710 [(set D:$dst, (sra D:$src, (ineg D16L:$amount)))]>; 711 712def SRA16i: F1<(outs D16:$dst), (ins D16:$src, i16imm:$amount), 713 "$dst = $src >>> $amount;", 714 [(set D16:$dst, (sra D16:$src, (i16 uimm4:$amount)))]>; 715 716def SRL16i: F1<(outs D16:$dst), (ins D16:$src, i16imm:$amount), 717 "$dst = $src >> $amount;", 718 [(set D16:$dst, (srl D16:$src, (i16 uimm4:$amount)))]>; 719 720// Arithmetic left-shift = saturing overflow. 721def SLA16r: F1<(outs D16:$dst), (ins D16:$src, D16L:$amount), 722 "$dst = ashift $src BY $amount;", 723 [(set D16:$dst, (srl D16:$src, (ineg D16L:$amount)))]>; 724 725def SLL16i: F1<(outs D16:$dst), (ins D16:$src, i16imm:$amount), 726 "$dst = $src << $amount;", 727 [(set D16:$dst, (shl D16:$src, (i16 uimm4:$amount)))]>; 728 729def SLL16r: F1<(outs D16:$dst), (ins D16:$src, D16L:$amount), 730 "$dst = lshift $src by $amount;", 731 [(set D16:$dst, (shl D16:$src, D16L:$amount))]>; 732 733} 734 735//===----------------------------------------------------------------------===// 736// Table C-17. Arithmetic Operations Instructions 737//===----------------------------------------------------------------------===// 738 739// TODO: ABS 740 741let Defs = [AZ, AN, AC0, V, VS] in { 742 743def ADD: F1<(outs D:$dst), (ins D:$src1, D:$src2), 744 "$dst = $src1 + $src2;", 745 [(set D:$dst, (add D:$src1, D:$src2))]>; 746 747def ADD16: F2<(outs D16:$dst), (ins D16:$src1, D16:$src2), 748 "$dst = $src1 + $src2;", 749 [(set D16:$dst, (add D16:$src1, D16:$src2))]>; 750 751let Constraints = "$src1 = $dst" in 752def ADDimm7: F1<(outs D:$dst), (ins D:$src1, i32imm:$src2), 753 "$dst += $src2;", 754 [(set D:$dst, (add D:$src1, imm7:$src2))]>; 755 756def SUB: F1<(outs D:$dst), (ins D:$src1, D:$src2), 757 "$dst = $src1 - $src2;", 758 [(set D:$dst, (sub D:$src1, D:$src2))]>; 759 760def SUB16: F2<(outs D16:$dst), (ins D16:$src1, D16:$src2), 761 "$dst = $src1 - $src2;", 762 [(set D16:$dst, (sub D16:$src1, D16:$src2))]>; 763 764} 765 766def : Pat<(addc D:$src1, D:$src2), (ADD D:$src1, D:$src2)>; 767def : Pat<(subc D:$src1, D:$src2), (SUB D:$src1, D:$src2)>; 768 769let Defs = [AZ, AN, V, VS] in 770def NEG: F1<(outs D:$dst), (ins D:$src), 771 "$dst = -$src;", 772 [(set D:$dst, (ineg D:$src))]>; 773 774// No pattern, it would confuse isel to have two i32 = i32+i32 patterns 775def ADDpp: F1<(outs P:$dst), (ins P:$src1, P:$src2), 776 "$dst = $src1 + $src2;", []>; 777 778let Constraints = "$src1 = $dst" in 779def ADDpp_imm7: F1<(outs P:$dst), (ins P:$src1, i32imm:$src2), 780 "$dst += $src2;", []>; 781 782let Defs = [AZ, AN, V] in 783def ADD_RND20: F2<(outs D16:$dst), (ins D:$src1, D:$src2), 784 "$dst = $src1 + $src2 (rnd20);", []>; 785 786let Defs = [V, VS] in { 787def MUL16: F2<(outs D16:$dst), (ins D16:$src1, D16:$src2), 788 "$dst = $src1 * $src2 (is);", 789 [(set D16:$dst, (mul D16:$src1, D16:$src2))]>; 790 791def MULHS16: F2<(outs D16:$dst), (ins D16:$src1, D16:$src2), 792 "$dst = $src1 * $src2 (ih);", 793 [(set D16:$dst, (mulhs D16:$src1, D16:$src2))]>; 794 795def MULhh32s: F2<(outs D:$dst), (ins D16:$src1, D16:$src2), 796 "$dst = $src1 * $src2 (is);", 797 [(set D:$dst, (mul (sext D16:$src1), (sext D16:$src2)))]>; 798 799def MULhh32u: F2<(outs D:$dst), (ins D16:$src1, D16:$src2), 800 "$dst = $src1 * $src2 (is);", 801 [(set D:$dst, (mul (zext D16:$src1), (zext D16:$src2)))]>; 802} 803 804 805let Constraints = "$src1 = $dst" in 806def MUL32: F1<(outs D:$dst), (ins D:$src1, D:$src2), 807 "$dst *= $src2;", 808 [(set D:$dst, (mul D:$src1, D:$src2))]>; 809 810//===----------------------------------------------------------------------===// 811// Table C-18. External Exent Management Instructions 812//===----------------------------------------------------------------------===// 813 814def IDLE : F1<(outs), (ins), "idle;", [(int_bfin_idle)]>; 815def CSYNC : F1<(outs), (ins), "csync;", [(int_bfin_csync)]>; 816def SSYNC : F1<(outs), (ins), "ssync;", [(int_bfin_ssync)]>; 817def EMUEXCPT : F1<(outs), (ins), "emuexcpt;", []>; 818def CLI : F1<(outs D:$mask), (ins), "cli $mask;", []>; 819def STI : F1<(outs), (ins D:$mask), "sti $mask;", []>; 820def RAISE : F1<(outs), (ins i32imm:$itr), "raise $itr;", []>; 821def EXCPT : F1<(outs), (ins i32imm:$exc), "excpt $exc;", []>; 822def NOP : F1<(outs), (ins), "nop;", []>; 823def MNOP : F2<(outs), (ins), "mnop;", []>; 824def ABORT : F1<(outs), (ins), "abort;", []>; 825 826//===----------------------------------------------------------------------===// 827// Table C-19. Cache Control Instructions 828//===----------------------------------------------------------------------===// 829 830//===----------------------------------------------------------------------===// 831// Table C-20. Video Pixel Operations Instructions 832//===----------------------------------------------------------------------===// 833 834def ALIGN8 : F2<(outs D:$dst), (ins D:$src1, D:$src2), 835 "$dst = align8($src1, $src2);", 836 [(set D:$dst, (or (shl D:$src1, (i32 24)), 837 (srl D:$src2, (i32 8))))]>; 838 839def ALIGN16 : F2<(outs D:$dst), (ins D:$src1, D:$src2), 840 "$dst = align16($src1, $src2);", 841 [(set D:$dst, (or (shl D:$src1, (i32 16)), 842 (srl D:$src2, (i32 16))))]>; 843 844def ALIGN24 : F2<(outs D:$dst), (ins D:$src1, D:$src2), 845 "$dst = align16($src1, $src2);", 846 [(set D:$dst, (or (shl D:$src1, (i32 8)), 847 (srl D:$src2, (i32 24))))]>; 848 849def DISALGNEXCPT : F2<(outs), (ins), "disalignexcpt;", []>; 850 851// TODO: BYTEOP3P, BYTEOP16P, BYTEOP1P, BYTEOP2P, BYTEOP16M, SAA, 852// BYTEPACK, BYTEUNPACK 853 854// Table C-21. Vector Operations Instructions 855 856// Patterns 857def : Pat<(BfinCall (i32 tglobaladdr:$dst)), 858 (CALLa tglobaladdr:$dst)>; 859def : Pat<(BfinCall (i32 texternalsym:$dst)), 860 (CALLa texternalsym:$dst)>; 861def : Pat<(i16 (trunc D:$src)), 862 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS D:$src, D)), lo16)>; 863