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