MSP430InstrInfo.td revision 05011a8aba3a4e8f011ac92990423947f8cbb15b
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_MSP430Cmp          : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
30def SDT_MSP430BrCC         : SDTypeProfile<0, 2, [SDTCisVT<0, OtherVT>,
31                                                  SDTCisVT<1, i8>]>;
32def SDT_MSP430SelectCC     : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, 
33                                                  SDTCisVT<3, i8>]>;
34def SDT_MSP430Shift        : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, SDTCisI8<2>]>;
35
36//===----------------------------------------------------------------------===//
37// MSP430 Specific Node Definitions.
38//===----------------------------------------------------------------------===//
39def MSP430retflag  : SDNode<"MSP430ISD::RET_FLAG", SDTNone,
40                       [SDNPHasChain, SDNPOptInFlag]>;
41def MSP430retiflag : SDNode<"MSP430ISD::RETI_FLAG", SDTNone,
42                       [SDNPHasChain, SDNPOptInFlag]>;
43
44def MSP430rra     : SDNode<"MSP430ISD::RRA", SDTIntUnaryOp, []>;
45def MSP430rla     : SDNode<"MSP430ISD::RLA", SDTIntUnaryOp, []>;
46def MSP430rrc     : SDNode<"MSP430ISD::RRC", SDTIntUnaryOp, []>;
47
48def MSP430call    : SDNode<"MSP430ISD::CALL", SDT_MSP430Call,
49                     [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag]>;
50def MSP430callseq_start :
51                 SDNode<"ISD::CALLSEQ_START", SDT_MSP430CallSeqStart,
52                        [SDNPHasChain, SDNPOutFlag]>;
53def MSP430callseq_end :
54                 SDNode<"ISD::CALLSEQ_END",   SDT_MSP430CallSeqEnd,
55                        [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
56def MSP430Wrapper : SDNode<"MSP430ISD::Wrapper", SDT_MSP430Wrapper>;
57def MSP430cmp     : SDNode<"MSP430ISD::CMP", SDT_MSP430Cmp, [SDNPOutFlag]>;
58def MSP430brcc    : SDNode<"MSP430ISD::BR_CC", SDT_MSP430BrCC, [SDNPHasChain, SDNPInFlag]>;
59def MSP430selectcc: SDNode<"MSP430ISD::SELECT_CC", SDT_MSP430SelectCC, [SDNPInFlag]>;
60def MSP430shl     : SDNode<"MSP430ISD::SHL", SDT_MSP430Shift, []>;
61def MSP430sra     : SDNode<"MSP430ISD::SRA", SDT_MSP430Shift, []>;
62def MSP430srl     : SDNode<"MSP430ISD::SRL", SDT_MSP430Shift, []>;
63
64//===----------------------------------------------------------------------===//
65// MSP430 Operand Definitions.
66//===----------------------------------------------------------------------===//
67
68// Address operands
69def memsrc : Operand<i16> {
70  let PrintMethod = "printSrcMemOperand";
71  let MIOperandInfo = (ops GR16, i16imm);
72}
73
74def memdst : Operand<i16> {
75  let PrintMethod = "printSrcMemOperand";
76  let MIOperandInfo = (ops GR16, i16imm);
77}
78
79// Branch targets have OtherVT type.
80def brtarget : Operand<OtherVT> {
81  let PrintMethod = "printPCRelImmOperand";
82}
83
84// Operand for printing out a condition code.
85def cc : Operand<i8> {
86  let PrintMethod = "printCCOperand";
87}
88
89//===----------------------------------------------------------------------===//
90// MSP430 Complex Pattern Definitions.
91//===----------------------------------------------------------------------===//
92
93def addr : ComplexPattern<iPTR, 2, "SelectAddr", [], []>;
94
95//===----------------------------------------------------------------------===//
96// Pattern Fragments
97def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>;
98def  extloadi16i8 : PatFrag<(ops node:$ptr), (i16 ( extloadi8 node:$ptr))>;
99def 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.
110let Defs = [SPW, SRW], Uses = [SPW] in {
111def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i16imm:$amt),
112                              "#ADJCALLSTACKDOWN",
113                              [(MSP430callseq_start timm:$amt)]>;
114def ADJCALLSTACKUP   : Pseudo<(outs), (ins i16imm:$amt1, i16imm:$amt2),
115                              "#ADJCALLSTACKUP",
116                              [(MSP430callseq_end timm:$amt1, timm:$amt2)]>;
117}
118
119let 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
151let neverHasSideEffects = 1 in
152def NOP : Pseudo<(outs), (ins), "nop", []>;
153
154//===----------------------------------------------------------------------===//
155//  Control Flow Instructions...
156//
157
158// FIXME: Provide proper encoding!
159let 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
165let isBranch = 1, isTerminator = 1 in {
166
167// FIXME: expand opcode & cond field for branches!
168
169// Direct branch
170let 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
177let 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//
187let 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//
209let Defs = [SPW], Uses = [SPW], neverHasSideEffects=1 in {
210let mayLoad = 1 in
211def POP16r   : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes,
212                       (outs GR16:$reg), (ins), "pop.w\t$reg", []>;
213
214let mayStore = 1 in
215def PUSH16r  : II16r<0x0,
216                     (outs), (ins GR16:$reg), "push.w\t$reg",[]>;
217}
218
219//===----------------------------------------------------------------------===//
220// Move Instructions
221
222// FIXME: Provide proper encoding!
223let neverHasSideEffects = 1 in {
224def MOV8rr  : I8rr<0x0,
225                   (outs GR8:$dst), (ins GR8:$src),
226                   "mov.b\t{$src, $dst}",
227                   []>;
228def MOV16rr : I16rr<0x0,
229                    (outs GR16:$dst), (ins GR16:$src),
230                    "mov.w\t{$src, $dst}",
231                    []>;
232}
233
234// FIXME: Provide proper encoding!
235let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
236def MOV8ri  : I8ri<0x0,
237                   (outs GR8:$dst), (ins i8imm:$src),
238                   "mov.b\t{$src, $dst}",
239                   [(set GR8:$dst, imm:$src)]>;
240def MOV16ri : I16ri<0x0,
241                    (outs GR16:$dst), (ins i16imm:$src),
242                    "mov.w\t{$src, $dst}",
243                    [(set GR16:$dst, imm:$src)]>;
244}
245
246let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in {
247def MOV8rm  : I8rm<0x0,
248                   (outs GR8:$dst), (ins memsrc:$src),
249                   "mov.b\t{$src, $dst}",
250                   [(set GR8:$dst, (load addr:$src))]>;
251def 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
257def MOVZX16rr8 : I8rr<0x0,
258                      (outs GR16:$dst), (ins GR8:$src),
259                      "mov.b\t{$src, $dst}",
260                      [(set GR16:$dst, (zext GR8:$src))]>;
261def MOVZX16rm8 : I8rm<0x0,
262                      (outs GR16:$dst), (ins memsrc:$src),
263                      "mov.b\t{$src, $dst}",
264                      [(set GR16:$dst, (zextloadi16i8 addr:$src))]>;
265
266let mayLoad = 1, hasExtraDefRegAllocReq = 1, Constraints = "$base = $base_wb" in {
267def MOV8rm_POST  : IForm8<0x0, DstReg, SrcPostInc, Size2Bytes,
268                         (outs GR8:$dst, GR16:$base_wb), (ins GR16:$base),
269                         "mov.b\t{@$base+, $dst}", []>;
270def 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.
279def 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.
287def : Pat<(i16 (zext def8:$src)),
288          (SUBREG_TO_REG (i16 0), GR8:$src, subreg_8bit)>;
289
290def MOV8mi  : I8mi<0x0,
291                   (outs), (ins memdst:$dst, i8imm:$src),
292                   "mov.b\t{$src, $dst}",
293                   [(store (i8 imm:$src), addr:$dst)]>;
294def MOV16mi : I16mi<0x0,
295                    (outs), (ins memdst:$dst, i16imm:$src),
296                    "mov.w\t{$src, $dst}",
297                    [(store (i16 imm:$src), addr:$dst)]>;
298
299def MOV8mr  : I8mr<0x0,
300                   (outs), (ins memdst:$dst, GR8:$src),
301                   "mov.b\t{$src, $dst}",
302                   [(store GR8:$src, addr:$dst)]>;
303def MOV16mr : I16mr<0x0,
304                    (outs), (ins memdst:$dst, GR16:$src),
305                    "mov.w\t{$src, $dst}",
306                    [(store GR16:$src, addr:$dst)]>;
307
308def MOV8mm  : I8mm<0x0,
309                   (outs), (ins memdst:$dst, memsrc:$src),
310                   "mov.b\t{$src, $dst}",
311                   [(store (i8 (load addr:$src)), addr:$dst)]>;
312def 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
320let isTwoAddress = 1 in {
321
322let Defs = [SRW] in {
323
324let isCommutable = 1 in { // X = ADD Y, Z  == X = ADD Z, Y
325
326def 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)]>;
331def 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
338def 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)]>;
343def 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
349let mayLoad = 1, hasExtraDefRegAllocReq = 1, 
350Constraints = "$base = $base_wb, $src1 = $dst" in {
351def 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}", []>;
355def 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
362def 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)]>;
367def 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
373let isTwoAddress = 0 in {
374def 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)]>;
379def 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
385def 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)]>;
390def 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
396def 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)]>;
402def 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
410let Uses = [SRW] in {
411
412let isCommutable = 1 in { // X = ADDC Y, Z  == X = ADDC Z, Y
413def 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)]>;
418def 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
425def 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)]>;
430def 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
436def 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)]>;
441def 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
447let isTwoAddress = 0 in {
448def 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)]>;
453def 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
459def 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)]>;
464def 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
470def 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)]>;
476def 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
486let isCommutable = 1 in { // X = AND Y, Z  == X = AND Z, Y
487def 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)]>;
492def 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
499def 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)]>;
504def 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
510def 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)]>;
515def 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
521let mayLoad = 1, hasExtraDefRegAllocReq = 1, 
522Constraints = "$base = $base_wb, $src1 = $dst" in {
523def 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}", []>;
527def 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
533let isTwoAddress = 0 in {
534def 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)]>;
539def 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
545def 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)]>;
550def 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
556def 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)]>;
562def 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
570let isCommutable = 1 in { // X = OR Y, Z  == X = OR Z, Y
571def 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))]>;
575def 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
581def 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))]>;
585def 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
590def 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)))]>;
594def 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
599let mayLoad = 1, hasExtraDefRegAllocReq = 1, 
600Constraints = "$base = $base_wb, $src1 = $dst" in {
601def 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}", []>;
605def 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
611let isTwoAddress = 0 in {
612def 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)]>;
616def 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
621def 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)]>;
625def 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
630def 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)]>;
635def 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
643def 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)))]>;
647def 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
652def 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)))))]>;
656def 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
661let isTwoAddress = 0 in {
662def 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)]>;
666def 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
671def 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)]>;
676def 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
683let isCommutable = 1 in { // X = XOR Y, Z  == X = XOR Z, Y
684def 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)]>;
689def 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
696def 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)]>;
701def 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
707def 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)]>;
712def 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
718let mayLoad = 1, hasExtraDefRegAllocReq = 1, 
719Constraints = "$base = $base_wb, $src1 = $dst" in {
720def 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}", []>;
724def 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
730let isTwoAddress = 0 in {
731def 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)]>;
736def 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
742def 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)]>;
747def 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
753def 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)]>;
758def 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
766def 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)]>;
771def 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
777def 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)]>;
782def 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
788def 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)]>;
793def 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
799let mayLoad = 1, hasExtraDefRegAllocReq = 1, 
800Constraints = "$base = $base_wb, $src1 = $dst" in {
801def 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}", []>;
805def 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
811let isTwoAddress = 0 in {
812def 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)]>;
817def 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
823def 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)]>;
828def 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
834def 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)]>;
840def 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
848let Uses = [SRW] in {
849def 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)]>;
854def 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
860def 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)]>;
865def 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
871def 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)]>;
876def 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
882let isTwoAddress = 0 in {
883def 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)]>;
888def 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
894def 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)]>;
899def 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
905def 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)]>;
911def 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!
922def 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)]>;
927def 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
933def 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)]>;
938def 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
944def 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)]>;
949def 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 ?
956def 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
964def 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?
970def 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
978let Defs = [SRW] in {
979def CMP8rr  : I8rr<0x0,
980                   (outs), (ins GR8:$src1, GR8:$src2),
981                   "cmp.b\t{$src2, $src1}",
982                   [(MSP430cmp GR8:$src1, GR8:$src2), (implicit SRW)]>;
983def 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
988def CMP8ri  : I8ri<0x0,
989                   (outs), (ins GR8:$src1, i8imm:$src2),
990                   "cmp.b\t{$src2, $src1}",
991                   [(MSP430cmp GR8:$src1, imm:$src2), (implicit SRW)]>;
992def 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
997def 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)]>;
1002def 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
1008def 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)]>;
1013def 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
1019def 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)]>;
1024def 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.
1033let isCommutable = 1 in {
1034def 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)]>;
1039def 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}
1045def 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)]>;
1050def 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
1056def 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)]>;
1061def 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
1067def 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)]>;
1072def 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
1078def 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)]>;
1083def 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
1089def 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)]>;
1096def 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
1109def : Pat<(extloadi16i8 addr:$src), (MOVZX16rm8 addr:$src)>;
1110
1111// anyext
1112def : Pat<(i16 (anyext GR8:$src)),
1113          (SUBREG_TO_REG (i16 0), GR8:$src, subreg_8bit)>;
1114
1115// truncs
1116def : Pat<(i8 (trunc GR16:$src)),
1117          (EXTRACT_SUBREG GR16:$src, subreg_8bit)>;
1118
1119// GlobalAddress, ExternalSymbol
1120def : Pat<(i16 (MSP430Wrapper tglobaladdr:$dst)), (MOV16ri tglobaladdr:$dst)>;
1121def : Pat<(i16 (MSP430Wrapper texternalsym:$dst)), (MOV16ri texternalsym:$dst)>;
1122
1123def : Pat<(add GR16:$src1, (MSP430Wrapper tglobaladdr :$src2)),
1124          (ADD16ri GR16:$src1, tglobaladdr:$src2)>;
1125def : Pat<(add GR16:$src1, (MSP430Wrapper texternalsym:$src2)),
1126          (ADD16ri GR16:$src1, texternalsym:$src2)>;
1127
1128def : Pat<(store (i16 (MSP430Wrapper tglobaladdr:$src)), addr:$dst),
1129          (MOV16mi addr:$dst, tglobaladdr:$src)>;
1130def : Pat<(store (i16 (MSP430Wrapper texternalsym:$src)), addr:$dst),
1131          (MOV16mi addr:$dst, texternalsym:$src)>;
1132
1133// calls
1134def : Pat<(MSP430call (i16 tglobaladdr:$dst)),
1135          (CALLi tglobaladdr:$dst)>;
1136def : Pat<(MSP430call (i16 texternalsym:$dst)),
1137          (CALLi texternalsym:$dst)>;
1138
1139// add and sub always produce carry
1140def : Pat<(addc GR16:$src1, GR16:$src2),
1141          (ADD16rr GR16:$src1, GR16:$src2)>;
1142def : Pat<(addc GR16:$src1, (load addr:$src2)),
1143          (ADD16rm GR16:$src1, addr:$src2)>;
1144def : Pat<(addc GR16:$src1, imm:$src2),
1145          (ADD16ri GR16:$src1, imm:$src2)>;
1146def : Pat<(store (addc (load addr:$dst), GR16:$src), addr:$dst),
1147          (ADD16mr addr:$dst, GR16:$src)>;
1148def : Pat<(store (addc (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
1149          (ADD16mm addr:$dst, addr:$src)>;
1150
1151def : Pat<(addc GR8:$src1, GR8:$src2),
1152          (ADD8rr GR8:$src1, GR8:$src2)>;
1153def : Pat<(addc GR8:$src1, (load addr:$src2)),
1154          (ADD8rm GR8:$src1, addr:$src2)>;
1155def : Pat<(addc GR8:$src1, imm:$src2),
1156          (ADD8ri GR8:$src1, imm:$src2)>;
1157def : Pat<(store (addc (load addr:$dst), GR8:$src), addr:$dst),
1158          (ADD8mr addr:$dst, GR8:$src)>;
1159def : Pat<(store (addc (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
1160          (ADD8mm addr:$dst, addr:$src)>;
1161
1162def : Pat<(subc GR16:$src1, GR16:$src2),
1163          (SUB16rr GR16:$src1, GR16:$src2)>;
1164def : Pat<(subc GR16:$src1, (load addr:$src2)),
1165          (SUB16rm GR16:$src1, addr:$src2)>;
1166def : Pat<(subc GR16:$src1, imm:$src2),
1167          (SUB16ri GR16:$src1, imm:$src2)>;
1168def : Pat<(store (subc (load addr:$dst), GR16:$src), addr:$dst),
1169          (SUB16mr addr:$dst, GR16:$src)>;
1170def : Pat<(store (subc (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
1171          (SUB16mm addr:$dst, addr:$src)>;
1172
1173def : Pat<(subc GR8:$src1, GR8:$src2),
1174          (SUB8rr GR8:$src1, GR8:$src2)>;
1175def : Pat<(subc GR8:$src1, (load addr:$src2)),
1176          (SUB8rm GR8:$src1, addr:$src2)>;
1177def : Pat<(subc GR8:$src1, imm:$src2),
1178          (SUB8ri GR8:$src1, imm:$src2)>;
1179def : Pat<(store (subc (load addr:$dst), GR8:$src), addr:$dst),
1180          (SUB8mr addr:$dst, GR8:$src)>;
1181def : Pat<(store (subc (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
1182          (SUB8mm addr:$dst, addr:$src)>;
1183
1184// peephole patterns
1185def : Pat<(and GR16:$src, 255), (ZEXT16r GR16:$src)>;
1186def : 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))>;
1189