Add bunch of mem-whatever patterns
[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
26 //===----------------------------------------------------------------------===//
27 // MSP430 Specific Node Definitions.
28 //===----------------------------------------------------------------------===//
29 def MSP430retflag : SDNode<"MSP430ISD::RET_FLAG", SDTNone,
30                      [SDNPHasChain, SDNPOptInFlag]>;
31
32 def MSP430rra     : SDNode<"MSP430ISD::RRA", SDTIntUnaryOp, []>;
33
34 //===----------------------------------------------------------------------===//
35 // MSP430 Operand Definitions.
36 //===----------------------------------------------------------------------===//
37
38 // Address operands
39 def memsrc : Operand<i16> {
40   let PrintMethod = "printSrcMemOperand";
41   let MIOperandInfo = (ops i16imm, GR16);
42 }
43
44 def memdst : Operand<i16> {
45   let PrintMethod = "printSrcMemOperand";
46   let MIOperandInfo = (ops i16imm, GR16);
47 }
48
49
50 //===----------------------------------------------------------------------===//
51 // MSP430 Complex Pattern Definitions.
52 //===----------------------------------------------------------------------===//
53
54 def addr : ComplexPattern<iPTR, 2, "SelectAddr", [], []>;
55
56 //===----------------------------------------------------------------------===//
57 // Pattern Fragments
58 def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>;
59 def  extloadi16i8 : PatFrag<(ops node:$ptr), (i16 ( extloadi8 node:$ptr))>;
60
61 //===----------------------------------------------------------------------===//
62 // Pseudo Instructions
63
64 let neverHasSideEffects = 1 in
65 def NOP : Pseudo<(outs), (ins), "nop", []>;
66
67 //===----------------------------------------------------------------------===//
68 // Real Instructions
69
70 // FIXME: Provide proper encoding!
71 let isReturn = 1, isTerminator = 1 in {
72   def RETI : Pseudo<(outs), (ins), "ret", [(MSP430retflag)]>;
73 }
74
75 //===----------------------------------------------------------------------===//
76 // Move Instructions
77
78 // FIXME: Provide proper encoding!
79 let neverHasSideEffects = 1 in {
80 def MOV8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src),
81                      "mov.b\t{$src, $dst|$dst, $src}",
82                      []>;
83 def MOV16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src),
84                      "mov.w\t{$src, $dst|$dst, $src}",
85                      []>;
86 }
87
88 // FIXME: Provide proper encoding!
89 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
90 def MOV8ri  : Pseudo<(outs GR8:$dst), (ins i8imm:$src),
91                      "mov.b\t{$src, $dst|$dst, $src}",
92                      [(set GR8:$dst, imm:$src)]>;
93 def MOV16ri : Pseudo<(outs GR16:$dst), (ins i16imm:$src),
94                      "mov.w\t{$src, $dst|$dst, $src}",
95                      [(set GR16:$dst, imm:$src)]>;
96 }
97
98 let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in {
99 def MOV8rm  : Pseudo<(outs GR8:$dst), (ins memsrc:$src),
100                 "mov.b\t{$src, $dst|$dst, $src}",
101                 [(set GR8:$dst, (load addr:$src))]>;
102 def MOV16rm : Pseudo<(outs GR16:$dst), (ins memsrc:$src),
103                 "mov.w\t{$src, $dst|$dst, $src}",
104                 [(set GR16:$dst, (load addr:$src))]>;
105 }
106
107 def MOVZX16rr8 : Pseudo<(outs GR16:$dst), (ins GR8:$src),
108                 "mov.b\t{$src, $dst|$dst, $src}",
109                 [(set GR16:$dst, (zext GR8:$src))]>;
110 def MOVZX16rm8 : Pseudo<(outs GR16:$dst), (ins memsrc:$src),
111                 "mov.b\t{$src, $dst|$dst, $src}",
112                 [(set GR16:$dst, (zextloadi16i8 addr:$src))]>;
113
114 def MOV8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
115                 "mov.b\t{$src, $dst|$dst, $src}",
116                 [(store (i8 imm:$src), addr:$dst)]>;
117 def MOV16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
118                 "mov.w\t{$src, $dst|$dst, $src}",
119                 [(store (i16 imm:$src), addr:$dst)]>;
120
121 def MOV8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
122                 "mov.b\t{$src, $dst|$dst, $src}",
123                 [(store GR8:$src, addr:$dst)]>;
124 def MOV16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
125                 "mov.w\t{$src, $dst|$dst, $src}",
126                 [(store GR16:$src, addr:$dst)]>;
127
128 //===----------------------------------------------------------------------===//
129 // Arithmetic Instructions
130
131 let isTwoAddress = 1 in {
132
133 let Defs = [SRW] in {
134
135 let isCommutable = 1 in { // X = ADD Y, Z  == X = ADD Z, Y
136 // FIXME: Provide proper encoding!
137 def ADD8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
138                      "add.b\t{$src2, $dst|$dst, $src2}",
139                      [(set GR8:$dst, (add GR8:$src1, GR8:$src2)),
140                       (implicit SRW)]>;
141 def ADD16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
142                      "add.w\t{$src2, $dst|$dst, $src2}",
143                      [(set GR16:$dst, (add GR16:$src1, GR16:$src2)),
144                       (implicit SRW)]>;
145 }
146
147 def ADD8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
148                      "add.b\t{$src2, $dst|$dst, $src2}",
149                      [(set GR8:$dst, (add GR8:$src1, (load addr:$src2))),
150                       (implicit SRW)]>;
151 def ADD16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
152                      "add.w\t{$src2, $dst|$dst, $src2}",
153                      [(set GR16:$dst, (add GR16:$src1, (load addr:$src2))),
154                       (implicit SRW)]>;
155
156 def ADD8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
157                      "add.b\t{$src2, $dst|$dst, $src2}",
158                      [(set GR8:$dst, (add GR8:$src1, imm:$src2)),
159                       (implicit SRW)]>;
160 def ADD16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
161                      "add.w\t{$src2, $dst|$dst, $src2}",
162                      [(set GR16:$dst, (add GR16:$src1, imm:$src2)),
163                       (implicit SRW)]>;
164
165 let isTwoAddress = 0 in {
166 def ADD8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
167                 "add.b\t{$src, $dst|$dst, $src}",
168                 [(store (add (load addr:$dst), GR8:$src), addr:$dst),
169                  (implicit SRW)]>;
170 def ADD16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
171                 "add.w\t{$src, $dst|$dst, $src}",
172                 [(store (add (load addr:$dst), GR16:$src), addr:$dst),
173                  (implicit SRW)]>;
174
175 def ADD8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
176                 "add.b\t{$src, $dst|$dst, $src}",
177                 [(store (add (load addr:$dst), (i8 imm:$src)), addr:$dst),
178                  (implicit SRW)]>;
179 def ADD16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
180                 "add.w\t{$src, $dst|$dst, $src}",
181                 [(store (add (load addr:$dst), (i16 imm:$src)), addr:$dst),
182                  (implicit SRW)]>;
183
184 def ADD8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
185                 "add.b\t{$src, $dst|$dst, $src}",
186                 [(store (add (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
187                  (implicit SRW)]>;
188 def ADD16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
189                 "add.w\t{$src, $dst|$dst, $src}",
190                 [(store (add (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
191                  (implicit SRW)]>;
192 }
193
194 let Uses = [SRW] in {
195
196 let isCommutable = 1 in { // X = ADDC Y, Z  == X = ADDC Z, Y
197 def ADC8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
198                      "addc.b\t{$src2, $dst|$dst, $src2}",
199                      [(set GR8:$dst, (adde GR8:$src1, GR8:$src2)),
200                       (implicit SRW)]>;
201 def ADC16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
202                      "addc.w\t{$src2, $dst|$dst, $src2}",
203                      [(set GR16:$dst, (adde GR16:$src1, GR16:$src2)),
204                       (implicit SRW)]>;
205 } // isCommutable
206
207 def ADC8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
208                      "addc.b\t{$src2, $dst|$dst, $src2}",
209                      [(set GR8:$dst, (adde GR8:$src1, imm:$src2)),
210                       (implicit SRW)]>;
211 def ADC16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
212                      "addc.w\t{$src2, $dst|$dst, $src2}",
213                      [(set GR16:$dst, (adde GR16:$src1, imm:$src2)),
214                       (implicit SRW)]>;
215
216 def ADC8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
217                      "addc.b\t{$src2, $dst|$dst, $src2}",
218                      [(set GR8:$dst, (adde GR8:$src1, (load addr:$src2))),
219                       (implicit SRW)]>;
220 def ADC16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
221                      "addc.w\t{$src2, $dst|$dst, $src2}",
222                      [(set GR16:$dst, (adde GR16:$src1, (load addr:$src2))),
223                       (implicit SRW)]>;
224
225 let isTwoAddress = 0 in {
226 def ADC8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
227                 "addc.b\t{$src, $dst|$dst, $src}",
228                 [(store (adde (load addr:$dst), GR8:$src), addr:$dst),
229                  (implicit SRW)]>;
230 def ADC16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
231                 "addc.w\t{$src, $dst|$dst, $src}",
232                 [(store (adde (load addr:$dst), GR16:$src), addr:$dst),
233                  (implicit SRW)]>;
234
235 def ADC8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
236                 "addc.b\t{$src, $dst|$dst, $src}",
237                 [(store (adde (load addr:$dst), (i8 imm:$src)), addr:$dst),
238                  (implicit SRW)]>;
239 def ADC16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
240                 "addc.w\t{$src, $dst|$dst, $src}",
241                 [(store (adde (load addr:$dst), (i16 imm:$src)), addr:$dst),
242                  (implicit SRW)]>;
243
244 def ADC8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
245                 "addc.b\t{$src, $dst|$dst, $src}",
246                 [(store (adde (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
247                  (implicit SRW)]>;
248 def ADC16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
249                 "addc.w\t{$src, $dst|$dst, $src}",
250                 [(store (adde (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
251                  (implicit SRW)]>;
252 }
253
254 } // Uses = [SRW]
255
256 let isCommutable = 1 in { // X = AND Y, Z  == X = AND Z, Y
257 def AND8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
258                      "and.b\t{$src2, $dst|$dst, $src2}",
259                      [(set GR8:$dst, (and GR8:$src1, GR8:$src2)),
260                       (implicit SRW)]>;
261 def AND16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
262                      "and.w\t{$src2, $dst|$dst, $src2}",
263                      [(set GR16:$dst, (and GR16:$src1, GR16:$src2)),
264                       (implicit SRW)]>;
265 }
266
267 def AND8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
268                      "and.b\t{$src2, $dst|$dst, $src2}",
269                      [(set GR8:$dst, (and GR8:$src1, imm:$src2)),
270                       (implicit SRW)]>;
271 def AND16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
272                      "and.w\t{$src2, $dst|$dst, $src2}",
273                      [(set GR16:$dst, (and GR16:$src1, imm:$src2)),
274                       (implicit SRW)]>;
275
276 def AND8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
277                      "and.b\t{$src2, $dst|$dst, $src2}",
278                      [(set GR8:$dst, (and GR8:$src1, (load addr:$src2))),
279                       (implicit SRW)]>;
280 def AND16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
281                      "and.w\t{$src2, $dst|$dst, $src2}",
282                      [(set GR16:$dst, (and GR16:$src1, (load addr:$src2))),
283                       (implicit SRW)]>;
284
285 let isTwoAddress = 0 in {
286 def AND8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
287                 "and.b\t{$src, $dst|$dst, $src}",
288                 [(store (and (load addr:$dst), GR8:$src), addr:$dst),
289                  (implicit SRW)]>;
290 def AND16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
291                 "and.w\t{$src, $dst|$dst, $src}",
292                 [(store (and (load addr:$dst), GR16:$src), addr:$dst),
293                  (implicit SRW)]>;
294
295 def AND8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
296                 "and.b\t{$src, $dst|$dst, $src}",
297                 [(store (and (load addr:$dst), (i8 imm:$src)), addr:$dst),
298                  (implicit SRW)]>;
299 def AND16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
300                 "and.w\t{$src, $dst|$dst, $src}",
301                 [(store (and (load addr:$dst), (i16 imm:$src)), addr:$dst),
302                  (implicit SRW)]>;
303
304 def AND8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
305                 "and.b\t{$src, $dst|$dst, $src}",
306                 [(store (and (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
307                  (implicit SRW)]>;
308 def AND16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
309                 "and.w\t{$src, $dst|$dst, $src}",
310                 [(store (and (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
311                  (implicit SRW)]>;
312 }
313
314
315 let isCommutable = 1 in { // X = XOR Y, Z  == X = XOR Z, Y
316 def XOR8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
317                      "xor.b\t{$src2, $dst|$dst, $src2}",
318                      [(set GR8:$dst, (xor GR8:$src1, GR8:$src2)),
319                       (implicit SRW)]>;
320 def XOR16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
321                      "xor.w\t{$src2, $dst|$dst, $src2}",
322                      [(set GR16:$dst, (xor GR16:$src1, GR16:$src2)),
323                       (implicit SRW)]>;
324 }
325
326 def XOR8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
327                      "xor.b\t{$src2, $dst|$dst, $src2}",
328                      [(set GR8:$dst, (xor GR8:$src1, imm:$src2)),
329                       (implicit SRW)]>;
330 def XOR16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
331                      "xor.w\t{$src2, $dst|$dst, $src2}",
332                      [(set GR16:$dst, (xor GR16:$src1, imm:$src2)),
333                       (implicit SRW)]>;
334
335 def XOR8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
336                      "xor.b\t{$src2, $dst|$dst, $src2}",
337                      [(set GR8:$dst, (xor GR8:$src1, (load addr:$src2))),
338                       (implicit SRW)]>;
339 def XOR16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
340                      "xor.w\t{$src2, $dst|$dst, $src2}",
341                      [(set GR16:$dst, (xor GR16:$src1, (load addr:$src2))),
342                       (implicit SRW)]>;
343
344 let isTwoAddress = 0 in {
345 def XOR8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
346                 "xor.b\t{$src, $dst|$dst, $src}",
347                 [(store (xor (load addr:$dst), GR8:$src), addr:$dst),
348                  (implicit SRW)]>;
349 def XOR16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
350                 "xor.w\t{$src, $dst|$dst, $src}",
351                 [(store (xor (load addr:$dst), GR16:$src), addr:$dst),
352                  (implicit SRW)]>;
353
354 def XOR8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
355                 "xor.b\t{$src, $dst|$dst, $src}",
356                 [(store (xor (load addr:$dst), (i8 imm:$src)), addr:$dst),
357                  (implicit SRW)]>;
358 def XOR16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
359                 "xor.w\t{$src, $dst|$dst, $src}",
360                 [(store (xor (load addr:$dst), (i16 imm:$src)), addr:$dst),
361                  (implicit SRW)]>;
362
363 def XOR8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
364                 "xor.b\t{$src, $dst|$dst, $src}",
365                 [(store (xor (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
366                  (implicit SRW)]>;
367 def XOR16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
368                 "xor.w\t{$src, $dst|$dst, $src}",
369                 [(store (xor (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
370                  (implicit SRW)]>;
371 }
372
373
374 def SUB8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
375                      "sub.b\t{$src2, $dst|$dst, $src2}",
376                      [(set GR8:$dst, (sub GR8:$src1, GR8:$src2)),
377                       (implicit SRW)]>;
378 def SUB16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
379                      "sub.w\t{$src2, $dst|$dst, $src2}",
380                      [(set GR16:$dst, (sub GR16:$src1, GR16:$src2)),
381                       (implicit SRW)]>;
382
383 def SUB8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
384                      "sub.b\t{$src2, $dst|$dst, $src2}",
385                      [(set GR8:$dst, (sub GR8:$src1, imm:$src2)),
386                       (implicit SRW)]>;
387 def SUB16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
388                      "sub.w\t{$src2, $dst|$dst, $src2}",
389                      [(set GR16:$dst, (sub GR16:$src1, imm:$src2)),
390                       (implicit SRW)]>;
391
392 def SUB8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
393                      "sub.b\t{$src2, $dst|$dst, $src2}",
394                      [(set GR8:$dst, (sub GR8:$src1, (load addr:$src2))),
395                       (implicit SRW)]>;
396 def SUB16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
397                      "sub.w\t{$src2, $dst|$dst, $src2}",
398                      [(set GR16:$dst, (sub GR16:$src1, (load addr:$src2))),
399                       (implicit SRW)]>;
400
401 let isTwoAddress = 0 in {
402 def SUB8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
403                 "sub.b\t{$src, $dst|$dst, $src}",
404                 [(store (sub (load addr:$dst), GR8:$src), addr:$dst),
405                  (implicit SRW)]>;
406 def SUB16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
407                 "sub.w\t{$src, $dst|$dst, $src}",
408                 [(store (sub (load addr:$dst), GR16:$src), addr:$dst),
409                  (implicit SRW)]>;
410
411 def SUB8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
412                 "sub.b\t{$src, $dst|$dst, $src}",
413                 [(store (sub (load addr:$dst), (i8 imm:$src)), addr:$dst),
414                  (implicit SRW)]>;
415 def SUB16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
416                 "sub.w\t{$src, $dst|$dst, $src}",
417                 [(store (sub (load addr:$dst), (i16 imm:$src)), addr:$dst),
418                  (implicit SRW)]>;
419
420 def SUB8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
421                 "sub.b\t{$src, $dst|$dst, $src}",
422                 [(store (sub (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
423                  (implicit SRW)]>;
424 def SUB16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
425                 "sub.w\t{$src, $dst|$dst, $src}",
426                 [(store (sub (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
427                  (implicit SRW)]>;
428 }
429
430 let Uses = [SRW] in {
431 def SBC8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
432                      "subc.b\t{$src2, $dst|$dst, $src2}",
433                      [(set GR8:$dst, (sube GR8:$src1, GR8:$src2)),
434                       (implicit SRW)]>;
435 def SBC16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
436                      "subc.w\t{$src2, $dst|$dst, $src2}",
437                      [(set GR16:$dst, (sube GR16:$src1, GR16:$src2)),
438                       (implicit SRW)]>;
439
440 def SBC8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
441                      "subc.b\t{$src2, $dst|$dst, $src2}",
442                      [(set GR8:$dst, (sube GR8:$src1, imm:$src2)),
443                       (implicit SRW)]>;
444 def SBC16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
445                      "subc.w\t{$src2, $dst|$dst, $src2}",
446                      [(set GR16:$dst, (sube GR16:$src1, imm:$src2)),
447                       (implicit SRW)]>;
448
449 def SBC8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
450                      "subc.b\t{$src2, $dst|$dst, $src2}",
451                      [(set GR8:$dst, (sube GR8:$src1, (load addr:$src2))),
452                       (implicit SRW)]>;
453 def SBC16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
454                      "subc.w\t{$src2, $dst|$dst, $src2}",
455                      [(set GR16:$dst, (sube GR16:$src1, (load addr:$src2))),
456                       (implicit SRW)]>;
457
458 let isTwoAddress = 0 in {
459 def SBC8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
460                 "subc.b\t{$src, $dst|$dst, $src}",
461                 [(store (sube (load addr:$dst), GR8:$src), addr:$dst),
462                  (implicit SRW)]>;
463 def SBC16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
464                 "subc.w\t{$src, $dst|$dst, $src}",
465                 [(store (sube (load addr:$dst), GR16:$src), addr:$dst),
466                  (implicit SRW)]>;
467
468 def SBC8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
469                 "subc.b\t{$src, $dst|$dst, $src}",
470                 [(store (sube (load addr:$dst), (i8 imm:$src)), addr:$dst),
471                  (implicit SRW)]>;
472 def SBC16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
473                 "subc.w\t{$src, $dst|$dst, $src}",
474                 [(store (sube (load addr:$dst), (i16 imm:$src)), addr:$dst),
475                  (implicit SRW)]>;
476
477 def SBC8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
478                 "subc.b\t{$src, $dst|$dst, $src}",
479                 [(store (sube (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
480                  (implicit SRW)]>;
481 def SBC16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
482                 "subc.w\t{$src, $dst|$dst, $src}",
483                 [(store (sube (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
484                  (implicit SRW)]>;
485 }
486
487 } // Uses = [SRW]
488
489 // FIXME: Provide proper encoding!
490 def SAR16r1 : Pseudo<(outs GR16:$dst), (ins GR16:$src),
491                      "rra.w\t$dst",
492                      [(set GR16:$dst, (MSP430rra GR16:$src)),
493                       (implicit SRW)]>;
494
495 def SEXT16r : Pseudo<(outs GR16:$dst), (ins GR16:$src),
496                      "sxt\t$dst",
497                      [(set GR16:$dst, (sext_inreg GR16:$src, i8)),
498                       (implicit SRW)]>;
499
500 //def SEXT16r : Pseudo<(outs GR16:$dst), (ins GR16:$src),
501 //                     "sxt\t$dst",
502 //                     [(set GR16:$dst, (sext_inreg GR16:$src, i8)),
503 //                      (implicit SRW)]>;
504
505 } // Defs = [SRW]
506
507 let isCommutable = 1 in { // X = OR Y, Z  == X = OR Z, Y
508 def OR8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
509                     "bis.b\t{$src2, $dst|$dst, $src2}",
510                     [(set GR8:$dst, (or GR8:$src1, GR8:$src2))]>;
511 def OR16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
512                     "bis.w\t{$src2, $dst|$dst, $src2}",
513                     [(set GR16:$dst, (or GR16:$src1, GR16:$src2))]>;
514 }
515
516 def OR8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
517                     "bis.b\t{$src2, $dst|$dst, $src2}",
518                     [(set GR8:$dst, (or GR8:$src1, imm:$src2))]>;
519 def OR16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
520                     "bis.w\t{$src2, $dst|$dst, $src2}",
521                     [(set GR16:$dst, (or GR16:$src1, imm:$src2))]>;
522
523 def OR8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
524                     "bis.b\t{$src2, $dst|$dst, $src2}",
525                     [(set GR8:$dst, (or GR8:$src1, (load addr:$src2)))]>;
526 def OR16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
527                     "bis.w\t{$src2, $dst|$dst, $src2}",
528                     [(set GR16:$dst, (or GR16:$src1, (load addr:$src2)))]>;
529
530 let isTwoAddress = 0 in {
531 def OR8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
532                 "bis.b\t{$src, $dst|$dst, $src}",
533                 [(store (or (load addr:$dst), GR8:$src), addr:$dst),
534                  (implicit SRW)]>;
535 def OR16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
536                 "bis.w\t{$src, $dst|$dst, $src}",
537                 [(store (or (load addr:$dst), GR16:$src), addr:$dst),
538                  (implicit SRW)]>;
539
540 def OR8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
541                 "bis.b\t{$src, $dst|$dst, $src}",
542                 [(store (or (load addr:$dst), (i8 imm:$src)), addr:$dst),
543                  (implicit SRW)]>;
544 def OR16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
545                 "bis.w\t{$src, $dst|$dst, $src}",
546                 [(store (or (load addr:$dst), (i16 imm:$src)), addr:$dst),
547                  (implicit SRW)]>;
548
549 def OR8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
550                 "bis.b\t{$src, $dst|$dst, $src}",
551                 [(store (or (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
552                  (implicit SRW)]>;
553 def OR16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
554                 "bis.w\t{$src, $dst|$dst, $src}",
555                 [(store (or (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
556                  (implicit SRW)]>;
557 }
558
559 } // isTwoAddress = 1
560
561 //===----------------------------------------------------------------------===//
562 // Non-Instruction Patterns
563
564 // extload
565 def : Pat<(extloadi16i8 addr:$src), (MOVZX16rm8 addr:$src)>;
566
567 // truncs
568 def : Pat<(i8 (trunc GR16:$src)),
569           (EXTRACT_SUBREG GR16:$src, subreg_8bit)>;