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