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