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