MSP430InstrInfo.td revision 198892
1//===- MSP430InstrInfo.td - MSP430 Instruction defs -----------*- tblgen-*-===//
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 MSP430 instructions in TableGen format.
11//
12//===----------------------------------------------------------------------===//
13
14include "MSP430InstrFormats.td"
15
16//===----------------------------------------------------------------------===//
17// Type Constraints.
18//===----------------------------------------------------------------------===//
19class SDTCisI8<int OpNum> : SDTCisVT<OpNum, i8>;
20class SDTCisI16<int OpNum> : SDTCisVT<OpNum, i16>;
21
22//===----------------------------------------------------------------------===//
23// Type Profiles.
24//===----------------------------------------------------------------------===//
25def SDT_MSP430Call         : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>;
26def SDT_MSP430CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i16>]>;
27def SDT_MSP430CallSeqEnd   : SDCallSeqEnd<[SDTCisVT<0, i16>, SDTCisVT<1, i16>]>;
28def SDT_MSP430Wrapper      : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
29def SDT_MSP430Cmp          : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
30def SDT_MSP430BrCC         : SDTypeProfile<0, 2, [SDTCisVT<0, OtherVT>,
31                                                  SDTCisVT<1, i8>]>;
32def SDT_MSP430SelectCC     : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, 
33                                                  SDTCisVT<3, i8>]>;
34
35//===----------------------------------------------------------------------===//
36// MSP430 Specific Node Definitions.
37//===----------------------------------------------------------------------===//
38def MSP430retflag : SDNode<"MSP430ISD::RET_FLAG", SDTNone,
39                     [SDNPHasChain, SDNPOptInFlag]>;
40
41def MSP430rra     : SDNode<"MSP430ISD::RRA", SDTIntUnaryOp, []>;
42def MSP430rla     : SDNode<"MSP430ISD::RLA", SDTIntUnaryOp, []>;
43def MSP430rrc     : SDNode<"MSP430ISD::RRC", SDTIntUnaryOp, []>;
44
45def MSP430call    : SDNode<"MSP430ISD::CALL", SDT_MSP430Call,
46                     [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag]>;
47def MSP430callseq_start :
48                 SDNode<"ISD::CALLSEQ_START", SDT_MSP430CallSeqStart,
49                        [SDNPHasChain, SDNPOutFlag]>;
50def MSP430callseq_end :
51                 SDNode<"ISD::CALLSEQ_END",   SDT_MSP430CallSeqEnd,
52                        [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
53def MSP430Wrapper : SDNode<"MSP430ISD::Wrapper", SDT_MSP430Wrapper>;
54def MSP430cmp     : SDNode<"MSP430ISD::CMP", SDT_MSP430Cmp, [SDNPOutFlag]>;
55def MSP430brcc    : SDNode<"MSP430ISD::BR_CC", SDT_MSP430BrCC, [SDNPHasChain, SDNPInFlag]>;
56def MSP430selectcc: SDNode<"MSP430ISD::SELECT_CC", SDT_MSP430SelectCC, [SDNPInFlag]>;
57
58//===----------------------------------------------------------------------===//
59// MSP430 Operand Definitions.
60//===----------------------------------------------------------------------===//
61
62// Address operands
63def memsrc : Operand<i16> {
64  let PrintMethod = "printSrcMemOperand";
65  let MIOperandInfo = (ops GR16, i16imm);
66}
67
68def memdst : Operand<i16> {
69  let PrintMethod = "printSrcMemOperand";
70  let MIOperandInfo = (ops GR16, i16imm);
71}
72
73// Branch targets have OtherVT type.
74def brtarget : Operand<OtherVT> {
75  let PrintMethod = "printPCRelImmOperand";
76}
77
78// Operand for printing out a condition code.
79def cc : Operand<i8> {
80  let PrintMethod = "printCCOperand";
81}
82
83//===----------------------------------------------------------------------===//
84// MSP430 Complex Pattern Definitions.
85//===----------------------------------------------------------------------===//
86
87def addr : ComplexPattern<iPTR, 2, "SelectAddr", [], []>;
88
89//===----------------------------------------------------------------------===//
90// Pattern Fragments
91def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>;
92def  extloadi16i8 : PatFrag<(ops node:$ptr), (i16 ( extloadi8 node:$ptr))>;
93
94//===----------------------------------------------------------------------===//
95// Instruction list..
96
97// ADJCALLSTACKDOWN/UP implicitly use/def SP because they may be expanded into
98// a stack adjustment and the codegen must know that they may modify the stack
99// pointer before prolog-epilog rewriting occurs.
100// Pessimistically assume ADJCALLSTACKDOWN / ADJCALLSTACKUP will become
101// sub / add which can clobber SRW.
102let Defs = [SPW, SRW], Uses = [SPW] in {
103def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i16imm:$amt),
104                              "#ADJCALLSTACKDOWN",
105                              [(MSP430callseq_start timm:$amt)]>;
106def ADJCALLSTACKUP   : Pseudo<(outs), (ins i16imm:$amt1, i16imm:$amt2),
107                              "#ADJCALLSTACKUP",
108                              [(MSP430callseq_end timm:$amt1, timm:$amt2)]>;
109}
110
111let usesCustomInserter = 1 in {
112  def Select8  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2, i8imm:$cc),
113                        "# Select8 PSEUDO",
114                        [(set GR8:$dst,
115                          (MSP430selectcc GR8:$src1, GR8:$src2, imm:$cc))]>;
116  def Select16 : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2, i8imm:$cc),
117                        "# Select16 PSEUDO",
118                        [(set GR16:$dst,
119                          (MSP430selectcc GR16:$src1, GR16:$src2, imm:$cc))]>;
120}
121
122let neverHasSideEffects = 1 in
123def NOP : Pseudo<(outs), (ins), "nop", []>;
124
125//===----------------------------------------------------------------------===//
126//  Control Flow Instructions...
127//
128
129// FIXME: Provide proper encoding!
130let isReturn = 1, isTerminator = 1 in {
131  def RET : Pseudo<(outs), (ins), "ret", [(MSP430retflag)]>;
132}
133
134let isBranch = 1, isTerminator = 1 in {
135
136// Direct branch
137let isBarrier = 1 in
138  def JMP : Pseudo<(outs), (ins brtarget:$dst),
139                   "jmp\t$dst",
140                   [(br bb:$dst)]>;
141
142// Conditional branches
143let Uses = [SRW] in
144  def JCC : Pseudo<(outs), (ins brtarget:$dst, cc:$cc),
145                            "j$cc $dst",
146                            [(MSP430brcc bb:$dst, imm:$cc)]>;
147} // isBranch, isTerminator
148
149//===----------------------------------------------------------------------===//
150//  Call Instructions...
151//
152let isCall = 1 in
153  // All calls clobber the non-callee saved registers. SPW is marked as
154  // a use to prevent stack-pointer assignments that appear immediately
155  // before calls from potentially appearing dead. Uses for argument
156  // registers are added manually.
157  let Defs = [R12W, R13W, R14W, R15W, SRW],
158      Uses = [SPW] in {
159    def CALLi     : Pseudo<(outs), (ins i16imm:$dst, variable_ops),
160                           "call\t$dst", [(MSP430call imm:$dst)]>;
161    def CALLr     : Pseudo<(outs), (ins GR16:$dst, variable_ops),
162                           "call\t$dst", [(MSP430call GR16:$dst)]>;
163    def CALLm     : Pseudo<(outs), (ins memsrc:$dst, variable_ops),
164                           "call\t${dst:mem}", [(MSP430call (load addr:$dst))]>;
165  }
166
167
168//===----------------------------------------------------------------------===//
169//  Miscellaneous Instructions...
170//
171let Defs = [SPW], Uses = [SPW], neverHasSideEffects=1 in {
172let mayLoad = 1 in
173def POP16r   : Pseudo<(outs GR16:$reg), (ins), "pop.w\t$reg", []>;
174
175let mayStore = 1 in
176def PUSH16r  : Pseudo<(outs), (ins GR16:$reg), "push.w\t$reg",[]>;
177}
178
179//===----------------------------------------------------------------------===//
180// Move Instructions
181
182// FIXME: Provide proper encoding!
183let neverHasSideEffects = 1 in {
184def MOV8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src),
185                     "mov.b\t{$src, $dst}",
186                     []>;
187def MOV16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src),
188                     "mov.w\t{$src, $dst}",
189                     []>;
190}
191
192// FIXME: Provide proper encoding!
193let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
194def MOV8ri  : Pseudo<(outs GR8:$dst), (ins i8imm:$src),
195                     "mov.b\t{$src, $dst}",
196                     [(set GR8:$dst, imm:$src)]>;
197def MOV16ri : Pseudo<(outs GR16:$dst), (ins i16imm:$src),
198                     "mov.w\t{$src, $dst}",
199                     [(set GR16:$dst, imm:$src)]>;
200}
201
202let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in {
203def MOV8rm  : Pseudo<(outs GR8:$dst), (ins memsrc:$src),
204                "mov.b\t{$src, $dst}",
205                [(set GR8:$dst, (load addr:$src))]>;
206def MOV16rm : Pseudo<(outs GR16:$dst), (ins memsrc:$src),
207                "mov.w\t{$src, $dst}",
208                [(set GR16:$dst, (load addr:$src))]>;
209}
210
211def MOVZX16rr8 : Pseudo<(outs GR16:$dst), (ins GR8:$src),
212                "mov.b\t{$src, $dst}",
213                [(set GR16:$dst, (zext GR8:$src))]>;
214def MOVZX16rm8 : Pseudo<(outs GR16:$dst), (ins memsrc:$src),
215                "mov.b\t{$src, $dst}",
216                [(set GR16:$dst, (zextloadi16i8 addr:$src))]>;
217
218// Any instruction that defines a 8-bit result leaves the high half of the
219// register. Truncate can be lowered to EXTRACT_SUBREG, and CopyFromReg may
220// be copying from a truncate, but any other 8-bit operation will zero-extend
221// up to 16 bits.
222def def8 : PatLeaf<(i8 GR8:$src), [{
223  return N->getOpcode() != ISD::TRUNCATE &&
224         N->getOpcode() != TargetInstrInfo::EXTRACT_SUBREG &&
225         N->getOpcode() != ISD::CopyFromReg;
226}]>;
227
228// In the case of a 8-bit def that is known to implicitly zero-extend,
229// we can use a SUBREG_TO_REG.
230def : Pat<(i16 (zext def8:$src)),
231          (SUBREG_TO_REG (i16 0), GR8:$src, subreg_8bit)>;
232
233
234def MOV8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
235                "mov.b\t{$src, $dst}",
236                [(store (i8 imm:$src), addr:$dst)]>;
237def MOV16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
238                "mov.w\t{$src, $dst}",
239                [(store (i16 imm:$src), addr:$dst)]>;
240
241def MOV8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
242                "mov.b\t{$src, $dst}",
243                [(store GR8:$src, addr:$dst)]>;
244def MOV16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
245                "mov.w\t{$src, $dst}",
246                [(store GR16:$src, addr:$dst)]>;
247
248def MOV8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
249                "mov.b\t{$src, $dst}",
250                [(store (i8 (load addr:$src)), addr:$dst)]>;
251def MOV16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
252                "mov.w\t{$src, $dst}",
253                [(store (i16 (load addr:$src)), addr:$dst)]>;
254
255//===----------------------------------------------------------------------===//
256// Arithmetic Instructions
257
258let isTwoAddress = 1 in {
259
260let Defs = [SRW] in {
261
262let isCommutable = 1 in { // X = ADD Y, Z  == X = ADD Z, Y
263// FIXME: Provide proper encoding!
264def ADD8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
265                     "add.b\t{$src2, $dst}",
266                     [(set GR8:$dst, (add GR8:$src1, GR8:$src2)),
267                      (implicit SRW)]>;
268def ADD16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
269                     "add.w\t{$src2, $dst}",
270                     [(set GR16:$dst, (add GR16:$src1, GR16:$src2)),
271                      (implicit SRW)]>;
272}
273
274def ADD8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
275                     "add.b\t{$src2, $dst}",
276                     [(set GR8:$dst, (add GR8:$src1, (load addr:$src2))),
277                      (implicit SRW)]>;
278def ADD16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
279                     "add.w\t{$src2, $dst}",
280                     [(set GR16:$dst, (add GR16:$src1, (load addr:$src2))),
281                      (implicit SRW)]>;
282
283def ADD8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
284                     "add.b\t{$src2, $dst}",
285                     [(set GR8:$dst, (add GR8:$src1, imm:$src2)),
286                      (implicit SRW)]>;
287def ADD16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
288                     "add.w\t{$src2, $dst}",
289                     [(set GR16:$dst, (add GR16:$src1, imm:$src2)),
290                      (implicit SRW)]>;
291
292let isTwoAddress = 0 in {
293def ADD8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
294                "add.b\t{$src, $dst}",
295                [(store (add (load addr:$dst), GR8:$src), addr:$dst),
296                 (implicit SRW)]>;
297def ADD16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
298                "add.w\t{$src, $dst}",
299                [(store (add (load addr:$dst), GR16:$src), addr:$dst),
300                 (implicit SRW)]>;
301
302def ADD8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
303                "add.b\t{$src, $dst}",
304                [(store (add (load addr:$dst), (i8 imm:$src)), addr:$dst),
305                 (implicit SRW)]>;
306def ADD16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
307                "add.w\t{$src, $dst}",
308                [(store (add (load addr:$dst), (i16 imm:$src)), addr:$dst),
309                 (implicit SRW)]>;
310
311def ADD8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
312                "add.b\t{$src, $dst}",
313                [(store (add (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
314                 (implicit SRW)]>;
315def ADD16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
316                "add.w\t{$src, $dst}",
317                [(store (add (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
318                 (implicit SRW)]>;
319}
320
321let Uses = [SRW] in {
322
323let isCommutable = 1 in { // X = ADDC Y, Z  == X = ADDC Z, Y
324def ADC8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
325                     "addc.b\t{$src2, $dst}",
326                     [(set GR8:$dst, (adde GR8:$src1, GR8:$src2)),
327                      (implicit SRW)]>;
328def ADC16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
329                     "addc.w\t{$src2, $dst}",
330                     [(set GR16:$dst, (adde GR16:$src1, GR16:$src2)),
331                      (implicit SRW)]>;
332} // isCommutable
333
334def ADC8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
335                     "addc.b\t{$src2, $dst}",
336                     [(set GR8:$dst, (adde GR8:$src1, imm:$src2)),
337                      (implicit SRW)]>;
338def ADC16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
339                     "addc.w\t{$src2, $dst}",
340                     [(set GR16:$dst, (adde GR16:$src1, imm:$src2)),
341                      (implicit SRW)]>;
342
343def ADC8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
344                     "addc.b\t{$src2, $dst}",
345                     [(set GR8:$dst, (adde GR8:$src1, (load addr:$src2))),
346                      (implicit SRW)]>;
347def ADC16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
348                     "addc.w\t{$src2, $dst}",
349                     [(set GR16:$dst, (adde GR16:$src1, (load addr:$src2))),
350                      (implicit SRW)]>;
351
352let isTwoAddress = 0 in {
353def ADC8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
354                "addc.b\t{$src, $dst}",
355                [(store (adde (load addr:$dst), GR8:$src), addr:$dst),
356                 (implicit SRW)]>;
357def ADC16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
358                "addc.w\t{$src, $dst}",
359                [(store (adde (load addr:$dst), GR16:$src), addr:$dst),
360                 (implicit SRW)]>;
361
362def ADC8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
363                "addc.b\t{$src, $dst}",
364                [(store (adde (load addr:$dst), (i8 imm:$src)), addr:$dst),
365                 (implicit SRW)]>;
366def ADC16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
367                "addc.w\t{$src, $dst}",
368                [(store (adde (load addr:$dst), (i16 imm:$src)), addr:$dst),
369                 (implicit SRW)]>;
370
371def ADC8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
372                "addc.b\t{$src, $dst}",
373                [(store (adde (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
374                 (implicit SRW)]>;
375def ADC16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
376                "addc.w\t{$src, $dst}",
377                [(store (adde (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
378                 (implicit SRW)]>;
379}
380
381} // Uses = [SRW]
382
383let isCommutable = 1 in { // X = AND Y, Z  == X = AND Z, Y
384def AND8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
385                     "and.b\t{$src2, $dst}",
386                     [(set GR8:$dst, (and GR8:$src1, GR8:$src2)),
387                      (implicit SRW)]>;
388def AND16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
389                     "and.w\t{$src2, $dst}",
390                     [(set GR16:$dst, (and GR16:$src1, GR16:$src2)),
391                      (implicit SRW)]>;
392}
393
394def AND8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
395                     "and.b\t{$src2, $dst}",
396                     [(set GR8:$dst, (and GR8:$src1, imm:$src2)),
397                      (implicit SRW)]>;
398def AND16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
399                     "and.w\t{$src2, $dst}",
400                     [(set GR16:$dst, (and GR16:$src1, imm:$src2)),
401                      (implicit SRW)]>;
402
403def AND8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
404                     "and.b\t{$src2, $dst}",
405                     [(set GR8:$dst, (and GR8:$src1, (load addr:$src2))),
406                      (implicit SRW)]>;
407def AND16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
408                     "and.w\t{$src2, $dst}",
409                     [(set GR16:$dst, (and GR16:$src1, (load addr:$src2))),
410                      (implicit SRW)]>;
411
412let isTwoAddress = 0 in {
413def AND8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
414                "and.b\t{$src, $dst}",
415                [(store (and (load addr:$dst), GR8:$src), addr:$dst),
416                 (implicit SRW)]>;
417def AND16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
418                "and.w\t{$src, $dst}",
419                [(store (and (load addr:$dst), GR16:$src), addr:$dst),
420                 (implicit SRW)]>;
421
422def AND8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
423                "and.b\t{$src, $dst}",
424                [(store (and (load addr:$dst), (i8 imm:$src)), addr:$dst),
425                 (implicit SRW)]>;
426def AND16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
427                "and.w\t{$src, $dst}",
428                [(store (and (load addr:$dst), (i16 imm:$src)), addr:$dst),
429                 (implicit SRW)]>;
430
431def AND8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
432                "and.b\t{$src, $dst}",
433                [(store (and (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
434                 (implicit SRW)]>;
435def AND16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
436                "and.w\t{$src, $dst}",
437                [(store (and (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
438                 (implicit SRW)]>;
439}
440
441
442let isCommutable = 1 in { // X = XOR Y, Z  == X = XOR Z, Y
443def XOR8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
444                     "xor.b\t{$src2, $dst}",
445                     [(set GR8:$dst, (xor GR8:$src1, GR8:$src2)),
446                      (implicit SRW)]>;
447def XOR16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
448                     "xor.w\t{$src2, $dst}",
449                     [(set GR16:$dst, (xor GR16:$src1, GR16:$src2)),
450                      (implicit SRW)]>;
451}
452
453def XOR8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
454                     "xor.b\t{$src2, $dst}",
455                     [(set GR8:$dst, (xor GR8:$src1, imm:$src2)),
456                      (implicit SRW)]>;
457def XOR16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
458                     "xor.w\t{$src2, $dst}",
459                     [(set GR16:$dst, (xor GR16:$src1, imm:$src2)),
460                      (implicit SRW)]>;
461
462def XOR8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
463                     "xor.b\t{$src2, $dst}",
464                     [(set GR8:$dst, (xor GR8:$src1, (load addr:$src2))),
465                      (implicit SRW)]>;
466def XOR16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
467                     "xor.w\t{$src2, $dst}",
468                     [(set GR16:$dst, (xor GR16:$src1, (load addr:$src2))),
469                      (implicit SRW)]>;
470
471let isTwoAddress = 0 in {
472def XOR8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
473                "xor.b\t{$src, $dst}",
474                [(store (xor (load addr:$dst), GR8:$src), addr:$dst),
475                 (implicit SRW)]>;
476def XOR16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
477                "xor.w\t{$src, $dst}",
478                [(store (xor (load addr:$dst), GR16:$src), addr:$dst),
479                 (implicit SRW)]>;
480
481def XOR8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
482                "xor.b\t{$src, $dst}",
483                [(store (xor (load addr:$dst), (i8 imm:$src)), addr:$dst),
484                 (implicit SRW)]>;
485def XOR16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
486                "xor.w\t{$src, $dst}",
487                [(store (xor (load addr:$dst), (i16 imm:$src)), addr:$dst),
488                 (implicit SRW)]>;
489
490def XOR8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
491                "xor.b\t{$src, $dst}",
492                [(store (xor (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
493                 (implicit SRW)]>;
494def XOR16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
495                "xor.w\t{$src, $dst}",
496                [(store (xor (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
497                 (implicit SRW)]>;
498}
499
500
501def SUB8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
502                     "sub.b\t{$src2, $dst}",
503                     [(set GR8:$dst, (sub GR8:$src1, GR8:$src2)),
504                      (implicit SRW)]>;
505def SUB16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
506                     "sub.w\t{$src2, $dst}",
507                     [(set GR16:$dst, (sub GR16:$src1, GR16:$src2)),
508                      (implicit SRW)]>;
509
510def SUB8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
511                     "sub.b\t{$src2, $dst}",
512                     [(set GR8:$dst, (sub GR8:$src1, imm:$src2)),
513                      (implicit SRW)]>;
514def SUB16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
515                     "sub.w\t{$src2, $dst}",
516                     [(set GR16:$dst, (sub GR16:$src1, imm:$src2)),
517                      (implicit SRW)]>;
518
519def SUB8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
520                     "sub.b\t{$src2, $dst}",
521                     [(set GR8:$dst, (sub GR8:$src1, (load addr:$src2))),
522                      (implicit SRW)]>;
523def SUB16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
524                     "sub.w\t{$src2, $dst}",
525                     [(set GR16:$dst, (sub GR16:$src1, (load addr:$src2))),
526                      (implicit SRW)]>;
527
528let isTwoAddress = 0 in {
529def SUB8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
530                "sub.b\t{$src, $dst}",
531                [(store (sub (load addr:$dst), GR8:$src), addr:$dst),
532                 (implicit SRW)]>;
533def SUB16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
534                "sub.w\t{$src, $dst}",
535                [(store (sub (load addr:$dst), GR16:$src), addr:$dst),
536                 (implicit SRW)]>;
537
538def SUB8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
539                "sub.b\t{$src, $dst}",
540                [(store (sub (load addr:$dst), (i8 imm:$src)), addr:$dst),
541                 (implicit SRW)]>;
542def SUB16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
543                "sub.w\t{$src, $dst}",
544                [(store (sub (load addr:$dst), (i16 imm:$src)), addr:$dst),
545                 (implicit SRW)]>;
546
547def SUB8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
548                "sub.b\t{$src, $dst}",
549                [(store (sub (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
550                 (implicit SRW)]>;
551def SUB16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
552                "sub.w\t{$src, $dst}",
553                [(store (sub (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
554                 (implicit SRW)]>;
555}
556
557let Uses = [SRW] in {
558def SBC8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
559                     "subc.b\t{$src2, $dst}",
560                     [(set GR8:$dst, (sube GR8:$src1, GR8:$src2)),
561                      (implicit SRW)]>;
562def SBC16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
563                     "subc.w\t{$src2, $dst}",
564                     [(set GR16:$dst, (sube GR16:$src1, GR16:$src2)),
565                      (implicit SRW)]>;
566
567def SBC8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
568                     "subc.b\t{$src2, $dst}",
569                     [(set GR8:$dst, (sube GR8:$src1, imm:$src2)),
570                      (implicit SRW)]>;
571def SBC16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
572                     "subc.w\t{$src2, $dst}",
573                     [(set GR16:$dst, (sube GR16:$src1, imm:$src2)),
574                      (implicit SRW)]>;
575
576def SBC8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
577                     "subc.b\t{$src2, $dst}",
578                     [(set GR8:$dst, (sube GR8:$src1, (load addr:$src2))),
579                      (implicit SRW)]>;
580def SBC16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
581                     "subc.w\t{$src2, $dst}",
582                     [(set GR16:$dst, (sube GR16:$src1, (load addr:$src2))),
583                      (implicit SRW)]>;
584
585let isTwoAddress = 0 in {
586def SBC8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
587                "subc.b\t{$src, $dst}",
588                [(store (sube (load addr:$dst), GR8:$src), addr:$dst),
589                 (implicit SRW)]>;
590def SBC16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
591                "subc.w\t{$src, $dst}",
592                [(store (sube (load addr:$dst), GR16:$src), addr:$dst),
593                 (implicit SRW)]>;
594
595def SBC8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
596                "subc.b\t{$src, $dst}",
597                [(store (sube (load addr:$dst), (i8 imm:$src)), addr:$dst),
598                 (implicit SRW)]>;
599def SBC16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
600                "subc.w\t{$src, $dst}",
601                [(store (sube (load addr:$dst), (i16 imm:$src)), addr:$dst),
602                 (implicit SRW)]>;
603
604def SBC8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
605                "subc.b\t{$src, $dst}",
606                [(store (sube (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
607                 (implicit SRW)]>;
608def SBC16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
609                "subc.w\t{$src, $dst}",
610                [(store (sube (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
611                 (implicit SRW)]>;
612}
613
614} // Uses = [SRW]
615
616// FIXME: Provide proper encoding!
617def SAR8r1  : Pseudo<(outs GR8:$dst), (ins GR8:$src),
618                     "rra.b\t$dst",
619                     [(set GR8:$dst, (MSP430rra GR8:$src)),
620                      (implicit SRW)]>;
621def SAR16r1 : Pseudo<(outs GR16:$dst), (ins GR16:$src),
622                     "rra.w\t$dst",
623                     [(set GR16:$dst, (MSP430rra GR16:$src)),
624                      (implicit SRW)]>;
625
626def SHL8r1  : Pseudo<(outs GR8:$dst), (ins GR8:$src),
627                     "rla.b\t$dst",
628                     [(set GR8:$dst, (MSP430rla GR8:$src)),
629                      (implicit SRW)]>;
630def SHL16r1 : Pseudo<(outs GR16:$dst), (ins GR16:$src),
631                     "rla.w\t$dst",
632                     [(set GR16:$dst, (MSP430rla GR16:$src)),
633                      (implicit SRW)]>;
634
635def SAR8r1c  : Pseudo<(outs GR8:$dst), (ins GR8:$src),
636                      "clrc\n\t"
637                      "rrc.b\t$dst",
638                      [(set GR8:$dst, (MSP430rrc GR8:$src)),
639                       (implicit SRW)]>;
640def SAR16r1c : Pseudo<(outs GR16:$dst), (ins GR16:$src),
641                      "clrc\n\t"
642                      "rrc.w\t$dst",
643                      [(set GR16:$dst, (MSP430rrc GR16:$src)),
644                       (implicit SRW)]>;
645
646def SEXT16r : Pseudo<(outs GR16:$dst), (ins GR16:$src),
647                     "sxt\t$dst",
648                     [(set GR16:$dst, (sext_inreg GR16:$src, i8)),
649                      (implicit SRW)]>;
650
651} // Defs = [SRW]
652
653def SWPB16r : Pseudo<(outs GR16:$dst), (ins GR16:$src),
654                     "swpb\t$dst",
655                     [(set GR16:$dst, (bswap GR16:$src))]>;
656
657let isCommutable = 1 in { // X = OR Y, Z  == X = OR Z, Y
658def OR8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
659                    "bis.b\t{$src2, $dst}",
660                    [(set GR8:$dst, (or GR8:$src1, GR8:$src2))]>;
661def OR16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
662                    "bis.w\t{$src2, $dst}",
663                    [(set GR16:$dst, (or GR16:$src1, GR16:$src2))]>;
664}
665
666def OR8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
667                    "bis.b\t{$src2, $dst}",
668                    [(set GR8:$dst, (or GR8:$src1, imm:$src2))]>;
669def OR16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
670                    "bis.w\t{$src2, $dst}",
671                    [(set GR16:$dst, (or GR16:$src1, imm:$src2))]>;
672
673def OR8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
674                    "bis.b\t{$src2, $dst}",
675                    [(set GR8:$dst, (or GR8:$src1, (load addr:$src2)))]>;
676def OR16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
677                    "bis.w\t{$src2, $dst}",
678                    [(set GR16:$dst, (or GR16:$src1, (load addr:$src2)))]>;
679
680let isTwoAddress = 0 in {
681def OR8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
682                "bis.b\t{$src, $dst}",
683                [(store (or (load addr:$dst), GR8:$src), addr:$dst)]>;
684def OR16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
685                "bis.w\t{$src, $dst}",
686                [(store (or (load addr:$dst), GR16:$src), addr:$dst)]>;
687
688def OR8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
689                "bis.b\t{$src, $dst}",
690                [(store (or (load addr:$dst), (i8 imm:$src)), addr:$dst)]>;
691def OR16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
692                "bis.w\t{$src, $dst}",
693                [(store (or (load addr:$dst), (i16 imm:$src)), addr:$dst)]>;
694
695def OR8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
696                "bis.b\t{$src, $dst}",
697                [(store (or (i8 (load addr:$dst)),
698                            (i8 (load addr:$src))), addr:$dst)]>;
699def OR16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
700                "bis.w\t{$src, $dst}",
701                 [(store (or (i16 (load addr:$dst)),
702                             (i16 (load addr:$src))), addr:$dst)]>;
703}
704
705} // isTwoAddress = 1
706
707// Integer comparisons
708let Defs = [SRW] in {
709def CMP8rr  : Pseudo<(outs), (ins GR8:$src1, GR8:$src2),
710                     "cmp.b\t{$src1, $src2}",
711                     [(MSP430cmp GR8:$src1, GR8:$src2), (implicit SRW)]>;
712def CMP16rr : Pseudo<(outs), (ins GR16:$src1, GR16:$src2),
713                     "cmp.w\t{$src1, $src2}",
714                     [(MSP430cmp GR16:$src1, GR16:$src2), (implicit SRW)]>;
715
716def CMP8ir  : Pseudo<(outs), (ins i8imm:$src1, GR8:$src2),
717                   "cmp.b\t{$src1, $src2}",
718                   [(MSP430cmp imm:$src1, GR8:$src2), (implicit SRW)]>;
719def CMP16ir : Pseudo<(outs), (ins i16imm:$src1, GR16:$src2),
720                     "cmp.w\t{$src1, $src2}",
721                     [(MSP430cmp imm:$src1, GR16:$src2), (implicit SRW)]>;
722
723def CMP8im  : Pseudo<(outs), (ins i8imm:$src1, memsrc:$src2),
724                     "cmp.b\t{$src1, $src2}",
725                      [(MSP430cmp (i8 imm:$src1), (load addr:$src2)), (implicit SRW)]>;
726def CMP16im : Pseudo<(outs), (ins i16imm:$src1, memsrc:$src2),
727                     "cmp.w\t{$src1, $src2}",
728                      [(MSP430cmp (i16 imm:$src1), (load addr:$src2)), (implicit SRW)]>;
729
730def CMP8rm  : Pseudo<(outs), (ins GR8:$src1, memsrc:$src2),
731                     "cmp.b\t{$src1, $src2}",
732                     [(MSP430cmp GR8:$src1, (load addr:$src2)), (implicit SRW)]>;
733def CMP16rm : Pseudo<(outs), (ins GR16:$src1, memsrc:$src2),
734                     "cmp.w\t{$src1, $src2}",
735                     [(MSP430cmp GR16:$src1, (load addr:$src2)), (implicit SRW)]>;
736
737def CMP8mr  : Pseudo<(outs), (ins memsrc:$src1, GR8:$src2),
738                "cmp.b\t{$src1, $src2}",
739                [(MSP430cmp (load addr:$src1), GR8:$src2), (implicit SRW)]>;
740def CMP16mr : Pseudo<(outs), (ins memsrc:$src1, GR16:$src2),
741                "cmp.w\t{$src1, $src2}",
742                [(MSP430cmp (load addr:$src1), GR16:$src2), (implicit SRW)]>;
743
744def CMP8mi0 : Pseudo<(outs), (ins memsrc:$src1),
745                "cmp.b\t{$src1, #0}",
746                [(MSP430cmp (load addr:$src1), (i8 0)), (implicit SRW)]>;
747def CMP16mi0: Pseudo<(outs), (ins memsrc:$src1),
748                "cmp.w\t{$src1, #0}",
749                [(MSP430cmp (load addr:$src1), (i16 0)), (implicit SRW)]>;
750def CMP8mi1 : Pseudo<(outs), (ins memsrc:$src1),
751                "cmp.b\t{$src1, #1}",
752                [(MSP430cmp (load addr:$src1), (i8 1)), (implicit SRW)]>;
753def CMP16mi1: Pseudo<(outs), (ins memsrc:$src1),
754                "cmp.w\t{$src1, #1}",
755                [(MSP430cmp (load addr:$src1), (i16 1)), (implicit SRW)]>;
756def CMP8mi2 : Pseudo<(outs), (ins memsrc:$src1),
757                "cmp.b\t{$src1, #2}",
758                [(MSP430cmp (load addr:$src1), (i8 2)), (implicit SRW)]>;
759def CMP16mi2: Pseudo<(outs), (ins memsrc:$src1),
760                "cmp.w\t{$src1, #2}",
761                [(MSP430cmp (load addr:$src1), (i16 2)), (implicit SRW)]>;
762def CMP8mi4 : Pseudo<(outs), (ins memsrc:$src1),
763                "cmp.b\t{$src1, #4}",
764                [(MSP430cmp (load addr:$src1), (i8 4)), (implicit SRW)]>;
765def CMP16mi4: Pseudo<(outs), (ins memsrc:$src1),
766                "cmp.w\t{$src1, #4}",
767                [(MSP430cmp (load addr:$src1), (i16 4)), (implicit SRW)]>;
768def CMP8mi8 : Pseudo<(outs), (ins memsrc:$src1),
769                "cmp.b\t{$src1, #8}",
770                [(MSP430cmp (load addr:$src1), (i8 8)), (implicit SRW)]>;
771def CMP16mi8: Pseudo<(outs), (ins memsrc:$src1),
772                "cmp.w\t{$src1, #8}",
773                [(MSP430cmp (load addr:$src1), (i16 8)), (implicit SRW)]>;
774
775} // Defs = [SRW]
776
777//===----------------------------------------------------------------------===//
778// Non-Instruction Patterns
779
780// extload
781def : Pat<(extloadi16i8 addr:$src), (MOVZX16rm8 addr:$src)>;
782
783// anyext
784def : Pat<(anyext addr:$src), (MOVZX16rr8 GR8:$src)>;
785
786// truncs
787def : Pat<(i8 (trunc GR16:$src)),
788          (EXTRACT_SUBREG GR16:$src, subreg_8bit)>;
789
790// GlobalAddress, ExternalSymbol
791def : Pat<(i16 (MSP430Wrapper tglobaladdr:$dst)), (MOV16ri tglobaladdr:$dst)>;
792def : Pat<(i16 (MSP430Wrapper texternalsym:$dst)), (MOV16ri texternalsym:$dst)>;
793
794def : Pat<(add GR16:$src1, (MSP430Wrapper tglobaladdr :$src2)),
795          (ADD16ri GR16:$src1, tglobaladdr:$src2)>;
796def : Pat<(add GR16:$src1, (MSP430Wrapper texternalsym:$src2)),
797          (ADD16ri GR16:$src1, texternalsym:$src2)>;
798
799def : Pat<(store (i16 (MSP430Wrapper tglobaladdr:$src)), addr:$dst),
800          (MOV16mi addr:$dst, tglobaladdr:$src)>;
801def : Pat<(store (i16 (MSP430Wrapper texternalsym:$src)), addr:$dst),
802          (MOV16mi addr:$dst, texternalsym:$src)>;
803
804// calls
805def : Pat<(MSP430call (i16 tglobaladdr:$dst)),
806          (CALLi tglobaladdr:$dst)>;
807def : Pat<(MSP430call (i16 texternalsym:$dst)),
808          (CALLi texternalsym:$dst)>;
809
810// add and sub always produce carry
811def : Pat<(addc GR16:$src1, GR16:$src2),
812          (ADD16rr GR16:$src1, GR16:$src2)>;
813def : Pat<(addc GR16:$src1, (load addr:$src2)),
814          (ADD16rm GR16:$src1, addr:$src2)>;
815def : Pat<(addc GR16:$src1, imm:$src2),
816          (ADD16ri GR16:$src1, imm:$src2)>;
817def : Pat<(store (addc (load addr:$dst), GR16:$src), addr:$dst),
818          (ADD16mr addr:$dst, GR16:$src)>;
819def : Pat<(store (addc (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
820          (ADD16mm addr:$dst, addr:$src)>;
821
822def : Pat<(addc GR8:$src1, GR8:$src2),
823          (ADD8rr GR8:$src1, GR8:$src2)>;
824def : Pat<(addc GR8:$src1, (load addr:$src2)),
825          (ADD8rm GR8:$src1, addr:$src2)>;
826def : Pat<(addc GR8:$src1, imm:$src2),
827          (ADD8ri GR8:$src1, imm:$src2)>;
828def : Pat<(store (addc (load addr:$dst), GR8:$src), addr:$dst),
829          (ADD8mr addr:$dst, GR8:$src)>;
830def : Pat<(store (addc (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
831          (ADD8mm addr:$dst, addr:$src)>;
832
833def : Pat<(subc GR16:$src1, GR16:$src2),
834          (SUB16rr GR16:$src1, GR16:$src2)>;
835def : Pat<(subc GR16:$src1, (load addr:$src2)),
836          (SUB16rm GR16:$src1, addr:$src2)>;
837def : Pat<(subc GR16:$src1, imm:$src2),
838          (SUB16ri GR16:$src1, imm:$src2)>;
839def : Pat<(store (subc (load addr:$dst), GR16:$src), addr:$dst),
840          (SUB16mr addr:$dst, GR16:$src)>;
841def : Pat<(store (subc (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
842          (SUB16mm addr:$dst, addr:$src)>;
843
844def : Pat<(subc GR8:$src1, GR8:$src2),
845          (SUB8rr GR8:$src1, GR8:$src2)>;
846def : Pat<(subc GR8:$src1, (load addr:$src2)),
847          (SUB8rm GR8:$src1, addr:$src2)>;
848def : Pat<(subc GR8:$src1, imm:$src2),
849          (SUB8ri GR8:$src1, imm:$src2)>;
850def : Pat<(store (subc (load addr:$dst), GR8:$src), addr:$dst),
851          (SUB8mr addr:$dst, GR8:$src)>;
852def : Pat<(store (subc (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
853          (SUB8mm addr:$dst, addr:$src)>;
854