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