XCoreInstrInfo.td revision 199511
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, isBarrier = 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 Defs = [R11], isReMaterializable = 1 in
683def LDAP_lu10_ba : _FLU10<(outs),
684                          (ins i32imm:$addr),
685                          "ldap r11, $addr",
686                          [(set R11, (pcrelwrapper tblockaddress:$addr))]>;
687
688let isCall=1,
689// All calls clobber the the link register and the non-callee-saved registers:
690Defs = [R0, R1, R2, R3, R11, LR] in {
691def BL_u10 : _FU10<
692                  (outs),
693                  (ins calltarget:$target, variable_ops),
694                  "bl $target",
695                  [(XCoreBranchLink immU10:$target)]>;
696
697def BL_lu10 : _FLU10<
698                  (outs),
699                  (ins calltarget:$target, variable_ops),
700                  "bl $target",
701                  [(XCoreBranchLink immU20:$target)]>;
702}
703
704// Two operand short
705// TODO getr, getst
706def NOT : _F2R<(outs GRRegs:$dst), (ins GRRegs:$b),
707                 "not $dst, $b",
708                 [(set GRRegs:$dst, (not GRRegs:$b))]>;
709
710def NEG : _F2R<(outs GRRegs:$dst), (ins GRRegs:$b),
711                 "neg $dst, $b",
712                 [(set GRRegs:$dst, (ineg GRRegs:$b))]>;
713
714// TODO setd, eet, eef, getts, setpt, outct, inct, chkct, outt, intt, out,
715// in, outshr, inshr, testct, testwct, tinitpc, tinitdp, tinitsp, tinitcp,
716// tsetmr, sext (reg), zext (reg)
717let isTwoAddress = 1 in {
718let neverHasSideEffects = 1 in
719def SEXT_rus : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$src1, i32imm:$src2),
720                 "sext $dst, $src2",
721                 []>;
722
723let neverHasSideEffects = 1 in
724def ZEXT_rus : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$src1, i32imm:$src2),
725                 "zext $dst, $src2",
726                 []>;
727
728def ANDNOT_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$src1, GRRegs:$src2),
729                 "andnot $dst, $src2",
730                 [(set GRRegs:$dst, (and GRRegs:$src1, (not GRRegs:$src2)))]>;
731}
732
733let isReMaterializable = 1, neverHasSideEffects = 1 in
734def MKMSK_rus : _FRUS<(outs GRRegs:$dst), (ins i32imm:$size),
735                 "mkmsk $dst, $size",
736                 []>;
737
738def MKMSK_2r : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$size),
739                 "mkmsk $dst, $size",
740                 [(set GRRegs:$dst, (add (shl 1, GRRegs:$size), 0xffffffff))]>;
741
742// Two operand long
743// TODO settw, setclk, setrdy, setpsc, endin, peek,
744// getd, testlcl, tinitlr, getps, setps
745def BITREV_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src),
746                 "bitrev $dst, $src",
747                 [(set GRRegs:$dst, (int_xcore_bitrev GRRegs:$src))]>;
748
749def BYTEREV_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src),
750                 "byterev $dst, $src",
751                 [(set GRRegs:$dst, (bswap GRRegs:$src))]>;
752
753def CLZ_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src),
754                 "clz $dst, $src",
755                 [(set GRRegs:$dst, (ctlz GRRegs:$src))]>;
756
757// One operand short
758// TODO edu, eeu, waitet, waitef, freer, tstart, msync, mjoin, syncr, clrtp
759// bru, setdp, setcp, setv, setev, kcall
760// dgetreg
761let isBranch=1, isIndirectBranch=1, isTerminator=1 in
762def BAU_1r : _F1R<(outs), (ins GRRegs:$addr),
763                 "bau $addr",
764                 [(brind GRRegs:$addr)]>;
765
766let Defs=[SP], neverHasSideEffects=1 in
767def SETSP_1r : _F1R<(outs), (ins GRRegs:$src),
768                 "set sp, $src",
769                 []>;
770
771let isBarrier = 1, hasCtrlDep = 1 in 
772def ECALLT_1r : _F1R<(outs), (ins GRRegs:$src),
773                 "ecallt $src",
774                 []>;
775
776let isBarrier = 1, hasCtrlDep = 1 in 
777def ECALLF_1r : _F1R<(outs), (ins GRRegs:$src),
778                 "ecallf $src",
779                 []>;
780
781let isCall=1, 
782// All calls clobber the the link register and the non-callee-saved registers:
783Defs = [R0, R1, R2, R3, R11, LR] in {
784def BLA_1r : _F1R<(outs), (ins GRRegs:$addr, variable_ops),
785                 "bla $addr",
786                 [(XCoreBranchLink GRRegs:$addr)]>;
787}
788
789// Zero operand short
790// TODO waiteu, clre, ssync, freet, ldspc, stspc, ldssr, stssr, ldsed, stsed,
791// stet, geted, getet, getkep, getksp, setkep, getid, kret, dcall, dret,
792// dentsp, drestsp
793
794let Defs = [R11] in
795def GETID_0R : _F0R<(outs), (ins),
796                 "get r11, id",
797                 [(set R11, (int_xcore_getid))]>;
798
799//===----------------------------------------------------------------------===//
800// Non-Instruction Patterns
801//===----------------------------------------------------------------------===//
802
803def : Pat<(XCoreBranchLink tglobaladdr:$addr), (BL_lu10 tglobaladdr:$addr)>;
804def : Pat<(XCoreBranchLink texternalsym:$addr), (BL_lu10 texternalsym:$addr)>;
805
806/// sext_inreg
807def : Pat<(sext_inreg GRRegs:$b, i1), (SEXT_rus GRRegs:$b, 1)>;
808def : Pat<(sext_inreg GRRegs:$b, i8), (SEXT_rus GRRegs:$b, 8)>;
809def : Pat<(sext_inreg GRRegs:$b, i16), (SEXT_rus GRRegs:$b, 16)>;
810
811/// loads
812def : Pat<(zextloadi8 (add GRRegs:$addr, GRRegs:$offset)),
813          (LD8U_3r GRRegs:$addr, GRRegs:$offset)>;
814def : Pat<(zextloadi8 GRRegs:$addr), (LD8U_3r GRRegs:$addr, (LDC_ru6 0))>;
815
816def : Pat<(sextloadi16 (lda16f GRRegs:$addr, GRRegs:$offset)),
817          (LD16S_3r GRRegs:$addr, GRRegs:$offset)>;
818def : Pat<(sextloadi16 GRRegs:$addr), (LD16S_3r GRRegs:$addr, (LDC_ru6 0))>;
819
820def : Pat<(load (ldawf GRRegs:$addr, GRRegs:$offset)),
821          (LDW_3r GRRegs:$addr, GRRegs:$offset)>;
822def : Pat<(load (add GRRegs:$addr, immUs4:$offset)),
823          (LDW_2rus GRRegs:$addr, (div4_xform immUs4:$offset))>;
824def : Pat<(load GRRegs:$addr), (LDW_2rus GRRegs:$addr, 0)>;
825
826/// anyext
827def : Pat<(extloadi8 (add GRRegs:$addr, GRRegs:$offset)),
828          (LD8U_3r GRRegs:$addr, GRRegs:$offset)>;
829def : Pat<(extloadi8 GRRegs:$addr), (LD8U_3r GRRegs:$addr, (LDC_ru6 0))>;
830def : Pat<(extloadi16 (lda16f GRRegs:$addr, GRRegs:$offset)),
831          (LD16S_3r GRRegs:$addr, GRRegs:$offset)>;
832def : Pat<(extloadi16 GRRegs:$addr), (LD16S_3r GRRegs:$addr, (LDC_ru6 0))>;
833
834/// stores
835def : Pat<(truncstorei8 GRRegs:$val, (add GRRegs:$addr, GRRegs:$offset)),
836          (ST8_l3r GRRegs:$val, GRRegs:$addr, GRRegs:$offset)>;
837def : Pat<(truncstorei8 GRRegs:$val, GRRegs:$addr),
838          (ST8_l3r GRRegs:$val, GRRegs:$addr, (LDC_ru6 0))>;
839          
840def : Pat<(truncstorei16 GRRegs:$val, (lda16f GRRegs:$addr, GRRegs:$offset)),
841          (ST16_l3r GRRegs:$val, GRRegs:$addr, GRRegs:$offset)>;
842def : Pat<(truncstorei16 GRRegs:$val, GRRegs:$addr),
843          (ST16_l3r GRRegs:$val, GRRegs:$addr, (LDC_ru6 0))>;
844
845def : Pat<(store GRRegs:$val, (ldawf GRRegs:$addr, GRRegs:$offset)),
846          (STW_3r GRRegs:$val, GRRegs:$addr, GRRegs:$offset)>;
847def : Pat<(store GRRegs:$val, (add GRRegs:$addr, immUs4:$offset)),
848          (STW_2rus GRRegs:$val, GRRegs:$addr, (div4_xform immUs4:$offset))>;
849def : Pat<(store GRRegs:$val, GRRegs:$addr),
850          (STW_2rus GRRegs:$val, GRRegs:$addr, 0)>;
851
852/// cttz
853def : Pat<(cttz GRRegs:$src), (CLZ_l2r (BITREV_l2r GRRegs:$src))>;
854
855/// trap
856def : Pat<(trap), (ECALLF_1r (LDC_ru6 0))>;
857
858///
859/// branch patterns
860///
861
862// unconditional branch
863def : Pat<(br bb:$addr), (BRFU_lu6 bb:$addr)>;
864
865// direct match equal/notequal zero brcond
866def : Pat<(brcond (setne GRRegs:$lhs, 0), bb:$dst),
867          (BRFT_lru6 GRRegs:$lhs, bb:$dst)>;
868def : Pat<(brcond (seteq GRRegs:$lhs, 0), bb:$dst),
869          (BRFF_lru6 GRRegs:$lhs, bb:$dst)>;
870
871def : Pat<(brcond (setle GRRegs:$lhs, GRRegs:$rhs), bb:$dst),
872          (BRFF_lru6 (LSS_3r GRRegs:$rhs, GRRegs:$lhs), bb:$dst)>;
873def : Pat<(brcond (setule GRRegs:$lhs, GRRegs:$rhs), bb:$dst),
874          (BRFF_lru6 (LSU_3r GRRegs:$rhs, GRRegs:$lhs), bb:$dst)>;
875def : Pat<(brcond (setge GRRegs:$lhs, GRRegs:$rhs), bb:$dst),
876          (BRFF_lru6 (LSS_3r GRRegs:$lhs, GRRegs:$rhs), bb:$dst)>;
877def : Pat<(brcond (setuge GRRegs:$lhs, GRRegs:$rhs), bb:$dst),
878          (BRFF_lru6 (LSU_3r GRRegs:$lhs, GRRegs:$rhs), bb:$dst)>;
879def : Pat<(brcond (setne GRRegs:$lhs, GRRegs:$rhs), bb:$dst),
880          (BRFF_lru6 (EQ_3r GRRegs:$lhs, GRRegs:$rhs), bb:$dst)>;
881def : Pat<(brcond (setne GRRegs:$lhs, immUs:$rhs), bb:$dst),
882          (BRFF_lru6 (EQ_2rus GRRegs:$lhs, immUs:$rhs), bb:$dst)>;
883
884// generic brcond pattern
885def : Pat<(brcond GRRegs:$cond, bb:$addr), (BRFT_lru6 GRRegs:$cond, bb:$addr)>;
886
887
888///
889/// Select patterns
890///
891
892// direct match equal/notequal zero select
893def : Pat<(select (setne GRRegs:$lhs, 0), GRRegs:$T, GRRegs:$F),
894        (SELECT_CC GRRegs:$lhs, GRRegs:$T, GRRegs:$F)>;
895
896def : Pat<(select (seteq GRRegs:$lhs, 0), GRRegs:$T, GRRegs:$F),
897        (SELECT_CC GRRegs:$lhs, GRRegs:$F, GRRegs:$T)>;
898
899def : Pat<(select (setle GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F),
900          (SELECT_CC (LSS_3r GRRegs:$rhs, GRRegs:$lhs), GRRegs:$F, GRRegs:$T)>;
901def : Pat<(select (setule GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F),
902          (SELECT_CC (LSU_3r GRRegs:$rhs, GRRegs:$lhs), GRRegs:$F, GRRegs:$T)>;
903def : Pat<(select (setge GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F),
904          (SELECT_CC (LSS_3r GRRegs:$lhs, GRRegs:$rhs), GRRegs:$F, GRRegs:$T)>;
905def : Pat<(select (setuge GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F),
906          (SELECT_CC (LSU_3r GRRegs:$lhs, GRRegs:$rhs), GRRegs:$F, GRRegs:$T)>;
907def : Pat<(select (setne GRRegs:$lhs, GRRegs:$rhs), GRRegs:$T, GRRegs:$F),
908          (SELECT_CC (EQ_3r GRRegs:$lhs, GRRegs:$rhs), GRRegs:$F, GRRegs:$T)>;
909def : Pat<(select (setne GRRegs:$lhs, immUs:$rhs), GRRegs:$T, GRRegs:$F),
910          (SELECT_CC (EQ_2rus GRRegs:$lhs, immUs:$rhs), GRRegs:$F, GRRegs:$T)>;
911
912///
913/// setcc patterns, only matched when none of the above brcond
914/// patterns match
915///
916
917// setcc 2 register operands
918def : Pat<(setle GRRegs:$lhs, GRRegs:$rhs),
919          (EQ_2rus (LSS_3r GRRegs:$rhs, GRRegs:$lhs), 0)>;
920def : Pat<(setule GRRegs:$lhs, GRRegs:$rhs),
921          (EQ_2rus (LSU_3r GRRegs:$rhs, GRRegs:$lhs), 0)>;
922
923def : Pat<(setgt GRRegs:$lhs, GRRegs:$rhs),
924          (LSS_3r GRRegs:$rhs, GRRegs:$lhs)>;
925def : Pat<(setugt GRRegs:$lhs, GRRegs:$rhs),
926          (LSU_3r GRRegs:$rhs, GRRegs:$lhs)>;
927
928def : Pat<(setge GRRegs:$lhs, GRRegs:$rhs),
929          (EQ_2rus (LSS_3r GRRegs:$lhs, GRRegs:$rhs), 0)>;
930def : Pat<(setuge GRRegs:$lhs, GRRegs:$rhs),
931          (EQ_2rus (LSU_3r GRRegs:$lhs, GRRegs:$rhs), 0)>;
932
933def : Pat<(setlt GRRegs:$lhs, GRRegs:$rhs),
934          (LSS_3r GRRegs:$lhs, GRRegs:$rhs)>;
935def : Pat<(setult GRRegs:$lhs, GRRegs:$rhs),
936          (LSU_3r GRRegs:$lhs, GRRegs:$rhs)>;
937
938def : Pat<(setne GRRegs:$lhs, GRRegs:$rhs),
939          (EQ_2rus (EQ_3r GRRegs:$lhs, GRRegs:$rhs), 0)>;
940
941def : Pat<(seteq GRRegs:$lhs, GRRegs:$rhs),
942          (EQ_3r GRRegs:$lhs, GRRegs:$rhs)>;
943
944// setcc reg/imm operands
945def : Pat<(seteq GRRegs:$lhs, immUs:$rhs),
946          (EQ_2rus GRRegs:$lhs, immUs:$rhs)>;
947def : Pat<(setne GRRegs:$lhs, immUs:$rhs),
948          (EQ_2rus (EQ_2rus GRRegs:$lhs, immUs:$rhs), 0)>;
949
950// misc
951def : Pat<(add GRRegs:$addr, immUs4:$offset),
952          (LDAWF_l2rus GRRegs:$addr, (div4_xform immUs4:$offset))>;
953
954def : Pat<(sub GRRegs:$addr, immUs4:$offset),
955          (LDAWB_l2rus GRRegs:$addr, (div4_xform immUs4:$offset))>;
956
957def : Pat<(and GRRegs:$val, immMskBitp:$mask),
958          (ZEXT_rus GRRegs:$val, (msksize_xform immMskBitp:$mask))>;
959
960// (sub X, imm) gets canonicalized to (add X, -imm).  Match this form.
961def : Pat<(add GRRegs:$src1, immUsNeg:$src2),
962          (SUB_2rus GRRegs:$src1, (neg_xform immUsNeg:$src2))>;
963
964def : Pat<(add GRRegs:$src1, immUs4Neg:$src2),
965          (LDAWB_l2rus GRRegs:$src1, (div4neg_xform immUs4Neg:$src2))>;
966
967///
968/// Some peepholes
969///
970
971def : Pat<(mul GRRegs:$src, 3),
972          (LDA16F_l3r GRRegs:$src, GRRegs:$src)>;
973
974def : Pat<(mul GRRegs:$src, 5),
975          (LDAWF_l3r GRRegs:$src, GRRegs:$src)>;
976
977def : Pat<(mul GRRegs:$src, -3),
978          (LDAWB_l3r GRRegs:$src, GRRegs:$src)>;
979
980// ashr X, 32 is equivalent to ashr X, 31 on the XCore.
981def : Pat<(sra GRRegs:$src, 31),
982          (ASHR_l2rus GRRegs:$src, 32)>;
983
984def : Pat<(brcond (setlt GRRegs:$lhs, 0), bb:$dst),
985          (BRFT_lru6 (ASHR_l2rus GRRegs:$lhs, 32), bb:$dst)>;
986
987// setge X, 0 is canonicalized to setgt X, -1
988def : Pat<(brcond (setgt GRRegs:$lhs, -1), bb:$dst),
989          (BRFF_lru6 (ASHR_l2rus GRRegs:$lhs, 32), bb:$dst)>;
990
991def : Pat<(select (setlt GRRegs:$lhs, 0), GRRegs:$T, GRRegs:$F),
992          (SELECT_CC (ASHR_l2rus GRRegs:$lhs, 32), GRRegs:$T, GRRegs:$F)>;
993
994def : Pat<(select (setgt GRRegs:$lhs, -1), GRRegs:$T, GRRegs:$F),
995          (SELECT_CC (ASHR_l2rus GRRegs:$lhs, 32), GRRegs:$F, GRRegs:$T)>;
996
997def : Pat<(setgt GRRegs:$lhs, -1),
998          (EQ_2rus (ASHR_l2rus GRRegs:$lhs, 32), 0)>;
999
1000def : Pat<(sra (shl GRRegs:$src, immBpwSubBitp:$imm), immBpwSubBitp:$imm),
1001          (SEXT_rus GRRegs:$src, (bpwsub_xform immBpwSubBitp:$imm))>;
1002