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