MSP430InstrInfo.td revision e699d0f549151a2cca993c21407aea4a6eff7d3f
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>]>;
29def SDT_MSP430SetCC        : SDTypeProfile<1, 2, [SDTCisVT<0, i8>,
30                                                  SDTCisVT<1, i8>, SDTCisVT<2, i16>]>;
31def SDT_MSP430Cmp          : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
32def SDT_MSP430BrCond       : SDTypeProfile<0, 3, [SDTCisVT<0, OtherVT>,
33                                                  SDTCisVT<1, i8>, SDTCisVT<2, i16>]>;
34def SDT_MSP430Select       : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, 
35                                                  SDTCisVT<3, i8>, SDTCisVT<4, i16>]>;
36def SDT_MSP430Clrc         : SDTypeProfile<0, 0, []>;
37
38//===----------------------------------------------------------------------===//
39// MSP430 Specific Node Definitions.
40//===----------------------------------------------------------------------===//
41def MSP430retflag : SDNode<"MSP430ISD::RET_FLAG", SDTNone,
42                     [SDNPHasChain, SDNPOptInFlag]>;
43
44def MSP430rra     : SDNode<"MSP430ISD::RRA", SDTIntUnaryOp, []>;
45def MSP430rla     : SDNode<"MSP430ISD::RLA", SDTIntUnaryOp, []>;
46def MSP430rrc     : SDNode<"MSP430ISD::RRC", SDTIntUnaryOp, [SDNPInFlag]>;
47
48def MSP430call    : SDNode<"MSP430ISD::CALL", SDT_MSP430Call,
49                     [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag]>;
50def MSP430callseq_start :
51                 SDNode<"ISD::CALLSEQ_START", SDT_MSP430CallSeqStart,
52                        [SDNPHasChain, SDNPOutFlag]>;
53def MSP430callseq_end :
54                 SDNode<"ISD::CALLSEQ_END",   SDT_MSP430CallSeqEnd,
55                        [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
56def MSP430Wrapper : SDNode<"MSP430ISD::Wrapper", SDT_MSP430Wrapper>;
57def MSP430setcc   : SDNode<"MSP430ISD::SETCC", SDT_MSP430SetCC>;
58def MSP430cmp     : SDNode<"MSP430ISD::CMP", SDT_MSP430Cmp>;
59def MSP430brcond  : SDNode<"MSP430ISD::BRCOND", SDT_MSP430BrCond, [SDNPHasChain]>;
60def MSP430select  : SDNode<"MSP430ISD::SELECT", SDT_MSP430Select>;
61def MSP430clrc    : SDNode<"MSP430ISD::CLRC", SDT_MSP430Clrc, [SDNPOutFlag]>;
62
63//===----------------------------------------------------------------------===//
64// MSP430 Operand Definitions.
65//===----------------------------------------------------------------------===//
66
67// Address operands
68def memsrc : Operand<i16> {
69  let PrintMethod = "printSrcMemOperand";
70  let MIOperandInfo = (ops GR16, i16imm);
71}
72
73def memdst : Operand<i16> {
74  let PrintMethod = "printSrcMemOperand";
75  let MIOperandInfo = (ops GR16, i16imm);
76}
77
78// Branch targets have OtherVT type.
79def brtarget : Operand<OtherVT>;
80
81// Operand for printing out a condition code.
82def cc : Operand<i8> {
83  let PrintMethod = "printCCOperand";
84}
85
86//===----------------------------------------------------------------------===//
87// MSP430 Complex Pattern Definitions.
88//===----------------------------------------------------------------------===//
89
90def addr : ComplexPattern<iPTR, 2, "SelectAddr", [], []>;
91
92//===----------------------------------------------------------------------===//
93// Pattern Fragments
94def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>;
95def  extloadi16i8 : PatFrag<(ops node:$ptr), (i16 ( extloadi8 node:$ptr))>;
96
97//===----------------------------------------------------------------------===//
98// Instruction list..
99
100// ADJCALLSTACKDOWN/UP implicitly use/def SP because they may be expanded into
101// a stack adjustment and the codegen must know that they may modify the stack
102// pointer before prolog-epilog rewriting occurs.
103// Pessimistically assume ADJCALLSTACKDOWN / ADJCALLSTACKUP will become
104// sub / add which can clobber SRW.
105let Defs = [SPW, SRW], Uses = [SPW] in {
106def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i16imm:$amt),
107                              "#ADJCALLSTACKDOWN",
108                              [(MSP430callseq_start timm:$amt)]>;
109def ADJCALLSTACKUP   : Pseudo<(outs), (ins i16imm:$amt1, i16imm:$amt2),
110                              "#ADJCALLSTACKUP",
111                              [(MSP430callseq_end timm:$amt1, timm:$amt2)]>;
112}
113
114let usesCustomDAGSchedInserter = 1 in {
115  def Select16 : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2, i8imm:$cc),
116                        "# Select16 PSEUDO",
117                        [(set GR16:$dst,
118                          (MSP430select GR16:$src1, GR16:$src2, imm:$cc, SRW))]>;
119}
120
121let neverHasSideEffects = 1 in
122def NOP : Pseudo<(outs), (ins), "nop", []>;
123
124//===----------------------------------------------------------------------===//
125//  Control Flow Instructions...
126//
127
128// FIXME: Provide proper encoding!
129let isReturn = 1, isTerminator = 1 in {
130  def RET : Pseudo<(outs), (ins), "ret", [(MSP430retflag)]>;
131}
132
133let isBranch = 1, isTerminator = 1 in {
134
135// Direct branch
136let isBarrier = 1 in
137  def JMP : Pseudo<(outs), (ins brtarget:$dst),
138                   "jmp\t$dst",
139                   [(br bb:$dst)]>;
140
141// Conditional branches
142let Uses = [SRW] in
143  def JCC : Pseudo<(outs), (ins brtarget:$dst, cc:$cc),
144                            "j$cc $dst",
145                            [(MSP430brcond bb:$dst, imm:$cc, SRW)]>;
146} // isBranch, isTerminator
147
148//===----------------------------------------------------------------------===//
149//  Call Instructions...
150//
151let isCall = 1 in
152  // All calls clobber the non-callee saved registers. SPW is marked as
153  // a use to prevent stack-pointer assignments that appear immediately
154  // before calls from potentially appearing dead. Uses for argument
155  // registers are added manually.
156  let Defs = [R12W, R13W, R14W, R15W, SRW],
157      Uses = [SPW] in {
158    def CALLi     : Pseudo<(outs), (ins i16imm:$dst, variable_ops),
159                           "call\t${dst:call}", [(MSP430call imm:$dst)]>;
160    def CALLr     : Pseudo<(outs), (ins GR16:$dst, variable_ops),
161                           "call\t$dst", [(MSP430call GR16:$dst)]>;
162    def CALLm     : Pseudo<(outs), (ins memsrc:$dst, variable_ops),
163                           "call\t${dst:mem}", [(MSP430call (load addr:$dst))]>;
164  }
165
166
167//===----------------------------------------------------------------------===//
168//  Miscellaneous Instructions...
169//
170let Defs = [SPW], Uses = [SPW], neverHasSideEffects=1 in {
171let mayLoad = 1 in
172def POP16r   : Pseudo<(outs GR16:$reg), (ins), "pop.w\t$reg", []>;
173
174let mayStore = 1 in
175def PUSH16r  : Pseudo<(outs), (ins GR16:$reg), "push.w\t$reg",[]>;
176}
177
178//===----------------------------------------------------------------------===//
179// Move Instructions
180
181// FIXME: Provide proper encoding!
182let neverHasSideEffects = 1 in {
183def MOV8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src),
184                     "mov.b\t{$src, $dst}",
185                     []>;
186def MOV16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src),
187                     "mov.w\t{$src, $dst}",
188                     []>;
189}
190
191// FIXME: Provide proper encoding!
192let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
193def MOV8ri  : Pseudo<(outs GR8:$dst), (ins i8imm:$src),
194                     "mov.b\t{$src, $dst}",
195                     [(set GR8:$dst, imm:$src)]>;
196def MOV16ri : Pseudo<(outs GR16:$dst), (ins i16imm:$src),
197                     "mov.w\t{$src, $dst}",
198                     [(set GR16:$dst, imm:$src)]>;
199}
200
201let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in {
202def MOV8rm  : Pseudo<(outs GR8:$dst), (ins memsrc:$src),
203                "mov.b\t{$src, $dst}",
204                [(set GR8:$dst, (load addr:$src))]>;
205def MOV16rm : Pseudo<(outs GR16:$dst), (ins memsrc:$src),
206                "mov.w\t{$src, $dst}",
207                [(set GR16:$dst, (load addr:$src))]>;
208}
209
210def MOVZX16rr8 : Pseudo<(outs GR16:$dst), (ins GR8:$src),
211                "mov.b\t{$src, $dst}",
212                [(set GR16:$dst, (zext GR8:$src))]>;
213def MOVZX16rm8 : Pseudo<(outs GR16:$dst), (ins memsrc:$src),
214                "mov.b\t{$src, $dst}",
215                [(set GR16:$dst, (zextloadi16i8 addr:$src))]>;
216
217def MOV8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
218                "mov.b\t{$src, $dst}",
219                [(store (i8 imm:$src), addr:$dst)]>;
220def MOV16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
221                "mov.w\t{$src, $dst}",
222                [(store (i16 imm:$src), addr:$dst)]>;
223
224def MOV8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
225                "mov.b\t{$src, $dst}",
226                [(store GR8:$src, addr:$dst)]>;
227def MOV16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
228                "mov.w\t{$src, $dst}",
229                [(store GR16:$src, addr:$dst)]>;
230
231//===----------------------------------------------------------------------===//
232// Arithmetic Instructions
233
234let isTwoAddress = 1 in {
235
236let Defs = [SRW] in {
237
238let isCommutable = 1 in { // X = ADD Y, Z  == X = ADD Z, Y
239// FIXME: Provide proper encoding!
240def ADD8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
241                     "add.b\t{$src2, $dst}",
242                     [(set GR8:$dst, (add GR8:$src1, GR8:$src2)),
243                      (implicit SRW)]>;
244def ADD16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
245                     "add.w\t{$src2, $dst}",
246                     [(set GR16:$dst, (add GR16:$src1, GR16:$src2)),
247                      (implicit SRW)]>;
248}
249
250def ADD8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
251                     "add.b\t{$src2, $dst}",
252                     [(set GR8:$dst, (add GR8:$src1, (load addr:$src2))),
253                      (implicit SRW)]>;
254def ADD16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
255                     "add.w\t{$src2, $dst}",
256                     [(set GR16:$dst, (add GR16:$src1, (load addr:$src2))),
257                      (implicit SRW)]>;
258
259def ADD8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
260                     "add.b\t{$src2, $dst}",
261                     [(set GR8:$dst, (add GR8:$src1, imm:$src2)),
262                      (implicit SRW)]>;
263def ADD16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
264                     "add.w\t{$src2, $dst}",
265                     [(set GR16:$dst, (add GR16:$src1, imm:$src2)),
266                      (implicit SRW)]>;
267
268let isTwoAddress = 0 in {
269def ADD8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
270                "add.b\t{$src, $dst}",
271                [(store (add (load addr:$dst), GR8:$src), addr:$dst),
272                 (implicit SRW)]>;
273def ADD16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
274                "add.w\t{$src, $dst}",
275                [(store (add (load addr:$dst), GR16:$src), addr:$dst),
276                 (implicit SRW)]>;
277
278def ADD8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
279                "add.b\t{$src, $dst}",
280                [(store (add (load addr:$dst), (i8 imm:$src)), addr:$dst),
281                 (implicit SRW)]>;
282def ADD16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
283                "add.w\t{$src, $dst}",
284                [(store (add (load addr:$dst), (i16 imm:$src)), addr:$dst),
285                 (implicit SRW)]>;
286
287def ADD8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
288                "add.b\t{$src, $dst}",
289                [(store (add (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
290                 (implicit SRW)]>;
291def ADD16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
292                "add.w\t{$src, $dst}",
293                [(store (add (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
294                 (implicit SRW)]>;
295}
296
297let Uses = [SRW] in {
298
299let isCommutable = 1 in { // X = ADDC Y, Z  == X = ADDC Z, Y
300def ADC8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
301                     "addc.b\t{$src2, $dst}",
302                     [(set GR8:$dst, (adde GR8:$src1, GR8:$src2)),
303                      (implicit SRW)]>;
304def ADC16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
305                     "addc.w\t{$src2, $dst}",
306                     [(set GR16:$dst, (adde GR16:$src1, GR16:$src2)),
307                      (implicit SRW)]>;
308} // isCommutable
309
310def ADC8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
311                     "addc.b\t{$src2, $dst}",
312                     [(set GR8:$dst, (adde GR8:$src1, imm:$src2)),
313                      (implicit SRW)]>;
314def ADC16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
315                     "addc.w\t{$src2, $dst}",
316                     [(set GR16:$dst, (adde GR16:$src1, imm:$src2)),
317                      (implicit SRW)]>;
318
319def ADC8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
320                     "addc.b\t{$src2, $dst}",
321                     [(set GR8:$dst, (adde GR8:$src1, (load addr:$src2))),
322                      (implicit SRW)]>;
323def ADC16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
324                     "addc.w\t{$src2, $dst}",
325                     [(set GR16:$dst, (adde GR16:$src1, (load addr:$src2))),
326                      (implicit SRW)]>;
327
328let isTwoAddress = 0 in {
329def ADC8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
330                "addc.b\t{$src, $dst}",
331                [(store (adde (load addr:$dst), GR8:$src), addr:$dst),
332                 (implicit SRW)]>;
333def ADC16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
334                "addc.w\t{$src, $dst}",
335                [(store (adde (load addr:$dst), GR16:$src), addr:$dst),
336                 (implicit SRW)]>;
337
338def ADC8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
339                "addc.b\t{$src, $dst}",
340                [(store (adde (load addr:$dst), (i8 imm:$src)), addr:$dst),
341                 (implicit SRW)]>;
342def ADC16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
343                "addc.w\t{$src, $dst}",
344                [(store (adde (load addr:$dst), (i16 imm:$src)), addr:$dst),
345                 (implicit SRW)]>;
346
347def ADC8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
348                "addc.b\t{$src, $dst}",
349                [(store (adde (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
350                 (implicit SRW)]>;
351def ADC16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
352                "addc.w\t{$src, $dst}",
353                [(store (adde (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
354                 (implicit SRW)]>;
355}
356
357} // Uses = [SRW]
358
359let isCommutable = 1 in { // X = AND Y, Z  == X = AND Z, Y
360def AND8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
361                     "and.b\t{$src2, $dst}",
362                     [(set GR8:$dst, (and GR8:$src1, GR8:$src2)),
363                      (implicit SRW)]>;
364def AND16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
365                     "and.w\t{$src2, $dst}",
366                     [(set GR16:$dst, (and GR16:$src1, GR16:$src2)),
367                      (implicit SRW)]>;
368}
369
370def AND8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
371                     "and.b\t{$src2, $dst}",
372                     [(set GR8:$dst, (and GR8:$src1, imm:$src2)),
373                      (implicit SRW)]>;
374def AND16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
375                     "and.w\t{$src2, $dst}",
376                     [(set GR16:$dst, (and GR16:$src1, imm:$src2)),
377                      (implicit SRW)]>;
378
379def AND8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
380                     "and.b\t{$src2, $dst}",
381                     [(set GR8:$dst, (and GR8:$src1, (load addr:$src2))),
382                      (implicit SRW)]>;
383def AND16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
384                     "and.w\t{$src2, $dst}",
385                     [(set GR16:$dst, (and GR16:$src1, (load addr:$src2))),
386                      (implicit SRW)]>;
387
388let isTwoAddress = 0 in {
389def AND8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
390                "and.b\t{$src, $dst}",
391                [(store (and (load addr:$dst), GR8:$src), addr:$dst),
392                 (implicit SRW)]>;
393def AND16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
394                "and.w\t{$src, $dst}",
395                [(store (and (load addr:$dst), GR16:$src), addr:$dst),
396                 (implicit SRW)]>;
397
398def AND8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
399                "and.b\t{$src, $dst}",
400                [(store (and (load addr:$dst), (i8 imm:$src)), addr:$dst),
401                 (implicit SRW)]>;
402def AND16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
403                "and.w\t{$src, $dst}",
404                [(store (and (load addr:$dst), (i16 imm:$src)), addr:$dst),
405                 (implicit SRW)]>;
406
407def AND8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
408                "and.b\t{$src, $dst}",
409                [(store (and (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
410                 (implicit SRW)]>;
411def AND16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
412                "and.w\t{$src, $dst}",
413                [(store (and (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
414                 (implicit SRW)]>;
415}
416
417
418let isCommutable = 1 in { // X = XOR Y, Z  == X = XOR Z, Y
419def XOR8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
420                     "xor.b\t{$src2, $dst}",
421                     [(set GR8:$dst, (xor GR8:$src1, GR8:$src2)),
422                      (implicit SRW)]>;
423def XOR16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
424                     "xor.w\t{$src2, $dst}",
425                     [(set GR16:$dst, (xor GR16:$src1, GR16:$src2)),
426                      (implicit SRW)]>;
427}
428
429def XOR8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
430                     "xor.b\t{$src2, $dst}",
431                     [(set GR8:$dst, (xor GR8:$src1, imm:$src2)),
432                      (implicit SRW)]>;
433def XOR16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
434                     "xor.w\t{$src2, $dst}",
435                     [(set GR16:$dst, (xor GR16:$src1, imm:$src2)),
436                      (implicit SRW)]>;
437
438def XOR8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
439                     "xor.b\t{$src2, $dst}",
440                     [(set GR8:$dst, (xor GR8:$src1, (load addr:$src2))),
441                      (implicit SRW)]>;
442def XOR16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
443                     "xor.w\t{$src2, $dst}",
444                     [(set GR16:$dst, (xor GR16:$src1, (load addr:$src2))),
445                      (implicit SRW)]>;
446
447let isTwoAddress = 0 in {
448def XOR8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
449                "xor.b\t{$src, $dst}",
450                [(store (xor (load addr:$dst), GR8:$src), addr:$dst),
451                 (implicit SRW)]>;
452def XOR16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
453                "xor.w\t{$src, $dst}",
454                [(store (xor (load addr:$dst), GR16:$src), addr:$dst),
455                 (implicit SRW)]>;
456
457def XOR8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
458                "xor.b\t{$src, $dst}",
459                [(store (xor (load addr:$dst), (i8 imm:$src)), addr:$dst),
460                 (implicit SRW)]>;
461def XOR16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
462                "xor.w\t{$src, $dst}",
463                [(store (xor (load addr:$dst), (i16 imm:$src)), addr:$dst),
464                 (implicit SRW)]>;
465
466def XOR8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
467                "xor.b\t{$src, $dst}",
468                [(store (xor (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
469                 (implicit SRW)]>;
470def XOR16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
471                "xor.w\t{$src, $dst}",
472                [(store (xor (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
473                 (implicit SRW)]>;
474}
475
476
477def SUB8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
478                     "sub.b\t{$src2, $dst}",
479                     [(set GR8:$dst, (sub GR8:$src1, GR8:$src2)),
480                      (implicit SRW)]>;
481def SUB16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
482                     "sub.w\t{$src2, $dst}",
483                     [(set GR16:$dst, (sub GR16:$src1, GR16:$src2)),
484                      (implicit SRW)]>;
485
486def SUB8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
487                     "sub.b\t{$src2, $dst}",
488                     [(set GR8:$dst, (sub GR8:$src1, imm:$src2)),
489                      (implicit SRW)]>;
490def SUB16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
491                     "sub.w\t{$src2, $dst}",
492                     [(set GR16:$dst, (sub GR16:$src1, imm:$src2)),
493                      (implicit SRW)]>;
494
495def SUB8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
496                     "sub.b\t{$src2, $dst}",
497                     [(set GR8:$dst, (sub GR8:$src1, (load addr:$src2))),
498                      (implicit SRW)]>;
499def SUB16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
500                     "sub.w\t{$src2, $dst}",
501                     [(set GR16:$dst, (sub GR16:$src1, (load addr:$src2))),
502                      (implicit SRW)]>;
503
504let isTwoAddress = 0 in {
505def SUB8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
506                "sub.b\t{$src, $dst}",
507                [(store (sub (load addr:$dst), GR8:$src), addr:$dst),
508                 (implicit SRW)]>;
509def SUB16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
510                "sub.w\t{$src, $dst}",
511                [(store (sub (load addr:$dst), GR16:$src), addr:$dst),
512                 (implicit SRW)]>;
513
514def SUB8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
515                "sub.b\t{$src, $dst}",
516                [(store (sub (load addr:$dst), (i8 imm:$src)), addr:$dst),
517                 (implicit SRW)]>;
518def SUB16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
519                "sub.w\t{$src, $dst}",
520                [(store (sub (load addr:$dst), (i16 imm:$src)), addr:$dst),
521                 (implicit SRW)]>;
522
523def SUB8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
524                "sub.b\t{$src, $dst}",
525                [(store (sub (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
526                 (implicit SRW)]>;
527def SUB16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
528                "sub.w\t{$src, $dst}",
529                [(store (sub (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
530                 (implicit SRW)]>;
531}
532
533let Uses = [SRW] in {
534def SBC8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
535                     "subc.b\t{$src2, $dst}",
536                     [(set GR8:$dst, (sube GR8:$src1, GR8:$src2)),
537                      (implicit SRW)]>;
538def SBC16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
539                     "subc.w\t{$src2, $dst}",
540                     [(set GR16:$dst, (sube GR16:$src1, GR16:$src2)),
541                      (implicit SRW)]>;
542
543def SBC8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
544                     "subc.b\t{$src2, $dst}",
545                     [(set GR8:$dst, (sube GR8:$src1, imm:$src2)),
546                      (implicit SRW)]>;
547def SBC16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
548                     "subc.w\t{$src2, $dst}",
549                     [(set GR16:$dst, (sube GR16:$src1, imm:$src2)),
550                      (implicit SRW)]>;
551
552def SBC8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
553                     "subc.b\t{$src2, $dst}",
554                     [(set GR8:$dst, (sube GR8:$src1, (load addr:$src2))),
555                      (implicit SRW)]>;
556def SBC16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
557                     "subc.w\t{$src2, $dst}",
558                     [(set GR16:$dst, (sube GR16:$src1, (load addr:$src2))),
559                      (implicit SRW)]>;
560
561let isTwoAddress = 0 in {
562def SBC8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
563                "subc.b\t{$src, $dst}",
564                [(store (sube (load addr:$dst), GR8:$src), addr:$dst),
565                 (implicit SRW)]>;
566def SBC16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
567                "subc.w\t{$src, $dst}",
568                [(store (sube (load addr:$dst), GR16:$src), addr:$dst),
569                 (implicit SRW)]>;
570
571def SBC8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
572                "subc.b\t{$src, $dst}",
573                [(store (sube (load addr:$dst), (i8 imm:$src)), addr:$dst),
574                 (implicit SRW)]>;
575def SBC16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
576                "subc.w\t{$src, $dst}",
577                [(store (sube (load addr:$dst), (i16 imm:$src)), addr:$dst),
578                 (implicit SRW)]>;
579
580def SBC8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
581                "subc.b\t{$src, $dst}",
582                [(store (sube (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
583                 (implicit SRW)]>;
584def SBC16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
585                "subc.w\t{$src, $dst}",
586                [(store (sube (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
587                 (implicit SRW)]>;
588}
589
590} // Uses = [SRW]
591
592// FIXME: Provide proper encoding!
593def SAR16r1 : Pseudo<(outs GR16:$dst), (ins GR16:$src),
594                     "rra.w\t$dst",
595                     [(set GR16:$dst, (MSP430rra GR16:$src)),
596                      (implicit SRW)]>;
597
598def SHL16r1 : Pseudo<(outs GR16:$dst), (ins GR16:$src),
599                     "rla.w\t$dst",
600                     [(set GR16:$dst, (MSP430rla GR16:$src)),
601                      (implicit SRW)]>;
602
603def SAR16r1c : Pseudo<(outs GR16:$dst), (ins GR16:$src),
604                      "rrc.w\t$dst",
605                      [(set GR16:$dst, (MSP430rrc GR16:$src)),
606                       (implicit SRW)]>;
607
608def SEXT16r : Pseudo<(outs GR16:$dst), (ins GR16:$src),
609                     "sxt\t$dst",
610                     [(set GR16:$dst, (sext_inreg GR16:$src, i8)),
611                      (implicit SRW)]>;
612
613} // Defs = [SRW]
614
615def SWPB16r : Pseudo<(outs GR16:$dst), (ins GR16:$src),
616                     "swpb\t$dst",
617                     [(set GR16:$dst, (bswap GR16:$src))]>;
618
619let isCommutable = 1 in { // X = OR Y, Z  == X = OR Z, Y
620def OR8rr  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
621                    "bis.b\t{$src2, $dst}",
622                    [(set GR8:$dst, (or GR8:$src1, GR8:$src2))]>;
623def OR16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
624                    "bis.w\t{$src2, $dst}",
625                    [(set GR16:$dst, (or GR16:$src1, GR16:$src2))]>;
626}
627
628def OR8ri  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
629                    "bis.b\t{$src2, $dst}",
630                    [(set GR8:$dst, (or GR8:$src1, imm:$src2))]>;
631def OR16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
632                    "bis.w\t{$src2, $dst}",
633                    [(set GR16:$dst, (or GR16:$src1, imm:$src2))]>;
634
635def OR8rm  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
636                    "bis.b\t{$src2, $dst}",
637                    [(set GR8:$dst, (or GR8:$src1, (load addr:$src2)))]>;
638def OR16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
639                    "bis.w\t{$src2, $dst}",
640                    [(set GR16:$dst, (or GR16:$src1, (load addr:$src2)))]>;
641
642let isTwoAddress = 0 in {
643def OR8mr  : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
644                "bis.b\t{$src, $dst}",
645                [(store (or (load addr:$dst), GR8:$src), addr:$dst),
646                 (implicit SRW)]>;
647def OR16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
648                "bis.w\t{$src, $dst}",
649                [(store (or (load addr:$dst), GR16:$src), addr:$dst),
650                 (implicit SRW)]>;
651
652def OR8mi  : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
653                "bis.b\t{$src, $dst}",
654                [(store (or (load addr:$dst), (i8 imm:$src)), addr:$dst),
655                 (implicit SRW)]>;
656def OR16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
657                "bis.w\t{$src, $dst}",
658                [(store (or (load addr:$dst), (i16 imm:$src)), addr:$dst),
659                 (implicit SRW)]>;
660
661def OR8mm  : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
662                "bis.b\t{$src, $dst}",
663                [(store (or (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
664                 (implicit SRW)]>;
665def OR16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
666                "bis.w\t{$src, $dst}",
667                [(store (or (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
668                 (implicit SRW)]>;
669}
670
671} // isTwoAddress = 1
672
673let Defs = [SRW] in
674def CLRC   : Pseudo<(outs), (ins),
675                     "clrc", [(MSP430clrc)]>;
676
677// Integer comparisons
678let Defs = [SRW] in {
679def CMP8rr  : Pseudo<(outs), (ins GR8:$src1, GR8:$src2),
680                     "cmp.b\t{$src1, $src2}",
681                     [(MSP430cmp GR8:$src1, GR8:$src2), (implicit SRW)]>;
682def CMP16rr : Pseudo<(outs), (ins GR16:$src1, GR16:$src2),
683                     "cmp.w\t{$src1, $src2}",
684                     [(MSP430cmp GR16:$src1, GR16:$src2), (implicit SRW)]>;
685
686def CMP8ri  : Pseudo<(outs), (ins GR8:$src1, i8imm:$src2),
687                     "cmp.b\t{$src1, $src2}",
688                     [(MSP430cmp GR8:$src1, imm:$src2), (implicit SRW)]>;
689def CMP16ri : Pseudo<(outs), (ins GR16:$src1, i16imm:$src2),
690                     "cmp.w\t{$src1, $src2}",
691                     [(MSP430cmp GR16:$src1, imm:$src2), (implicit SRW)]>;
692
693def CMP8rm  : Pseudo<(outs), (ins GR8:$src1, memsrc:$src2),
694                     "cmp.b\t{$src1, $src2}",
695                     [(MSP430cmp GR8:$src1, (load addr:$src2)), (implicit SRW)]>;
696def CMP16rm : Pseudo<(outs), (ins GR16:$src1, memsrc:$src2),
697                     "cmp.w\t{$src1, $src2}",
698                     [(MSP430cmp GR16:$src1, (load addr:$src2)), (implicit SRW)]>;
699
700def CMP8mr  : Pseudo<(outs), (ins memsrc:$src1, GR8:$src2),
701                "cmp.b\t{$src1, $src2}",
702                [(MSP430cmp (load addr:$src1), GR8:$src2), (implicit SRW)]>;
703def CMP16mr : Pseudo<(outs), (ins memsrc:$src1, GR16:$src2),
704                "cmp.w\t{$src1, $src2}",
705                [(MSP430cmp (load addr:$src1), GR16:$src2), (implicit SRW)]>;
706
707def CMP8mi  : Pseudo<(outs), (ins memsrc:$src1, i8imm:$src2),
708                "cmp.b\t{$src1, $src2}",
709                [(MSP430cmp (load addr:$src1), (i8 imm:$src2)), (implicit SRW)]>;
710def CMP16mi : Pseudo<(outs), (ins memsrc:$src1, i16imm:$src2),
711                "cmp.w\t{$src1, $src2}",
712                [(MSP430cmp (load addr:$src1), (i16 imm:$src2)), (implicit SRW)]>;
713
714def CMP8mm  : Pseudo<(outs), (ins memsrc:$src1, memsrc:$src2),
715                "cmp.b\t{$src1, $src2}",
716                [(MSP430cmp (load addr:$src1), (i8 (load addr:$src2))), (implicit SRW)]>;
717def CMP16mm : Pseudo<(outs), (ins memsrc:$src1, memsrc:$src2),
718                "cmp.w\t{$src1, $src2}",
719                [(MSP430cmp (load addr:$src1), (i16 (load addr:$src2))), (implicit SRW)]>;
720} // Defs = [SRW]
721
722//===----------------------------------------------------------------------===//
723// Non-Instruction Patterns
724
725// extload
726def : Pat<(extloadi16i8 addr:$src), (MOVZX16rm8 addr:$src)>;
727
728// anyext
729def : Pat<(anyext addr:$src), (MOVZX16rr8 GR8:$src)>;
730
731// truncs
732def : Pat<(i8 (trunc GR16:$src)),
733          (EXTRACT_SUBREG GR16:$src, subreg_8bit)>;
734
735// GlobalAddress, ExternalSymbol
736def : Pat<(i16 (MSP430Wrapper tglobaladdr:$dst)), (MOV16ri tglobaladdr:$dst)>;
737def : Pat<(i16 (MSP430Wrapper texternalsym:$dst)), (MOV16ri texternalsym:$dst)>;
738
739def : Pat<(add GR16:$src1, (MSP430Wrapper tglobaladdr :$src2)),
740          (ADD16ri GR16:$src1, tglobaladdr:$src2)>;
741def : Pat<(add GR16:$src1, (MSP430Wrapper texternalsym:$src2)),
742          (ADD16ri GR16:$src1, texternalsym:$src2)>;
743
744def : Pat<(store (i16 (MSP430Wrapper tglobaladdr:$src)), addr:$dst),
745          (MOV16mi addr:$dst, tglobaladdr:$src)>;
746def : Pat<(store (i16 (MSP430Wrapper texternalsym:$src)), addr:$dst),
747          (MOV16mi addr:$dst, texternalsym:$src)>;
748
749// calls
750def : Pat<(MSP430call (i16 tglobaladdr:$dst)),
751          (CALLi tglobaladdr:$dst)>;
752def : Pat<(MSP430call (i16 texternalsym:$dst)),
753          (CALLi texternalsym:$dst)>;
754
755// add and sub always produce carry
756def : Pat<(addc GR16:$src1, GR16:$src2),
757          (ADD16rr GR16:$src1, GR16:$src2)>;
758def : Pat<(addc GR16:$src1, (load addr:$src2)),
759          (ADD16rm GR16:$src1, addr:$src2)>;
760def : Pat<(addc GR16:$src1, imm:$src2),
761          (ADD16ri GR16:$src1, imm:$src2)>;
762def : Pat<(store (addc (load addr:$dst), GR16:$src), addr:$dst),
763          (ADD16mr addr:$dst, GR16:$src)>;
764def : Pat<(store (addc (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
765          (ADD16mm addr:$dst, addr:$src)>;
766
767def : Pat<(addc GR8:$src1, GR8:$src2),
768          (ADD8rr GR8:$src1, GR8:$src2)>;
769def : Pat<(addc GR8:$src1, (load addr:$src2)),
770          (ADD8rm GR8:$src1, addr:$src2)>;
771def : Pat<(addc GR8:$src1, imm:$src2),
772          (ADD8ri GR8:$src1, imm:$src2)>;
773def : Pat<(store (addc (load addr:$dst), GR8:$src), addr:$dst),
774          (ADD8mr addr:$dst, GR8:$src)>;
775def : Pat<(store (addc (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
776          (ADD8mm addr:$dst, addr:$src)>;
777
778def : Pat<(subc GR16:$src1, GR16:$src2),
779          (SUB16rr GR16:$src1, GR16:$src2)>;
780def : Pat<(subc GR16:$src1, (load addr:$src2)),
781          (SUB16rm GR16:$src1, addr:$src2)>;
782def : Pat<(subc GR16:$src1, imm:$src2),
783          (SUB16ri GR16:$src1, imm:$src2)>;
784def : Pat<(store (subc (load addr:$dst), GR16:$src), addr:$dst),
785          (SUB16mr addr:$dst, GR16:$src)>;
786def : Pat<(store (subc (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
787          (SUB16mm addr:$dst, addr:$src)>;
788
789def : Pat<(subc GR8:$src1, GR8:$src2),
790          (SUB8rr GR8:$src1, GR8:$src2)>;
791def : Pat<(subc GR8:$src1, (load addr:$src2)),
792          (SUB8rm GR8:$src1, addr:$src2)>;
793def : Pat<(subc GR8:$src1, imm:$src2),
794          (SUB8ri GR8:$src1, imm:$src2)>;
795def : Pat<(store (subc (load addr:$dst), GR8:$src), addr:$dst),
796          (SUB8mr addr:$dst, GR8:$src)>;
797def : Pat<(store (subc (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
798          (SUB8mm addr:$dst, addr:$src)>;
799