XCoreInstrInfo.td revision 193323
1//===- XCoreInstrInfo.td - Target Description for XCore ----*- tablegen -*-===//
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 XCore instructions in TableGen format.
11//
12//===----------------------------------------------------------------------===//
13
14// Uses of CP, DP are not currently reflected in the patterns, since
15// having a physical register as an operand prevents loop hoisting and
16// since the value of these registers never changes during the life of the
17// function.
18
19//===----------------------------------------------------------------------===//
20// Instruction format superclass.
21//===----------------------------------------------------------------------===//
22
23include "XCoreInstrFormats.td"
24
25//===----------------------------------------------------------------------===//
26// Feature predicates.
27//===----------------------------------------------------------------------===//
28
29// HasXS1A - This predicate is true when the target processor supports XS1A
30// instructions.
31def HasXS1A   : Predicate<"Subtarget.isXS1A()">;
32
33// HasXS1B - This predicate is true when the target processor supports XS1B
34// instructions.
35def HasXS1B : Predicate<"Subtarget.isXS1B()">;
36
37//===----------------------------------------------------------------------===//
38// XCore specific DAG Nodes.
39//
40
41// Call
42def SDT_XCoreBranchLink : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
43def XCoreBranchLink     : SDNode<"XCoreISD::BL",SDT_XCoreBranchLink,
44                            [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
45
46def XCoreRetsp       : SDNode<"XCoreISD::RETSP", SDTNone,
47                         [SDNPHasChain, SDNPOptInFlag]>;
48
49def SDT_XCoreAddress    : SDTypeProfile<1, 1,
50                            [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
51
52def pcrelwrapper : SDNode<"XCoreISD::PCRelativeWrapper", SDT_XCoreAddress,
53                           []>;
54
55def dprelwrapper : SDNode<"XCoreISD::DPRelativeWrapper", SDT_XCoreAddress,
56                           []>;
57
58def cprelwrapper : SDNode<"XCoreISD::CPRelativeWrapper", SDT_XCoreAddress,
59                           []>;
60
61def SDT_XCoreStwsp    : SDTypeProfile<0, 2, [SDTCisInt<1>]>;
62def XCoreStwsp        : SDNode<"XCoreISD::STWSP", SDT_XCoreStwsp,
63                               [SDNPHasChain]>;
64
65// These are target-independent nodes, but have target-specific formats.
66def SDT_XCoreCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>;
67def SDT_XCoreCallSeqEnd   : SDCallSeqEnd<[ SDTCisVT<0, i32>,
68                                        SDTCisVT<1, i32> ]>;
69
70def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_XCoreCallSeqStart,
71                           [SDNPHasChain, SDNPOutFlag]>;
72def callseq_end   : SDNode<"ISD::CALLSEQ_END",   SDT_XCoreCallSeqEnd,
73                           [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
74
75//===----------------------------------------------------------------------===//
76// Instruction Pattern Stuff
77//===----------------------------------------------------------------------===//
78
79def div4_xform : SDNodeXForm<imm, [{
80  // Transformation function: imm/4
81  assert(N->getZExtValue() % 4 == 0);
82  return getI32Imm(N->getZExtValue()/4);
83}]>;
84
85def msksize_xform : SDNodeXForm<imm, [{
86  // Transformation function: get the size of a mask
87  assert(isMask_32(N->getZExtValue()));
88  // look for the first non-zero bit
89  return getI32Imm(32 - CountLeadingZeros_32(N->getZExtValue()));
90}]>;
91
92def neg_xform : SDNodeXForm<imm, [{
93  // Transformation function: -imm
94  uint32_t value = N->getZExtValue();
95  return getI32Imm(-value);
96}]>;
97
98def div4neg_xform : SDNodeXForm<imm, [{
99  // Transformation function: -imm/4
100  uint32_t value = N->getZExtValue();
101  assert(-value % 4 == 0);
102  return getI32Imm(-value/4);
103}]>;
104
105def immUs4Neg : PatLeaf<(imm), [{
106  uint32_t value = (uint32_t)N->getZExtValue();
107  return (-value)%4 == 0 && (-value)/4 <= 11;
108}]>;
109
110def immUs4 : PatLeaf<(imm), [{
111  uint32_t value = (uint32_t)N->getZExtValue();
112  return value%4 == 0 && value/4 <= 11;
113}]>;
114
115def immUsNeg : PatLeaf<(imm), [{
116  return -((uint32_t)N->getZExtValue()) <= 11;
117}]>;
118
119def immUs : PatLeaf<(imm), [{
120  return (uint32_t)N->getZExtValue() <= 11;
121}]>;
122
123def immU6 : PatLeaf<(imm), [{
124  return (uint32_t)N->getZExtValue() < (1 << 6);
125}]>;
126
127def immU10 : PatLeaf<(imm), [{
128  return (uint32_t)N->getZExtValue() < (1 << 10);
129}]>;
130
131def immU16 : PatLeaf<(imm), [{
132  return (uint32_t)N->getZExtValue() < (1 << 16);
133}]>;
134
135def immU20 : PatLeaf<(imm), [{
136  return (uint32_t)N->getZExtValue() < (1 << 20);
137}]>;
138
139// FIXME check subtarget. Currently we check if the immediate
140// is in the common subset of legal immediate values for both
141// XS1A and XS1B.
142def immMskBitp : PatLeaf<(imm), [{
143  uint32_t value = (uint32_t)N->getZExtValue();
144  if (!isMask_32(value)) {
145    return false;
146  }
147  int msksize = 32 - CountLeadingZeros_32(value);
148  return (msksize >= 1 && msksize <= 8)
149          || msksize == 16
150          || msksize == 24
151          || msksize == 32;
152}]>;
153
154// FIXME check subtarget. Currently we check if the immediate
155// is in the common subset of legal immediate values for both
156// XS1A and XS1B.
157def immBitp : PatLeaf<(imm), [{
158  uint32_t value = (uint32_t)N->getZExtValue();
159  return (value >= 1 && value <= 8)
160          || value == 16
161          || value == 24
162          || value == 32;
163}]>;
164
165def lda16f : PatFrag<(ops node:$addr, node:$offset),
166                     (add node:$addr, (shl node:$offset, 1))>;
167def lda16b : PatFrag<(ops node:$addr, node:$offset),
168                     (sub node:$addr, (shl node:$offset, 1))>;
169def ldawf : PatFrag<(ops node:$addr, node:$offset),
170                     (add node:$addr, (shl node:$offset, 2))>;
171def ldawb : PatFrag<(ops node:$addr, node:$offset),
172                     (sub node:$addr, (shl node:$offset, 2))>;
173
174// Instruction operand types
175def calltarget  : Operand<i32>;
176def brtarget : Operand<OtherVT>;
177def pclabel : Operand<i32>;
178
179// Addressing modes
180def ADDRspii : ComplexPattern<i32, 2, "SelectADDRspii", [add, frameindex], []>;
181def ADDRdpii : ComplexPattern<i32, 2, "SelectADDRdpii", [add, dprelwrapper],
182                 []>;
183def ADDRcpii : ComplexPattern<i32, 2, "SelectADDRcpii", [add, cprelwrapper],
184                 []>;
185
186// Address operands
187def MEMii : Operand<i32> {
188  let PrintMethod = "printMemOperand";
189  let MIOperandInfo = (ops i32imm, i32imm);
190}
191
192//===----------------------------------------------------------------------===//
193// Instruction Class Templates
194//===----------------------------------------------------------------------===//
195
196// Three operand short
197
198multiclass F3R_2RUS<string OpcStr, SDNode OpNode> {
199  def _3r: _F3R<
200                 (outs GRRegs:$dst), (ins GRRegs:$b, GRRegs:$c),
201                 !strconcat(OpcStr, " $dst, $b, $c"),
202                 [(set GRRegs:$dst, (OpNode GRRegs:$b, GRRegs:$c))]>;
203  def _2rus : _F2RUS<
204                 (outs GRRegs:$dst), (ins GRRegs:$b, i32imm:$c),
205                 !strconcat(OpcStr, " $dst, $b, $c"),
206                 [(set GRRegs:$dst, (OpNode GRRegs:$b, immUs:$c))]>;
207}
208
209multiclass F3R_2RUS_np<string OpcStr> {
210  def _3r: _F3R<
211                 (outs GRRegs:$dst), (ins GRRegs:$b, GRRegs:$c),
212                 !strconcat(OpcStr, " $dst, $b, $c"),
213                 []>;
214  def _2rus : _F2RUS<
215                 (outs GRRegs:$dst), (ins GRRegs:$b, i32imm:$c),
216                 !strconcat(OpcStr, " $dst, $b, $c"),
217                 []>;
218}
219
220multiclass F3R_2RBITP<string OpcStr, SDNode OpNode> {
221  def _3r: _F3R<
222                 (outs GRRegs:$dst), (ins GRRegs:$b, GRRegs:$c),
223                 !strconcat(OpcStr, " $dst, $b, $c"),
224                 [(set GRRegs:$dst, (OpNode GRRegs:$b, GRRegs:$c))]>;
225  def _2rus : _F2RUS<
226                 (outs GRRegs:$dst), (ins GRRegs:$b, i32imm:$c),
227                 !strconcat(OpcStr, " $dst, $b, $c"),
228                 [(set GRRegs:$dst, (OpNode GRRegs:$b, immBitp:$c))]>;
229}
230
231class F3R<string OpcStr, SDNode OpNode> : _F3R<
232                 (outs GRRegs:$dst), (ins GRRegs:$b, GRRegs:$c),
233                 !strconcat(OpcStr, " $dst, $b, $c"),
234                 [(set GRRegs:$dst, (OpNode GRRegs:$b, GRRegs:$c))]>;
235
236class F3R_np<string OpcStr> : _F3R<
237                 (outs GRRegs:$dst), (ins GRRegs:$b, GRRegs:$c),
238                 !strconcat(OpcStr, " $dst, $b, $c"),
239                 []>;
240// Three operand long
241
242/// FL3R_L2RUS multiclass - Define a normal FL3R/FL2RUS pattern in one shot.
243multiclass FL3R_L2RUS<string OpcStr, SDNode OpNode> {
244  def _l3r: _FL3R<
245                 (outs GRRegs:$dst), (ins GRRegs:$b, GRRegs:$c),
246                 !strconcat(OpcStr, " $dst, $b, $c"),
247                 [(set GRRegs:$dst, (OpNode GRRegs:$b, GRRegs:$c))]>;
248  def _l2rus : _FL2RUS<
249                 (outs GRRegs:$dst), (ins GRRegs:$b, i32imm:$c),
250                 !strconcat(OpcStr, " $dst, $b, $c"),
251                 [(set GRRegs:$dst, (OpNode GRRegs:$b, immUs:$c))]>;
252}
253
254/// FL3R_L2RUS multiclass - Define a normal FL3R/FL2RUS pattern in one shot.
255multiclass FL3R_L2RBITP<string OpcStr, SDNode OpNode> {
256  def _l3r: _FL3R<
257                 (outs GRRegs:$dst), (ins GRRegs:$b, GRRegs:$c),
258                 !strconcat(OpcStr, " $dst, $b, $c"),
259                 [(set GRRegs:$dst, (OpNode GRRegs:$b, GRRegs:$c))]>;
260  def _l2rus : _FL2RUS<
261                 (outs GRRegs:$dst), (ins GRRegs:$b, i32imm:$c),
262                 !strconcat(OpcStr, " $dst, $b, $c"),
263                 [(set GRRegs:$dst, (OpNode GRRegs:$b, immBitp:$c))]>;
264}
265
266class FL3R<string OpcStr, SDNode OpNode> : _FL3R<
267                 (outs GRRegs:$dst), (ins GRRegs:$b, GRRegs:$c),
268                 !strconcat(OpcStr, " $dst, $b, $c"),
269                 [(set GRRegs:$dst, (OpNode GRRegs:$b, GRRegs:$c))]>;
270
271// Register - U6
272// Operand register - U6
273multiclass FRU6_LRU6_branch<string OpcStr> {
274  def _ru6: _FRU6<
275                 (outs), (ins GRRegs:$cond, brtarget:$dest),
276                 !strconcat(OpcStr, " $cond, $dest"),
277                 []>;
278  def _lru6: _FLRU6<
279                 (outs), (ins GRRegs:$cond, brtarget:$dest),
280                 !strconcat(OpcStr, " $cond, $dest"),
281                 []>;
282}
283
284multiclass FRU6_LRU6_cp<string OpcStr> {
285  def _ru6: _FRU6<
286                 (outs GRRegs:$dst), (ins i32imm:$a),
287                 !strconcat(OpcStr, " $dst, cp[$a]"),
288                 []>;
289  def _lru6: _FLRU6<
290                 (outs GRRegs:$dst), (ins i32imm:$a),
291                 !strconcat(OpcStr, " $dst, cp[$a]"),
292                 []>;
293}
294
295// U6
296multiclass FU6_LU6<string OpcStr, SDNode OpNode> {
297  def _u6: _FU6<
298                 (outs), (ins i32imm:$b),
299                 !strconcat(OpcStr, " $b"),
300                 [(OpNode immU6:$b)]>;
301  def _lu6: _FLU6<
302                 (outs), (ins i32imm:$b),
303                 !strconcat(OpcStr, " $b"),
304                 [(OpNode immU16:$b)]>;
305}
306
307multiclass FU6_LU6_np<string OpcStr> {
308  def _u6: _FU6<
309                 (outs), (ins i32imm:$b),
310                 !strconcat(OpcStr, " $b"),
311                 []>;
312  def _lu6: _FLU6<
313                 (outs), (ins i32imm:$b),
314                 !strconcat(OpcStr, " $b"),
315                 []>;
316}
317
318// U10
319multiclass FU10_LU10_np<string OpcStr> {
320  def _u10: _FU10<
321                 (outs), (ins i32imm:$b),
322                 !strconcat(OpcStr, " $b"),
323                 []>;
324  def _lu10: _FLU10<
325                 (outs), (ins i32imm:$b),
326                 !strconcat(OpcStr, " $b"),
327                 []>;
328}
329
330// Two operand short
331
332class F2R_np<string OpcStr> : _F2R<
333                 (outs GRRegs:$dst), (ins GRRegs:$b),
334                 !strconcat(OpcStr, " $dst, $b"),
335                 []>;
336
337// Two operand long
338
339//===----------------------------------------------------------------------===//
340// Pseudo Instructions
341//===----------------------------------------------------------------------===//
342
343let Defs = [SP], Uses = [SP] in {
344def ADJCALLSTACKDOWN : PseudoInstXCore<(outs), (ins i32imm:$amt),
345                               "${:comment} ADJCALLSTACKDOWN $amt",
346                               [(callseq_start timm:$amt)]>;
347def ADJCALLSTACKUP : PseudoInstXCore<(outs), (ins i32imm:$amt1, i32imm:$amt2),
348                            "${:comment} ADJCALLSTACKUP $amt1",
349                            [(callseq_end timm:$amt1, timm:$amt2)]>;
350}
351
352def LDWFI : PseudoInstXCore<(outs GRRegs:$dst), (ins MEMii:$addr),
353                             "${:comment} LDWFI $dst, $addr",
354                             [(set GRRegs:$dst, (load ADDRspii:$addr))]>;
355
356def LDAWFI : PseudoInstXCore<(outs GRRegs:$dst), (ins MEMii:$addr),
357                             "${:comment} LDAWFI $dst, $addr",
358                             [(set GRRegs:$dst, ADDRspii:$addr)]>;
359
360def STWFI : PseudoInstXCore<(outs), (ins GRRegs:$src, MEMii:$addr),
361                            "${:comment} STWFI $src, $addr",
362                            [(store GRRegs:$src, ADDRspii:$addr)]>;
363
364// SELECT_CC_* - Used to implement the SELECT_CC DAG operation.  Expanded by the
365// scheduler into a branch sequence.
366let usesCustomDAGSchedInserter = 1 in {
367  def SELECT_CC : PseudoInstXCore<(outs GRRegs:$dst),
368                              (ins GRRegs:$cond, GRRegs:$T, GRRegs:$F),
369                              "${:comment} SELECT_CC PSEUDO!",
370                              [(set GRRegs:$dst,
371                                 (select GRRegs:$cond, GRRegs:$T, GRRegs:$F))]>;
372}
373
374//===----------------------------------------------------------------------===//
375// Instructions
376//===----------------------------------------------------------------------===//
377
378// Three operand short
379defm ADD : F3R_2RUS<"add", add>;
380defm SUB : F3R_2RUS<"sub", sub>;
381let neverHasSideEffects = 1 in {
382defm EQ : F3R_2RUS_np<"eq">;
383def LSS_3r : F3R_np<"lss">;
384def LSU_3r : F3R_np<"lsu">;
385}
386def AND_3r : F3R<"and", and>;
387def OR_3r : F3R<"or", or>;
388
389let mayLoad=1 in {
390def LDW_3r : _F3R<(outs GRRegs:$dst), (ins GRRegs:$addr, GRRegs:$offset),
391                  "ldw $dst, $addr[$offset]",
392                  []>;
393
394def LDW_2rus : _F2RUS<(outs GRRegs:$dst), (ins GRRegs:$addr, i32imm:$offset),
395                  "ldw $dst, $addr[$offset]",
396                  []>;
397
398def LD16S_3r :  _F3R<(outs GRRegs:$dst), (ins GRRegs:$addr, GRRegs:$offset),
399                  "ld16s $dst, $addr[$offset]",
400                  []>;
401
402def LD8U_3r :  _F3R<(outs GRRegs:$dst), (ins GRRegs:$addr, GRRegs:$offset),
403                  "ld8u $dst, $addr[$offset]",
404                  []>;
405}
406
407let mayStore=1 in {
408def STW_3r : _F3R<(outs), (ins GRRegs:$val, GRRegs:$addr, GRRegs:$offset),
409                  "stw $val, $addr[$offset]",
410                  []>;
411
412def STW_2rus : _F2RUS<(outs), (ins GRRegs:$val, GRRegs:$addr, i32imm:$offset),
413                  "stw $val, $addr[$offset]",
414                  []>;
415}
416
417defm SHL : F3R_2RBITP<"shl", shl>;
418defm SHR : F3R_2RBITP<"shr", srl>;
419// TODO tsetr
420
421// Three operand long
422def LDAWF_l3r : _FL3R<(outs GRRegs:$dst), (ins GRRegs:$addr, GRRegs:$offset),
423                  "ldaw $dst, $addr[$offset]",
424                  [(set GRRegs:$dst, (ldawf GRRegs:$addr, GRRegs:$offset))]>;
425
426let neverHasSideEffects = 1 in
427def LDAWF_l2rus : _FL2RUS<(outs GRRegs:$dst),
428                    (ins GRRegs:$addr, i32imm:$offset),
429                    "ldaw $dst, $addr[$offset]",
430                    []>;
431
432def LDAWB_l3r : _FL3R<(outs GRRegs:$dst), (ins GRRegs:$addr, GRRegs:$offset),
433                  "ldaw $dst, $addr[-$offset]",
434                  [(set GRRegs:$dst, (ldawb GRRegs:$addr, GRRegs:$offset))]>;
435
436let neverHasSideEffects = 1 in
437def LDAWB_l2rus : _FL2RUS<(outs GRRegs:$dst),
438                    (ins GRRegs:$addr, i32imm:$offset),
439                    "ldaw $dst, $addr[-$offset]",
440                    []>;
441
442def LDA16F_l3r : _FL3R<(outs GRRegs:$dst), (ins GRRegs:$addr, GRRegs:$offset),
443                  "lda16 $dst, $addr[$offset]",
444                  [(set GRRegs:$dst, (lda16f GRRegs:$addr, GRRegs:$offset))]>;
445
446def LDA16B_l3r : _FL3R<(outs GRRegs:$dst), (ins GRRegs:$addr, GRRegs:$offset),
447                  "lda16 $dst, $addr[-$offset]",
448                  [(set GRRegs:$dst, (lda16b GRRegs:$addr, GRRegs:$offset))]>;
449
450def MUL_l3r : FL3R<"mul", mul>;
451// Instructions which may trap are marked as side effecting.
452let hasSideEffects = 1 in {
453def DIVS_l3r : FL3R<"divs", sdiv>;
454def DIVU_l3r : FL3R<"divu", udiv>;
455def REMS_l3r : FL3R<"rems", srem>;
456def REMU_l3r : FL3R<"remu", urem>;
457}
458def XOR_l3r : FL3R<"xor", xor>;
459defm ASHR : FL3R_L2RBITP<"ashr", sra>;
460// TODO crc32, crc8, inpw, outpw
461let mayStore=1 in {
462def ST16_l3r : _FL3R<(outs), (ins GRRegs:$val, GRRegs:$addr, GRRegs:$offset),
463                "st16 $val, $addr[$offset]",
464                []>;
465
466def ST8_l3r : _FL3R<(outs), (ins GRRegs:$val, GRRegs:$addr, GRRegs:$offset),
467                "st8 $val, $addr[$offset]",
468                []>;
469}
470
471// Four operand long
472let Predicates = [HasXS1B], Constraints = "$src1 = $dst1,$src2 = $dst2" in {
473def MACCU_l4r : _L4R<(outs GRRegs:$dst1, GRRegs:$dst2),
474                    (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3,
475                      GRRegs:$src4),
476                    "maccu $dst1, $dst2, $src3, $src4",
477                    []>;
478
479def MACCS_l4r : _L4R<(outs GRRegs:$dst1, GRRegs:$dst2),
480                    (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3,
481                      GRRegs:$src4),
482                    "maccs $dst1, $dst2, $src3, $src4",
483                    []>;
484}
485
486// Five operand long
487
488let Predicates = [HasXS1B] in {
489def LADD_l5r : _L5R<(outs GRRegs:$dst1, GRRegs:$dst2),
490                    (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3),
491                    "ladd $dst1, $dst2, $src1, $src2, $src3",
492                    []>;
493
494def LSUB_l5r : _L5R<(outs GRRegs:$dst1, GRRegs:$dst2),
495                    (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3),
496                    "lsub $dst1, $dst2, $src1, $src2, $src3",
497                    []>;
498
499def LDIV_l5r : _L5R<(outs GRRegs:$dst1, GRRegs:$dst2),
500                    (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3),
501                    "ldiv $dst1, $dst2, $src1, $src2, $src3",
502                    []>;
503}
504
505// Six operand long
506
507def LMUL_l6r : _L6R<(outs GRRegs:$dst1, GRRegs:$dst2),
508                    (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3,
509                      GRRegs:$src4),
510                    "lmul $dst1, $dst2, $src1, $src2, $src3, $src4",
511                    []>;
512
513let Predicates = [HasXS1A] in
514def MACC_l6r : _L6R<(outs GRRegs:$dst1, GRRegs:$dst2),
515                    (ins GRRegs:$src1, GRRegs:$src2, GRRegs:$src3,
516                      GRRegs:$src4),
517                    "macc $dst1, $dst2, $src1, $src2, $src3, $src4",
518                    []>;
519
520// Register - U6
521
522//let Uses = [DP] in ...
523let neverHasSideEffects = 1, isReMaterializable = 1 in
524def LDAWDP_ru6: _FRU6<(outs GRRegs:$dst), (ins MEMii:$a),
525                    "ldaw $dst, dp[$a]",
526                    []>;
527
528let isReMaterializable = 1 in                    
529def LDAWDP_lru6: _FLRU6<
530                    (outs GRRegs:$dst), (ins MEMii:$a),
531                    "ldaw $dst, dp[$a]",
532                    [(set GRRegs:$dst, ADDRdpii:$a)]>;
533
534let mayLoad=1 in
535def LDWDP_ru6: _FRU6<(outs GRRegs:$dst), (ins MEMii:$a),
536                    "ldw $dst, dp[$a]",
537                    []>;
538                    
539def LDWDP_lru6: _FLRU6<
540                    (outs GRRegs:$dst), (ins MEMii:$a),
541                    "ldw $dst, dp[$a]",
542                    [(set GRRegs:$dst, (load ADDRdpii:$a))]>;
543
544let mayStore=1 in
545def STWDP_ru6 : _FRU6<(outs), (ins GRRegs:$val, MEMii:$addr),
546                  "stw $val, dp[$addr]",
547                  []>;
548
549def STWDP_lru6 : _FLRU6<(outs), (ins GRRegs:$val, MEMii:$addr),
550                  "stw $val, dp[$addr]",
551                  [(store GRRegs:$val, ADDRdpii:$addr)]>;
552
553//let Uses = [CP] in ..
554let mayLoad = 1, isReMaterializable = 1 in
555defm LDWCP : FRU6_LRU6_cp<"ldw">;
556
557let Uses = [SP] in {
558let mayStore=1 in {
559def STWSP_ru6 : _FRU6<
560                 (outs), (ins GRRegs:$val, i32imm:$index),
561                 "stw $val, sp[$index]",
562                 [(XCoreStwsp GRRegs:$val, immU6:$index)]>;
563
564def STWSP_lru6 : _FLRU6<
565                 (outs), (ins GRRegs:$val, i32imm:$index),
566                 "stw $val, sp[$index]",
567                 [(XCoreStwsp GRRegs:$val, immU16:$index)]>;
568}
569
570let mayLoad=1 in {
571def LDWSP_ru6 : _FRU6<
572                 (outs GRRegs:$dst), (ins i32imm:$b),
573                 "ldw $dst, sp[$b]",
574                 []>;
575
576def LDWSP_lru6 : _FLRU6<
577                 (outs GRRegs:$dst), (ins i32imm:$b),
578                 "ldw $dst, sp[$b]",
579                 []>;
580}
581
582let neverHasSideEffects = 1 in {
583def LDAWSP_ru6 : _FRU6<
584                 (outs GRRegs:$dst), (ins i32imm:$b),
585                 "ldaw $dst, sp[$b]",
586                 []>;
587
588def LDAWSP_lru6 : _FLRU6<
589                 (outs GRRegs:$dst), (ins i32imm:$b),
590                 "ldaw $dst, sp[$b]",
591                 []>;
592
593def LDAWSP_ru6_RRegs : _FRU6<
594                 (outs RRegs:$dst), (ins i32imm:$b),
595                 "ldaw $dst, sp[$b]",
596                 []>;
597
598def LDAWSP_lru6_RRegs : _FLRU6<
599                 (outs RRegs:$dst), (ins i32imm:$b),
600                 "ldaw $dst, sp[$b]",
601                 []>;
602}
603}
604
605let isReMaterializable = 1 in {
606def LDC_ru6 : _FRU6<
607                 (outs GRRegs:$dst), (ins i32imm:$b),
608                 "ldc $dst, $b",
609                 [(set GRRegs:$dst, immU6:$b)]>;
610
611def LDC_lru6 : _FLRU6<
612                 (outs GRRegs:$dst), (ins i32imm:$b),
613                 "ldc $dst, $b",
614                 [(set GRRegs:$dst, immU16:$b)]>;
615}
616
617// Operand register - U6
618// TODO setc
619let isBranch = 1, isTerminator = 1 in {
620defm BRFT: FRU6_LRU6_branch<"bt">;
621defm BRBT: FRU6_LRU6_branch<"bt">;
622defm BRFF: FRU6_LRU6_branch<"bf">;
623defm BRBF: FRU6_LRU6_branch<"bf">;
624}
625
626// U6
627let Defs = [SP], Uses = [SP] in {
628let neverHasSideEffects = 1 in
629defm EXTSP : FU6_LU6_np<"extsp">;
630let mayStore = 1 in
631defm ENTSP : FU6_LU6_np<"entsp">;
632
633let isReturn = 1, isTerminator = 1, mayLoad = 1 in {
634defm RETSP : FU6_LU6<"retsp", XCoreRetsp>;
635}
636}
637
638// TODO extdp, kentsp, krestsp, blat, setsr
639// clrsr, getsr, kalli
640let isBranch = 1, isTerminator = 1 in {
641def BRBU_u6 : _FU6<
642                 (outs),
643                 (ins brtarget:$target),
644                 "bu $target",
645                 []>;
646
647def BRBU_lu6 : _FLU6<
648                 (outs),
649                 (ins brtarget:$target),
650                 "bu $target",
651                 []>;
652
653def BRFU_u6 : _FU6<
654                 (outs),
655                 (ins brtarget:$target),
656                 "bu $target",
657                 []>;
658
659def BRFU_lu6 : _FLU6<
660                 (outs),
661                 (ins brtarget:$target),
662                 "bu $target",
663                 []>;
664}
665
666//let Uses = [CP] in ...
667let Predicates = [HasXS1B], Defs = [R11], neverHasSideEffects = 1,
668  isReMaterializable = 1 in
669def LDAWCP_u6: _FRU6<(outs), (ins MEMii:$a),
670                    "ldaw r11, cp[$a]",
671                    []>;
672
673let Predicates = [HasXS1B], Defs = [R11], isReMaterializable = 1 in
674def LDAWCP_lu6: _FLRU6<
675                    (outs), (ins MEMii:$a),
676                    "ldaw r11, cp[$a]",
677                    [(set R11, ADDRcpii:$a)]>;
678
679// U10
680// TODO ldwcpl, blacp
681
682let Defs = [R11], isReMaterializable = 1, neverHasSideEffects = 1 in
683def LDAP_u10 : _FU10<
684                  (outs),
685                  (ins i32imm:$addr),
686                  "ldap r11, $addr",
687                  []>;
688
689let Defs = [R11], isReMaterializable = 1 in
690def LDAP_lu10 : _FLU10<
691                  (outs),
692                  (ins i32imm:$addr),
693                  "ldap r11, $addr",
694                  [(set R11, (pcrelwrapper tglobaladdr:$addr))]>;
695
696let isCall=1,
697// All calls clobber the the link register and the non-callee-saved registers:
698Defs = [R0, R1, R2, R3, R11, LR] in {
699def BL_u10 : _FU10<
700                  (outs),
701                  (ins calltarget:$target, variable_ops),
702                  "bl $target",
703                  [(XCoreBranchLink immU10:$target)]>;
704
705def BL_lu10 : _FLU10<
706                  (outs),
707                  (ins calltarget:$target, variable_ops),
708                  "bl $target",
709                  [(XCoreBranchLink immU20:$target)]>;
710}
711
712// Two operand short
713// TODO getr, getst
714def NOT : _F2R<(outs GRRegs:$dst), (ins GRRegs:$b),
715                 "not $dst, $b",
716                 [(set GRRegs:$dst, (not GRRegs:$b))]>;
717
718def NEG : _F2R<(outs GRRegs:$dst), (ins GRRegs:$b),
719                 "neg $dst, $b",
720                 [(set GRRegs:$dst, (ineg GRRegs:$b))]>;
721
722// TODO setd, eet, eef, getts, setpt, outct, inct, chkct, outt, intt, out,
723// in, outshr, inshr, testct, testwct, tinitpc, tinitdp, tinitsp, tinitcp,
724// tsetmr, sext (reg), zext (reg)
725let isTwoAddress = 1 in {
726let neverHasSideEffects = 1 in
727def SEXT_rus : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$src1, i32imm:$src2),
728                 "sext $dst, $src2",
729                 []>;
730
731let neverHasSideEffects = 1 in
732def ZEXT_rus : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$src1, i32imm:$src2),
733                 "zext $dst, $src2",
734                 []>;
735
736def ANDNOT_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$src1, GRRegs:$src2),
737                 "andnot $dst, $src2",
738                 [(set GRRegs:$dst, (and GRRegs:$src1, (not GRRegs:$src2)))]>;
739}
740
741let isReMaterializable = 1, neverHasSideEffects = 1 in
742def MKMSK_rus : _FRUS<(outs GRRegs:$dst), (ins i32imm:$size),
743                 "mkmsk $dst, $size",
744                 []>;
745
746def MKMSK_2r : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$size),
747                 "mkmsk $dst, $size",
748                 [(set GRRegs:$dst, (add (shl 1, GRRegs:$size), 0xffffffff))]>;
749
750// Two operand long
751// TODO settw, setclk, setrdy, setpsc, endin, peek,
752// getd, testlcl, tinitlr, getps, setps
753def BITREV_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src),
754                 "bitrev $dst, $src",
755                 [(set GRRegs:$dst, (int_xcore_bitrev GRRegs:$src))]>;
756
757def BYTEREV_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src),
758                 "byterev $dst, $src",
759                 [(set GRRegs:$dst, (bswap GRRegs:$src))]>;
760
761def CLZ_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src),
762                 "clz $dst, $src",
763                 [(set GRRegs:$dst, (ctlz GRRegs:$src))]>;
764
765// One operand short
766// TODO edu, eeu, waitet, waitef, freer, tstart, msync, mjoin, syncr, clrtp
767// bru, setdp, setcp, setv, setev, kcall
768// dgetreg
769let isBranch=1, isIndirectBranch=1, isTerminator=1 in
770def BAU_1r : _F1R<(outs), (ins GRRegs:$addr),
771                 "bau $addr",
772                 [(brind GRRegs:$addr)]>;
773
774let Defs=[SP], neverHasSideEffects=1 in
775def SETSP_1r : _F1R<(outs), (ins GRRegs:$src),
776                 "set sp, $src",
777                 []>;
778
779let isBarrier = 1, hasCtrlDep = 1 in 
780def ECALLT_1r : _F1R<(outs), (ins GRRegs:$src),
781                 "ecallt $src",
782                 []>;
783
784let isBarrier = 1, hasCtrlDep = 1 in 
785def ECALLF_1r : _F1R<(outs), (ins GRRegs:$src),
786                 "ecallf $src",
787                 []>;
788
789let isCall=1, 
790// All calls clobber the the link register and the non-callee-saved registers:
791Defs = [R0, R1, R2, R3, R11, LR] in {
792def BLA_1r : _F1R<(outs), (ins GRRegs:$addr, variable_ops),
793                 "bla $addr",
794                 [(XCoreBranchLink GRRegs:$addr)]>;
795}
796
797// Zero operand short
798// TODO waiteu, clre, ssync, freet, ldspc, stspc, ldssr, stssr, ldsed, stsed,
799// stet, geted, getet, getkep, getksp, setkep, getid, kret, dcall, dret,
800// dentsp, drestsp
801
802let Defs = [R11] in
803def GETID_0R : _F0R<(outs), (ins),
804                 "get r11, id",
805                 [(set R11, (int_xcore_getid))]>;
806
807//===----------------------------------------------------------------------===//
808// Non-Instruction Patterns
809//===----------------------------------------------------------------------===//
810
811def : Pat<(XCoreBranchLink tglobaladdr:$addr), (BL_lu10 tglobaladdr:$addr)>;
812def : Pat<(XCoreBranchLink texternalsym:$addr), (BL_lu10 texternalsym:$addr)>;
813
814/// sext_inreg
815def : Pat<(sext_inreg GRRegs:$b, i1), (SEXT_rus GRRegs:$b, 1)>;
816def : Pat<(sext_inreg GRRegs:$b, i8), (SEXT_rus GRRegs:$b, 8)>;
817def : Pat<(sext_inreg GRRegs:$b, i16), (SEXT_rus GRRegs:$b, 16)>;
818
819/// loads
820def : Pat<(zextloadi8 (add GRRegs:$addr, GRRegs:$offset)),
821          (LD8U_3r GRRegs:$addr, GRRegs:$offset)>;
822def : Pat<(zextloadi8 GRRegs:$addr), (LD8U_3r GRRegs:$addr, (LDC_ru6 0))>;
823
824def : Pat<(zextloadi16 (lda16f GRRegs:$addr, GRRegs:$offset)),
825          (LD16S_3r GRRegs:$addr, GRRegs:$offset)>;
826def : Pat<(sextloadi16 GRRegs:$addr), (LD16S_3r GRRegs:$addr, (LDC_ru6 0))>;
827
828def : Pat<(load (ldawf GRRegs:$addr, GRRegs:$offset)),
829          (LDW_3r GRRegs:$addr, GRRegs:$offset)>;
830def : Pat<(load (add GRRegs:$addr, immUs4:$offset)),
831          (LDW_2rus GRRegs:$addr, (div4_xform immUs4:$offset))>;
832def : Pat<(load GRRegs:$addr), (LDW_2rus GRRegs:$addr, 0)>;
833
834/// anyext
835def : Pat<(extloadi8 (add GRRegs:$addr, GRRegs:$offset)),
836          (LD8U_3r GRRegs:$addr, GRRegs:$offset)>;
837def : Pat<(extloadi8 GRRegs:$addr), (LD8U_3r GRRegs:$addr, (LDC_ru6 0))>;
838def : Pat<(extloadi16 (lda16f GRRegs:$addr, GRRegs:$offset)),
839          (LD16S_3r GRRegs:$addr, GRRegs:$offset)>;
840def : Pat<(extloadi16 GRRegs:$addr), (LD16S_3r GRRegs:$addr, (LDC_ru6 0))>;
841
842/// stores
843def : Pat<(truncstorei8 GRRegs:$val, (add GRRegs:$addr, GRRegs:$offset)),
844          (ST8_l3r GRRegs:$val, GRRegs:$addr, GRRegs:$offset)>;
845def : Pat<(truncstorei8 GRRegs:$val, GRRegs:$addr),
846          (ST8_l3r GRRegs:$val, GRRegs:$addr, (LDC_ru6 0))>;
847          
848def : Pat<(truncstorei16 GRRegs:$val, (lda16f GRRegs:$addr, GRRegs:$offset)),
849          (ST16_l3r GRRegs:$val, GRRegs:$addr, GRRegs:$offset)>;
850def : Pat<(truncstorei16 GRRegs:$val, GRRegs:$addr),
851          (ST16_l3r GRRegs:$val, GRRegs:$addr, (LDC_ru6 0))>;
852
853def : Pat<(store GRRegs:$val, (ldawf GRRegs:$addr, GRRegs:$offset)),
854          (STW_3r GRRegs:$val, GRRegs:$addr, GRRegs:$offset)>;
855def : Pat<(store GRRegs:$val, (add GRRegs:$addr, immUs4:$offset)),
856          (STW_2rus GRRegs:$val, GRRegs:$addr, (div4_xform immUs4:$offset))>;
857def : Pat<(store GRRegs:$val, GRRegs:$addr),
858          (STW_2rus GRRegs:$val, GRRegs:$addr, 0)>;
859
860/// cttz
861def : Pat<(cttz GRRegs:$src), (CLZ_l2r (BITREV_l2r GRRegs:$src))>;
862
863/// trap
864def : Pat<(trap), (ECALLF_1r (LDC_ru6 0))>;
865
866///
867/// branch patterns
868///
869
870// unconditional branch
871def : Pat<(br bb:$addr), (BRFU_lu6 bb:$addr)>;
872
873// direct match equal/notequal zero brcond
874def : Pat<(brcond (setne GRRegs:$lhs, 0), bb:$dst),
875          (BRFT_lru6 GRRegs:$lhs, bb:$dst)>;
876def : Pat<(brcond (seteq GRRegs:$lhs, 0), bb:$dst),
877          (BRFF_lru6 GRRegs:$lhs, bb:$dst)>;
878
879def : Pat<(brcond (setle GRRegs:$lhs, GRRegs:$rhs), bb:$dst),
880          (BRFF_lru6 (LSS_3r GRRegs:$rhs, GRRegs:$lhs), bb:$dst)>;
881def : Pat<(brcond (setule GRRegs:$lhs, GRRegs:$rhs), bb:$dst),
882          (BRFF_lru6 (LSU_3r GRRegs:$rhs, GRRegs:$lhs), bb:$dst)>;
883def : Pat<(brcond (setge GRRegs:$lhs, GRRegs:$rhs), bb:$dst),
884          (BRFF_lru6 (LSS_3r GRRegs:$lhs, GRRegs:$rhs), bb:$dst)>;
885def : Pat<(brcond (setuge GRRegs:$lhs, GRRegs:$rhs), bb:$dst),
886          (BRFF_lru6 (LSU_3r GRRegs:$lhs, GRRegs:$rhs), bb:$dst)>;
887def : Pat<(brcond (setne GRRegs:$lhs, GRRegs:$rhs), bb:$dst),
888          (BRFF_lru6 (EQ_3r GRRegs:$lhs, GRRegs:$rhs), bb:$dst)>;
889def : Pat<(brcond (setne GRRegs:$lhs, immUs:$rhs), bb:$dst),
890          (BRFF_lru6 (EQ_2rus GRRegs:$lhs, immUs:$rhs), bb:$dst)>;
891
892// generic brcond pattern
893def : Pat<(brcond GRRegs:$cond, bb:$addr), (BRFT_lru6 GRRegs:$cond, bb:$addr)>;
894
895
896///
897/// Select patterns
898///
899
900// direct match equal/notequal zero select
901def : Pat<(select (setne GRRegs:$lhs, 0), GRRegs:$T, GRRegs:$F),
902        (SELECT_CC GRRegs:$lhs, GRRegs:$T, GRRegs:$F)>;
903
904def : Pat<(select (seteq GRRegs:$lhs, 0), GRRegs:$T, GRRegs:$F),
905        (SELECT_CC GRRegs:$lhs, GRRegs:$F, GRRegs:$T)>;
906
907def : Pat<(select (setle GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F),
908          (SELECT_CC (LSS_3r GRRegs:$rhs, GRRegs:$lhs), GRRegs:$F, GRRegs:$T)>;
909def : Pat<(select (setule GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F),
910          (SELECT_CC (LSU_3r GRRegs:$rhs, GRRegs:$lhs), GRRegs:$F, GRRegs:$T)>;
911def : Pat<(select (setge GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F),
912          (SELECT_CC (LSS_3r GRRegs:$lhs, GRRegs:$rhs), GRRegs:$F, GRRegs:$T)>;
913def : Pat<(select (setuge GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F),
914          (SELECT_CC (LSU_3r GRRegs:$lhs, GRRegs:$rhs), GRRegs:$F, GRRegs:$T)>;
915def : Pat<(select (setne GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F),
916          (SELECT_CC (EQ_3r GRRegs:$lhs, GRRegs:$rhs), GRRegs:$F, GRRegs:$T)>;
917def : Pat<(select (setne GRRegs:$lhs, immUs:$rhs), GRRegs:$T, GRRegs:$F),
918          (SELECT_CC (EQ_2rus GRRegs:$lhs, immUs:$rhs), GRRegs:$F, GRRegs:$T)>;
919
920///
921/// setcc patterns, only matched when none of the above brcond
922/// patterns match
923///
924
925// setcc 2 register operands
926def : Pat<(setle GRRegs:$lhs, GRRegs:$rhs),
927          (EQ_2rus (LSS_3r GRRegs:$rhs, GRRegs:$lhs), 0)>;
928def : Pat<(setule GRRegs:$lhs, GRRegs:$rhs),
929          (EQ_2rus (LSU_3r GRRegs:$rhs, GRRegs:$lhs), 0)>;
930
931def : Pat<(setgt GRRegs:$lhs, GRRegs:$rhs),
932          (LSS_3r GRRegs:$rhs, GRRegs:$lhs)>;
933def : Pat<(setugt GRRegs:$lhs, GRRegs:$rhs),
934          (LSU_3r GRRegs:$rhs, GRRegs:$lhs)>;
935
936def : Pat<(setge GRRegs:$lhs, GRRegs:$rhs),
937          (EQ_2rus (LSS_3r GRRegs:$lhs, GRRegs:$rhs), 0)>;
938def : Pat<(setuge GRRegs:$lhs, GRRegs:$rhs),
939          (EQ_2rus (LSU_3r GRRegs:$lhs, GRRegs:$rhs), 0)>;
940
941def : Pat<(setlt GRRegs:$lhs, GRRegs:$rhs),
942          (LSS_3r GRRegs:$lhs, GRRegs:$rhs)>;
943def : Pat<(setult GRRegs:$lhs, GRRegs:$rhs),
944          (LSU_3r GRRegs:$lhs, GRRegs:$rhs)>;
945
946def : Pat<(setne GRRegs:$lhs, GRRegs:$rhs),
947          (EQ_2rus (EQ_3r GRRegs:$lhs, GRRegs:$rhs), 0)>;
948
949def : Pat<(seteq GRRegs:$lhs, GRRegs:$rhs),
950          (EQ_3r GRRegs:$lhs, GRRegs:$rhs)>;
951
952// setcc reg/imm operands
953def : Pat<(seteq GRRegs:$lhs, immUs:$rhs),
954          (EQ_2rus GRRegs:$lhs, immUs:$rhs)>;
955def : Pat<(setne GRRegs:$lhs, immUs:$rhs),
956          (EQ_2rus (EQ_2rus GRRegs:$lhs, immUs:$rhs), 0)>;
957
958// misc
959def : Pat<(add GRRegs:$addr, immUs4:$offset),
960          (LDAWF_l2rus GRRegs:$addr, (div4_xform immUs4:$offset))>;
961
962def : Pat<(sub GRRegs:$addr, immUs4:$offset),
963          (LDAWB_l2rus GRRegs:$addr, (div4_xform immUs4:$offset))>;
964
965def : Pat<(and GRRegs:$val, immMskBitp:$mask),
966          (ZEXT_rus GRRegs:$val, (msksize_xform immMskBitp:$mask))>;
967
968// (sub X, imm) gets canonicalized to (add X, -imm).  Match this form.
969def : Pat<(add GRRegs:$src1, immUsNeg:$src2),
970          (SUB_2rus GRRegs:$src1, (neg_xform immUsNeg:$src2))>;
971
972def : Pat<(add GRRegs:$src1, immUs4Neg:$src2),
973          (LDAWB_l2rus GRRegs:$src1, (div4neg_xform immUs4Neg:$src2))>;
974
975///
976/// Some peepholes
977///
978
979def : Pat<(mul GRRegs:$src, 3),
980          (LDA16F_l3r GRRegs:$src, GRRegs:$src)>;
981
982def : Pat<(mul GRRegs:$src, 5),
983          (LDAWF_l3r GRRegs:$src, GRRegs:$src)>;
984
985def : Pat<(mul GRRegs:$src, -3),
986          (LDAWB_l3r GRRegs:$src, GRRegs:$src)>;
987
988// ashr X, 32 is equivalent to ashr X, 31 on the XCore.
989def : Pat<(sra GRRegs:$src, 31),
990          (ASHR_l2rus GRRegs:$src, 32)>;
991
992