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