First try of the post-inc operands handling... Not fully worked, though :(
[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
41 def MSP430rra     : SDNode<"MSP430ISD::RRA", SDTIntUnaryOp, []>;
42 def MSP430rla     : SDNode<"MSP430ISD::RLA", SDTIntUnaryOp, []>;
43 def MSP430rrc     : SDNode<"MSP430ISD::RRC", SDTIntUnaryOp, []>;
44
45 def MSP430call    : SDNode<"MSP430ISD::CALL", SDT_MSP430Call,
46                      [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag]>;
47 def MSP430callseq_start :
48                  SDNode<"ISD::CALLSEQ_START", SDT_MSP430CallSeqStart,
49                         [SDNPHasChain, SDNPOutFlag]>;
50 def MSP430callseq_end :
51                  SDNode<"ISD::CALLSEQ_END",   SDT_MSP430CallSeqEnd,
52                         [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
53 def MSP430Wrapper : SDNode<"MSP430ISD::Wrapper", SDT_MSP430Wrapper>;
54 def MSP430cmp     : SDNode<"MSP430ISD::CMP", SDT_MSP430Cmp, [SDNPOutFlag]>;
55 def MSP430brcc    : SDNode<"MSP430ISD::BR_CC", SDT_MSP430BrCC, [SDNPHasChain, SDNPInFlag]>;
56 def MSP430selectcc: SDNode<"MSP430ISD::SELECT_CC", SDT_MSP430SelectCC, [SDNPInFlag]>;
57
58 //===----------------------------------------------------------------------===//
59 // MSP430 Operand Definitions.
60 //===----------------------------------------------------------------------===//
61
62 // Address operands
63 def memsrc : Operand<i16> {
64   let PrintMethod = "printSrcMemOperand";
65   let MIOperandInfo = (ops GR16, i16imm);
66 }
67
68 def memdst : Operand<i16> {
69   let PrintMethod = "printSrcMemOperand";
70   let MIOperandInfo = (ops GR16, i16imm);
71 }
72
73 // Branch targets have OtherVT type.
74 def brtarget : Operand<OtherVT> {
75   let PrintMethod = "printPCRelImmOperand";
76 }
77
78 // Operand for printing out a condition code.
79 def cc : Operand<i8> {
80   let PrintMethod = "printCCOperand";
81 }
82
83 //===----------------------------------------------------------------------===//
84 // MSP430 Complex Pattern Definitions.
85 //===----------------------------------------------------------------------===//
86
87 def addr : ComplexPattern<iPTR, 2, "SelectAddr", [], []>;
88
89 //===----------------------------------------------------------------------===//
90 // Pattern Fragments
91 def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>;
92 def  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.
102 let Defs = [SPW, SRW], Uses = [SPW] in {
103 def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i16imm:$amt),
104                               "#ADJCALLSTACKDOWN",
105                               [(MSP430callseq_start timm:$amt)]>;
106 def ADJCALLSTACKUP   : Pseudo<(outs), (ins i16imm:$amt1, i16imm:$amt2),
107                               "#ADJCALLSTACKUP",
108                               [(MSP430callseq_end timm:$amt1, timm:$amt2)]>;
109 }
110
111 let 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
122 let neverHasSideEffects = 1 in
123 def NOP : Pseudo<(outs), (ins), "nop", []>;
124
125 //===----------------------------------------------------------------------===//
126 //  Control Flow Instructions...
127 //
128
129 // FIXME: Provide proper encoding!
130 let isReturn = 1, isTerminator = 1 in {
131   def RET : Pseudo<(outs), (ins), "ret", [(MSP430retflag)]>;
132 }
133
134 let isBranch = 1, isTerminator = 1 in {
135
136 // Direct branch
137 let isBarrier = 1 in
138   def JMP : Pseudo<(outs), (ins brtarget:$dst),
139                    "jmp\t$dst",
140                    [(br bb:$dst)]>;
141
142 // Conditional branches
143 let 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 //
152 let 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 //
171 let Defs = [SPW], Uses = [SPW], neverHasSideEffects=1 in {
172 let mayLoad = 1 in
173 def POP16r   : Pseudo<(outs GR16:$reg), (ins), "pop.w\t$reg", []>;
174
175 let mayStore = 1 in
176 def PUSH16r  : Pseudo<(outs), (ins GR16:$reg), "push.w\t$reg",[]>;
177 }
178
179 //===----------------------------------------------------------------------===//
180 // Move Instructions
181
182 // FIXME: Provide proper encoding!
183 let neverHasSideEffects = 1 in {
184 def MOV8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src),
185                      "mov.b\t{$src, $dst}",
186                      []>;
187 def MOV16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src),
188                      "mov.w\t{$src, $dst}",
189                      []>;
190 }
191
192 // FIXME: Provide proper encoding!
193 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
194 def MOV8ri  : Pseudo<(outs GR8:$dst), (ins i8imm:$src),
195                      "mov.b\t{$src, $dst}",
196                      [(set GR8:$dst, imm:$src)]>;
197 def MOV16ri : Pseudo<(outs GR16:$dst), (ins i16imm:$src),
198                      "mov.w\t{$src, $dst}",
199                      [(set GR16:$dst, imm:$src)]>;
200 }
201
202 let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in {
203 def MOV8rm  : Pseudo<(outs GR8:$dst), (ins memsrc:$src),
204                 "mov.b\t{$src, $dst}",
205                 [(set GR8:$dst, (load addr:$src))]>;
206 def MOV16rm : Pseudo<(outs GR16:$dst), (ins memsrc:$src),
207                 "mov.w\t{$src, $dst}",
208                 [(set GR16:$dst, (load addr:$src))]>;
209 }
210
211 def MOVZX16rr8 : Pseudo<(outs GR16:$dst), (ins GR8:$src),
212                 "mov.b\t{$src, $dst}",
213                 [(set GR16:$dst, (zext GR8:$src))]>;
214 def MOVZX16rm8 : Pseudo<(outs GR16:$dst), (ins memsrc:$src),
215                 "mov.b\t{$src, $dst}",
216                 [(set GR16:$dst, (zextloadi16i8 addr:$src))]>;
217
218 let mayLoad = 1, hasExtraDefRegAllocReq = 1, Constraints = "$base = $base_wb" in {
219 def MOV8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR16:$base),
220                           "mov.b\t{@$base+, $dst}", []>;
221 def 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.
229 def 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.
237 def : Pat<(i16 (zext def8:$src)),
238           (SUBREG_TO_REG (i16 0), GR8:$src, subreg_8bit)>;
239
240
241 def MOV8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
242                 "mov.b\t{$src, $dst}",
243                 [(store (i8 imm:$src), addr:$dst)]>;
244 def MOV16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
245                 "mov.w\t{$src, $dst}",
246                 [(store (i16 imm:$src), addr:$dst)]>;
247
248 def MOV8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
249                 "mov.b\t{$src, $dst}",
250                 [(store GR8:$src, addr:$dst)]>;
251 def MOV16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
252                 "mov.w\t{$src, $dst}",
253                 [(store GR16:$src, addr:$dst)]>;
254
255 def MOV8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
256                 "mov.b\t{$src, $dst}",
257                 [(store (i8 (load addr:$src)), addr:$dst)]>;
258 def 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
265 let isTwoAddress = 1 in {
266
267 let Defs = [SRW] in {
268
269 let isCommutable = 1 in { // X = ADD Y, Z  == X = ADD Z, Y
270 // FIXME: Provide proper encoding!
271 def 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)]>;
275 def 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
281 def 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)]>;
285 def 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
290 let mayLoad = 1, hasExtraDefRegAllocReq = 1, 
291 Constraints = "$base = $base_wb, $src1 = $dst" in {
292 def ADD8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR8:$src1, GR16:$base),
293                           "add.b\t{@$base+, $dst}", []>;
294 def ADD16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$src1, GR16:$base),
295                           "add.w\t{@$base+, $dst}", []>;
296 }
297
298
299 def 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)]>;
303 def 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
308 let isTwoAddress = 0 in {
309 def 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)]>;
313 def 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
318 def 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)]>;
322 def 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
327 def 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)]>;
331 def 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
337 let Uses = [SRW] in {
338
339 let isCommutable = 1 in { // X = ADDC Y, Z  == X = ADDC Z, Y
340 def 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)]>;
344 def 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
350 def 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)]>;
354 def 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
359 def 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)]>;
363 def 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
368 let isTwoAddress = 0 in {
369 def 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)]>;
373 def 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
378 def 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)]>;
382 def 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
387 def 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)]>;
391 def 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
399 let isCommutable = 1 in { // X = AND Y, Z  == X = AND Z, Y
400 def 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)]>;
404 def 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
410 def 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)]>;
414 def 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
419 def 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)]>;
423 def 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
428 let isTwoAddress = 0 in {
429 def AND8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
430                 "and.b\t{$src, $dst}",
431                 [(store (and (load addr:$dst), GR8:$src), addr:$dst),
432                  (implicit SRW)]>;
433 def AND16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
434                 "and.w\t{$src, $dst}",
435                 [(store (and (load addr:$dst), GR16:$src), addr:$dst),
436                  (implicit SRW)]>;
437
438 def AND8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
439                 "and.b\t{$src, $dst}",
440                 [(store (and (load addr:$dst), (i8 imm:$src)), addr:$dst),
441                  (implicit SRW)]>;
442 def AND16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
443                 "and.w\t{$src, $dst}",
444                 [(store (and (load addr:$dst), (i16 imm:$src)), addr:$dst),
445                  (implicit SRW)]>;
446
447 def AND8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
448                 "and.b\t{$src, $dst}",
449                 [(store (and (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
450                  (implicit SRW)]>;
451 def AND16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
452                 "and.w\t{$src, $dst}",
453                 [(store (and (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
454                  (implicit SRW)]>;
455 }
456
457
458 let isCommutable = 1 in { // X = XOR Y, Z  == X = XOR Z, Y
459 def XOR8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
460                      "xor.b\t{$src2, $dst}",
461                      [(set GR8:$dst, (xor GR8:$src1, GR8:$src2)),
462                       (implicit SRW)]>;
463 def XOR16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
464                      "xor.w\t{$src2, $dst}",
465                      [(set GR16:$dst, (xor GR16:$src1, GR16:$src2)),
466                       (implicit SRW)]>;
467 }
468
469 def XOR8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
470                      "xor.b\t{$src2, $dst}",
471                      [(set GR8:$dst, (xor GR8:$src1, imm:$src2)),
472                       (implicit SRW)]>;
473 def XOR16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
474                      "xor.w\t{$src2, $dst}",
475                      [(set GR16:$dst, (xor GR16:$src1, imm:$src2)),
476                       (implicit SRW)]>;
477
478 def XOR8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
479                      "xor.b\t{$src2, $dst}",
480                      [(set GR8:$dst, (xor GR8:$src1, (load addr:$src2))),
481                       (implicit SRW)]>;
482 def XOR16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
483                      "xor.w\t{$src2, $dst}",
484                      [(set GR16:$dst, (xor GR16:$src1, (load addr:$src2))),
485                       (implicit SRW)]>;
486
487 let isTwoAddress = 0 in {
488 def XOR8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
489                 "xor.b\t{$src, $dst}",
490                 [(store (xor (load addr:$dst), GR8:$src), addr:$dst),
491                  (implicit SRW)]>;
492 def XOR16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
493                 "xor.w\t{$src, $dst}",
494                 [(store (xor (load addr:$dst), GR16:$src), addr:$dst),
495                  (implicit SRW)]>;
496
497 def XOR8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
498                 "xor.b\t{$src, $dst}",
499                 [(store (xor (load addr:$dst), (i8 imm:$src)), addr:$dst),
500                  (implicit SRW)]>;
501 def XOR16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
502                 "xor.w\t{$src, $dst}",
503                 [(store (xor (load addr:$dst), (i16 imm:$src)), addr:$dst),
504                  (implicit SRW)]>;
505
506 def XOR8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
507                 "xor.b\t{$src, $dst}",
508                 [(store (xor (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
509                  (implicit SRW)]>;
510 def XOR16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
511                 "xor.w\t{$src, $dst}",
512                 [(store (xor (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
513                  (implicit SRW)]>;
514 }
515
516
517 def SUB8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
518                      "sub.b\t{$src2, $dst}",
519                      [(set GR8:$dst, (sub GR8:$src1, GR8:$src2)),
520                       (implicit SRW)]>;
521 def SUB16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
522                      "sub.w\t{$src2, $dst}",
523                      [(set GR16:$dst, (sub GR16:$src1, GR16:$src2)),
524                       (implicit SRW)]>;
525
526 def SUB8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
527                      "sub.b\t{$src2, $dst}",
528                      [(set GR8:$dst, (sub GR8:$src1, imm:$src2)),
529                       (implicit SRW)]>;
530 def SUB16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
531                      "sub.w\t{$src2, $dst}",
532                      [(set GR16:$dst, (sub GR16:$src1, imm:$src2)),
533                       (implicit SRW)]>;
534
535 def SUB8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
536                      "sub.b\t{$src2, $dst}",
537                      [(set GR8:$dst, (sub GR8:$src1, (load addr:$src2))),
538                       (implicit SRW)]>;
539 def SUB16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
540                      "sub.w\t{$src2, $dst}",
541                      [(set GR16:$dst, (sub GR16:$src1, (load addr:$src2))),
542                       (implicit SRW)]>;
543
544 let isTwoAddress = 0 in {
545 def SUB8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
546                 "sub.b\t{$src, $dst}",
547                 [(store (sub (load addr:$dst), GR8:$src), addr:$dst),
548                  (implicit SRW)]>;
549 def SUB16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
550                 "sub.w\t{$src, $dst}",
551                 [(store (sub (load addr:$dst), GR16:$src), addr:$dst),
552                  (implicit SRW)]>;
553
554 def SUB8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
555                 "sub.b\t{$src, $dst}",
556                 [(store (sub (load addr:$dst), (i8 imm:$src)), addr:$dst),
557                  (implicit SRW)]>;
558 def SUB16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
559                 "sub.w\t{$src, $dst}",
560                 [(store (sub (load addr:$dst), (i16 imm:$src)), addr:$dst),
561                  (implicit SRW)]>;
562
563 def SUB8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
564                 "sub.b\t{$src, $dst}",
565                 [(store (sub (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
566                  (implicit SRW)]>;
567 def SUB16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
568                 "sub.w\t{$src, $dst}",
569                 [(store (sub (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
570                  (implicit SRW)]>;
571 }
572
573 let Uses = [SRW] in {
574 def SBC8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
575                      "subc.b\t{$src2, $dst}",
576                      [(set GR8:$dst, (sube GR8:$src1, GR8:$src2)),
577                       (implicit SRW)]>;
578 def SBC16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
579                      "subc.w\t{$src2, $dst}",
580                      [(set GR16:$dst, (sube GR16:$src1, GR16:$src2)),
581                       (implicit SRW)]>;
582
583 def SBC8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
584                      "subc.b\t{$src2, $dst}",
585                      [(set GR8:$dst, (sube GR8:$src1, imm:$src2)),
586                       (implicit SRW)]>;
587 def SBC16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
588                      "subc.w\t{$src2, $dst}",
589                      [(set GR16:$dst, (sube GR16:$src1, imm:$src2)),
590                       (implicit SRW)]>;
591
592 def SBC8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
593                      "subc.b\t{$src2, $dst}",
594                      [(set GR8:$dst, (sube GR8:$src1, (load addr:$src2))),
595                       (implicit SRW)]>;
596 def SBC16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
597                      "subc.w\t{$src2, $dst}",
598                      [(set GR16:$dst, (sube GR16:$src1, (load addr:$src2))),
599                       (implicit SRW)]>;
600
601 let isTwoAddress = 0 in {
602 def SBC8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
603                 "subc.b\t{$src, $dst}",
604                 [(store (sube (load addr:$dst), GR8:$src), addr:$dst),
605                  (implicit SRW)]>;
606 def SBC16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
607                 "subc.w\t{$src, $dst}",
608                 [(store (sube (load addr:$dst), GR16:$src), addr:$dst),
609                  (implicit SRW)]>;
610
611 def SBC8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
612                 "subc.b\t{$src, $dst}",
613                 [(store (sube (load addr:$dst), (i8 imm:$src)), addr:$dst),
614                  (implicit SRW)]>;
615 def SBC16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
616                 "subc.w\t{$src, $dst}",
617                 [(store (sube (load addr:$dst), (i16 imm:$src)), addr:$dst),
618                  (implicit SRW)]>;
619
620 def SBC8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
621                 "subc.b\t{$src, $dst}",
622                 [(store (sube (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
623                  (implicit SRW)]>;
624 def SBC16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
625                 "subc.w\t{$src, $dst}",
626                 [(store (sube (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
627                  (implicit SRW)]>;
628 }
629
630 } // Uses = [SRW]
631
632 // FIXME: Provide proper encoding!
633 def SAR8r1  : Pseudo<(outs GR8:$dst), (ins GR8:$src),
634                      "rra.b\t$dst",
635                      [(set GR8:$dst, (MSP430rra GR8:$src)),
636                       (implicit SRW)]>;
637 def SAR16r1 : Pseudo<(outs GR16:$dst), (ins GR16:$src),
638                      "rra.w\t$dst",
639                      [(set GR16:$dst, (MSP430rra GR16:$src)),
640                       (implicit SRW)]>;
641
642 def SHL8r1  : Pseudo<(outs GR8:$dst), (ins GR8:$src),
643                      "rla.b\t$dst",
644                      [(set GR8:$dst, (MSP430rla GR8:$src)),
645                       (implicit SRW)]>;
646 def SHL16r1 : Pseudo<(outs GR16:$dst), (ins GR16:$src),
647                      "rla.w\t$dst",
648                      [(set GR16:$dst, (MSP430rla GR16:$src)),
649                       (implicit SRW)]>;
650
651 def SAR8r1c  : Pseudo<(outs GR8:$dst), (ins GR8:$src),
652                       "clrc\n\t"
653                       "rrc.b\t$dst",
654                       [(set GR8:$dst, (MSP430rrc GR8:$src)),
655                        (implicit SRW)]>;
656 def SAR16r1c : Pseudo<(outs GR16:$dst), (ins GR16:$src),
657                       "clrc\n\t"
658                       "rrc.w\t$dst",
659                       [(set GR16:$dst, (MSP430rrc GR16:$src)),
660                        (implicit SRW)]>;
661
662 def SEXT16r : Pseudo<(outs GR16:$dst), (ins GR16:$src),
663                      "sxt\t$dst",
664                      [(set GR16:$dst, (sext_inreg GR16:$src, i8)),
665                       (implicit SRW)]>;
666
667 } // Defs = [SRW]
668
669 def SWPB16r : Pseudo<(outs GR16:$dst), (ins GR16:$src),
670                      "swpb\t$dst",
671                      [(set GR16:$dst, (bswap GR16:$src))]>;
672
673 let isCommutable = 1 in { // X = OR Y, Z  == X = OR Z, Y
674 def OR8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
675                     "bis.b\t{$src2, $dst}",
676                     [(set GR8:$dst, (or GR8:$src1, GR8:$src2))]>;
677 def OR16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
678                     "bis.w\t{$src2, $dst}",
679                     [(set GR16:$dst, (or GR16:$src1, GR16:$src2))]>;
680 }
681
682 def OR8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
683                     "bis.b\t{$src2, $dst}",
684                     [(set GR8:$dst, (or GR8:$src1, imm:$src2))]>;
685 def OR16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
686                     "bis.w\t{$src2, $dst}",
687                     [(set GR16:$dst, (or GR16:$src1, imm:$src2))]>;
688
689 def OR8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
690                     "bis.b\t{$src2, $dst}",
691                     [(set GR8:$dst, (or GR8:$src1, (load addr:$src2)))]>;
692 def OR16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
693                     "bis.w\t{$src2, $dst}",
694                     [(set GR16:$dst, (or GR16:$src1, (load addr:$src2)))]>;
695
696 let isTwoAddress = 0 in {
697 def OR8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
698                 "bis.b\t{$src, $dst}",
699                 [(store (or (load addr:$dst), GR8:$src), addr:$dst)]>;
700 def OR16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
701                 "bis.w\t{$src, $dst}",
702                 [(store (or (load addr:$dst), GR16:$src), addr:$dst)]>;
703
704 def OR8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
705                 "bis.b\t{$src, $dst}",
706                 [(store (or (load addr:$dst), (i8 imm:$src)), addr:$dst)]>;
707 def OR16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
708                 "bis.w\t{$src, $dst}",
709                 [(store (or (load addr:$dst), (i16 imm:$src)), addr:$dst)]>;
710
711 def OR8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
712                 "bis.b\t{$src, $dst}",
713                 [(store (or (i8 (load addr:$dst)),
714                             (i8 (load addr:$src))), addr:$dst)]>;
715 def OR16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
716                 "bis.w\t{$src, $dst}",
717                  [(store (or (i16 (load addr:$dst)),
718                              (i16 (load addr:$src))), addr:$dst)]>;
719 }
720
721 } // isTwoAddress = 1
722
723 // Integer comparisons
724 let Defs = [SRW] in {
725 def CMP8rr  : Pseudo<(outs), (ins GR8:$src1, GR8:$src2),
726                      "cmp.b\t{$src1, $src2}",
727                      [(MSP430cmp GR8:$src1, GR8:$src2), (implicit SRW)]>;
728 def CMP16rr : Pseudo<(outs), (ins GR16:$src1, GR16:$src2),
729                      "cmp.w\t{$src1, $src2}",
730                      [(MSP430cmp GR16:$src1, GR16:$src2), (implicit SRW)]>;
731
732 def CMP8ir  : Pseudo<(outs), (ins i8imm:$src1, GR8:$src2),
733                    "cmp.b\t{$src1, $src2}",
734                    [(MSP430cmp imm:$src1, GR8:$src2), (implicit SRW)]>;
735 def CMP16ir : Pseudo<(outs), (ins i16imm:$src1, GR16:$src2),
736                      "cmp.w\t{$src1, $src2}",
737                      [(MSP430cmp imm:$src1, GR16:$src2), (implicit SRW)]>;
738
739 def CMP8im  : Pseudo<(outs), (ins i8imm:$src1, memsrc:$src2),
740                      "cmp.b\t{$src1, $src2}",
741                       [(MSP430cmp (i8 imm:$src1), (load addr:$src2)), (implicit SRW)]>;
742 def CMP16im : Pseudo<(outs), (ins i16imm:$src1, memsrc:$src2),
743                      "cmp.w\t{$src1, $src2}",
744                       [(MSP430cmp (i16 imm:$src1), (load addr:$src2)), (implicit SRW)]>;
745
746 def CMP8rm  : Pseudo<(outs), (ins GR8:$src1, memsrc:$src2),
747                      "cmp.b\t{$src1, $src2}",
748                      [(MSP430cmp GR8:$src1, (load addr:$src2)), (implicit SRW)]>;
749 def CMP16rm : Pseudo<(outs), (ins GR16:$src1, memsrc:$src2),
750                      "cmp.w\t{$src1, $src2}",
751                      [(MSP430cmp GR16:$src1, (load addr:$src2)), (implicit SRW)]>;
752
753 def CMP8mr  : Pseudo<(outs), (ins memsrc:$src1, GR8:$src2),
754                 "cmp.b\t{$src1, $src2}",
755                 [(MSP430cmp (load addr:$src1), GR8:$src2), (implicit SRW)]>;
756 def CMP16mr : Pseudo<(outs), (ins memsrc:$src1, GR16:$src2),
757                 "cmp.w\t{$src1, $src2}",
758                 [(MSP430cmp (load addr:$src1), GR16:$src2), (implicit SRW)]>;
759
760 def CMP8mi0 : Pseudo<(outs), (ins memsrc:$src1),
761                 "cmp.b\t{$src1, #0}",
762                 [(MSP430cmp (load addr:$src1), (i8 0)), (implicit SRW)]>;
763 def CMP16mi0: Pseudo<(outs), (ins memsrc:$src1),
764                 "cmp.w\t{$src1, #0}",
765                 [(MSP430cmp (load addr:$src1), (i16 0)), (implicit SRW)]>;
766 def CMP8mi1 : Pseudo<(outs), (ins memsrc:$src1),
767                 "cmp.b\t{$src1, #1}",
768                 [(MSP430cmp (load addr:$src1), (i8 1)), (implicit SRW)]>;
769 def CMP16mi1: Pseudo<(outs), (ins memsrc:$src1),
770                 "cmp.w\t{$src1, #1}",
771                 [(MSP430cmp (load addr:$src1), (i16 1)), (implicit SRW)]>;
772 def CMP8mi2 : Pseudo<(outs), (ins memsrc:$src1),
773                 "cmp.b\t{$src1, #2}",
774                 [(MSP430cmp (load addr:$src1), (i8 2)), (implicit SRW)]>;
775 def CMP16mi2: Pseudo<(outs), (ins memsrc:$src1),
776                 "cmp.w\t{$src1, #2}",
777                 [(MSP430cmp (load addr:$src1), (i16 2)), (implicit SRW)]>;
778 def CMP8mi4 : Pseudo<(outs), (ins memsrc:$src1),
779                 "cmp.b\t{$src1, #4}",
780                 [(MSP430cmp (load addr:$src1), (i8 4)), (implicit SRW)]>;
781 def CMP16mi4: Pseudo<(outs), (ins memsrc:$src1),
782                 "cmp.w\t{$src1, #4}",
783                 [(MSP430cmp (load addr:$src1), (i16 4)), (implicit SRW)]>;
784 def CMP8mi8 : Pseudo<(outs), (ins memsrc:$src1),
785                 "cmp.b\t{$src1, #8}",
786                 [(MSP430cmp (load addr:$src1), (i8 8)), (implicit SRW)]>;
787 def CMP16mi8: Pseudo<(outs), (ins memsrc:$src1),
788                 "cmp.w\t{$src1, #8}",
789                 [(MSP430cmp (load addr:$src1), (i16 8)), (implicit SRW)]>;
790
791 } // Defs = [SRW]
792
793 //===----------------------------------------------------------------------===//
794 // Non-Instruction Patterns
795
796 // extload
797 def : Pat<(extloadi16i8 addr:$src), (MOVZX16rm8 addr:$src)>;
798
799 // anyext
800 def : Pat<(anyext addr:$src), (MOVZX16rr8 GR8:$src)>;
801
802 // truncs
803 def : Pat<(i8 (trunc GR16:$src)),
804           (EXTRACT_SUBREG GR16:$src, subreg_8bit)>;
805
806 // GlobalAddress, ExternalSymbol
807 def : Pat<(i16 (MSP430Wrapper tglobaladdr:$dst)), (MOV16ri tglobaladdr:$dst)>;
808 def : Pat<(i16 (MSP430Wrapper texternalsym:$dst)), (MOV16ri texternalsym:$dst)>;
809
810 def : Pat<(add GR16:$src1, (MSP430Wrapper tglobaladdr :$src2)),
811           (ADD16ri GR16:$src1, tglobaladdr:$src2)>;
812 def : Pat<(add GR16:$src1, (MSP430Wrapper texternalsym:$src2)),
813           (ADD16ri GR16:$src1, texternalsym:$src2)>;
814
815 def : Pat<(store (i16 (MSP430Wrapper tglobaladdr:$src)), addr:$dst),
816           (MOV16mi addr:$dst, tglobaladdr:$src)>;
817 def : Pat<(store (i16 (MSP430Wrapper texternalsym:$src)), addr:$dst),
818           (MOV16mi addr:$dst, texternalsym:$src)>;
819
820 // calls
821 def : Pat<(MSP430call (i16 tglobaladdr:$dst)),
822           (CALLi tglobaladdr:$dst)>;
823 def : Pat<(MSP430call (i16 texternalsym:$dst)),
824           (CALLi texternalsym:$dst)>;
825
826 // add and sub always produce carry
827 def : Pat<(addc GR16:$src1, GR16:$src2),
828           (ADD16rr GR16:$src1, GR16:$src2)>;
829 def : Pat<(addc GR16:$src1, (load addr:$src2)),
830           (ADD16rm GR16:$src1, addr:$src2)>;
831 def : Pat<(addc GR16:$src1, imm:$src2),
832           (ADD16ri GR16:$src1, imm:$src2)>;
833 def : Pat<(store (addc (load addr:$dst), GR16:$src), addr:$dst),
834           (ADD16mr addr:$dst, GR16:$src)>;
835 def : Pat<(store (addc (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
836           (ADD16mm addr:$dst, addr:$src)>;
837
838 def : Pat<(addc GR8:$src1, GR8:$src2),
839           (ADD8rr GR8:$src1, GR8:$src2)>;
840 def : Pat<(addc GR8:$src1, (load addr:$src2)),
841           (ADD8rm GR8:$src1, addr:$src2)>;
842 def : Pat<(addc GR8:$src1, imm:$src2),
843           (ADD8ri GR8:$src1, imm:$src2)>;
844 def : Pat<(store (addc (load addr:$dst), GR8:$src), addr:$dst),
845           (ADD8mr addr:$dst, GR8:$src)>;
846 def : Pat<(store (addc (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
847           (ADD8mm addr:$dst, addr:$src)>;
848
849 def : Pat<(subc GR16:$src1, GR16:$src2),
850           (SUB16rr GR16:$src1, GR16:$src2)>;
851 def : Pat<(subc GR16:$src1, (load addr:$src2)),
852           (SUB16rm GR16:$src1, addr:$src2)>;
853 def : Pat<(subc GR16:$src1, imm:$src2),
854           (SUB16ri GR16:$src1, imm:$src2)>;
855 def : Pat<(store (subc (load addr:$dst), GR16:$src), addr:$dst),
856           (SUB16mr addr:$dst, GR16:$src)>;
857 def : Pat<(store (subc (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
858           (SUB16mm addr:$dst, addr:$src)>;
859
860 def : Pat<(subc GR8:$src1, GR8:$src2),
861           (SUB8rr GR8:$src1, GR8:$src2)>;
862 def : Pat<(subc GR8:$src1, (load addr:$src2)),
863           (SUB8rm GR8:$src1, addr:$src2)>;
864 def : Pat<(subc GR8:$src1, imm:$src2),
865           (SUB8ri GR8:$src1, imm:$src2)>;
866 def : Pat<(store (subc (load addr:$dst), GR8:$src), addr:$dst),
867           (SUB8mr addr:$dst, GR8:$src)>;
868 def : Pat<(store (subc (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
869           (SUB8mm addr:$dst, addr:$src)>;