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