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