Home | History | Annotate | Download | only in Blackfin
      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