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