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