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