Provide instruction sizes & encoding. No opcodes yet (but not needed so far).
[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_MSP430Cmp          : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
30 def SDT_MSP430BrCC         : SDTypeProfile<0, 2, [SDTCisVT<0, OtherVT>,
31                                                   SDTCisVT<1, i8>]>;
32 def SDT_MSP430SelectCC     : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, 
33                                                   SDTCisVT<3, i8>]>;
34 def SDT_MSP430Shift        : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, SDTCisI8<2>]>;
35
36 //===----------------------------------------------------------------------===//
37 // MSP430 Specific Node Definitions.
38 //===----------------------------------------------------------------------===//
39 def MSP430retflag  : SDNode<"MSP430ISD::RET_FLAG", SDTNone,
40                        [SDNPHasChain, SDNPOptInFlag]>;
41 def MSP430retiflag : SDNode<"MSP430ISD::RETI_FLAG", SDTNone,
42                        [SDNPHasChain, SDNPOptInFlag]>;
43
44 def MSP430rra     : SDNode<"MSP430ISD::RRA", SDTIntUnaryOp, []>;
45 def MSP430rla     : SDNode<"MSP430ISD::RLA", SDTIntUnaryOp, []>;
46 def MSP430rrc     : SDNode<"MSP430ISD::RRC", SDTIntUnaryOp, []>;
47
48 def MSP430call    : SDNode<"MSP430ISD::CALL", SDT_MSP430Call,
49                      [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag]>;
50 def MSP430callseq_start :
51                  SDNode<"ISD::CALLSEQ_START", SDT_MSP430CallSeqStart,
52                         [SDNPHasChain, SDNPOutFlag]>;
53 def MSP430callseq_end :
54                  SDNode<"ISD::CALLSEQ_END",   SDT_MSP430CallSeqEnd,
55                         [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
56 def MSP430Wrapper : SDNode<"MSP430ISD::Wrapper", SDT_MSP430Wrapper>;
57 def MSP430cmp     : SDNode<"MSP430ISD::CMP", SDT_MSP430Cmp, [SDNPOutFlag]>;
58 def MSP430brcc    : SDNode<"MSP430ISD::BR_CC", SDT_MSP430BrCC, [SDNPHasChain, SDNPInFlag]>;
59 def MSP430selectcc: SDNode<"MSP430ISD::SELECT_CC", SDT_MSP430SelectCC, [SDNPInFlag]>;
60 def MSP430shl     : SDNode<"MSP430ISD::SHL", SDT_MSP430Shift, []>;
61 def MSP430sra     : SDNode<"MSP430ISD::SRA", SDT_MSP430Shift, []>;
62 def MSP430srl     : SDNode<"MSP430ISD::SRL", SDT_MSP430Shift, []>;
63
64 //===----------------------------------------------------------------------===//
65 // MSP430 Operand Definitions.
66 //===----------------------------------------------------------------------===//
67
68 // Address operands
69 def memsrc : Operand<i16> {
70   let PrintMethod = "printSrcMemOperand";
71   let MIOperandInfo = (ops GR16, i16imm);
72 }
73
74 def memdst : Operand<i16> {
75   let PrintMethod = "printSrcMemOperand";
76   let MIOperandInfo = (ops GR16, i16imm);
77 }
78
79 // Branch targets have OtherVT type.
80 def brtarget : Operand<OtherVT> {
81   let PrintMethod = "printPCRelImmOperand";
82 }
83
84 // Operand for printing out a condition code.
85 def cc : Operand<i8> {
86   let PrintMethod = "printCCOperand";
87 }
88
89 //===----------------------------------------------------------------------===//
90 // MSP430 Complex Pattern Definitions.
91 //===----------------------------------------------------------------------===//
92
93 def addr : ComplexPattern<iPTR, 2, "SelectAddr", [], []>;
94
95 //===----------------------------------------------------------------------===//
96 // Pattern Fragments
97 def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>;
98 def  extloadi16i8 : PatFrag<(ops node:$ptr), (i16 ( extloadi8 node:$ptr))>;
99 def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{
100   return N->hasOneUse();
101 }]>;
102 //===----------------------------------------------------------------------===//
103 // Instruction list..
104
105 // ADJCALLSTACKDOWN/UP implicitly use/def SP because they may be expanded into
106 // a stack adjustment and the codegen must know that they may modify the stack
107 // pointer before prolog-epilog rewriting occurs.
108 // Pessimistically assume ADJCALLSTACKDOWN / ADJCALLSTACKUP will become
109 // sub / add which can clobber SRW.
110 let Defs = [SPW, SRW], Uses = [SPW] in {
111 def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i16imm:$amt),
112                               "#ADJCALLSTACKDOWN",
113                               [(MSP430callseq_start timm:$amt)]>;
114 def ADJCALLSTACKUP   : Pseudo<(outs), (ins i16imm:$amt1, i16imm:$amt2),
115                               "#ADJCALLSTACKUP",
116                               [(MSP430callseq_end timm:$amt1, timm:$amt2)]>;
117 }
118
119 let usesCustomInserter = 1 in {
120   def Select8  : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2, i8imm:$cc),
121                         "# Select8 PSEUDO",
122                         [(set GR8:$dst,
123                           (MSP430selectcc GR8:$src1, GR8:$src2, imm:$cc))]>;
124   def Select16 : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2, i8imm:$cc),
125                         "# Select16 PSEUDO",
126                         [(set GR16:$dst,
127                           (MSP430selectcc GR16:$src1, GR16:$src2, imm:$cc))]>;
128   let Defs = [SRW] in {
129   def Shl8     : Pseudo<(outs GR8:$dst), (ins GR8:$src, GR8:$cnt),
130                         "# Shl8 PSEUDO",
131                         [(set GR8:$dst, (MSP430shl GR8:$src, GR8:$cnt))]>;
132   def Shl16    : Pseudo<(outs GR16:$dst), (ins GR16:$src, GR8:$cnt),
133                         "# Shl16 PSEUDO",
134                         [(set GR16:$dst, (MSP430shl GR16:$src, GR8:$cnt))]>;
135   def Sra8     : Pseudo<(outs GR8:$dst), (ins GR8:$src, GR8:$cnt),
136                         "# Sra8 PSEUDO",
137                         [(set GR8:$dst, (MSP430sra GR8:$src, GR8:$cnt))]>;
138   def Sra16    : Pseudo<(outs GR16:$dst), (ins GR16:$src, GR8:$cnt),
139                         "# Sra16 PSEUDO",
140                         [(set GR16:$dst, (MSP430sra GR16:$src, GR8:$cnt))]>;
141   def Srl8     : Pseudo<(outs GR8:$dst), (ins GR8:$src, GR8:$cnt),
142                         "# Srl8 PSEUDO",
143                         [(set GR8:$dst, (MSP430srl GR8:$src, GR8:$cnt))]>;
144   def Srl16    : Pseudo<(outs GR16:$dst), (ins GR16:$src, GR8:$cnt),
145                         "# Srl16 PSEUDO",
146                         [(set GR16:$dst, (MSP430srl GR16:$src, GR8:$cnt))]>;
147
148   }
149 }
150
151 let neverHasSideEffects = 1 in
152 def NOP : Pseudo<(outs), (ins), "nop", []>;
153
154 //===----------------------------------------------------------------------===//
155 //  Control Flow Instructions...
156 //
157
158 // FIXME: Provide proper encoding!
159 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
160   def RET  : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes,
161                      (outs), (ins), "ret",  [(MSP430retflag)]>;
162   def RETI : II16r<0x0, (outs), (ins), "reti", [(MSP430retiflag)]>;
163 }
164
165 let isBranch = 1, isTerminator = 1 in {
166
167 // FIXME: expand opcode & cond field for branches!
168
169 // Direct branch
170 let isBarrier = 1 in
171   def JMP : CJForm<0, 0,
172                    (outs), (ins brtarget:$dst),
173                    "jmp\t$dst",
174                    [(br bb:$dst)]>;
175
176 // Conditional branches
177 let Uses = [SRW] in
178   def JCC : CJForm<0, 0,
179                    (outs), (ins brtarget:$dst, cc:$cc),
180                    "j$cc\t$dst",
181                    [(MSP430brcc bb:$dst, imm:$cc)]>;
182 } // isBranch, isTerminator
183
184 //===----------------------------------------------------------------------===//
185 //  Call Instructions...
186 //
187 let isCall = 1 in
188   // All calls clobber the non-callee saved registers. SPW is marked as
189   // a use to prevent stack-pointer assignments that appear immediately
190   // before calls from potentially appearing dead. Uses for argument
191   // registers are added manually.
192   let Defs = [R12W, R13W, R14W, R15W, SRW],
193       Uses = [SPW] in {
194     def CALLi     : II16i<0x0,
195                           (outs), (ins i16imm:$dst, variable_ops),
196                           "call\t$dst", [(MSP430call imm:$dst)]>;
197     def CALLr     : II16r<0x0,
198                           (outs), (ins GR16:$dst, variable_ops),
199                           "call\t$dst", [(MSP430call GR16:$dst)]>;
200     def CALLm     : II16m<0x0,
201                           (outs), (ins memsrc:$dst, variable_ops),
202                           "call\t${dst:mem}", [(MSP430call (load addr:$dst))]>;
203   }
204
205
206 //===----------------------------------------------------------------------===//
207 //  Miscellaneous Instructions...
208 //
209 let Defs = [SPW], Uses = [SPW], neverHasSideEffects=1 in {
210 let mayLoad = 1 in
211 def POP16r   : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes,
212                        (outs GR16:$reg), (ins), "pop.w\t$reg", []>;
213
214 let mayStore = 1 in
215 def PUSH16r  : II16r<0x0,
216                      (outs), (ins GR16:$reg), "push.w\t$reg",[]>;
217 }
218
219 //===----------------------------------------------------------------------===//
220 // Move Instructions
221
222 // FIXME: Provide proper encoding!
223 let neverHasSideEffects = 1 in {
224 def MOV8rr  : I8rr<0x0,
225                    (outs GR8:$dst), (ins GR8:$src),
226                    "mov.b\t{$src, $dst}",
227                    []>;
228 def MOV16rr : I16rr<0x0,
229                     (outs GR16:$dst), (ins GR16:$src),
230                     "mov.w\t{$src, $dst}",
231                     []>;
232 }
233
234 // FIXME: Provide proper encoding!
235 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
236 def MOV8ri  : I8ri<0x0,
237                    (outs GR8:$dst), (ins i8imm:$src),
238                    "mov.b\t{$src, $dst}",
239                    [(set GR8:$dst, imm:$src)]>;
240 def MOV16ri : I16ri<0x0,
241                     (outs GR16:$dst), (ins i16imm:$src),
242                     "mov.w\t{$src, $dst}",
243                     [(set GR16:$dst, imm:$src)]>;
244 }
245
246 let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in {
247 def MOV8rm  : I8rm<0x0,
248                    (outs GR8:$dst), (ins memsrc:$src),
249                    "mov.b\t{$src, $dst}",
250                    [(set GR8:$dst, (load addr:$src))]>;
251 def MOV16rm : I16rm<0x0,
252                     (outs GR16:$dst), (ins memsrc:$src),
253                     "mov.w\t{$src, $dst}",
254                     [(set GR16:$dst, (load addr:$src))]>;
255 }
256
257 def MOVZX16rr8 : I8rr<0x0,
258                       (outs GR16:$dst), (ins GR8:$src),
259                       "mov.b\t{$src, $dst}",
260                       [(set GR16:$dst, (zext GR8:$src))]>;
261 def MOVZX16rm8 : I8rm<0x0,
262                       (outs GR16:$dst), (ins memsrc:$src),
263                       "mov.b\t{$src, $dst}",
264                       [(set GR16:$dst, (zextloadi16i8 addr:$src))]>;
265
266 let mayLoad = 1, hasExtraDefRegAllocReq = 1, Constraints = "$base = $base_wb" in {
267 def MOV8rm_POST  : IForm8<0x0, DstReg, SrcPostInc, Size2Bytes,
268                          (outs GR8:$dst, GR16:$base_wb), (ins GR16:$base),
269                          "mov.b\t{@$base+, $dst}", []>;
270 def MOV16rm_POST : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes,
271                            (outs GR16:$dst, GR16:$base_wb), (ins GR16:$base),
272                            "mov.w\t{@$base+, $dst}", []>;
273 }
274
275 // Any instruction that defines a 8-bit result leaves the high half of the
276 // register. Truncate can be lowered to EXTRACT_SUBREG, and CopyFromReg may
277 // be copying from a truncate, but any other 8-bit operation will zero-extend
278 // up to 16 bits.
279 def def8 : PatLeaf<(i8 GR8:$src), [{
280   return N->getOpcode() != ISD::TRUNCATE &&
281          N->getOpcode() != TargetInstrInfo::EXTRACT_SUBREG &&
282          N->getOpcode() != ISD::CopyFromReg;
283 }]>;
284
285 // In the case of a 8-bit def that is known to implicitly zero-extend,
286 // we can use a SUBREG_TO_REG.
287 def : Pat<(i16 (zext def8:$src)),
288           (SUBREG_TO_REG (i16 0), GR8:$src, subreg_8bit)>;
289
290 def MOV8mi  : I8mi<0x0,
291                    (outs), (ins memdst:$dst, i8imm:$src),
292                    "mov.b\t{$src, $dst}",
293                    [(store (i8 imm:$src), addr:$dst)]>;
294 def MOV16mi : I16mi<0x0,
295                     (outs), (ins memdst:$dst, i16imm:$src),
296                     "mov.w\t{$src, $dst}",
297                     [(store (i16 imm:$src), addr:$dst)]>;
298
299 def MOV8mr  : I8mr<0x0,
300                    (outs), (ins memdst:$dst, GR8:$src),
301                    "mov.b\t{$src, $dst}",
302                    [(store GR8:$src, addr:$dst)]>;
303 def MOV16mr : I16mr<0x0,
304                     (outs), (ins memdst:$dst, GR16:$src),
305                     "mov.w\t{$src, $dst}",
306                     [(store GR16:$src, addr:$dst)]>;
307
308 def MOV8mm  : I8mm<0x0,
309                    (outs), (ins memdst:$dst, memsrc:$src),
310                    "mov.b\t{$src, $dst}",
311                    [(store (i8 (load addr:$src)), addr:$dst)]>;
312 def MOV16mm : I16mm<0x0,
313                     (outs), (ins memdst:$dst, memsrc:$src),
314                     "mov.w\t{$src, $dst}",
315                     [(store (i16 (load addr:$src)), addr:$dst)]>;
316
317 //===----------------------------------------------------------------------===//
318 // Arithmetic Instructions
319
320 let isTwoAddress = 1 in {
321
322 let Defs = [SRW] in {
323
324 let isCommutable = 1 in { // X = ADD Y, Z  == X = ADD Z, Y
325
326 def ADD8rr  : I8rr<0x0,
327                    (outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
328                    "add.b\t{$src2, $dst}",
329                    [(set GR8:$dst, (add GR8:$src1, GR8:$src2)),
330                     (implicit SRW)]>;
331 def ADD16rr : I16rr<0x0,
332                     (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
333                     "add.w\t{$src2, $dst}",
334                     [(set GR16:$dst, (add GR16:$src1, GR16:$src2)),
335                      (implicit SRW)]>;
336 }
337
338 def ADD8rm  : I8rm<0x0,
339                    (outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
340                    "add.b\t{$src2, $dst}",
341                    [(set GR8:$dst, (add GR8:$src1, (load addr:$src2))),
342                     (implicit SRW)]>;
343 def ADD16rm : I16rm<0x0,
344                     (outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
345                     "add.w\t{$src2, $dst}",
346                     [(set GR16:$dst, (add GR16:$src1, (load addr:$src2))),
347                      (implicit SRW)]>;
348
349 let mayLoad = 1, hasExtraDefRegAllocReq = 1, 
350 Constraints = "$base = $base_wb, $src1 = $dst" in {
351 def ADD8rm_POST : IForm8<0x0, DstReg, SrcPostInc, Size2Bytes,
352                          (outs GR8:$dst, GR16:$base_wb),
353                          (ins GR8:$src1, GR16:$base),
354                          "add.b\t{@$base+, $dst}", []>;
355 def ADD16rm_POST : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes,
356                            (outs GR16:$dst, GR16:$base_wb),
357                            (ins GR16:$src1, GR16:$base),
358                           "add.w\t{@$base+, $dst}", []>;
359 }
360
361
362 def ADD8ri  : I8ri<0x0,
363                    (outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
364                    "add.b\t{$src2, $dst}",
365                    [(set GR8:$dst, (add GR8:$src1, imm:$src2)),
366                     (implicit SRW)]>;
367 def ADD16ri : I16ri<0x0,
368                     (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
369                     "add.w\t{$src2, $dst}",
370                     [(set GR16:$dst, (add GR16:$src1, imm:$src2)),
371                      (implicit SRW)]>;
372
373 let isTwoAddress = 0 in {
374 def ADD8mr  : I8mr<0x0,
375                    (outs), (ins memdst:$dst, GR8:$src),
376                    "add.b\t{$src, $dst}",
377                    [(store (add (load addr:$dst), GR8:$src), addr:$dst),
378                     (implicit SRW)]>;
379 def ADD16mr : I16mr<0x0,
380                     (outs), (ins memdst:$dst, GR16:$src),
381                     "add.w\t{$src, $dst}",
382                     [(store (add (load addr:$dst), GR16:$src), addr:$dst),
383                      (implicit SRW)]>;
384
385 def ADD8mi  : I8mi<0x0,
386                    (outs), (ins memdst:$dst, i8imm:$src),
387                    "add.b\t{$src, $dst}",
388                    [(store (add (load addr:$dst), (i8 imm:$src)), addr:$dst),
389                     (implicit SRW)]>;
390 def ADD16mi : I16mi<0x0,
391                     (outs), (ins memdst:$dst, i16imm:$src),
392                     "add.w\t{$src, $dst}",
393                     [(store (add (load addr:$dst), (i16 imm:$src)), addr:$dst),
394                      (implicit SRW)]>;
395
396 def ADD8mm  : I8mm<0x0,
397                    (outs), (ins memdst:$dst, memsrc:$src),
398                    "add.b\t{$src, $dst}",
399                    [(store (add (load addr:$dst), 
400                                 (i8 (load addr:$src))), addr:$dst),
401                     (implicit SRW)]>;
402 def ADD16mm : I16mm<0x0,
403                     (outs), (ins memdst:$dst, memsrc:$src),
404                     "add.w\t{$src, $dst}",
405                     [(store (add (load addr:$dst), 
406                                   (i16 (load addr:$src))), addr:$dst),
407                      (implicit SRW)]>;
408 }
409
410 let Uses = [SRW] in {
411
412 let isCommutable = 1 in { // X = ADDC Y, Z  == X = ADDC Z, Y
413 def ADC8rr  : I8rr<0x0,
414                    (outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
415                    "addc.b\t{$src2, $dst}",
416                    [(set GR8:$dst, (adde GR8:$src1, GR8:$src2)),
417                     (implicit SRW)]>;
418 def ADC16rr : I16rr<0x0,
419                     (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
420                     "addc.w\t{$src2, $dst}",
421                     [(set GR16:$dst, (adde GR16:$src1, GR16:$src2)),
422                      (implicit SRW)]>;
423 } // isCommutable
424
425 def ADC8ri  : I8ri<0x0,
426                    (outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
427                    "addc.b\t{$src2, $dst}",
428                    [(set GR8:$dst, (adde GR8:$src1, imm:$src2)),
429                     (implicit SRW)]>;
430 def ADC16ri : I16ri<0x0,
431                     (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
432                     "addc.w\t{$src2, $dst}",
433                     [(set GR16:$dst, (adde GR16:$src1, imm:$src2)),
434                      (implicit SRW)]>;
435
436 def ADC8rm  : I8rm<0x0,
437                    (outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
438                    "addc.b\t{$src2, $dst}",
439                    [(set GR8:$dst, (adde GR8:$src1, (load addr:$src2))),
440                     (implicit SRW)]>;
441 def ADC16rm : I16rm<0x0,
442                     (outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
443                     "addc.w\t{$src2, $dst}",
444                     [(set GR16:$dst, (adde GR16:$src1, (load addr:$src2))),
445                      (implicit SRW)]>;
446
447 let isTwoAddress = 0 in {
448 def ADC8mr  : I8mr<0x0,
449                    (outs), (ins memdst:$dst, GR8:$src),
450                    "addc.b\t{$src, $dst}",
451                    [(store (adde (load addr:$dst), GR8:$src), addr:$dst),
452                     (implicit SRW)]>;
453 def ADC16mr : I16mr<0x0,
454                     (outs), (ins memdst:$dst, GR16:$src),
455                     "addc.w\t{$src, $dst}",
456                     [(store (adde (load addr:$dst), GR16:$src), addr:$dst),
457                      (implicit SRW)]>;
458
459 def ADC8mi  : I8mi<0x0,
460                    (outs), (ins memdst:$dst, i8imm:$src),
461                    "addc.b\t{$src, $dst}",
462                    [(store (adde (load addr:$dst), (i8 imm:$src)), addr:$dst),
463                     (implicit SRW)]>;
464 def ADC16mi : I16mi<0x0,
465                     (outs), (ins memdst:$dst, i16imm:$src),
466                     "addc.w\t{$src, $dst}",
467                     [(store (adde (load addr:$dst), (i16 imm:$src)), addr:$dst),
468                      (implicit SRW)]>;
469
470 def ADC8mm  : I8mm<0x0,
471                    (outs), (ins memdst:$dst, memsrc:$src),
472                    "addc.b\t{$src, $dst}",
473                    [(store (adde (load addr:$dst), 
474                                  (i8 (load addr:$src))), addr:$dst),
475                     (implicit SRW)]>;
476 def ADC16mm : I8mm<0x0,
477                    (outs), (ins memdst:$dst, memsrc:$src),
478                    "addc.w\t{$src, $dst}",
479                    [(store (adde (load addr:$dst), 
480                                  (i16 (load addr:$src))), addr:$dst),
481                     (implicit SRW)]>;
482 }
483
484 } // Uses = [SRW]
485
486 let isCommutable = 1 in { // X = AND Y, Z  == X = AND Z, Y
487 def AND8rr  : I8rr<0x0,
488                    (outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
489                    "and.b\t{$src2, $dst}",
490                    [(set GR8:$dst, (and GR8:$src1, GR8:$src2)),
491                     (implicit SRW)]>;
492 def AND16rr : I16rr<0x0,
493                     (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
494                     "and.w\t{$src2, $dst}",
495                     [(set GR16:$dst, (and GR16:$src1, GR16:$src2)),
496                      (implicit SRW)]>;
497 }
498
499 def AND8ri  : I8ri<0x0,
500                    (outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
501                    "and.b\t{$src2, $dst}",
502                    [(set GR8:$dst, (and GR8:$src1, imm:$src2)),
503                     (implicit SRW)]>;
504 def AND16ri : I16ri<0x0,
505                     (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
506                     "and.w\t{$src2, $dst}",
507                     [(set GR16:$dst, (and GR16:$src1, imm:$src2)),
508                      (implicit SRW)]>;
509
510 def AND8rm  : I8rm<0x0,
511                    (outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
512                    "and.b\t{$src2, $dst}",
513                    [(set GR8:$dst, (and GR8:$src1, (load addr:$src2))),
514                     (implicit SRW)]>;
515 def AND16rm : I16rm<0x0,
516                     (outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
517                     "and.w\t{$src2, $dst}",
518                     [(set GR16:$dst, (and GR16:$src1, (load addr:$src2))),
519                      (implicit SRW)]>;
520
521 let mayLoad = 1, hasExtraDefRegAllocReq = 1, 
522 Constraints = "$base = $base_wb, $src1 = $dst" in {
523 def AND8rm_POST : IForm8<0x0, DstReg, SrcPostInc, Size2Bytes,
524                          (outs GR8:$dst, GR16:$base_wb),
525                          (ins GR8:$src1, GR16:$base),
526                          "and.b\t{@$base+, $dst}", []>;
527 def AND16rm_POST : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes,
528                            (outs GR16:$dst, GR16:$base_wb),
529                            (ins GR16:$src1, GR16:$base),
530                            "and.w\t{@$base+, $dst}", []>;
531 }
532
533 let isTwoAddress = 0 in {
534 def AND8mr  : I8mr<0x0,
535                    (outs), (ins memdst:$dst, GR8:$src),
536                    "and.b\t{$src, $dst}",
537                    [(store (and (load addr:$dst), GR8:$src), addr:$dst),
538                     (implicit SRW)]>;
539 def AND16mr : I16mr<0x0,
540                     (outs), (ins memdst:$dst, GR16:$src),
541                     "and.w\t{$src, $dst}",
542                     [(store (and (load addr:$dst), GR16:$src), addr:$dst),
543                      (implicit SRW)]>;
544
545 def AND8mi  : I8mi<0x0,
546                    (outs), (ins memdst:$dst, i8imm:$src),
547                    "and.b\t{$src, $dst}",
548                    [(store (and (load addr:$dst), (i8 imm:$src)), addr:$dst),
549                     (implicit SRW)]>;
550 def AND16mi : I16mi<0x0,
551                     (outs), (ins memdst:$dst, i16imm:$src),
552                     "and.w\t{$src, $dst}",
553                     [(store (and (load addr:$dst), (i16 imm:$src)), addr:$dst),
554                      (implicit SRW)]>;
555
556 def AND8mm  : I8mm<0x0,
557                    (outs), (ins memdst:$dst, memsrc:$src),
558                    "and.b\t{$src, $dst}",
559                    [(store (and (load addr:$dst), 
560                                 (i8 (load addr:$src))), addr:$dst),
561                     (implicit SRW)]>;
562 def AND16mm : I16mm<0x0,
563                     (outs), (ins memdst:$dst, memsrc:$src),
564                     "and.w\t{$src, $dst}",
565                     [(store (and (load addr:$dst), 
566                                  (i16 (load addr:$src))), addr:$dst),
567                      (implicit SRW)]>;
568 }
569
570 let isCommutable = 1 in { // X = OR Y, Z  == X = OR Z, Y
571 def OR8rr  : I8rr<0x0,
572                   (outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
573                   "bis.b\t{$src2, $dst}",
574                   [(set GR8:$dst, (or GR8:$src1, GR8:$src2))]>;
575 def OR16rr : I16rr<0x0,
576                    (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
577                    "bis.w\t{$src2, $dst}",
578                    [(set GR16:$dst, (or GR16:$src1, GR16:$src2))]>;
579 }
580
581 def OR8ri  : I8ri<0x0,
582                   (outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
583                   "bis.b\t{$src2, $dst}",
584                   [(set GR8:$dst, (or GR8:$src1, imm:$src2))]>;
585 def OR16ri : I16ri<0x0,
586                    (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
587                    "bis.w\t{$src2, $dst}",
588                    [(set GR16:$dst, (or GR16:$src1, imm:$src2))]>;
589
590 def OR8rm  : I8rm<0x0,
591                   (outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
592                   "bis.b\t{$src2, $dst}",
593                   [(set GR8:$dst, (or GR8:$src1, (load addr:$src2)))]>;
594 def OR16rm : I16rm<0x0,
595                    (outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
596                    "bis.w\t{$src2, $dst}",
597                    [(set GR16:$dst, (or GR16:$src1, (load addr:$src2)))]>;
598
599 let mayLoad = 1, hasExtraDefRegAllocReq = 1, 
600 Constraints = "$base = $base_wb, $src1 = $dst" in {
601 def OR8rm_POST : IForm8<0x0, DstReg, SrcPostInc, Size2Bytes,
602                         (outs GR8:$dst, GR16:$base_wb),
603                         (ins GR8:$src1, GR16:$base),
604                         "bis.b\t{@$base+, $dst}", []>;
605 def OR16rm_POST : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes,
606                           (outs GR16:$dst, GR16:$base_wb),
607                           (ins GR16:$src1, GR16:$base),
608                           "bis.w\t{@$base+, $dst}", []>;
609 }
610
611 let isTwoAddress = 0 in {
612 def OR8mr  : I8mr<0x0,
613                   (outs), (ins memdst:$dst, GR8:$src),
614                   "bis.b\t{$src, $dst}",
615                   [(store (or (load addr:$dst), GR8:$src), addr:$dst)]>;
616 def OR16mr : I16mr<0x0,
617                    (outs), (ins memdst:$dst, GR16:$src),
618                    "bis.w\t{$src, $dst}",
619                    [(store (or (load addr:$dst), GR16:$src), addr:$dst)]>;
620
621 def OR8mi  : I8mi<0x0, 
622                   (outs), (ins memdst:$dst, i8imm:$src),
623                   "bis.b\t{$src, $dst}",
624                   [(store (or (load addr:$dst), (i8 imm:$src)), addr:$dst)]>;
625 def OR16mi : I16mi<0x0,
626                    (outs), (ins memdst:$dst, i16imm:$src),
627                    "bis.w\t{$src, $dst}",
628                    [(store (or (load addr:$dst), (i16 imm:$src)), addr:$dst)]>;
629
630 def OR8mm  : I8mm<0x0,
631                   (outs), (ins memdst:$dst, memsrc:$src),
632                   "bis.b\t{$src, $dst}",
633                   [(store (or (i8 (load addr:$dst)),
634                               (i8 (load addr:$src))), addr:$dst)]>;
635 def OR16mm : I16mm<0x0,
636                    (outs), (ins memdst:$dst, memsrc:$src),
637                    "bis.w\t{$src, $dst}",
638                    [(store (or (i16 (load addr:$dst)),
639                                (i16 (load addr:$src))), addr:$dst)]>;
640 }
641
642 // bic does not modify condition codes
643 def BIC8rr :  I8rr<0x0,
644                    (outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
645                    "bic.b\t{$src2, $dst}",
646                    [(set GR8:$dst, (and GR8:$src1, (not GR8:$src2)))]>;
647 def BIC16rr : I16rr<0x0,
648                     (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
649                     "bic.w\t{$src2, $dst}",
650                     [(set GR16:$dst, (and GR16:$src1, (not GR16:$src2)))]>;
651
652 def BIC8rm :  I8rm<0x0,
653                    (outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
654                    "bic.b\t{$src2, $dst}",
655                     [(set GR8:$dst, (and GR8:$src1, (not (i8 (load addr:$src2)))))]>;
656 def BIC16rm : I16rm<0x0,
657                     (outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
658                     "bic.w\t{$src2, $dst}",
659                     [(set GR16:$dst, (and GR16:$src1, (not (i16 (load addr:$src2)))))]>;
660
661 let isTwoAddress = 0 in {
662 def BIC8mr :  I8mr<0x0,
663                    (outs), (ins memdst:$dst, GR8:$src),
664                    "bic.b\t{$src, $dst}",
665                    [(store (and (load addr:$dst), (not GR8:$src)), addr:$dst)]>;
666 def BIC16mr : I16mr<0x0,
667                     (outs), (ins memdst:$dst, GR16:$src),
668                     "bic.w\t{$src, $dst}",
669                     [(store (and (load addr:$dst), (not GR16:$src)), addr:$dst)]>;
670
671 def BIC8mm :  I8mm<0x0,
672                    (outs), (ins memdst:$dst, memsrc:$src),
673                    "bic.b\t{$src, $dst}",
674                    [(store (and (load addr:$dst),
675                                 (not (i8 (load addr:$src)))), addr:$dst)]>;
676 def BIC16mm : I16mm<0x0,
677                     (outs), (ins memdst:$dst, memsrc:$src),
678                     "bic.w\t{$src, $dst}",
679                     [(store (and (load addr:$dst),
680                                  (not (i16 (load addr:$src)))), addr:$dst)]>;
681 }
682
683 let isCommutable = 1 in { // X = XOR Y, Z  == X = XOR Z, Y
684 def XOR8rr  : I8rr<0x0,
685                    (outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
686                    "xor.b\t{$src2, $dst}",
687                    [(set GR8:$dst, (xor GR8:$src1, GR8:$src2)),
688                     (implicit SRW)]>;
689 def XOR16rr : I16rr<0x0,
690                     (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
691                     "xor.w\t{$src2, $dst}",
692                     [(set GR16:$dst, (xor GR16:$src1, GR16:$src2)),
693                      (implicit SRW)]>;
694 }
695
696 def XOR8ri  : I8ri<0x0,
697                    (outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
698                    "xor.b\t{$src2, $dst}",
699                    [(set GR8:$dst, (xor GR8:$src1, imm:$src2)),
700                     (implicit SRW)]>;
701 def XOR16ri : I16ri<0x0,
702                     (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
703                     "xor.w\t{$src2, $dst}",
704                     [(set GR16:$dst, (xor GR16:$src1, imm:$src2)),
705                      (implicit SRW)]>;
706
707 def XOR8rm  : I8rm<0x0,
708                    (outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
709                    "xor.b\t{$src2, $dst}",
710                    [(set GR8:$dst, (xor GR8:$src1, (load addr:$src2))),
711                     (implicit SRW)]>;
712 def XOR16rm : I16rm<0x0,
713                     (outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
714                     "xor.w\t{$src2, $dst}",
715                     [(set GR16:$dst, (xor GR16:$src1, (load addr:$src2))),
716                      (implicit SRW)]>;
717
718 let mayLoad = 1, hasExtraDefRegAllocReq = 1, 
719 Constraints = "$base = $base_wb, $src1 = $dst" in {
720 def XOR8rm_POST : IForm8<0x0, DstReg, SrcPostInc, Size2Bytes,
721                          (outs GR8:$dst, GR16:$base_wb),
722                          (ins GR8:$src1, GR16:$base),
723                          "xor.b\t{@$base+, $dst}", []>;
724 def XOR16rm_POST : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes,
725                            (outs GR16:$dst, GR16:$base_wb),
726                            (ins GR16:$src1, GR16:$base),
727                            "xor.w\t{@$base+, $dst}", []>;
728 }
729
730 let isTwoAddress = 0 in {
731 def XOR8mr  : I8mr<0x0,
732                    (outs), (ins memdst:$dst, GR8:$src),
733                    "xor.b\t{$src, $dst}",
734                    [(store (xor (load addr:$dst), GR8:$src), addr:$dst),
735                     (implicit SRW)]>;
736 def XOR16mr : I16mr<0x0,
737                     (outs), (ins memdst:$dst, GR16:$src),
738                     "xor.w\t{$src, $dst}",
739                     [(store (xor (load addr:$dst), GR16:$src), addr:$dst),
740                      (implicit SRW)]>;
741
742 def XOR8mi  : I8mi<0x0,
743                    (outs), (ins memdst:$dst, i8imm:$src),
744                    "xor.b\t{$src, $dst}",
745                    [(store (xor (load addr:$dst), (i8 imm:$src)), addr:$dst),
746                     (implicit SRW)]>;
747 def XOR16mi : I16mi<0x0,
748                     (outs), (ins memdst:$dst, i16imm:$src),
749                     "xor.w\t{$src, $dst}",
750                     [(store (xor (load addr:$dst), (i16 imm:$src)), addr:$dst),
751                      (implicit SRW)]>;
752
753 def XOR8mm  : I8mm<0x0,
754                    (outs), (ins memdst:$dst, memsrc:$src),
755                    "xor.b\t{$src, $dst}",
756                    [(store (xor (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
757                     (implicit SRW)]>;
758 def XOR16mm : I16mm<0x0,
759                     (outs), (ins memdst:$dst, memsrc:$src),
760                     "xor.w\t{$src, $dst}",
761                     [(store (xor (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
762                      (implicit SRW)]>;
763 }
764
765
766 def SUB8rr  : I8rr<0x0,
767                    (outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
768                    "sub.b\t{$src2, $dst}",
769                    [(set GR8:$dst, (sub GR8:$src1, GR8:$src2)),
770                     (implicit SRW)]>;
771 def SUB16rr : I16rr<0x0,
772                     (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
773                     "sub.w\t{$src2, $dst}",
774                     [(set GR16:$dst, (sub GR16:$src1, GR16:$src2)),
775                      (implicit SRW)]>;
776
777 def SUB8ri  : I8ri<0x0,
778                    (outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
779                    "sub.b\t{$src2, $dst}",
780                    [(set GR8:$dst, (sub GR8:$src1, imm:$src2)),
781                     (implicit SRW)]>;
782 def SUB16ri : I16ri<0x0,
783                     (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
784                     "sub.w\t{$src2, $dst}",
785                     [(set GR16:$dst, (sub GR16:$src1, imm:$src2)),
786                      (implicit SRW)]>;
787
788 def SUB8rm  : I8rm<0x0,
789                    (outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
790                    "sub.b\t{$src2, $dst}",
791                    [(set GR8:$dst, (sub GR8:$src1, (load addr:$src2))),
792                     (implicit SRW)]>;
793 def SUB16rm : I16rm<0x0,
794                     (outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
795                     "sub.w\t{$src2, $dst}",
796                     [(set GR16:$dst, (sub GR16:$src1, (load addr:$src2))),
797                      (implicit SRW)]>;
798
799 let mayLoad = 1, hasExtraDefRegAllocReq = 1, 
800 Constraints = "$base = $base_wb, $src1 = $dst" in {
801 def SUB8rm_POST : IForm8<0x0, DstReg, SrcPostInc, Size2Bytes,
802                          (outs GR8:$dst, GR16:$base_wb),
803                          (ins GR8:$src1, GR16:$base),
804                          "sub.b\t{@$base+, $dst}", []>;
805 def SUB16rm_POST : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes,
806                           (outs GR16:$dst, GR16:$base_wb),
807                           (ins GR16:$src1, GR16:$base),
808                           "sub.w\t{@$base+, $dst}", []>;
809 }
810
811 let isTwoAddress = 0 in {
812 def SUB8mr  : I8mr<0x0,
813                    (outs), (ins memdst:$dst, GR8:$src),
814                    "sub.b\t{$src, $dst}",
815                    [(store (sub (load addr:$dst), GR8:$src), addr:$dst),
816                     (implicit SRW)]>;
817 def SUB16mr : I16mr<0x0,
818                     (outs), (ins memdst:$dst, GR16:$src),
819                     "sub.w\t{$src, $dst}",
820                     [(store (sub (load addr:$dst), GR16:$src), addr:$dst),
821                      (implicit SRW)]>;
822
823 def SUB8mi  : I8mi<0x0,
824                    (outs), (ins memdst:$dst, i8imm:$src),
825                    "sub.b\t{$src, $dst}",
826                    [(store (sub (load addr:$dst), (i8 imm:$src)), addr:$dst),
827                     (implicit SRW)]>;
828 def SUB16mi : I16mi<0x0,
829                     (outs), (ins memdst:$dst, i16imm:$src),
830                     "sub.w\t{$src, $dst}",
831                     [(store (sub (load addr:$dst), (i16 imm:$src)), addr:$dst),
832                      (implicit SRW)]>;
833
834 def SUB8mm  : I8mm<0x0,
835                    (outs), (ins memdst:$dst, memsrc:$src),
836                    "sub.b\t{$src, $dst}",
837                    [(store (sub (load addr:$dst), 
838                                 (i8 (load addr:$src))), addr:$dst),
839                     (implicit SRW)]>;
840 def SUB16mm : I16mm<0x0,
841                     (outs), (ins memdst:$dst, memsrc:$src),
842                     "sub.w\t{$src, $dst}",
843                     [(store (sub (load addr:$dst), 
844                                  (i16 (load addr:$src))), addr:$dst),
845                      (implicit SRW)]>;
846 }
847
848 let Uses = [SRW] in {
849 def SBC8rr  : I8rr<0x0,
850                    (outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
851                    "subc.b\t{$src2, $dst}",
852                    [(set GR8:$dst, (sube GR8:$src1, GR8:$src2)),
853                     (implicit SRW)]>;
854 def SBC16rr : I16rr<0x0,
855                     (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
856                     "subc.w\t{$src2, $dst}",
857                     [(set GR16:$dst, (sube GR16:$src1, GR16:$src2)),
858                      (implicit SRW)]>;
859
860 def SBC8ri  : I8ri<0x0,
861                    (outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
862                    "subc.b\t{$src2, $dst}",
863                    [(set GR8:$dst, (sube GR8:$src1, imm:$src2)),
864                     (implicit SRW)]>;
865 def SBC16ri : I16ri<0x0,
866                     (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
867                     "subc.w\t{$src2, $dst}",
868                     [(set GR16:$dst, (sube GR16:$src1, imm:$src2)),
869                      (implicit SRW)]>;
870
871 def SBC8rm  : I8rm<0x0,
872                    (outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
873                    "subc.b\t{$src2, $dst}",
874                    [(set GR8:$dst, (sube GR8:$src1, (load addr:$src2))),
875                     (implicit SRW)]>;
876 def SBC16rm : I16rm<0x0,
877                     (outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
878                     "subc.w\t{$src2, $dst}",
879                     [(set GR16:$dst, (sube GR16:$src1, (load addr:$src2))),
880                      (implicit SRW)]>;
881
882 let isTwoAddress = 0 in {
883 def SBC8mr  : I8mr<0x0,
884                    (outs), (ins memdst:$dst, GR8:$src),
885                    "subc.b\t{$src, $dst}",
886                   [(store (sube (load addr:$dst), GR8:$src), addr:$dst),
887                    (implicit SRW)]>;
888 def SBC16mr : I16mr<0x0,
889                     (outs), (ins memdst:$dst, GR16:$src),
890                     "subc.w\t{$src, $dst}",
891                     [(store (sube (load addr:$dst), GR16:$src), addr:$dst),
892                      (implicit SRW)]>;
893
894 def SBC8mi  : I8mi<0x0,
895                    (outs), (ins memdst:$dst, i8imm:$src),
896                    "subc.b\t{$src, $dst}",
897                    [(store (sube (load addr:$dst), (i8 imm:$src)), addr:$dst),
898                     (implicit SRW)]>;
899 def SBC16mi : I16mi<0x0,
900                     (outs), (ins memdst:$dst, i16imm:$src),
901                     "subc.w\t{$src, $dst}",
902                     [(store (sube (load addr:$dst), (i16 imm:$src)), addr:$dst),
903                      (implicit SRW)]>;
904
905 def SBC8mm  : I8mm<0x0,
906                    (outs), (ins memdst:$dst, memsrc:$src),
907                    "subc.b\t{$src, $dst}",
908                    [(store (sube (load addr:$dst),
909                                  (i8 (load addr:$src))), addr:$dst),
910                     (implicit SRW)]>;
911 def SBC16mm : I16mm<0x0,
912                     (outs), (ins memdst:$dst, memsrc:$src),
913                     "subc.w\t{$src, $dst}",
914                     [(store (sube (load addr:$dst),
915                             (i16 (load addr:$src))), addr:$dst),
916                      (implicit SRW)]>;
917 }
918
919 } // Uses = [SRW]
920
921 // FIXME: memory variant!
922 def SAR8r1  : II8r<0x0,
923                    (outs GR8:$dst), (ins GR8:$src),
924                    "rra.b\t$dst",
925                    [(set GR8:$dst, (MSP430rra GR8:$src)),
926                     (implicit SRW)]>;
927 def SAR16r1 : II16r<0x0,
928                     (outs GR16:$dst), (ins GR16:$src),
929                     "rra.w\t$dst",
930                     [(set GR16:$dst, (MSP430rra GR16:$src)),
931                      (implicit SRW)]>;
932
933 def SHL8r1  : I8rr<0x0,
934                    (outs GR8:$dst), (ins GR8:$src),
935                    "rla.b\t$dst",
936                    [(set GR8:$dst, (MSP430rla GR8:$src)),
937                     (implicit SRW)]>;
938 def SHL16r1 : I16rr<0x0,
939                     (outs GR16:$dst), (ins GR16:$src),
940                     "rla.w\t$dst",
941                     [(set GR16:$dst, (MSP430rla GR16:$src)),
942                      (implicit SRW)]>;
943
944 def SAR8r1c  : Pseudo<(outs GR8:$dst), (ins GR8:$src),
945                       "clrc\n\t"
946                       "rrc.b\t$dst",
947                       [(set GR8:$dst, (MSP430rrc GR8:$src)),
948                        (implicit SRW)]>;
949 def SAR16r1c : Pseudo<(outs GR16:$dst), (ins GR16:$src),
950                       "clrc\n\t"
951                       "rrc.w\t$dst",
952                       [(set GR16:$dst, (MSP430rrc GR16:$src)),
953                        (implicit SRW)]>;
954
955 // FIXME: Memory sext's ?
956 def SEXT16r : II16r<0x0,
957                     (outs GR16:$dst), (ins GR16:$src),
958                     "sxt\t$dst",
959                     [(set GR16:$dst, (sext_inreg GR16:$src, i8)),
960                      (implicit SRW)]>;
961
962 } // Defs = [SRW]
963
964 def ZEXT16r : I8rr<0x0,
965                    (outs GR16:$dst), (ins GR16:$src),
966                    "mov.b\t{$src, $dst}",
967                    [(set GR16:$dst, (zext (trunc GR16:$src)))]>;
968
969 // FIXME: Memory bitswaps?
970 def SWPB16r : II16r<0x0,
971                     (outs GR16:$dst), (ins GR16:$src),
972                     "swpb\t$dst",
973                     [(set GR16:$dst, (bswap GR16:$src))]>;
974
975 } // isTwoAddress = 1
976
977 // Integer comparisons
978 let Defs = [SRW] in {
979 def CMP8rr  : I8rr<0x0,
980                    (outs), (ins GR8:$src1, GR8:$src2),
981                    "cmp.b\t{$src2, $src1}",
982                    [(MSP430cmp GR8:$src1, GR8:$src2), (implicit SRW)]>;
983 def CMP16rr : I16rr<0x0,
984                     (outs), (ins GR16:$src1, GR16:$src2),
985                     "cmp.w\t{$src2, $src1}",
986                     [(MSP430cmp GR16:$src1, GR16:$src2), (implicit SRW)]>;
987
988 def CMP8ri  : I8ri<0x0,
989                    (outs), (ins GR8:$src1, i8imm:$src2),
990                    "cmp.b\t{$src2, $src1}",
991                    [(MSP430cmp GR8:$src1, imm:$src2), (implicit SRW)]>;
992 def CMP16ri : I16ri<0x0,
993                     (outs), (ins GR16:$src1, i16imm:$src2),
994                     "cmp.w\t{$src2, $src1}",
995                     [(MSP430cmp GR16:$src1, imm:$src2), (implicit SRW)]>;
996
997 def CMP8mi  : I8mi<0x0,
998                    (outs), (ins memsrc:$src1, i8imm:$src2),
999                    "cmp.b\t{$src2, $src1}",
1000                    [(MSP430cmp (load addr:$src1),
1001                                (i8 imm:$src2)), (implicit SRW)]>;
1002 def CMP16mi : I16mi<0x0,
1003                     (outs), (ins memsrc:$src1, i16imm:$src2),
1004                     "cmp.w\t{$src2, $src1}",
1005                      [(MSP430cmp (load addr:$src1),
1006                                  (i16 imm:$src2)), (implicit SRW)]>;
1007
1008 def CMP8rm  : I8rm<0x0,
1009                    (outs), (ins GR8:$src1, memsrc:$src2),
1010                    "cmp.b\t{$src2, $src1}",
1011                    [(MSP430cmp GR8:$src1, (load addr:$src2)), 
1012                     (implicit SRW)]>;
1013 def CMP16rm : I16rm<0x0,
1014                     (outs), (ins GR16:$src1, memsrc:$src2),
1015                     "cmp.w\t{$src2, $src1}",
1016                     [(MSP430cmp GR16:$src1, (load addr:$src2)),
1017                      (implicit SRW)]>;
1018
1019 def CMP8mr  : I8mr<0x0,
1020                    (outs), (ins memsrc:$src1, GR8:$src2),
1021                    "cmp.b\t{$src2, $src1}",
1022                    [(MSP430cmp (load addr:$src1), GR8:$src2),
1023                     (implicit SRW)]>;
1024 def CMP16mr : I16mr<0x0,
1025                     (outs), (ins memsrc:$src1, GR16:$src2),
1026                     "cmp.w\t{$src2, $src1}",
1027                     [(MSP430cmp (load addr:$src1), GR16:$src2), 
1028                      (implicit SRW)]>;
1029
1030
1031 // BIT TESTS, just sets condition codes
1032 // Note that the C condition is set differently than when using CMP.
1033 let isCommutable = 1 in {
1034 def BIT8rr  : I8rr<0x0,
1035                    (outs), (ins GR8:$src1, GR8:$src2),
1036                    "bit.b\t{$src2, $src1}",
1037                    [(MSP430cmp (and_su GR8:$src1, GR8:$src2), 0),
1038                     (implicit SRW)]>;
1039 def BIT16rr : I16rr<0x0,
1040                     (outs), (ins GR16:$src1, GR16:$src2),
1041                     "bit.w\t{$src2, $src1}",
1042                     [(MSP430cmp (and_su GR16:$src1, GR16:$src2), 0),
1043                      (implicit SRW)]>;
1044 }
1045 def BIT8ri  : I8ri<0x0,
1046                    (outs), (ins GR8:$src1, i8imm:$src2),
1047                    "bit.b\t{$src2, $src1}",
1048                    [(MSP430cmp (and_su GR8:$src1, imm:$src2), 0),
1049                     (implicit SRW)]>;
1050 def BIT16ri : I16ri<0x0,
1051                     (outs), (ins GR16:$src1, i16imm:$src2),
1052                     "bit.w\t{$src2, $src1}",
1053                     [(MSP430cmp (and_su GR16:$src1, imm:$src2), 0),
1054                      (implicit SRW)]>;
1055
1056 def BIT8rm  : I8rm<0x0,
1057                    (outs), (ins GR8:$src1, memdst:$src2),
1058                    "bit.b\t{$src2, $src1}",
1059                    [(MSP430cmp (and_su GR8:$src1,  (load addr:$src2)), 0),
1060                     (implicit SRW)]>;
1061 def BIT16rm : I16rm<0x0,
1062                     (outs), (ins GR16:$src1, memdst:$src2),
1063                     "bit.w\t{$src2, $src1}",
1064                     [(MSP430cmp (and_su GR16:$src1,  (load addr:$src2)), 0),
1065                      (implicit SRW)]>;
1066
1067 def BIT8mr  : I8mr<0x0,
1068                   (outs), (ins memsrc:$src1, GR8:$src2),
1069                   "bit.b\t{$src2, $src1}",
1070                   [(MSP430cmp (and_su (load addr:$src1), GR8:$src2), 0),
1071                    (implicit SRW)]>;
1072 def BIT16mr : I16mr<0x0,
1073                     (outs), (ins memsrc:$src1, GR16:$src2),
1074                     "bit.w\t{$src2, $src1}",
1075                     [(MSP430cmp (and_su (load addr:$src1), GR16:$src2), 0),
1076                      (implicit SRW)]>;
1077
1078 def BIT8mi  : I8mi<0x0,
1079                    (outs), (ins memsrc:$src1, i8imm:$src2),
1080                    "bit.b\t{$src2, $src1}",
1081                    [(MSP430cmp (and_su (load addr:$src1), (i8 imm:$src2)), 0),
1082                     (implicit SRW)]>;
1083 def BIT16mi : I16mi<0x0,
1084                     (outs), (ins memsrc:$src1, i16imm:$src2),
1085                     "bit.w\t{$src2, $src1}",
1086                     [(MSP430cmp (and_su (load addr:$src1), (i16 imm:$src2)), 0),
1087                      (implicit SRW)]>;
1088
1089 def BIT8mm  : I8mm<0x0,
1090                    (outs), (ins memsrc:$src1, memsrc:$src2),
1091                    "bit.b\t{$src2, $src1}",
1092                    [(MSP430cmp (and_su (i8 (load addr:$src1)),
1093                                        (load addr:$src2)),
1094                                  0),
1095                       (implicit SRW)]>;
1096 def BIT16mm : I16mm<0x0,
1097                     (outs), (ins memsrc:$src1, memsrc:$src2),
1098                     "bit.w\t{$src2, $src1}",
1099                     [(MSP430cmp (and_su (i16 (load addr:$src1)),
1100                                         (load addr:$src2)),
1101                                  0),
1102                      (implicit SRW)]>;
1103 } // Defs = [SRW]
1104
1105 //===----------------------------------------------------------------------===//
1106 // Non-Instruction Patterns
1107
1108 // extload
1109 def : Pat<(extloadi16i8 addr:$src), (MOVZX16rm8 addr:$src)>;
1110
1111 // anyext
1112 def : Pat<(i16 (anyext GR8:$src)),
1113           (SUBREG_TO_REG (i16 0), GR8:$src, subreg_8bit)>;
1114
1115 // truncs
1116 def : Pat<(i8 (trunc GR16:$src)),
1117           (EXTRACT_SUBREG GR16:$src, subreg_8bit)>;
1118
1119 // GlobalAddress, ExternalSymbol
1120 def : Pat<(i16 (MSP430Wrapper tglobaladdr:$dst)), (MOV16ri tglobaladdr:$dst)>;
1121 def : Pat<(i16 (MSP430Wrapper texternalsym:$dst)), (MOV16ri texternalsym:$dst)>;
1122
1123 def : Pat<(add GR16:$src1, (MSP430Wrapper tglobaladdr :$src2)),
1124           (ADD16ri GR16:$src1, tglobaladdr:$src2)>;
1125 def : Pat<(add GR16:$src1, (MSP430Wrapper texternalsym:$src2)),
1126           (ADD16ri GR16:$src1, texternalsym:$src2)>;
1127
1128 def : Pat<(store (i16 (MSP430Wrapper tglobaladdr:$src)), addr:$dst),
1129           (MOV16mi addr:$dst, tglobaladdr:$src)>;
1130 def : Pat<(store (i16 (MSP430Wrapper texternalsym:$src)), addr:$dst),
1131           (MOV16mi addr:$dst, texternalsym:$src)>;
1132
1133 // calls
1134 def : Pat<(MSP430call (i16 tglobaladdr:$dst)),
1135           (CALLi tglobaladdr:$dst)>;
1136 def : Pat<(MSP430call (i16 texternalsym:$dst)),
1137           (CALLi texternalsym:$dst)>;
1138
1139 // add and sub always produce carry
1140 def : Pat<(addc GR16:$src1, GR16:$src2),
1141           (ADD16rr GR16:$src1, GR16:$src2)>;
1142 def : Pat<(addc GR16:$src1, (load addr:$src2)),
1143           (ADD16rm GR16:$src1, addr:$src2)>;
1144 def : Pat<(addc GR16:$src1, imm:$src2),
1145           (ADD16ri GR16:$src1, imm:$src2)>;
1146 def : Pat<(store (addc (load addr:$dst), GR16:$src), addr:$dst),
1147           (ADD16mr addr:$dst, GR16:$src)>;
1148 def : Pat<(store (addc (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
1149           (ADD16mm addr:$dst, addr:$src)>;
1150
1151 def : Pat<(addc GR8:$src1, GR8:$src2),
1152           (ADD8rr GR8:$src1, GR8:$src2)>;
1153 def : Pat<(addc GR8:$src1, (load addr:$src2)),
1154           (ADD8rm GR8:$src1, addr:$src2)>;
1155 def : Pat<(addc GR8:$src1, imm:$src2),
1156           (ADD8ri GR8:$src1, imm:$src2)>;
1157 def : Pat<(store (addc (load addr:$dst), GR8:$src), addr:$dst),
1158           (ADD8mr addr:$dst, GR8:$src)>;
1159 def : Pat<(store (addc (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
1160           (ADD8mm addr:$dst, addr:$src)>;
1161
1162 def : Pat<(subc GR16:$src1, GR16:$src2),
1163           (SUB16rr GR16:$src1, GR16:$src2)>;
1164 def : Pat<(subc GR16:$src1, (load addr:$src2)),
1165           (SUB16rm GR16:$src1, addr:$src2)>;
1166 def : Pat<(subc GR16:$src1, imm:$src2),
1167           (SUB16ri GR16:$src1, imm:$src2)>;
1168 def : Pat<(store (subc (load addr:$dst), GR16:$src), addr:$dst),
1169           (SUB16mr addr:$dst, GR16:$src)>;
1170 def : Pat<(store (subc (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
1171           (SUB16mm addr:$dst, addr:$src)>;
1172
1173 def : Pat<(subc GR8:$src1, GR8:$src2),
1174           (SUB8rr GR8:$src1, GR8:$src2)>;
1175 def : Pat<(subc GR8:$src1, (load addr:$src2)),
1176           (SUB8rm GR8:$src1, addr:$src2)>;
1177 def : Pat<(subc GR8:$src1, imm:$src2),
1178           (SUB8ri GR8:$src1, imm:$src2)>;
1179 def : Pat<(store (subc (load addr:$dst), GR8:$src), addr:$dst),
1180           (SUB8mr addr:$dst, GR8:$src)>;
1181 def : Pat<(store (subc (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
1182           (SUB8mm addr:$dst, addr:$src)>;
1183
1184 // peephole patterns
1185 def : Pat<(and GR16:$src, 255), (ZEXT16r GR16:$src)>;
1186 def : Pat<(MSP430cmp (trunc (and_su GR16:$src1, GR16:$src2)), 0),
1187           (BIT8rr (EXTRACT_SUBREG GR16:$src1, subreg_8bit),
1188                   (EXTRACT_SUBREG GR16:$src2, subreg_8bit))>;