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