MSP430InstrInfo.td revision 49ebc2278472656e05541248eaedccb13e1b7d7d
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_MSP430SetCC        : SDTypeProfile<1, 2, [SDTCisVT<0, i8>,
30                                                  SDTCisVT<1, i8>, SDTCisVT<2, i16>]>;
31def SDT_MSP430Cmp          : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
32def SDT_MSP430BrCond       : SDTypeProfile<0, 3, [SDTCisVT<0, OtherVT>,
33                                                  SDTCisVT<1, i8>, SDTCisVT<2, i16>]>;
34def SDT_MSP430Select       : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, 
35                                                  SDTCisVT<3, i8>, SDTCisVT<4, i16>]>;
36
37//===----------------------------------------------------------------------===//
38// MSP430 Specific Node Definitions.
39//===----------------------------------------------------------------------===//
40def MSP430retflag : SDNode<"MSP430ISD::RET_FLAG", SDTNone,
41                     [SDNPHasChain, SDNPOptInFlag]>;
42
43def MSP430rra     : SDNode<"MSP430ISD::RRA", SDTIntUnaryOp, []>;
44def MSP430rla     : SDNode<"MSP430ISD::RLA", SDTIntUnaryOp, []>;
45
46def MSP430call    : SDNode<"MSP430ISD::CALL", SDT_MSP430Call,
47                     [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag]>;
48def MSP430callseq_start :
49                 SDNode<"ISD::CALLSEQ_START", SDT_MSP430CallSeqStart,
50                        [SDNPHasChain, SDNPOutFlag]>;
51def MSP430callseq_end :
52                 SDNode<"ISD::CALLSEQ_END",   SDT_MSP430CallSeqEnd,
53                        [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
54def MSP430Wrapper : SDNode<"MSP430ISD::Wrapper", SDT_MSP430Wrapper>;
55def MSP430setcc   : SDNode<"MSP430ISD::SETCC", SDT_MSP430SetCC>;
56def MSP430cmp     : SDNode<"MSP430ISD::CMP", SDT_MSP430Cmp>;
57def MSP430brcond  : SDNode<"MSP430ISD::BRCOND", SDT_MSP430BrCond, [SDNPHasChain]>;
58def MSP430select  : SDNode<"MSP430ISD::SELECT", SDT_MSP430Select>;
59
60//===----------------------------------------------------------------------===//
61// MSP430 Operand Definitions.
62//===----------------------------------------------------------------------===//
63
64// Address operands
65def memsrc : Operand<i16> {
66  let PrintMethod = "printSrcMemOperand";
67  let MIOperandInfo = (ops GR16, i16imm);
68}
69
70def memdst : Operand<i16> {
71  let PrintMethod = "printSrcMemOperand";
72  let MIOperandInfo = (ops GR16, i16imm);
73}
74
75// Branch targets have OtherVT type.
76def brtarget : Operand<OtherVT>;
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 usesCustomDAGSchedInserter = 1 in {
112  def Select16 : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2, i8imm:$cc),
113                        "# Select16 PSEUDO",
114                        [(set GR16:$dst,
115                          (MSP430select GR16:$src1, GR16:$src2, imm:$cc, SRW))]>;
116}
117
118let neverHasSideEffects = 1 in
119def NOP : Pseudo<(outs), (ins), "nop", []>;
120
121//===----------------------------------------------------------------------===//
122//  Control Flow Instructions...
123//
124
125// FIXME: Provide proper encoding!
126let isReturn = 1, isTerminator = 1 in {
127  def RET : Pseudo<(outs), (ins), "ret", [(MSP430retflag)]>;
128}
129
130let isBranch = 1, isTerminator = 1 in {
131
132// Direct branch
133let isBarrier = 1 in
134  def JMP : Pseudo<(outs), (ins brtarget:$dst),
135                   "jmp\t$dst",
136                   [(br bb:$dst)]>;
137
138// Conditional branches
139let Uses = [SRW] in
140  def JCC : Pseudo<(outs), (ins brtarget:$dst, cc:$cc),
141                            "j$cc $dst",
142                            [(MSP430brcond bb:$dst, imm:$cc, SRW)]>;
143} // isBranch, isTerminator
144
145//===----------------------------------------------------------------------===//
146//  Call Instructions...
147//
148let isCall = 1 in
149  // All calls clobber the non-callee saved registers. SPW is marked as
150  // a use to prevent stack-pointer assignments that appear immediately
151  // before calls from potentially appearing dead. Uses for argument
152  // registers are added manually.
153  let Defs = [R12W, R13W, R14W, R15W, SRW],
154      Uses = [SPW] in {
155    def CALLi     : Pseudo<(outs), (ins i16imm:$dst, variable_ops),
156                           "call\t${dst:call}", [(MSP430call imm:$dst)]>;
157    def CALLr     : Pseudo<(outs), (ins GR16:$dst, variable_ops),
158                           "call\t$dst", [(MSP430call GR16:$dst)]>;
159    def CALLm     : Pseudo<(outs), (ins memsrc:$dst, variable_ops),
160                           "call\t${dst:mem}", [(MSP430call (load addr:$dst))]>;
161  }
162
163
164//===----------------------------------------------------------------------===//
165//  Miscellaneous Instructions...
166//
167let Defs = [SPW], Uses = [SPW], neverHasSideEffects=1 in {
168let mayLoad = 1 in
169def POP16r   : Pseudo<(outs GR16:$reg), (ins), "pop.w\t$reg", []>;
170
171let mayStore = 1 in
172def PUSH16r  : Pseudo<(outs), (ins GR16:$reg), "push.w\t$reg",[]>;
173}
174
175//===----------------------------------------------------------------------===//
176// Move Instructions
177
178// FIXME: Provide proper encoding!
179let neverHasSideEffects = 1 in {
180def MOV8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src),
181                     "mov.b\t{$src, $dst}",
182                     []>;
183def MOV16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src),
184                     "mov.w\t{$src, $dst}",
185                     []>;
186}
187
188// FIXME: Provide proper encoding!
189let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
190def MOV8ri  : Pseudo<(outs GR8:$dst), (ins i8imm:$src),
191                     "mov.b\t{$src, $dst}",
192                     [(set GR8:$dst, imm:$src)]>;
193def MOV16ri : Pseudo<(outs GR16:$dst), (ins i16imm:$src),
194                     "mov.w\t{$src, $dst}",
195                     [(set GR16:$dst, imm:$src)]>;
196}
197
198let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in {
199def MOV8rm  : Pseudo<(outs GR8:$dst), (ins memsrc:$src),
200                "mov.b\t{$src, $dst}",
201                [(set GR8:$dst, (load addr:$src))]>;
202def MOV16rm : Pseudo<(outs GR16:$dst), (ins memsrc:$src),
203                "mov.w\t{$src, $dst}",
204                [(set GR16:$dst, (load addr:$src))]>;
205}
206
207def MOVZX16rr8 : Pseudo<(outs GR16:$dst), (ins GR8:$src),
208                "mov.b\t{$src, $dst}",
209                [(set GR16:$dst, (zext GR8:$src))]>;
210def MOVZX16rm8 : Pseudo<(outs GR16:$dst), (ins memsrc:$src),
211                "mov.b\t{$src, $dst}",
212                [(set GR16:$dst, (zextloadi16i8 addr:$src))]>;
213
214def MOV8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
215                "mov.b\t{$src, $dst}",
216                [(store (i8 imm:$src), addr:$dst)]>;
217def MOV16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
218                "mov.w\t{$src, $dst}",
219                [(store (i16 imm:$src), addr:$dst)]>;
220
221def MOV8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
222                "mov.b\t{$src, $dst}",
223                [(store GR8:$src, addr:$dst)]>;
224def MOV16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
225                "mov.w\t{$src, $dst}",
226                [(store GR16:$src, addr:$dst)]>;
227
228//===----------------------------------------------------------------------===//
229// Arithmetic Instructions
230
231let isTwoAddress = 1 in {
232
233let Defs = [SRW] in {
234
235let isCommutable = 1 in { // X = ADD Y, Z  == X = ADD Z, Y
236// FIXME: Provide proper encoding!
237def ADD8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
238                     "add.b\t{$src2, $dst}",
239                     [(set GR8:$dst, (add GR8:$src1, GR8:$src2)),
240                      (implicit SRW)]>;
241def ADD16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
242                     "add.w\t{$src2, $dst}",
243                     [(set GR16:$dst, (add GR16:$src1, GR16:$src2)),
244                      (implicit SRW)]>;
245}
246
247def ADD8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
248                     "add.b\t{$src2, $dst}",
249                     [(set GR8:$dst, (add GR8:$src1, (load addr:$src2))),
250                      (implicit SRW)]>;
251def ADD16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
252                     "add.w\t{$src2, $dst}",
253                     [(set GR16:$dst, (add GR16:$src1, (load addr:$src2))),
254                      (implicit SRW)]>;
255
256def ADD8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
257                     "add.b\t{$src2, $dst}",
258                     [(set GR8:$dst, (add GR8:$src1, imm:$src2)),
259                      (implicit SRW)]>;
260def ADD16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
261                     "add.w\t{$src2, $dst}",
262                     [(set GR16:$dst, (add GR16:$src1, imm:$src2)),
263                      (implicit SRW)]>;
264
265let isTwoAddress = 0 in {
266def ADD8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
267                "add.b\t{$src, $dst}",
268                [(store (add (load addr:$dst), GR8:$src), addr:$dst),
269                 (implicit SRW)]>;
270def ADD16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
271                "add.w\t{$src, $dst}",
272                [(store (add (load addr:$dst), GR16:$src), addr:$dst),
273                 (implicit SRW)]>;
274
275def ADD8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
276                "add.b\t{$src, $dst}",
277                [(store (add (load addr:$dst), (i8 imm:$src)), addr:$dst),
278                 (implicit SRW)]>;
279def ADD16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
280                "add.w\t{$src, $dst}",
281                [(store (add (load addr:$dst), (i16 imm:$src)), addr:$dst),
282                 (implicit SRW)]>;
283
284def ADD8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
285                "add.b\t{$src, $dst}",
286                [(store (add (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
287                 (implicit SRW)]>;
288def ADD16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
289                "add.w\t{$src, $dst}",
290                [(store (add (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
291                 (implicit SRW)]>;
292}
293
294let Uses = [SRW] in {
295
296let isCommutable = 1 in { // X = ADDC Y, Z  == X = ADDC Z, Y
297def ADC8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
298                     "addc.b\t{$src2, $dst}",
299                     [(set GR8:$dst, (adde GR8:$src1, GR8:$src2)),
300                      (implicit SRW)]>;
301def ADC16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
302                     "addc.w\t{$src2, $dst}",
303                     [(set GR16:$dst, (adde GR16:$src1, GR16:$src2)),
304                      (implicit SRW)]>;
305} // isCommutable
306
307def ADC8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
308                     "addc.b\t{$src2, $dst}",
309                     [(set GR8:$dst, (adde GR8:$src1, imm:$src2)),
310                      (implicit SRW)]>;
311def ADC16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
312                     "addc.w\t{$src2, $dst}",
313                     [(set GR16:$dst, (adde GR16:$src1, imm:$src2)),
314                      (implicit SRW)]>;
315
316def ADC8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
317                     "addc.b\t{$src2, $dst}",
318                     [(set GR8:$dst, (adde GR8:$src1, (load addr:$src2))),
319                      (implicit SRW)]>;
320def ADC16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
321                     "addc.w\t{$src2, $dst}",
322                     [(set GR16:$dst, (adde GR16:$src1, (load addr:$src2))),
323                      (implicit SRW)]>;
324
325let isTwoAddress = 0 in {
326def ADC8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
327                "addc.b\t{$src, $dst}",
328                [(store (adde (load addr:$dst), GR8:$src), addr:$dst),
329                 (implicit SRW)]>;
330def ADC16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
331                "addc.w\t{$src, $dst}",
332                [(store (adde (load addr:$dst), GR16:$src), addr:$dst),
333                 (implicit SRW)]>;
334
335def ADC8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
336                "addc.b\t{$src, $dst}",
337                [(store (adde (load addr:$dst), (i8 imm:$src)), addr:$dst),
338                 (implicit SRW)]>;
339def ADC16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
340                "addc.w\t{$src, $dst}",
341                [(store (adde (load addr:$dst), (i16 imm:$src)), addr:$dst),
342                 (implicit SRW)]>;
343
344def ADC8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
345                "addc.b\t{$src, $dst}",
346                [(store (adde (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
347                 (implicit SRW)]>;
348def ADC16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
349                "addc.w\t{$src, $dst}",
350                [(store (adde (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
351                 (implicit SRW)]>;
352}
353
354} // Uses = [SRW]
355
356let isCommutable = 1 in { // X = AND Y, Z  == X = AND Z, Y
357def AND8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
358                     "and.b\t{$src2, $dst}",
359                     [(set GR8:$dst, (and GR8:$src1, GR8:$src2)),
360                      (implicit SRW)]>;
361def AND16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
362                     "and.w\t{$src2, $dst}",
363                     [(set GR16:$dst, (and GR16:$src1, GR16:$src2)),
364                      (implicit SRW)]>;
365}
366
367def AND8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
368                     "and.b\t{$src2, $dst}",
369                     [(set GR8:$dst, (and GR8:$src1, imm:$src2)),
370                      (implicit SRW)]>;
371def AND16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
372                     "and.w\t{$src2, $dst}",
373                     [(set GR16:$dst, (and GR16:$src1, imm:$src2)),
374                      (implicit SRW)]>;
375
376def AND8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
377                     "and.b\t{$src2, $dst}",
378                     [(set GR8:$dst, (and GR8:$src1, (load addr:$src2))),
379                      (implicit SRW)]>;
380def AND16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
381                     "and.w\t{$src2, $dst}",
382                     [(set GR16:$dst, (and GR16:$src1, (load addr:$src2))),
383                      (implicit SRW)]>;
384
385let isTwoAddress = 0 in {
386def AND8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
387                "and.b\t{$src, $dst}",
388                [(store (and (load addr:$dst), GR8:$src), addr:$dst),
389                 (implicit SRW)]>;
390def AND16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
391                "and.w\t{$src, $dst}",
392                [(store (and (load addr:$dst), GR16:$src), addr:$dst),
393                 (implicit SRW)]>;
394
395def AND8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
396                "and.b\t{$src, $dst}",
397                [(store (and (load addr:$dst), (i8 imm:$src)), addr:$dst),
398                 (implicit SRW)]>;
399def AND16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
400                "and.w\t{$src, $dst}",
401                [(store (and (load addr:$dst), (i16 imm:$src)), addr:$dst),
402                 (implicit SRW)]>;
403
404def AND8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
405                "and.b\t{$src, $dst}",
406                [(store (and (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
407                 (implicit SRW)]>;
408def AND16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
409                "and.w\t{$src, $dst}",
410                [(store (and (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
411                 (implicit SRW)]>;
412}
413
414
415let isCommutable = 1 in { // X = XOR Y, Z  == X = XOR Z, Y
416def XOR8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
417                     "xor.b\t{$src2, $dst}",
418                     [(set GR8:$dst, (xor GR8:$src1, GR8:$src2)),
419                      (implicit SRW)]>;
420def XOR16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
421                     "xor.w\t{$src2, $dst}",
422                     [(set GR16:$dst, (xor GR16:$src1, GR16:$src2)),
423                      (implicit SRW)]>;
424}
425
426def XOR8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
427                     "xor.b\t{$src2, $dst}",
428                     [(set GR8:$dst, (xor GR8:$src1, imm:$src2)),
429                      (implicit SRW)]>;
430def XOR16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
431                     "xor.w\t{$src2, $dst}",
432                     [(set GR16:$dst, (xor GR16:$src1, imm:$src2)),
433                      (implicit SRW)]>;
434
435def XOR8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
436                     "xor.b\t{$src2, $dst}",
437                     [(set GR8:$dst, (xor GR8:$src1, (load addr:$src2))),
438                      (implicit SRW)]>;
439def XOR16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
440                     "xor.w\t{$src2, $dst}",
441                     [(set GR16:$dst, (xor GR16:$src1, (load addr:$src2))),
442                      (implicit SRW)]>;
443
444let isTwoAddress = 0 in {
445def XOR8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
446                "xor.b\t{$src, $dst}",
447                [(store (xor (load addr:$dst), GR8:$src), addr:$dst),
448                 (implicit SRW)]>;
449def XOR16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
450                "xor.w\t{$src, $dst}",
451                [(store (xor (load addr:$dst), GR16:$src), addr:$dst),
452                 (implicit SRW)]>;
453
454def XOR8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
455                "xor.b\t{$src, $dst}",
456                [(store (xor (load addr:$dst), (i8 imm:$src)), addr:$dst),
457                 (implicit SRW)]>;
458def XOR16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
459                "xor.w\t{$src, $dst}",
460                [(store (xor (load addr:$dst), (i16 imm:$src)), addr:$dst),
461                 (implicit SRW)]>;
462
463def XOR8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
464                "xor.b\t{$src, $dst}",
465                [(store (xor (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
466                 (implicit SRW)]>;
467def XOR16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
468                "xor.w\t{$src, $dst}",
469                [(store (xor (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
470                 (implicit SRW)]>;
471}
472
473
474def SUB8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
475                     "sub.b\t{$src2, $dst}",
476                     [(set GR8:$dst, (sub GR8:$src1, GR8:$src2)),
477                      (implicit SRW)]>;
478def SUB16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
479                     "sub.w\t{$src2, $dst}",
480                     [(set GR16:$dst, (sub GR16:$src1, GR16:$src2)),
481                      (implicit SRW)]>;
482
483def SUB8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
484                     "sub.b\t{$src2, $dst}",
485                     [(set GR8:$dst, (sub GR8:$src1, imm:$src2)),
486                      (implicit SRW)]>;
487def SUB16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
488                     "sub.w\t{$src2, $dst}",
489                     [(set GR16:$dst, (sub GR16:$src1, imm:$src2)),
490                      (implicit SRW)]>;
491
492def SUB8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
493                     "sub.b\t{$src2, $dst}",
494                     [(set GR8:$dst, (sub GR8:$src1, (load addr:$src2))),
495                      (implicit SRW)]>;
496def SUB16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
497                     "sub.w\t{$src2, $dst}",
498                     [(set GR16:$dst, (sub GR16:$src1, (load addr:$src2))),
499                      (implicit SRW)]>;
500
501let isTwoAddress = 0 in {
502def SUB8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
503                "sub.b\t{$src, $dst}",
504                [(store (sub (load addr:$dst), GR8:$src), addr:$dst),
505                 (implicit SRW)]>;
506def SUB16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
507                "sub.w\t{$src, $dst}",
508                [(store (sub (load addr:$dst), GR16:$src), addr:$dst),
509                 (implicit SRW)]>;
510
511def SUB8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
512                "sub.b\t{$src, $dst}",
513                [(store (sub (load addr:$dst), (i8 imm:$src)), addr:$dst),
514                 (implicit SRW)]>;
515def SUB16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
516                "sub.w\t{$src, $dst}",
517                [(store (sub (load addr:$dst), (i16 imm:$src)), addr:$dst),
518                 (implicit SRW)]>;
519
520def SUB8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
521                "sub.b\t{$src, $dst}",
522                [(store (sub (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
523                 (implicit SRW)]>;
524def SUB16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
525                "sub.w\t{$src, $dst}",
526                [(store (sub (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
527                 (implicit SRW)]>;
528}
529
530let Uses = [SRW] in {
531def SBC8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
532                     "subc.b\t{$src2, $dst}",
533                     [(set GR8:$dst, (sube GR8:$src1, GR8:$src2)),
534                      (implicit SRW)]>;
535def SBC16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
536                     "subc.w\t{$src2, $dst}",
537                     [(set GR16:$dst, (sube GR16:$src1, GR16:$src2)),
538                      (implicit SRW)]>;
539
540def SBC8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
541                     "subc.b\t{$src2, $dst}",
542                     [(set GR8:$dst, (sube GR8:$src1, imm:$src2)),
543                      (implicit SRW)]>;
544def SBC16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
545                     "subc.w\t{$src2, $dst}",
546                     [(set GR16:$dst, (sube GR16:$src1, imm:$src2)),
547                      (implicit SRW)]>;
548
549def SBC8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
550                     "subc.b\t{$src2, $dst}",
551                     [(set GR8:$dst, (sube GR8:$src1, (load addr:$src2))),
552                      (implicit SRW)]>;
553def SBC16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
554                     "subc.w\t{$src2, $dst}",
555                     [(set GR16:$dst, (sube GR16:$src1, (load addr:$src2))),
556                      (implicit SRW)]>;
557
558let isTwoAddress = 0 in {
559def SBC8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
560                "subc.b\t{$src, $dst}",
561                [(store (sube (load addr:$dst), GR8:$src), addr:$dst),
562                 (implicit SRW)]>;
563def SBC16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
564                "subc.w\t{$src, $dst}",
565                [(store (sube (load addr:$dst), GR16:$src), addr:$dst),
566                 (implicit SRW)]>;
567
568def SBC8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
569                "subc.b\t{$src, $dst}",
570                [(store (sube (load addr:$dst), (i8 imm:$src)), addr:$dst),
571                 (implicit SRW)]>;
572def SBC16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
573                "subc.w\t{$src, $dst}",
574                [(store (sube (load addr:$dst), (i16 imm:$src)), addr:$dst),
575                 (implicit SRW)]>;
576
577def SBC8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
578                "subc.b\t{$src, $dst}",
579                [(store (sube (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
580                 (implicit SRW)]>;
581def SBC16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
582                "subc.w\t{$src, $dst}",
583                [(store (sube (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
584                 (implicit SRW)]>;
585}
586
587} // Uses = [SRW]
588
589// FIXME: Provide proper encoding!
590def SAR16r1 : Pseudo<(outs GR16:$dst), (ins GR16:$src),
591                     "rra.w\t$dst",
592                     [(set GR16:$dst, (MSP430rra GR16:$src)),
593                      (implicit SRW)]>;
594
595def SHL16r1 : Pseudo<(outs GR16:$dst), (ins GR16:$src),
596                     "rla.w\t$dst",
597                     [(set GR16:$dst, (MSP430rla GR16:$src)),
598                      (implicit SRW)]>;
599
600def SEXT16r : Pseudo<(outs GR16:$dst), (ins GR16:$src),
601                     "sxt\t$dst",
602                     [(set GR16:$dst, (sext_inreg GR16:$src, i8)),
603                      (implicit SRW)]>;
604
605} // Defs = [SRW]
606
607def SWPB16r : Pseudo<(outs GR16:$dst), (ins GR16:$src),
608                     "swpb\t$dst",
609                     [(set GR16:$dst, (bswap GR16:$src))]>;
610
611let isCommutable = 1 in { // X = OR Y, Z  == X = OR Z, Y
612def OR8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
613                    "bis.b\t{$src2, $dst}",
614                    [(set GR8:$dst, (or GR8:$src1, GR8:$src2))]>;
615def OR16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
616                    "bis.w\t{$src2, $dst}",
617                    [(set GR16:$dst, (or GR16:$src1, GR16:$src2))]>;
618}
619
620def OR8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
621                    "bis.b\t{$src2, $dst}",
622                    [(set GR8:$dst, (or GR8:$src1, imm:$src2))]>;
623def OR16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
624                    "bis.w\t{$src2, $dst}",
625                    [(set GR16:$dst, (or GR16:$src1, imm:$src2))]>;
626
627def OR8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
628                    "bis.b\t{$src2, $dst}",
629                    [(set GR8:$dst, (or GR8:$src1, (load addr:$src2)))]>;
630def OR16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
631                    "bis.w\t{$src2, $dst}",
632                    [(set GR16:$dst, (or GR16:$src1, (load addr:$src2)))]>;
633
634let isTwoAddress = 0 in {
635def OR8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
636                "bis.b\t{$src, $dst}",
637                [(store (or (load addr:$dst), GR8:$src), addr:$dst),
638                 (implicit SRW)]>;
639def OR16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
640                "bis.w\t{$src, $dst}",
641                [(store (or (load addr:$dst), GR16:$src), addr:$dst),
642                 (implicit SRW)]>;
643
644def OR8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
645                "bis.b\t{$src, $dst}",
646                [(store (or (load addr:$dst), (i8 imm:$src)), addr:$dst),
647                 (implicit SRW)]>;
648def OR16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
649                "bis.w\t{$src, $dst}",
650                [(store (or (load addr:$dst), (i16 imm:$src)), addr:$dst),
651                 (implicit SRW)]>;
652
653def OR8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
654                "bis.b\t{$src, $dst}",
655                [(store (or (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
656                 (implicit SRW)]>;
657def OR16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
658                "bis.w\t{$src, $dst}",
659                [(store (or (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
660                 (implicit SRW)]>;
661}
662
663} // isTwoAddress = 1
664
665// Integer comparisons
666let Defs = [SRW] in {
667def CMP8rr  : Pseudo<(outs), (ins GR8:$src1, GR8:$src2),
668                     "cmp.b\t{$src1, $src2}",
669                     [(MSP430cmp GR8:$src1, GR8:$src2), (implicit SRW)]>;
670def CMP16rr : Pseudo<(outs), (ins GR16:$src1, GR16:$src2),
671                     "cmp.w\t{$src1, $src2}",
672                     [(MSP430cmp GR16:$src1, GR16:$src2), (implicit SRW)]>;
673
674def CMP8ri  : Pseudo<(outs), (ins GR8:$src1, i8imm:$src2),
675                     "cmp.b\t{$src1, $src2}",
676                     [(MSP430cmp GR8:$src1, imm:$src2), (implicit SRW)]>;
677def CMP16ri : Pseudo<(outs), (ins GR16:$src1, i16imm:$src2),
678                     "cmp.w\t{$src1, $src2}",
679                     [(MSP430cmp GR16:$src1, imm:$src2), (implicit SRW)]>;
680
681def CMP8rm  : Pseudo<(outs), (ins GR8:$src1, memsrc:$src2),
682                     "cmp.b\t{$src1, $src2}",
683                     [(MSP430cmp GR8:$src1, (load addr:$src2)), (implicit SRW)]>;
684def CMP16rm : Pseudo<(outs), (ins GR16:$src1, memsrc:$src2),
685                     "cmp.w\t{$src1, $src2}",
686                     [(MSP430cmp GR16:$src1, (load addr:$src2)), (implicit SRW)]>;
687
688def CMP8mr  : Pseudo<(outs), (ins memsrc:$src1, GR8:$src2),
689                "cmp.b\t{$src1, $src2}",
690                [(MSP430cmp (load addr:$src1), GR8:$src2), (implicit SRW)]>;
691def CMP16mr : Pseudo<(outs), (ins memsrc:$src1, GR16:$src2),
692                "cmp.w\t{$src1, $src2}",
693                [(MSP430cmp (load addr:$src1), GR16:$src2), (implicit SRW)]>;
694
695def CMP8mi  : Pseudo<(outs), (ins memsrc:$src1, i8imm:$src2),
696                "cmp.b\t{$src1, $src2}",
697                [(MSP430cmp (load addr:$src1), (i8 imm:$src2)), (implicit SRW)]>;
698def CMP16mi : Pseudo<(outs), (ins memsrc:$src1, i16imm:$src2),
699                "cmp.w\t{$src1, $src2}",
700                [(MSP430cmp (load addr:$src1), (i16 imm:$src2)), (implicit SRW)]>;
701
702def CMP8mm  : Pseudo<(outs), (ins memsrc:$src1, memsrc:$src2),
703                "cmp.b\t{$src1, $src2}",
704                [(MSP430cmp (load addr:$src1), (i8 (load addr:$src2))), (implicit SRW)]>;
705def CMP16mm : Pseudo<(outs), (ins memsrc:$src1, memsrc:$src2),
706                "cmp.w\t{$src1, $src2}",
707                [(MSP430cmp (load addr:$src1), (i16 (load addr:$src2))), (implicit SRW)]>;
708} // Defs = [SRW]
709
710//===----------------------------------------------------------------------===//
711// Non-Instruction Patterns
712
713// extload
714def : Pat<(extloadi16i8 addr:$src), (MOVZX16rm8 addr:$src)>;
715
716// truncs
717def : Pat<(i8 (trunc GR16:$src)),
718          (EXTRACT_SUBREG GR16:$src, subreg_8bit)>;
719
720// GlobalAddress, ExternalSymbol
721def : Pat<(i16 (MSP430Wrapper tglobaladdr:$dst)), (MOV16ri tglobaladdr:$dst)>;
722def : Pat<(i16 (MSP430Wrapper texternalsym:$dst)), (MOV16ri texternalsym:$dst)>;
723
724def : Pat<(add GR16:$src1, (MSP430Wrapper tglobaladdr :$src2)),
725          (ADD16ri GR16:$src1, tglobaladdr:$src2)>;
726def : Pat<(add GR16:$src1, (MSP430Wrapper texternalsym:$src2)),
727          (ADD16ri GR16:$src1, texternalsym:$src2)>;
728
729def : Pat<(store (i16 (MSP430Wrapper tglobaladdr:$src)), addr:$dst),
730          (MOV16mi addr:$dst, tglobaladdr:$src)>;
731def : Pat<(store (i16 (MSP430Wrapper texternalsym:$src)), addr:$dst),
732          (MOV16mi addr:$dst, texternalsym:$src)>;
733
734// calls
735def : Pat<(MSP430call (i16 tglobaladdr:$dst)),
736          (CALLi tglobaladdr:$dst)>;
737def : Pat<(MSP430call (i16 texternalsym:$dst)),
738          (CALLi texternalsym:$dst)>;
739
740// add and sub always produce carry
741def : Pat<(addc GR16:$src1, GR16:$src2),
742          (ADD16rr GR16:$src1, GR16:$src2)>;
743def : Pat<(addc GR16:$src1, (load addr:$src2)),
744          (ADD16rm GR16:$src1, addr:$src2)>;
745def : Pat<(addc GR16:$src1, imm:$src2),
746          (ADD16ri GR16:$src1, imm:$src2)>;
747def : Pat<(store (addc (load addr:$dst), GR16:$src), addr:$dst),
748          (ADD16mr addr:$dst, GR16:$src)>;
749def : Pat<(store (addc (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
750          (ADD16mm addr:$dst, addr:$src)>;
751
752def : Pat<(addc GR8:$src1, GR8:$src2),
753          (ADD8rr GR8:$src1, GR8:$src2)>;
754def : Pat<(addc GR8:$src1, (load addr:$src2)),
755          (ADD8rm GR8:$src1, addr:$src2)>;
756def : Pat<(addc GR8:$src1, imm:$src2),
757          (ADD8ri GR8:$src1, imm:$src2)>;
758def : Pat<(store (addc (load addr:$dst), GR8:$src), addr:$dst),
759          (ADD8mr addr:$dst, GR8:$src)>;
760def : Pat<(store (addc (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
761          (ADD8mm addr:$dst, addr:$src)>;
762
763def : Pat<(subc GR16:$src1, GR16:$src2),
764          (SUB16rr GR16:$src1, GR16:$src2)>;
765def : Pat<(subc GR16:$src1, (load addr:$src2)),
766          (SUB16rm GR16:$src1, addr:$src2)>;
767def : Pat<(subc GR16:$src1, imm:$src2),
768          (SUB16ri GR16:$src1, imm:$src2)>;
769def : Pat<(store (subc (load addr:$dst), GR16:$src), addr:$dst),
770          (SUB16mr addr:$dst, GR16:$src)>;
771def : Pat<(store (subc (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
772          (SUB16mm addr:$dst, addr:$src)>;
773
774def : Pat<(subc GR8:$src1, GR8:$src2),
775          (SUB8rr GR8:$src1, GR8:$src2)>;
776def : Pat<(subc GR8:$src1, (load addr:$src2)),
777          (SUB8rm GR8:$src1, addr:$src2)>;
778def : Pat<(subc GR8:$src1, imm:$src2),
779          (SUB8ri GR8:$src1, imm:$src2)>;
780def : Pat<(store (subc (load addr:$dst), GR8:$src), addr:$dst),
781          (SUB8mr addr:$dst, GR8:$src)>;
782def : Pat<(store (subc (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
783          (SUB8mm addr:$dst, addr:$src)>;
784