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