1 //===- BlackfinInstrInfo.td - Target Description for Blackfin Target ------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file describes the Blackfin instructions in TableGen format.
12 //===----------------------------------------------------------------------===//
14 //===----------------------------------------------------------------------===//
15 // Instruction format superclass
16 //===----------------------------------------------------------------------===//
18 include "BlackfinInstrFormats.td"
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>,
25 def BfinCallseqStart : SDNode<"ISD::CALLSEQ_START", SDT_BfinCallSeqStart,
26 [SDNPHasChain, SDNPOutFlag]>;
27 def BfinCallseqEnd : SDNode<"ISD::CALLSEQ_END", SDT_BfinCallSeqEnd,
28 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
30 def SDT_BfinCall : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
31 def BfinCall : SDNode<"BFISD::CALL", SDT_BfinCall,
32 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
34 def BfinRet: SDNode<"BFISD::RET_FLAG", SDTNone,
35 [SDNPHasChain, SDNPOptInFlag]>;
37 def BfinWrapper: SDNode<"BFISD::Wrapper", SDTIntUnaryOp>;
39 //===----------------------------------------------------------------------===//
41 //===----------------------------------------------------------------------===//
43 def trailingZeros_xform : SDNodeXForm<imm, [{
44 return CurDAG->getTargetConstant(N->getAPIntValue().countTrailingZeros(),
48 def trailingOnes_xform : SDNodeXForm<imm, [{
49 return CurDAG->getTargetConstant(N->getAPIntValue().countTrailingOnes(),
53 def LO16 : SDNodeXForm<imm, [{
54 return CurDAG->getTargetConstant((unsigned short)N->getZExtValue(), MVT::i16);
57 def HI16 : SDNodeXForm<imm, [{
58 // Transformation function: shift the immediate value down into the low bits.
59 return CurDAG->getTargetConstant((unsigned)N->getZExtValue() >> 16, MVT::i16);
62 //===----------------------------------------------------------------------===//
64 //===----------------------------------------------------------------------===//
66 def imm3 : PatLeaf<(imm), [{return isInt<3>(N->getSExtValue());}]>;
67 def uimm3 : PatLeaf<(imm), [{return isUint<3>(N->getZExtValue());}]>;
68 def uimm4 : PatLeaf<(imm), [{return isUint<4>(N->getZExtValue());}]>;
69 def uimm5 : PatLeaf<(imm), [{return isUint<5>(N->getZExtValue());}]>;
71 def uimm5m2 : PatLeaf<(imm), [{
72 uint64_t value = N->getZExtValue();
73 return value % 2 == 0 && isUint<5>(value);
76 def uimm6m4 : PatLeaf<(imm), [{
77 uint64_t value = N->getZExtValue();
78 return value % 4 == 0 && isUint<6>(value);
81 def imm7 : PatLeaf<(imm), [{return isInt<7>(N->getSExtValue());}]>;
82 def imm16 : PatLeaf<(imm), [{return isInt<16>(N->getSExtValue());}]>;
83 def uimm16 : PatLeaf<(imm), [{return isUint<16>(N->getZExtValue());}]>;
85 def ximm16 : PatLeaf<(imm), [{
86 int64_t value = N->getSExtValue();
87 return value < (1<<16) && value >= -(1<<15);
90 def imm17m2 : PatLeaf<(imm), [{
91 int64_t value = N->getSExtValue();
92 return value % 2 == 0 && isInt<17>(value);
95 def imm18m4 : PatLeaf<(imm), [{
96 int64_t value = N->getSExtValue();
97 return value % 4 == 0 && isInt<18>(value);
100 // 32-bit bitmask transformed to a bit number
101 def uimm5mask : Operand<i32>, PatLeaf<(imm), [{
102 return isPowerOf2_32(N->getZExtValue());
103 }], trailingZeros_xform>;
105 // 32-bit inverse bitmask transformed to a bit number
106 def uimm5imask : Operand<i32>, PatLeaf<(imm), [{
107 return isPowerOf2_32(~N->getZExtValue());
108 }], trailingOnes_xform>;
110 //===----------------------------------------------------------------------===//
112 //===----------------------------------------------------------------------===//
114 def calltarget : Operand<iPTR>;
116 def brtarget : Operand<OtherVT>;
119 def ADDRspii : ComplexPattern<i32, 2, "SelectADDRspii", [add, frameindex], []>;
122 def MEMii : Operand<i32> {
123 let PrintMethod = "printMemoryOperand";
124 let MIOperandInfo = (ops i32imm, i32imm);
127 //===----------------------------------------------------------------------===//
129 //===----------------------------------------------------------------------===//
131 // Pseudo instructions.
132 class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
133 : InstBfin<outs, ins, asmstr, pattern>;
135 let Defs = [SP], Uses = [SP] in {
136 def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt),
137 "${:comment}ADJCALLSTACKDOWN $amt",
138 [(BfinCallseqStart timm:$amt)]>;
139 def ADJCALLSTACKUP : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
140 "${:comment}ADJCALLSTACKUP $amt1 $amt2",
141 [(BfinCallseqEnd timm:$amt1, timm:$amt2)]>;
144 //===----------------------------------------------------------------------===//
145 // Table C-9. Program Flow Control Instructions
146 //===----------------------------------------------------------------------===//
148 let isBranch = 1, isTerminator = 1 in {
150 let isIndirectBranch = 1 in
151 def JUMPp : F1<(outs), (ins P:$target),
153 [(brind P:$target)]>;
157 // NOTE: assembler chooses between JUMP.S and JUMP.L
158 def JUMPa : F1<(outs), (ins brtarget:$target),
162 def JUMPcc : F1<(outs), (ins AnyCC:$cc, brtarget:$target),
163 "if $cc jump $target;",
164 [(brcond AnyCC:$cc, bb:$target)]>;
168 Defs = [R0, R1, R2, R3, P0, P1, P2, LB0, LB1, LC0, LC1, RETS, ASTAT] in {
169 def CALLa: F1<(outs), (ins calltarget:$func, variable_ops),
171 def CALLp: F1<(outs), (ins P:$func, variable_ops),
172 "call ($func);", [(BfinCall P:$func)]>;
179 def RTS: F1<(outs), (ins), "rts;", [(BfinRet)]>;
181 //===----------------------------------------------------------------------===//
182 // Table C-10. Load / Store Instructions
183 //===----------------------------------------------------------------------===//
185 // Immediate constant loads
187 // sext immediate, i32 D/P regs
188 def LOADimm7: F1<(outs DP:$dst), (ins i32imm:$src),
190 [(set DP:$dst, imm7:$src)]>;
192 // zext immediate, i32 reg groups 0-3
193 def LOADuimm16: F2<(outs GR:$dst), (ins i32imm:$src),
195 [(set GR:$dst, uimm16:$src)]>;
197 // sext immediate, i32 reg groups 0-3
198 def LOADimm16: F2<(outs GR:$dst), (ins i32imm:$src),
200 [(set GR:$dst, imm16:$src)]>;
202 // Pseudo-instruction for loading a general 32-bit constant.
203 def LOAD32imm: Pseudo<(outs GR:$dst), (ins i32imm:$src),
204 "$dst.h = ($src >> 16); $dst.l = ($src & 0xffff);",
205 [(set GR:$dst, imm:$src)]>;
207 def LOAD32sym: Pseudo<(outs GR:$dst), (ins i32imm:$src),
208 "$dst.h = $src; $dst.l = $src;", []>;
211 // 16-bit immediate, i16 reg groups 0-3
212 def LOAD16i: F2<(outs GR16:$dst), (ins i16imm:$src),
215 def : Pat<(BfinWrapper (i32 tglobaladdr:$addr)),
216 (LOAD32sym tglobaladdr:$addr)>;
218 def : Pat<(BfinWrapper (i32 tjumptable:$addr)),
219 (LOAD32sym tjumptable:$addr)>;
221 // We cannot copy from GR16 to D16, and codegen wants to insert copies if we
222 // emit GR16 instructions. As a hack, we use this fake instruction instead.
223 def LOAD16i_d16: F2<(outs D16:$dst), (ins i16imm:$src),
225 [(set D16:$dst, ximm16:$src)]>;
227 // Memory loads with patterns
229 def LOAD32p: F1<(outs DP:$dst), (ins P:$ptr),
231 [(set DP:$dst, (load P:$ptr))]>;
233 // Pseudo-instruction for loading a stack slot
234 def LOAD32fi: Pseudo<(outs DP:$dst), (ins MEMii:$mem),
235 "${:comment}FI $dst = [$mem];",
236 [(set DP:$dst, (load ADDRspii:$mem))]>;
238 // Note: Expands to multiple insns
239 def LOAD16fi: Pseudo<(outs D16:$dst), (ins MEMii:$mem),
240 "${:comment}FI $dst = [$mem];",
241 [(set D16:$dst, (load ADDRspii:$mem))]>;
243 // Pseudo-instruction for loading a stack slot, used for AnyCC regs.
244 // Replaced with Load D + CC=D
245 def LOAD8fi: Pseudo<(outs AnyCC:$dst), (ins MEMii:$mem),
246 "${:comment}FI $dst = B[$mem];",
247 [(set AnyCC:$dst, (load ADDRspii:$mem))]>;
249 def LOAD32p_uimm6m4: F1<(outs DP:$dst), (ins P:$ptr, i32imm:$off),
250 "$dst = [$ptr + $off];",
251 [(set DP:$dst, (load (add P:$ptr, uimm6m4:$off)))]>;
253 def LOAD32p_imm18m4: F2<(outs DP:$dst), (ins P:$ptr, i32imm:$off),
254 "$dst = [$ptr + $off];",
255 [(set DP:$dst, (load (add P:$ptr, imm18m4:$off)))]>;
257 def LOAD32p_16z: F1<(outs D:$dst), (ins P:$ptr),
258 "$dst = W[$ptr] (z);",
259 [(set D:$dst, (zextloadi16 P:$ptr))]>;
261 def : Pat<(i32 (extloadi16 P:$ptr)),(LOAD32p_16z P:$ptr)>;
263 def LOAD32p_uimm5m2_16z: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off),
264 "$dst = w[$ptr + $off] (z);",
265 [(set D:$dst, (zextloadi16 (add P:$ptr,
268 def : Pat<(i32 (extloadi16 (add P:$ptr, uimm5m2:$off))),
269 (LOAD32p_uimm5m2_16z P:$ptr, imm:$off)>;
271 def LOAD32p_imm17m2_16z: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off),
272 "$dst = w[$ptr + $off] (z);",
274 (zextloadi16 (add P:$ptr, imm17m2:$off)))]>;
276 def : Pat<(i32 (extloadi16 (add P:$ptr, imm17m2:$off))),
277 (LOAD32p_imm17m2_16z P:$ptr, imm:$off)>;
279 def LOAD32p_16s: F1<(outs D:$dst), (ins P:$ptr),
280 "$dst = w[$ptr] (x);",
281 [(set D:$dst, (sextloadi16 P:$ptr))]>;
283 def LOAD32p_uimm5m2_16s: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off),
284 "$dst = w[$ptr + $off] (x);",
286 (sextloadi16 (add P:$ptr, uimm5m2:$off)))]>;
288 def LOAD32p_imm17m2_16s: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off),
289 "$dst = w[$ptr + $off] (x);",
291 (sextloadi16 (add P:$ptr, imm17m2:$off)))]>;
293 def LOAD16pi: F1<(outs D16:$dst), (ins PI:$ptr),
295 [(set D16:$dst, (load PI:$ptr))]>;
297 def LOAD32p_8z: F1<(outs D:$dst), (ins P:$ptr),
298 "$dst = B[$ptr] (z);",
299 [(set D:$dst, (zextloadi8 P:$ptr))]>;
301 def : Pat<(i32 (extloadi8 P:$ptr)), (LOAD32p_8z P:$ptr)>;
302 def : Pat<(i16 (extloadi8 P:$ptr)),
303 (EXTRACT_SUBREG (LOAD32p_8z P:$ptr), bfin_subreg_lo16)>;
304 def : Pat<(i16 (zextloadi8 P:$ptr)),
305 (EXTRACT_SUBREG (LOAD32p_8z P:$ptr), bfin_subreg_lo16)>;
307 def LOAD32p_imm16_8z: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off),
308 "$dst = b[$ptr + $off] (z);",
309 [(set D:$dst, (zextloadi8 (add P:$ptr, imm16:$off)))]>;
311 def : Pat<(i32 (extloadi8 (add P:$ptr, imm16:$off))),
312 (LOAD32p_imm16_8z P:$ptr, imm:$off)>;
313 def : Pat<(i16 (extloadi8 (add P:$ptr, imm16:$off))),
314 (EXTRACT_SUBREG (LOAD32p_imm16_8z P:$ptr, imm:$off),
316 def : Pat<(i16 (zextloadi8 (add P:$ptr, imm16:$off))),
317 (EXTRACT_SUBREG (LOAD32p_imm16_8z P:$ptr, imm:$off),
320 def LOAD32p_8s: F1<(outs D:$dst), (ins P:$ptr),
321 "$dst = b[$ptr] (x);",
322 [(set D:$dst, (sextloadi8 P:$ptr))]>;
324 def : Pat<(i16 (sextloadi8 P:$ptr)),
325 (EXTRACT_SUBREG (LOAD32p_8s P:$ptr), bfin_subreg_lo16)>;
327 def LOAD32p_imm16_8s: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off),
328 "$dst = b[$ptr + $off] (x);",
329 [(set D:$dst, (sextloadi8 (add P:$ptr, imm16:$off)))]>;
331 def : Pat<(i16 (sextloadi8 (add P:$ptr, imm16:$off))),
332 (EXTRACT_SUBREG (LOAD32p_imm16_8s P:$ptr, imm:$off),
334 // Memory loads without patterns
338 multiclass LOAD_incdec<RegisterClass drc, RegisterClass prc,
339 string mem="", string suf=";"> {
340 def _inc : F1<(outs drc:$dst, prc:$ptr_wb), (ins prc:$ptr),
341 !strconcat(!subst("M", mem, "$dst = M[$ptr++]"), suf), []>;
342 def _dec : F1<(outs drc:$dst, prc:$ptr_wb), (ins prc:$ptr),
343 !strconcat(!subst("M", mem, "$dst = M[$ptr--]"), suf), []>;
345 multiclass LOAD_incdecpost<RegisterClass drc, RegisterClass prc,
346 string mem="", string suf=";">
347 : LOAD_incdec<drc, prc, mem, suf> {
348 def _post : F1<(outs drc:$dst, prc:$ptr_wb), (ins prc:$ptr, prc:$off),
349 !strconcat(!subst("M", mem, "$dst = M[$ptr++$off]"), suf), []>;
352 defm LOAD32p: LOAD_incdec<DP, P>;
353 defm LOAD32i: LOAD_incdec<D, I>;
354 defm LOAD8z32p: LOAD_incdec<D, P, "b", " (z);">;
355 defm LOAD8s32p: LOAD_incdec<D, P, "b", " (x);">;
356 defm LOADhi: LOAD_incdec<D16, I, "w">;
357 defm LOAD16z32p: LOAD_incdecpost<D, P, "w", " (z);">;
358 defm LOAD16s32p: LOAD_incdecpost<D, P, "w", " (x);">;
360 def LOAD32p_post: F1<(outs D:$dst, P:$ptr_wb), (ins P:$ptr, P:$off),
361 "$dst = [$ptr ++ $off];", []>;
363 // Note: $fp MUST be FP
364 def LOAD32fp_nimm7m4: F1<(outs DP:$dst), (ins P:$fp, i32imm:$off),
365 "$dst = [$fp - $off];", []>;
367 def LOAD32i: F1<(outs D:$dst), (ins I:$ptr),
368 "$dst = [$ptr];", []>;
369 def LOAD32i_post: F1<(outs D:$dst, I:$ptr_wb), (ins I:$ptr, M:$off),
370 "$dst = [$ptr ++ $off];", []>;
374 def LOADhp_post: F1<(outs D16:$dst, P:$ptr_wb), (ins P:$ptr, P:$off),
375 "$dst = w[$ptr ++ $off];", []>;
380 // Memory stores with patterns
381 def STORE32p: F1<(outs), (ins DP:$val, P:$ptr),
383 [(store DP:$val, P:$ptr)]>;
385 // Pseudo-instructions for storing to a stack slot
386 def STORE32fi: Pseudo<(outs), (ins DP:$val, MEMii:$mem),
387 "${:comment}FI [$mem] = $val;",
388 [(store DP:$val, ADDRspii:$mem)]>;
390 // Note: This stack-storing pseudo-instruction is expanded to multiple insns
391 def STORE16fi: Pseudo<(outs), (ins D16:$val, MEMii:$mem),
392 "${:comment}FI [$mem] = $val;",
393 [(store D16:$val, ADDRspii:$mem)]>;
395 // Pseudo-instructions for storing AnyCC register to a stack slot.
396 // Replaced with D=CC + STORE byte
397 def STORE8fi: Pseudo<(outs), (ins AnyCC:$val, MEMii:$mem),
398 "${:comment}FI b[$mem] = $val;",
399 [(store AnyCC:$val, ADDRspii:$mem)]>;
401 def STORE32p_uimm6m4: F1<(outs), (ins DP:$val, P:$ptr, i32imm:$off),
402 "[$ptr + $off] = $val;",
403 [(store DP:$val, (add P:$ptr, uimm6m4:$off))]>;
405 def STORE32p_imm18m4: F1<(outs), (ins DP:$val, P:$ptr, i32imm:$off),
406 "[$ptr + $off] = $val;",
407 [(store DP:$val, (add P:$ptr, imm18m4:$off))]>;
409 def STORE16pi: F1<(outs), (ins D16:$val, PI:$ptr),
411 [(store D16:$val, PI:$ptr)]>;
413 def STORE8p: F1<(outs), (ins D:$val, P:$ptr),
415 [(truncstorei8 D:$val, P:$ptr)]>;
417 def STORE8p_imm16: F1<(outs), (ins D:$val, P:$ptr, i32imm:$off),
418 "b[$ptr + $off] = $val;",
419 [(truncstorei8 D:$val, (add P:$ptr, imm16:$off))]>;
421 let Constraints = "$ptr = $ptr_wb" in {
423 multiclass STORE_incdec<RegisterClass drc, RegisterClass prc,
424 int off=4, string pre=""> {
425 def _inc : F1<(outs prc:$ptr_wb), (ins drc:$val, prc:$ptr),
426 !strconcat(pre, "[$ptr++] = $val;"),
427 [(set prc:$ptr_wb, (post_store drc:$val, prc:$ptr, off))]>;
428 def _dec : F1<(outs prc:$ptr_wb), (ins drc:$val, prc:$ptr),
429 !strconcat(pre, "[$ptr--] = $val;"),
430 [(set prc:$ptr_wb, (post_store drc:$val, prc:$ptr,
434 defm STORE32p: STORE_incdec<DP, P>;
435 defm STORE16i: STORE_incdec<D16, I, 2, "w">;
436 defm STORE8p: STORE_incdec<D, P, 1, "b">;
438 def STORE32p_post: F1<(outs P:$ptr_wb), (ins D:$val, P:$ptr, P:$off),
439 "[$ptr ++ $off] = $val;",
440 [(set P:$ptr_wb, (post_store D:$val, P:$ptr, P:$off))]>;
442 def STORE16p_post: F1<(outs P:$ptr_wb), (ins D16:$val, P:$ptr, P:$off),
443 "w[$ptr ++ $off] = $val;",
444 [(set P:$ptr_wb, (post_store D16:$val, P:$ptr, P:$off))]>;
447 // Memory stores without patterns
449 let mayStore = 1 in {
451 // Note: only works for $fp == FP
452 def STORE32fp_nimm7m4: F1<(outs), (ins DP:$val, P:$fp, i32imm:$off),
453 "[$fp - $off] = $val;", []>;
455 def STORE32i: F1<(outs), (ins D:$val, I:$ptr),
456 "[$ptr] = $val;", []>;
458 def STORE32i_inc: F1<(outs I:$ptr_wb), (ins D:$val, I:$ptr),
459 "[$ptr++] = $val;", []>;
461 def STORE32i_dec: F1<(outs I:$ptr_wb), (ins D:$val, I:$ptr),
462 "[$ptr--] = $val;", []>;
464 def STORE32i_post: F1<(outs I:$ptr_wb), (ins D:$val, I:$ptr, M:$off),
465 "[$ptr ++ $off] = $val;", []>;
468 def : Pat<(truncstorei16 D:$val, PI:$ptr),
469 (STORE16pi (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS D:$val, D)),
470 bfin_subreg_lo16), PI:$ptr)>;
472 def : Pat<(truncstorei16 (srl D:$val, (i16 16)), PI:$ptr),
473 (STORE16pi (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS D:$val, D)),
474 bfin_subreg_hi16), PI:$ptr)>;
476 def : Pat<(truncstorei8 D16L:$val, P:$ptr),
477 (STORE8p (INSERT_SUBREG (i32 (IMPLICIT_DEF)),
478 (i16 (COPY_TO_REGCLASS D16L:$val, D16L)),
482 //===----------------------------------------------------------------------===//
483 // Table C-11. Move Instructions.
484 //===----------------------------------------------------------------------===//
486 def MOVE: F1<(outs ALL:$dst), (ins ALL:$src),
490 let isTwoAddress = 1 in
491 def MOVEcc: F1<(outs DP:$dst), (ins DP:$src1, DP:$src2, AnyCC:$cc),
492 "if $cc $dst = $src2;",
493 [(set DP:$dst, (select AnyCC:$cc, DP:$src2, DP:$src1))]>;
495 let Defs = [AZ, AN, AC0, V] in {
496 def MOVEzext: F1<(outs D:$dst), (ins D16L:$src),
498 [(set D:$dst, (zext D16L:$src))]>;
500 def MOVEsext: F1<(outs D:$dst), (ins D16L:$src),
502 [(set D:$dst, (sext D16L:$src))]>;
504 def MOVEzext8: F1<(outs D:$dst), (ins D:$src),
505 "$dst = $src.b (z);",
506 [(set D:$dst, (and D:$src, 0xff))]>;
508 def MOVEsext8: F1<(outs D:$dst), (ins D:$src),
509 "$dst = $src.b (x);",
510 [(set D:$dst, (sext_inreg D:$src, i8))]>;
514 def : Pat<(sext_inreg D16L:$src, i8),
515 (EXTRACT_SUBREG (MOVEsext8
516 (INSERT_SUBREG (i32 (IMPLICIT_DEF)),
521 def : Pat<(sext_inreg D:$src, i16),
522 (MOVEsext (EXTRACT_SUBREG D:$src, bfin_subreg_lo16))>;
524 def : Pat<(and D:$src, 0xffff),
525 (MOVEzext (EXTRACT_SUBREG D:$src, bfin_subreg_lo16))>;
527 def : Pat<(i32 (anyext D16L:$src)),
528 (INSERT_SUBREG (i32 (IMPLICIT_DEF)),
529 (i16 (COPY_TO_REGCLASS D16L:$src, D16L)),
532 // TODO Dreg = Dreg_byte (X/Z)
534 // TODO Accumulator moves
536 //===----------------------------------------------------------------------===//
537 // Table C-12. Stack Control Instructions
538 //===----------------------------------------------------------------------===//
540 let Uses = [SP], Defs = [SP] in {
541 def PUSH: F1<(outs), (ins ALL:$src),
542 "[--sp] = $src;", []> { let mayStore = 1; }
544 // NOTE: POP does not work for DP regs, use LOAD instead
545 def POP: F1<(outs ALL:$dst), (ins),
546 "$dst = [sp++];", []> { let mayLoad = 1; }
549 // TODO: push/pop multiple
551 def LINK: F2<(outs), (ins i32imm:$amount),
552 "link $amount;", []>;
554 def UNLINK: F2<(outs), (ins),
557 //===----------------------------------------------------------------------===//
558 // Table C-13. Control Code Bit Management Instructions
559 //===----------------------------------------------------------------------===//
561 multiclass SETCC<PatFrag opnode, PatFrag invnode, string cond, string suf=";"> {
562 def dd : F1<(outs JustCC:$cc), (ins D:$a, D:$b),
563 !strconcat(!subst("XX", cond, "cc = $a XX $b"), suf),
564 [(set JustCC:$cc, (opnode D:$a, D:$b))]>;
566 def ri : F1<(outs JustCC:$cc), (ins DP:$a, i32imm:$b),
567 !strconcat(!subst("XX", cond, "cc = $a XX $b"), suf),
568 [(set JustCC:$cc, (opnode DP:$a, imm3:$b))]>;
570 def pp : F1<(outs JustCC:$cc), (ins P:$a, P:$b),
571 !strconcat(!subst("XX", cond, "cc = $a XX $b"), suf),
574 def ri_not : F1<(outs NotCC:$cc), (ins DP:$a, i32imm:$b),
575 !strconcat(!subst("XX", cond, "cc = $a XX $b"), suf),
576 [(set NotCC:$cc, (invnode DP:$a, imm3:$b))]>;
579 defm SETEQ : SETCC<seteq, setne, "==">;
580 defm SETLT : SETCC<setlt, setge, "<">;
581 defm SETLE : SETCC<setle, setgt, "<=">;
582 defm SETULT : SETCC<setult, setuge, "<", " (iu);">;
583 defm SETULE : SETCC<setule, setugt, "<=", " (iu);">;
585 def SETNEdd : F1<(outs NotCC:$cc), (ins D:$a, D:$b),
587 [(set NotCC:$cc, (setne D:$a, D:$b))]>;
589 def : Pat<(setgt D:$a, D:$b), (SETLTdd D:$b, D:$a)>;
590 def : Pat<(setge D:$a, D:$b), (SETLEdd D:$b, D:$a)>;
591 def : Pat<(setugt D:$a, D:$b), (SETULTdd D:$b, D:$a)>;
592 def : Pat<(setuge D:$a, D:$b), (SETULEdd D:$b, D:$a)>;
594 // TODO: compare pointer for P-P comparisons
595 // TODO: compare accumulator
598 def OR_ac0_cc : F1<(outs), (ins JustCC:$cc),
602 def MOVE_cc_ac0 : F1<(outs JustCC:$cc), (ins),
605 def MOVE_ccncc : F1<(outs JustCC:$cc), (ins NotCC:$sb),
608 def MOVE_ncccc : F1<(outs NotCC:$cc), (ins JustCC:$sb),
611 def MOVECC_zext : F1<(outs D:$dst), (ins JustCC:$cc),
613 [(set D:$dst, (zext JustCC:$cc))]>;
615 def MOVENCC_z : F1<(outs D:$dst), (ins NotCC:$cc),
618 def MOVECC_nz : F1<(outs AnyCC:$cc), (ins D:$src),
620 [(set AnyCC:$cc, (setne D:$src, 0))]>;
622 //===----------------------------------------------------------------------===//
623 // Table C-14. Logical Operations Instructions
624 //===----------------------------------------------------------------------===//
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))]>;
630 def NOT: F1<(outs D:$dst), (ins D:$src),
632 [(set D:$dst, (not D:$src))]>;
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))]>;
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))]>;
642 // missing: BXOR, BXORSHIFT
644 //===----------------------------------------------------------------------===//
645 // Table C-15. Bit Operations Instructions
646 //===----------------------------------------------------------------------===//
648 let isTwoAddress = 1 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))]>;
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))]>;
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))]>;
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),
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),
672 // TODO: DEPOSIT, EXTRACT, BITMUX
674 def ONES: F2<(outs D16L:$dst), (ins D:$src),
676 [(set D16L:$dst, (trunc (ctpop D:$src)))]>;
678 def : Pat<(ctpop D:$src), (MOVEzext (ONES D:$src))>;
680 //===----------------------------------------------------------------------===//
681 // Table C-16. Shift / Rotate Instructions
682 //===----------------------------------------------------------------------===//
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))]>;
693 let Defs = [AZ, AN, V, VS],
694 isTwoAddress = 1 in {
695 defm SRA : SHIFT32<sra, ">>>">;
696 defm SRL : SHIFT32<srl, ">>">;
697 defm SLL : SHIFT32<shl, "<<">;
700 // TODO: automatic switching between 2-addr and 3-addr (?)
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))]>;
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)))]>;
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)))]>;
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)))]>;
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)))]>;
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)))]>;
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))]>;
735 //===----------------------------------------------------------------------===//
736 // Table C-17. Arithmetic Operations Instructions
737 //===----------------------------------------------------------------------===//
741 let Defs = [AZ, AN, AC0, V, VS] in {
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))]>;
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))]>;
751 let isTwoAddress = 1 in
752 def ADDimm7: F1<(outs D:$dst), (ins D:$src1, i32imm:$src2),
754 [(set D:$dst, (add D:$src1, imm7:$src2))]>;
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))]>;
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))]>;
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)>;
769 let Defs = [AZ, AN, V, VS] in
770 def NEG: F1<(outs D:$dst), (ins D:$src),
772 [(set D:$dst, (ineg D:$src))]>;
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;", []>;
778 let isTwoAddress = 1 in
779 def ADDpp_imm7: F1<(outs P:$dst), (ins P:$src1, i32imm:$src2),
780 "$dst += $src2;", []>;
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);", []>;
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))]>;
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))]>;
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)))]>;
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)))]>;
805 let isTwoAddress = 1 in
806 def MUL32: F1<(outs D:$dst), (ins D:$src1, D:$src2),
808 [(set D:$dst, (mul D:$src1, D:$src2))]>;
810 //===----------------------------------------------------------------------===//
811 // Table C-18. External Exent Management Instructions
812 //===----------------------------------------------------------------------===//
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;", []>;
826 //===----------------------------------------------------------------------===//
827 // Table C-19. Cache Control Instructions
828 //===----------------------------------------------------------------------===//
830 //===----------------------------------------------------------------------===//
831 // Table C-20. Video Pixel Operations Instructions
832 //===----------------------------------------------------------------------===//
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))))]>;
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))))]>;
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))))]>;
849 def DISALGNEXCPT : F2<(outs), (ins), "disalignexcpt;", []>;
851 // TODO: BYTEOP3P, BYTEOP16P, BYTEOP1P, BYTEOP2P, BYTEOP16M, SAA,
852 // BYTEPACK, BYTEUNPACK
854 // Table C-21. Vector Operations Instructions
857 def : Pat<(BfinCall (i32 tglobaladdr:$dst)),
858 (CALLa tglobaladdr:$dst)>;
859 def : Pat<(BfinCall (i32 texternalsym:$dst)),
860 (CALLa texternalsym:$dst)>;
862 def : Pat<(sext JustCC:$cc),
863 (NEG (MOVECC_zext JustCC:$cc))>;
864 def : Pat<(anyext JustCC:$cc),
865 (MOVECC_zext JustCC:$cc)>;
866 def : Pat<(i16 (zext JustCC:$cc)),
867 (EXTRACT_SUBREG (MOVECC_zext JustCC:$cc), bfin_subreg_lo16)>;
868 def : Pat<(i16 (sext JustCC:$cc)),
869 (EXTRACT_SUBREG (NEG (MOVECC_zext JustCC:$cc)), bfin_subreg_lo16)>;
870 def : Pat<(i16 (anyext JustCC:$cc)),
871 (EXTRACT_SUBREG (MOVECC_zext JustCC:$cc), bfin_subreg_lo16)>;
873 def : Pat<(i16 (trunc D:$src)),
874 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS D:$src, D)), bfin_subreg_lo16)>;