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