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 18 include "BlackfinInstrFormats.td" 19 20 // These are target-independent nodes, but have target-specific formats. 21 def SDT_BfinCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>; 22 def SDT_BfinCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, 23 SDTCisVT<1, i32> ]>; 24 25 def BfinCallseqStart : SDNode<"ISD::CALLSEQ_START", SDT_BfinCallSeqStart, 26 [SDNPHasChain, SDNPOutGlue]>; 27 def BfinCallseqEnd : SDNode<"ISD::CALLSEQ_END", SDT_BfinCallSeqEnd, 28 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 29 30 def SDT_BfinCall : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>; 31 def BfinCall : SDNode<"BFISD::CALL", SDT_BfinCall, 32 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 33 SDNPVariadic]>; 34 35 def BfinRet: SDNode<"BFISD::RET_FLAG", SDTNone, 36 [SDNPHasChain, SDNPOptInGlue]>; 37 38 def BfinWrapper: SDNode<"BFISD::Wrapper", SDTIntUnaryOp>; 39 40 //===----------------------------------------------------------------------===// 41 // Transformations 42 //===----------------------------------------------------------------------===// 43 44 def trailingZeros_xform : SDNodeXForm<imm, [{ 45 return CurDAG->getTargetConstant(N->getAPIntValue().countTrailingZeros(), 46 MVT::i32); 47 }]>; 48 49 def trailingOnes_xform : SDNodeXForm<imm, [{ 50 return CurDAG->getTargetConstant(N->getAPIntValue().countTrailingOnes(), 51 MVT::i32); 52 }]>; 53 54 def LO16 : SDNodeXForm<imm, [{ 55 return CurDAG->getTargetConstant((unsigned short)N->getZExtValue(), MVT::i16); 56 }]>; 57 58 def 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 67 def imm3 : PatLeaf<(imm), [{return isInt<3>(N->getSExtValue());}]>; 68 def uimm3 : PatLeaf<(imm), [{return isUInt<3>(N->getZExtValue());}]>; 69 def uimm4 : PatLeaf<(imm), [{return isUInt<4>(N->getZExtValue());}]>; 70 def uimm5 : PatLeaf<(imm), [{return isUInt<5>(N->getZExtValue());}]>; 71 72 def uimm5m2 : PatLeaf<(imm), [{ 73 uint64_t value = N->getZExtValue(); 74 return value % 2 == 0 && isUInt<5>(value); 75 }]>; 76 77 def uimm6m4 : PatLeaf<(imm), [{ 78 uint64_t value = N->getZExtValue(); 79 return value % 4 == 0 && isUInt<6>(value); 80 }]>; 81 82 def imm7 : PatLeaf<(imm), [{return isInt<7>(N->getSExtValue());}]>; 83 def imm16 : PatLeaf<(imm), [{return isInt<16>(N->getSExtValue());}]>; 84 def uimm16 : PatLeaf<(imm), [{return isUInt<16>(N->getZExtValue());}]>; 85 86 def ximm16 : PatLeaf<(imm), [{ 87 int64_t value = N->getSExtValue(); 88 return value < (1<<16) && value >= -(1<<15); 89 }]>; 90 91 def imm17m2 : PatLeaf<(imm), [{ 92 int64_t value = N->getSExtValue(); 93 return value % 2 == 0 && isInt<17>(value); 94 }]>; 95 96 def 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 102 def 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 107 def uimm5imask : Operand<i32>, PatLeaf<(imm), [{ 108 return isPowerOf2_32(~N->getZExtValue()); 109 }], trailingOnes_xform>; 110 111 //===----------------------------------------------------------------------===// 112 // Operands 113 //===----------------------------------------------------------------------===// 114 115 def calltarget : Operand<iPTR>; 116 117 def brtarget : Operand<OtherVT>; 118 119 // Addressing modes 120 def ADDRspii : ComplexPattern<i32, 2, "SelectADDRspii", [add, frameindex], []>; 121 122 // Address operands 123 def MEMii : Operand<i32> { 124 let PrintMethod = "printMemoryOperand"; 125 let MIOperandInfo = (ops i32imm, i32imm); 126 } 127 128 //===----------------------------------------------------------------------===// 129 // Instructions 130 //===----------------------------------------------------------------------===// 131 132 // Pseudo instructions. 133 class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern> 134 : InstBfin<outs, ins, asmstr, pattern>; 135 136 let Defs = [SP], Uses = [SP] in { 137 def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt), 138 "${:comment}ADJCALLSTACKDOWN $amt", 139 [(BfinCallseqStart timm:$amt)]>; 140 def 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 149 let isBranch = 1, isTerminator = 1 in { 150 151 let isIndirectBranch = 1 in 152 def 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 159 def JUMPa : F1<(outs), (ins brtarget:$target), 160 "jump $target;", 161 [(br bb:$target)]>; 162 163 def JUMPcc : F1<(outs), (ins AnyCC:$cc, brtarget:$target), 164 "if $cc jump $target;", 165 [(brcond AnyCC:$cc, bb:$target)]>; 166 } 167 168 let isCall = 1, 169 Defs = [R0, R1, R2, R3, P0, P1, P2, LB0, LB1, LC0, LC1, RETS, ASTAT] in { 170 def CALLa: F1<(outs), (ins calltarget:$func, variable_ops), 171 "call $func;", []>; 172 def CALLp: F1<(outs), (ins P:$func, variable_ops), 173 "call ($func);", [(BfinCall P:$func)]>; 174 } 175 176 let isReturn = 1, 177 isTerminator = 1, 178 isBarrier = 1, 179 Uses = [RETS] in 180 def 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 189 def 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 194 def 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 199 def 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. 204 def LOAD32imm: Pseudo<(outs GR:$dst), (ins i32imm:$src), 205 "$dst.h = ($src >> 16); $dst.l = ($src & 0xffff);", 206 [(set GR:$dst, imm:$src)]>; 207 208 def 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 213 def LOAD16i: F2<(outs GR16:$dst), (ins i16imm:$src), 214 "$dst = $src;", []>; 215 216 def : Pat<(BfinWrapper (i32 tglobaladdr:$addr)), 217 (LOAD32sym tglobaladdr:$addr)>; 218 219 def : 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. 224 def 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 230 def 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 235 def 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 240 def 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 246 def LOAD8fi: Pseudo<(outs AnyCC:$dst), (ins MEMii:$mem), 247 "${:comment}FI $dst = B[$mem];", 248 [(set AnyCC:$dst, (load ADDRspii:$mem))]>; 249 250 def 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 254 def 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 258 def LOAD32p_16z: F1<(outs D:$dst), (ins P:$ptr), 259 "$dst = W[$ptr] (z);", 260 [(set D:$dst, (zextloadi16 P:$ptr))]>; 261 262 def : Pat<(i32 (extloadi16 P:$ptr)),(LOAD32p_16z P:$ptr)>; 263 264 def 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 269 def : Pat<(i32 (extloadi16 (add P:$ptr, uimm5m2:$off))), 270 (LOAD32p_uimm5m2_16z P:$ptr, imm:$off)>; 271 272 def 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 277 def : Pat<(i32 (extloadi16 (add P:$ptr, imm17m2:$off))), 278 (LOAD32p_imm17m2_16z P:$ptr, imm:$off)>; 279 280 def LOAD32p_16s: F1<(outs D:$dst), (ins P:$ptr), 281 "$dst = w[$ptr] (x);", 282 [(set D:$dst, (sextloadi16 P:$ptr))]>; 283 284 def 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 289 def 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 294 def LOAD16pi: F1<(outs D16:$dst), (ins PI:$ptr), 295 "$dst = w[$ptr];", 296 [(set D16:$dst, (load PI:$ptr))]>; 297 298 def LOAD32p_8z: F1<(outs D:$dst), (ins P:$ptr), 299 "$dst = B[$ptr] (z);", 300 [(set D:$dst, (zextloadi8 P:$ptr))]>; 301 302 def : Pat<(i32 (extloadi8 P:$ptr)), (LOAD32p_8z P:$ptr)>; 303 def : Pat<(i16 (extloadi8 P:$ptr)), 304 (EXTRACT_SUBREG (LOAD32p_8z P:$ptr), lo16)>; 305 def : Pat<(i16 (zextloadi8 P:$ptr)), 306 (EXTRACT_SUBREG (LOAD32p_8z P:$ptr), lo16)>; 307 308 def 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 312 def : Pat<(i32 (extloadi8 (add P:$ptr, imm16:$off))), 313 (LOAD32p_imm16_8z P:$ptr, imm:$off)>; 314 def : Pat<(i16 (extloadi8 (add P:$ptr, imm16:$off))), 315 (EXTRACT_SUBREG (LOAD32p_imm16_8z P:$ptr, imm:$off), 316 lo16)>; 317 def : Pat<(i16 (zextloadi8 (add P:$ptr, imm16:$off))), 318 (EXTRACT_SUBREG (LOAD32p_imm16_8z P:$ptr, imm:$off), 319 lo16)>; 320 321 def LOAD32p_8s: F1<(outs D:$dst), (ins P:$ptr), 322 "$dst = b[$ptr] (x);", 323 [(set D:$dst, (sextloadi8 P:$ptr))]>; 324 325 def : Pat<(i16 (sextloadi8 P:$ptr)), 326 (EXTRACT_SUBREG (LOAD32p_8s P:$ptr), lo16)>; 327 328 def 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 332 def : 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 337 let mayLoad = 1 in { 338 339 multiclass 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 } 346 multiclass 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 353 defm LOAD32p: LOAD_incdec<DP, P>; 354 defm LOAD32i: LOAD_incdec<D, I>; 355 defm LOAD8z32p: LOAD_incdec<D, P, "b", " (z);">; 356 defm LOAD8s32p: LOAD_incdec<D, P, "b", " (x);">; 357 defm LOADhi: LOAD_incdec<D16, I, "w">; 358 defm LOAD16z32p: LOAD_incdecpost<D, P, "w", " (z);">; 359 defm LOAD16s32p: LOAD_incdecpost<D, P, "w", " (x);">; 360 361 def 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 365 def LOAD32fp_nimm7m4: F1<(outs DP:$dst), (ins P:$fp, i32imm:$off), 366 "$dst = [$fp - $off];", []>; 367 368 def LOAD32i: F1<(outs D:$dst), (ins I:$ptr), 369 "$dst = [$ptr];", []>; 370 def LOAD32i_post: F1<(outs D:$dst, I:$ptr_wb), (ins I:$ptr, M:$off), 371 "$dst = [$ptr ++ $off];", []>; 372 373 374 375 def 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 382 def 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 387 def 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 392 def 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 398 def STORE8fi: Pseudo<(outs), (ins AnyCC:$val, MEMii:$mem), 399 "${:comment}FI b[$mem] = $val;", 400 [(store AnyCC:$val, ADDRspii:$mem)]>; 401 402 def 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 406 def 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 410 def STORE16pi: F1<(outs), (ins D16:$val, PI:$ptr), 411 "w[$ptr] = $val;", 412 [(store D16:$val, PI:$ptr)]>; 413 414 def STORE8p: F1<(outs), (ins D:$val, P:$ptr), 415 "b[$ptr] = $val;", 416 [(truncstorei8 D:$val, P:$ptr)]>; 417 418 def 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 422 let Constraints = "$ptr = $ptr_wb" in { 423 424 multiclass 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 435 defm STORE32p: STORE_incdec<DP, P>; 436 defm STORE16i: STORE_incdec<D16, I, 2, "w">; 437 defm STORE8p: STORE_incdec<D, P, 1, "b">; 438 439 def 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 443 def 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 450 let mayStore = 1 in { 451 452 // Note: only works for $fp == FP 453 def STORE32fp_nimm7m4: F1<(outs), (ins DP:$val, P:$fp, i32imm:$off), 454 "[$fp - $off] = $val;", []>; 455 456 def STORE32i: F1<(outs), (ins D:$val, I:$ptr), 457 "[$ptr] = $val;", []>; 458 459 def STORE32i_inc: F1<(outs I:$ptr_wb), (ins D:$val, I:$ptr), 460 "[$ptr++] = $val;", []>; 461 462 def STORE32i_dec: F1<(outs I:$ptr_wb), (ins D:$val, I:$ptr), 463 "[$ptr--] = $val;", []>; 464 465 def STORE32i_post: F1<(outs I:$ptr_wb), (ins D:$val, I:$ptr, M:$off), 466 "[$ptr ++ $off] = $val;", []>; 467 } 468 469 def : Pat<(truncstorei16 D:$val, PI:$ptr), 470 (STORE16pi (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS D:$val, D)), 471 lo16), PI:$ptr)>; 472 473 def : 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 477 def : 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 487 def MOVE: F1<(outs ALL:$dst), (ins ALL:$src), 488 "$dst = $src;", 489 []>; 490 491 let Constraints = "$src1 = $dst" in 492 def 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 496 let Defs = [AZ, AN, AC0, V] in { 497 def MOVEzext: F1<(outs D:$dst), (ins D16L:$src), 498 "$dst = $src (z);", 499 [(set D:$dst, (zext D16L:$src))]>; 500 501 def MOVEsext: F1<(outs D:$dst), (ins D16L:$src), 502 "$dst = $src (x);", 503 [(set D:$dst, (sext D16L:$src))]>; 504 505 def MOVEzext8: F1<(outs D:$dst), (ins D:$src), 506 "$dst = $src.b (z);", 507 [(set D:$dst, (and D:$src, 0xff))]>; 508 509 def 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 515 def : Pat<(sext_inreg D16L:$src, i8), 516 (EXTRACT_SUBREG (MOVEsext8 517 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), 518 D16L:$src, 519 lo16)), 520 lo16)>; 521 522 def : Pat<(sext_inreg D:$src, i16), 523 (MOVEsext (EXTRACT_SUBREG D:$src, lo16))>; 524 525 def : Pat<(and D:$src, 0xffff), 526 (MOVEzext (EXTRACT_SUBREG D:$src, lo16))>; 527 528 def : 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 541 let Uses = [SP], Defs = [SP] in { 542 def 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 546 def POP: F1<(outs ALL:$dst), (ins), 547 "$dst = [sp++];", []> { let mayLoad = 1; } 548 } 549 550 // TODO: push/pop multiple 551 552 def LINK: F2<(outs), (ins i32imm:$amount), 553 "link $amount;", []>; 554 555 def UNLINK: F2<(outs), (ins), 556 "unlink;", []>; 557 558 //===----------------------------------------------------------------------===// 559 // Table C-13. Control Code Bit Management Instructions 560 //===----------------------------------------------------------------------===// 561 562 multiclass 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 580 defm SETEQ : SETCC<seteq, setne, "==">; 581 defm SETLT : SETCC<setlt, setge, "<">; 582 defm SETLE : SETCC<setle, setgt, "<=">; 583 defm SETULT : SETCC<setult, setuge, "<", " (iu);">; 584 defm SETULE : SETCC<setule, setugt, "<=", " (iu);">; 585 586 def SETNEdd : F1<(outs NotCC:$cc), (ins D:$a, D:$b), 587 "cc = $a == $b;", 588 [(set NotCC:$cc, (setne D:$a, D:$b))]>; 589 590 def : Pat<(setgt D:$a, D:$b), (SETLTdd D:$b, D:$a)>; 591 def : Pat<(setge D:$a, D:$b), (SETLEdd D:$b, D:$a)>; 592 def : Pat<(setugt D:$a, D:$b), (SETULTdd D:$b, D:$a)>; 593 def : 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 598 let Defs = [AC0] in 599 def OR_ac0_cc : F1<(outs), (ins JustCC:$cc), 600 "ac0 \\|= cc;", []>; 601 602 let Uses = [AC0] in 603 def MOVE_cc_ac0 : F1<(outs JustCC:$cc), (ins), 604 "cc = ac0;", []>; 605 606 def MOVE_ccncc : F1<(outs JustCC:$cc), (ins NotCC:$sb), 607 "cc = !cc;", []>; 608 609 def MOVE_ncccc : F1<(outs NotCC:$cc), (ins JustCC:$sb), 610 "cc = !cc;", []>; 611 612 def MOVECC_zext : F1<(outs D:$dst), (ins JustCC:$cc), 613 "$dst = $cc;", []>; 614 615 def MOVENCC_z : F1<(outs D:$dst), (ins NotCC:$cc), 616 "$dst = cc;", []>; 617 618 def 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 626 def AND: F1<(outs D:$dst), (ins D:$src1, D:$src2), 627 "$dst = $src1 & $src2;", 628 [(set D:$dst, (and D:$src1, D:$src2))]>; 629 630 def NOT: F1<(outs D:$dst), (ins D:$src), 631 "$dst = ~$src;", 632 [(set D:$dst, (not D:$src))]>; 633 634 def OR: F1<(outs D:$dst), (ins D:$src1, D:$src2), 635 "$dst = $src1 \\| $src2;", 636 [(set D:$dst, (or D:$src1, D:$src2))]>; 637 638 def 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 648 let Constraints = "$src1 = $dst" in { 649 def BITCLR: F1<(outs D:$dst), (ins D:$src1, uimm5imask:$src2), 650 "bitclr($dst, $src2);", 651 [(set D:$dst, (and D:$src1, uimm5imask:$src2))]>; 652 653 def BITSET: F1<(outs D:$dst), (ins D:$src1, uimm5mask:$src2), 654 "bitset($dst, $src2);", 655 [(set D:$dst, (or D:$src1, uimm5mask:$src2))]>; 656 657 def 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 662 def 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 667 def 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 674 def ONES: F2<(outs D16L:$dst), (ins D:$src), 675 "$dst = ones $src;", 676 [(set D16L:$dst, (trunc (ctpop D:$src)))]>; 677 678 def : Pat<(ctpop D:$src), (MOVEzext (ONES D:$src))>; 679 680 //===----------------------------------------------------------------------===// 681 // Table C-16. Shift / Rotate Instructions 682 //===----------------------------------------------------------------------===// 683 684 multiclass 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 693 let Defs = [AZ, AN, V, VS], 694 Constraints = "$src = $dst" in { 695 defm SRA : SHIFT32<sra, ">>>">; 696 defm SRL : SHIFT32<srl, ">>">; 697 defm SLL : SHIFT32<shl, "<<">; 698 } 699 700 // TODO: automatic switching between 2-addr and 3-addr (?) 701 702 let Defs = [AZ, AN, V, VS] in { 703 def 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. 708 def 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 712 def 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 716 def 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. 721 def 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 725 def 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 729 def 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 741 let Defs = [AZ, AN, AC0, V, VS] in { 742 743 def ADD: F1<(outs D:$dst), (ins D:$src1, D:$src2), 744 "$dst = $src1 + $src2;", 745 [(set D:$dst, (add D:$src1, D:$src2))]>; 746 747 def ADD16: F2<(outs D16:$dst), (ins D16:$src1, D16:$src2), 748 "$dst = $src1 + $src2;", 749 [(set D16:$dst, (add D16:$src1, D16:$src2))]>; 750 751 let Constraints = "$src1 = $dst" in 752 def ADDimm7: F1<(outs D:$dst), (ins D:$src1, i32imm:$src2), 753 "$dst += $src2;", 754 [(set D:$dst, (add D:$src1, imm7:$src2))]>; 755 756 def SUB: F1<(outs D:$dst), (ins D:$src1, D:$src2), 757 "$dst = $src1 - $src2;", 758 [(set D:$dst, (sub D:$src1, D:$src2))]>; 759 760 def 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 766 def : Pat<(addc D:$src1, D:$src2), (ADD D:$src1, D:$src2)>; 767 def : Pat<(subc D:$src1, D:$src2), (SUB D:$src1, D:$src2)>; 768 769 let Defs = [AZ, AN, V, VS] in 770 def 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 775 def ADDpp: F1<(outs P:$dst), (ins P:$src1, P:$src2), 776 "$dst = $src1 + $src2;", []>; 777 778 let Constraints = "$src1 = $dst" in 779 def ADDpp_imm7: F1<(outs P:$dst), (ins P:$src1, i32imm:$src2), 780 "$dst += $src2;", []>; 781 782 let Defs = [AZ, AN, V] in 783 def ADD_RND20: F2<(outs D16:$dst), (ins D:$src1, D:$src2), 784 "$dst = $src1 + $src2 (rnd20);", []>; 785 786 let Defs = [V, VS] in { 787 def 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 791 def 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 795 def 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 799 def 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 805 let Constraints = "$src1 = $dst" in 806 def 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 814 def IDLE : F1<(outs), (ins), "idle;", [(int_bfin_idle)]>; 815 def CSYNC : F1<(outs), (ins), "csync;", [(int_bfin_csync)]>; 816 def SSYNC : F1<(outs), (ins), "ssync;", [(int_bfin_ssync)]>; 817 def EMUEXCPT : F1<(outs), (ins), "emuexcpt;", []>; 818 def CLI : F1<(outs D:$mask), (ins), "cli $mask;", []>; 819 def STI : F1<(outs), (ins D:$mask), "sti $mask;", []>; 820 def RAISE : F1<(outs), (ins i32imm:$itr), "raise $itr;", []>; 821 def EXCPT : F1<(outs), (ins i32imm:$exc), "excpt $exc;", []>; 822 def NOP : F1<(outs), (ins), "nop;", []>; 823 def MNOP : F2<(outs), (ins), "mnop;", []>; 824 def 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 834 def 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 839 def 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 844 def 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 849 def 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 857 def : Pat<(BfinCall (i32 tglobaladdr:$dst)), 858 (CALLa tglobaladdr:$dst)>; 859 def : Pat<(BfinCall (i32 texternalsym:$dst)), 860 (CALLa texternalsym:$dst)>; 861 def : Pat<(i16 (trunc D:$src)), 862 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS D:$src, D)), lo16)>; 863