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