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