1 //===- MSP430InstrInfo.td - MSP430 Instruction defs -----------*- tblgen-*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file describes the MSP430 instructions in TableGen format.
12 //===----------------------------------------------------------------------===//
14 include "MSP430InstrFormats.td"
16 //===----------------------------------------------------------------------===//
18 //===----------------------------------------------------------------------===//
19 class SDTCisI8<int OpNum> : SDTCisVT<OpNum, i8>;
20 class SDTCisI16<int OpNum> : SDTCisVT<OpNum, i16>;
22 //===----------------------------------------------------------------------===//
24 //===----------------------------------------------------------------------===//
25 def SDT_MSP430Call : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>;
26 def SDT_MSP430CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i16>]>;
27 def SDT_MSP430CallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i16>, SDTCisVT<1, i16>]>;
28 def SDT_MSP430Wrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
29 def SDT_MSP430Cmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
30 def SDT_MSP430BrCC : SDTypeProfile<0, 2, [SDTCisVT<0, OtherVT>,
32 def SDT_MSP430SelectCC : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>,
35 //===----------------------------------------------------------------------===//
36 // MSP430 Specific Node Definitions.
37 //===----------------------------------------------------------------------===//
38 def MSP430retflag : SDNode<"MSP430ISD::RET_FLAG", SDTNone,
39 [SDNPHasChain, SDNPOptInFlag]>;
40 def MSP430retiflag : SDNode<"MSP430ISD::RETI_FLAG", SDTNone,
41 [SDNPHasChain, SDNPOptInFlag]>;
43 def MSP430rra : SDNode<"MSP430ISD::RRA", SDTIntUnaryOp, []>;
44 def MSP430rla : SDNode<"MSP430ISD::RLA", SDTIntUnaryOp, []>;
45 def MSP430rrc : SDNode<"MSP430ISD::RRC", SDTIntUnaryOp, []>;
47 def MSP430call : SDNode<"MSP430ISD::CALL", SDT_MSP430Call,
48 [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag]>;
49 def MSP430callseq_start :
50 SDNode<"ISD::CALLSEQ_START", SDT_MSP430CallSeqStart,
51 [SDNPHasChain, SDNPOutFlag]>;
52 def MSP430callseq_end :
53 SDNode<"ISD::CALLSEQ_END", SDT_MSP430CallSeqEnd,
54 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
55 def MSP430Wrapper : SDNode<"MSP430ISD::Wrapper", SDT_MSP430Wrapper>;
56 def MSP430cmp : SDNode<"MSP430ISD::CMP", SDT_MSP430Cmp, [SDNPOutFlag]>;
57 def MSP430brcc : SDNode<"MSP430ISD::BR_CC", SDT_MSP430BrCC, [SDNPHasChain, SDNPInFlag]>;
58 def MSP430selectcc: SDNode<"MSP430ISD::SELECT_CC", SDT_MSP430SelectCC, [SDNPInFlag]>;
60 //===----------------------------------------------------------------------===//
61 // MSP430 Operand Definitions.
62 //===----------------------------------------------------------------------===//
65 def memsrc : Operand<i16> {
66 let PrintMethod = "printSrcMemOperand";
67 let MIOperandInfo = (ops GR16, i16imm);
70 def memdst : Operand<i16> {
71 let PrintMethod = "printSrcMemOperand";
72 let MIOperandInfo = (ops GR16, i16imm);
75 // Branch targets have OtherVT type.
76 def brtarget : Operand<OtherVT> {
77 let PrintMethod = "printPCRelImmOperand";
80 // Operand for printing out a condition code.
81 def cc : Operand<i8> {
82 let PrintMethod = "printCCOperand";
85 //===----------------------------------------------------------------------===//
86 // MSP430 Complex Pattern Definitions.
87 //===----------------------------------------------------------------------===//
89 def addr : ComplexPattern<iPTR, 2, "SelectAddr", [], []>;
91 //===----------------------------------------------------------------------===//
93 def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>;
94 def extloadi16i8 : PatFrag<(ops node:$ptr), (i16 ( extloadi8 node:$ptr))>;
95 def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{
96 return N->hasOneUse();
98 //===----------------------------------------------------------------------===//
101 // ADJCALLSTACKDOWN/UP implicitly use/def SP because they may be expanded into
102 // a stack adjustment and the codegen must know that they may modify the stack
103 // pointer before prolog-epilog rewriting occurs.
104 // Pessimistically assume ADJCALLSTACKDOWN / ADJCALLSTACKUP will become
105 // sub / add which can clobber SRW.
106 let Defs = [SPW, SRW], Uses = [SPW] in {
107 def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i16imm:$amt),
109 [(MSP430callseq_start timm:$amt)]>;
110 def ADJCALLSTACKUP : Pseudo<(outs), (ins i16imm:$amt1, i16imm:$amt2),
112 [(MSP430callseq_end timm:$amt1, timm:$amt2)]>;
115 let usesCustomInserter = 1 in {
116 def Select8 : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2, i8imm:$cc),
119 (MSP430selectcc GR8:$src1, GR8:$src2, imm:$cc))]>;
120 def Select16 : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2, i8imm:$cc),
123 (MSP430selectcc GR16:$src1, GR16:$src2, imm:$cc))]>;
126 let neverHasSideEffects = 1 in
127 def NOP : Pseudo<(outs), (ins), "nop", []>;
129 //===----------------------------------------------------------------------===//
130 // Control Flow Instructions...
133 // FIXME: Provide proper encoding!
134 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
135 def RET : Pseudo<(outs), (ins), "ret", [(MSP430retflag)]>;
136 def RETI : Pseudo<(outs), (ins), "reti", [(MSP430retiflag)]>;
139 let isBranch = 1, isTerminator = 1 in {
143 def JMP : Pseudo<(outs), (ins brtarget:$dst),
147 // Conditional branches
149 def JCC : Pseudo<(outs), (ins brtarget:$dst, cc:$cc),
151 [(MSP430brcc bb:$dst, imm:$cc)]>;
152 } // isBranch, isTerminator
154 //===----------------------------------------------------------------------===//
155 // Call Instructions...
158 // All calls clobber the non-callee saved registers. SPW is marked as
159 // a use to prevent stack-pointer assignments that appear immediately
160 // before calls from potentially appearing dead. Uses for argument
161 // registers are added manually.
162 let Defs = [R12W, R13W, R14W, R15W, SRW],
164 def CALLi : Pseudo<(outs), (ins i16imm:$dst, variable_ops),
165 "call\t$dst", [(MSP430call imm:$dst)]>;
166 def CALLr : Pseudo<(outs), (ins GR16:$dst, variable_ops),
167 "call\t$dst", [(MSP430call GR16:$dst)]>;
168 def CALLm : Pseudo<(outs), (ins memsrc:$dst, variable_ops),
169 "call\t${dst:mem}", [(MSP430call (load addr:$dst))]>;
173 //===----------------------------------------------------------------------===//
174 // Miscellaneous Instructions...
176 let Defs = [SPW], Uses = [SPW], neverHasSideEffects=1 in {
178 def POP16r : Pseudo<(outs GR16:$reg), (ins), "pop.w\t$reg", []>;
181 def PUSH16r : Pseudo<(outs), (ins GR16:$reg), "push.w\t$reg",[]>;
184 //===----------------------------------------------------------------------===//
187 // FIXME: Provide proper encoding!
188 let neverHasSideEffects = 1 in {
189 def MOV8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src),
190 "mov.b\t{$src, $dst}",
192 def MOV16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src),
193 "mov.w\t{$src, $dst}",
197 // FIXME: Provide proper encoding!
198 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
199 def MOV8ri : Pseudo<(outs GR8:$dst), (ins i8imm:$src),
200 "mov.b\t{$src, $dst}",
201 [(set GR8:$dst, imm:$src)]>;
202 def MOV16ri : Pseudo<(outs GR16:$dst), (ins i16imm:$src),
203 "mov.w\t{$src, $dst}",
204 [(set GR16:$dst, imm:$src)]>;
207 let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in {
208 def MOV8rm : Pseudo<(outs GR8:$dst), (ins memsrc:$src),
209 "mov.b\t{$src, $dst}",
210 [(set GR8:$dst, (load addr:$src))]>;
211 def MOV16rm : Pseudo<(outs GR16:$dst), (ins memsrc:$src),
212 "mov.w\t{$src, $dst}",
213 [(set GR16:$dst, (load addr:$src))]>;
216 def MOVZX16rr8 : Pseudo<(outs GR16:$dst), (ins GR8:$src),
217 "mov.b\t{$src, $dst}",
218 [(set GR16:$dst, (zext GR8:$src))]>;
219 def MOVZX16rm8 : Pseudo<(outs GR16:$dst), (ins memsrc:$src),
220 "mov.b\t{$src, $dst}",
221 [(set GR16:$dst, (zextloadi16i8 addr:$src))]>;
223 let mayLoad = 1, hasExtraDefRegAllocReq = 1, Constraints = "$base = $base_wb" in {
224 def MOV8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR16:$base),
225 "mov.b\t{@$base+, $dst}", []>;
226 def MOV16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$base),
227 "mov.w\t{@$base+, $dst}", []>;
230 // Any instruction that defines a 8-bit result leaves the high half of the
231 // register. Truncate can be lowered to EXTRACT_SUBREG, and CopyFromReg may
232 // be copying from a truncate, but any other 8-bit operation will zero-extend
234 def def8 : PatLeaf<(i8 GR8:$src), [{
235 return N->getOpcode() != ISD::TRUNCATE &&
236 N->getOpcode() != TargetInstrInfo::EXTRACT_SUBREG &&
237 N->getOpcode() != ISD::CopyFromReg;
240 // In the case of a 8-bit def that is known to implicitly zero-extend,
241 // we can use a SUBREG_TO_REG.
242 def : Pat<(i16 (zext def8:$src)),
243 (SUBREG_TO_REG (i16 0), GR8:$src, subreg_8bit)>;
246 def MOV8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
247 "mov.b\t{$src, $dst}",
248 [(store (i8 imm:$src), addr:$dst)]>;
249 def MOV16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
250 "mov.w\t{$src, $dst}",
251 [(store (i16 imm:$src), addr:$dst)]>;
253 def MOV8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
254 "mov.b\t{$src, $dst}",
255 [(store GR8:$src, addr:$dst)]>;
256 def MOV16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
257 "mov.w\t{$src, $dst}",
258 [(store GR16:$src, addr:$dst)]>;
260 def MOV8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
261 "mov.b\t{$src, $dst}",
262 [(store (i8 (load addr:$src)), addr:$dst)]>;
263 def MOV16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
264 "mov.w\t{$src, $dst}",
265 [(store (i16 (load addr:$src)), addr:$dst)]>;
267 //===----------------------------------------------------------------------===//
268 // Arithmetic Instructions
270 let isTwoAddress = 1 in {
272 let Defs = [SRW] in {
274 let isCommutable = 1 in { // X = ADD Y, Z == X = ADD Z, Y
275 // FIXME: Provide proper encoding!
276 def ADD8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
277 "add.b\t{$src2, $dst}",
278 [(set GR8:$dst, (add GR8:$src1, GR8:$src2)),
280 def ADD16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
281 "add.w\t{$src2, $dst}",
282 [(set GR16:$dst, (add GR16:$src1, GR16:$src2)),
286 def ADD8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
287 "add.b\t{$src2, $dst}",
288 [(set GR8:$dst, (add GR8:$src1, (load addr:$src2))),
290 def ADD16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
291 "add.w\t{$src2, $dst}",
292 [(set GR16:$dst, (add GR16:$src1, (load addr:$src2))),
295 let mayLoad = 1, hasExtraDefRegAllocReq = 1,
296 Constraints = "$base = $base_wb, $src1 = $dst" in {
297 def ADD8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR8:$src1, GR16:$base),
298 "add.b\t{@$base+, $dst}", []>;
299 def ADD16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$src1, GR16:$base),
300 "add.w\t{@$base+, $dst}", []>;
304 def ADD8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
305 "add.b\t{$src2, $dst}",
306 [(set GR8:$dst, (add GR8:$src1, imm:$src2)),
308 def ADD16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
309 "add.w\t{$src2, $dst}",
310 [(set GR16:$dst, (add GR16:$src1, imm:$src2)),
313 let isTwoAddress = 0 in {
314 def ADD8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
315 "add.b\t{$src, $dst}",
316 [(store (add (load addr:$dst), GR8:$src), addr:$dst),
318 def ADD16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
319 "add.w\t{$src, $dst}",
320 [(store (add (load addr:$dst), GR16:$src), addr:$dst),
323 def ADD8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
324 "add.b\t{$src, $dst}",
325 [(store (add (load addr:$dst), (i8 imm:$src)), addr:$dst),
327 def ADD16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
328 "add.w\t{$src, $dst}",
329 [(store (add (load addr:$dst), (i16 imm:$src)), addr:$dst),
332 def ADD8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
333 "add.b\t{$src, $dst}",
334 [(store (add (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
336 def ADD16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
337 "add.w\t{$src, $dst}",
338 [(store (add (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
342 let Uses = [SRW] in {
344 let isCommutable = 1 in { // X = ADDC Y, Z == X = ADDC Z, Y
345 def ADC8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
346 "addc.b\t{$src2, $dst}",
347 [(set GR8:$dst, (adde GR8:$src1, GR8:$src2)),
349 def ADC16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
350 "addc.w\t{$src2, $dst}",
351 [(set GR16:$dst, (adde GR16:$src1, GR16:$src2)),
355 def ADC8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
356 "addc.b\t{$src2, $dst}",
357 [(set GR8:$dst, (adde GR8:$src1, imm:$src2)),
359 def ADC16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
360 "addc.w\t{$src2, $dst}",
361 [(set GR16:$dst, (adde GR16:$src1, imm:$src2)),
364 def ADC8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
365 "addc.b\t{$src2, $dst}",
366 [(set GR8:$dst, (adde GR8:$src1, (load addr:$src2))),
368 def ADC16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
369 "addc.w\t{$src2, $dst}",
370 [(set GR16:$dst, (adde GR16:$src1, (load addr:$src2))),
373 let isTwoAddress = 0 in {
374 def ADC8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
375 "addc.b\t{$src, $dst}",
376 [(store (adde (load addr:$dst), GR8:$src), addr:$dst),
378 def ADC16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
379 "addc.w\t{$src, $dst}",
380 [(store (adde (load addr:$dst), GR16:$src), addr:$dst),
383 def ADC8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
384 "addc.b\t{$src, $dst}",
385 [(store (adde (load addr:$dst), (i8 imm:$src)), addr:$dst),
387 def ADC16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
388 "addc.w\t{$src, $dst}",
389 [(store (adde (load addr:$dst), (i16 imm:$src)), addr:$dst),
392 def ADC8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
393 "addc.b\t{$src, $dst}",
394 [(store (adde (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
396 def ADC16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
397 "addc.w\t{$src, $dst}",
398 [(store (adde (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
404 let isCommutable = 1 in { // X = AND Y, Z == X = AND Z, Y
405 def AND8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
406 "and.b\t{$src2, $dst}",
407 [(set GR8:$dst, (and GR8:$src1, GR8:$src2)),
409 def AND16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
410 "and.w\t{$src2, $dst}",
411 [(set GR16:$dst, (and GR16:$src1, GR16:$src2)),
415 def AND8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
416 "and.b\t{$src2, $dst}",
417 [(set GR8:$dst, (and GR8:$src1, imm:$src2)),
419 def AND16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
420 "and.w\t{$src2, $dst}",
421 [(set GR16:$dst, (and GR16:$src1, imm:$src2)),
424 def AND8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
425 "and.b\t{$src2, $dst}",
426 [(set GR8:$dst, (and GR8:$src1, (load addr:$src2))),
428 def AND16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
429 "and.w\t{$src2, $dst}",
430 [(set GR16:$dst, (and GR16:$src1, (load addr:$src2))),
433 let mayLoad = 1, hasExtraDefRegAllocReq = 1,
434 Constraints = "$base = $base_wb, $src1 = $dst" in {
435 def AND8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR8:$src1, GR16:$base),
436 "and.b\t{@$base+, $dst}", []>;
437 def AND16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$src1, GR16:$base),
438 "and.w\t{@$base+, $dst}", []>;
441 let isTwoAddress = 0 in {
442 def AND8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
443 "and.b\t{$src, $dst}",
444 [(store (and (load addr:$dst), GR8:$src), addr:$dst),
446 def AND16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
447 "and.w\t{$src, $dst}",
448 [(store (and (load addr:$dst), GR16:$src), addr:$dst),
451 def AND8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
452 "and.b\t{$src, $dst}",
453 [(store (and (load addr:$dst), (i8 imm:$src)), addr:$dst),
455 def AND16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
456 "and.w\t{$src, $dst}",
457 [(store (and (load addr:$dst), (i16 imm:$src)), addr:$dst),
460 def AND8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
461 "and.b\t{$src, $dst}",
462 [(store (and (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
464 def AND16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
465 "and.w\t{$src, $dst}",
466 [(store (and (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
470 let isCommutable = 1 in { // X = OR Y, Z == X = OR Z, Y
471 def OR8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
472 "bis.b\t{$src2, $dst}",
473 [(set GR8:$dst, (or GR8:$src1, GR8:$src2))]>;
474 def OR16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
475 "bis.w\t{$src2, $dst}",
476 [(set GR16:$dst, (or GR16:$src1, GR16:$src2))]>;
479 def OR8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
480 "bis.b\t{$src2, $dst}",
481 [(set GR8:$dst, (or GR8:$src1, imm:$src2))]>;
482 def OR16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
483 "bis.w\t{$src2, $dst}",
484 [(set GR16:$dst, (or GR16:$src1, imm:$src2))]>;
486 def OR8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
487 "bis.b\t{$src2, $dst}",
488 [(set GR8:$dst, (or GR8:$src1, (load addr:$src2)))]>;
489 def OR16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
490 "bis.w\t{$src2, $dst}",
491 [(set GR16:$dst, (or GR16:$src1, (load addr:$src2)))]>;
493 let mayLoad = 1, hasExtraDefRegAllocReq = 1,
494 Constraints = "$base = $base_wb, $src1 = $dst" in {
495 def OR8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR8:$src1, GR16:$base),
496 "bis.b\t{@$base+, $dst}", []>;
497 def OR16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$src1, GR16:$base),
498 "bis.w\t{@$base+, $dst}", []>;
501 let isTwoAddress = 0 in {
502 def OR8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
503 "bis.b\t{$src, $dst}",
504 [(store (or (load addr:$dst), GR8:$src), addr:$dst)]>;
505 def OR16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
506 "bis.w\t{$src, $dst}",
507 [(store (or (load addr:$dst), GR16:$src), addr:$dst)]>;
509 def OR8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
510 "bis.b\t{$src, $dst}",
511 [(store (or (load addr:$dst), (i8 imm:$src)), addr:$dst)]>;
512 def OR16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
513 "bis.w\t{$src, $dst}",
514 [(store (or (load addr:$dst), (i16 imm:$src)), addr:$dst)]>;
516 def OR8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
517 "bis.b\t{$src, $dst}",
518 [(store (or (i8 (load addr:$dst)),
519 (i8 (load addr:$src))), addr:$dst)]>;
520 def OR16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
521 "bis.w\t{$src, $dst}",
522 [(store (or (i16 (load addr:$dst)),
523 (i16 (load addr:$src))), addr:$dst)]>;
526 // bic does not modify condition codes
527 def BIC8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
528 "bic.b\t{$src2, $dst}",
529 [(set GR8:$dst, (and GR8:$src1, (not GR8:$src2)))]>;
530 def BIC16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
531 "bic.w\t{$src2, $dst}",
532 [(set GR16:$dst, (and GR16:$src1, (not GR16:$src2)))]>;
534 def BIC8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
535 "bic.b\t{$src2, $dst}",
536 [(set GR8:$dst, (and GR8:$src1, (not (i8 (load addr:$src2)))))]>;
537 def BIC16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
538 "bic.w\t{$src2, $dst}",
539 [(set GR16:$dst, (and GR16:$src1, (not (i16 (load addr:$src2)))))]>;
541 let isTwoAddress = 0 in {
542 def BIC8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
543 "bic.b\t{$src, $dst}",
544 [(store (and (load addr:$dst), (not GR8:$src)), addr:$dst)]>;
545 def BIC16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
546 "bic.w\t{$src, $dst}",
547 [(store (and (load addr:$dst), (not GR16:$src)), addr:$dst)]>;
549 def BIC8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
550 "bic.b\t{$src, $dst}",
551 [(store (and (load addr:$dst), (not (i8 (load addr:$src)))), addr:$dst)]>;
552 def BIC16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
553 "bic.w\t{$src, $dst}",
554 [(store (and (load addr:$dst), (not (i16 (load addr:$src)))), addr:$dst)]>;
557 let isCommutable = 1 in { // X = XOR Y, Z == X = XOR Z, Y
558 def XOR8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
559 "xor.b\t{$src2, $dst}",
560 [(set GR8:$dst, (xor GR8:$src1, GR8:$src2)),
562 def XOR16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
563 "xor.w\t{$src2, $dst}",
564 [(set GR16:$dst, (xor GR16:$src1, GR16:$src2)),
568 def XOR8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
569 "xor.b\t{$src2, $dst}",
570 [(set GR8:$dst, (xor GR8:$src1, imm:$src2)),
572 def XOR16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
573 "xor.w\t{$src2, $dst}",
574 [(set GR16:$dst, (xor GR16:$src1, imm:$src2)),
577 def XOR8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
578 "xor.b\t{$src2, $dst}",
579 [(set GR8:$dst, (xor GR8:$src1, (load addr:$src2))),
581 def XOR16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
582 "xor.w\t{$src2, $dst}",
583 [(set GR16:$dst, (xor GR16:$src1, (load addr:$src2))),
586 let mayLoad = 1, hasExtraDefRegAllocReq = 1,
587 Constraints = "$base = $base_wb, $src1 = $dst" in {
588 def XOR8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR8:$src1, GR16:$base),
589 "xor.b\t{@$base+, $dst}", []>;
590 def XOR16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$src1, GR16:$base),
591 "xor.w\t{@$base+, $dst}", []>;
594 let isTwoAddress = 0 in {
595 def XOR8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
596 "xor.b\t{$src, $dst}",
597 [(store (xor (load addr:$dst), GR8:$src), addr:$dst),
599 def XOR16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
600 "xor.w\t{$src, $dst}",
601 [(store (xor (load addr:$dst), GR16:$src), addr:$dst),
604 def XOR8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
605 "xor.b\t{$src, $dst}",
606 [(store (xor (load addr:$dst), (i8 imm:$src)), addr:$dst),
608 def XOR16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
609 "xor.w\t{$src, $dst}",
610 [(store (xor (load addr:$dst), (i16 imm:$src)), addr:$dst),
613 def XOR8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
614 "xor.b\t{$src, $dst}",
615 [(store (xor (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
617 def XOR16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
618 "xor.w\t{$src, $dst}",
619 [(store (xor (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
624 def SUB8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
625 "sub.b\t{$src2, $dst}",
626 [(set GR8:$dst, (sub GR8:$src1, GR8:$src2)),
628 def SUB16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
629 "sub.w\t{$src2, $dst}",
630 [(set GR16:$dst, (sub GR16:$src1, GR16:$src2)),
633 def SUB8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
634 "sub.b\t{$src2, $dst}",
635 [(set GR8:$dst, (sub GR8:$src1, imm:$src2)),
637 def SUB16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
638 "sub.w\t{$src2, $dst}",
639 [(set GR16:$dst, (sub GR16:$src1, imm:$src2)),
642 def SUB8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
643 "sub.b\t{$src2, $dst}",
644 [(set GR8:$dst, (sub GR8:$src1, (load addr:$src2))),
646 def SUB16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
647 "sub.w\t{$src2, $dst}",
648 [(set GR16:$dst, (sub GR16:$src1, (load addr:$src2))),
651 let mayLoad = 1, hasExtraDefRegAllocReq = 1,
652 Constraints = "$base = $base_wb, $src1 = $dst" in {
653 def SUB8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR8:$src1, GR16:$base),
654 "sub.b\t{@$base+, $dst}", []>;
655 def SUB16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$src1, GR16:$base),
656 "sub.w\t{@$base+, $dst}", []>;
659 let isTwoAddress = 0 in {
660 def SUB8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
661 "sub.b\t{$src, $dst}",
662 [(store (sub (load addr:$dst), GR8:$src), addr:$dst),
664 def SUB16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
665 "sub.w\t{$src, $dst}",
666 [(store (sub (load addr:$dst), GR16:$src), addr:$dst),
669 def SUB8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
670 "sub.b\t{$src, $dst}",
671 [(store (sub (load addr:$dst), (i8 imm:$src)), addr:$dst),
673 def SUB16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
674 "sub.w\t{$src, $dst}",
675 [(store (sub (load addr:$dst), (i16 imm:$src)), addr:$dst),
678 def SUB8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
679 "sub.b\t{$src, $dst}",
680 [(store (sub (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
682 def SUB16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
683 "sub.w\t{$src, $dst}",
684 [(store (sub (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
688 let Uses = [SRW] in {
689 def SBC8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
690 "subc.b\t{$src2, $dst}",
691 [(set GR8:$dst, (sube GR8:$src1, GR8:$src2)),
693 def SBC16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
694 "subc.w\t{$src2, $dst}",
695 [(set GR16:$dst, (sube GR16:$src1, GR16:$src2)),
698 def SBC8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
699 "subc.b\t{$src2, $dst}",
700 [(set GR8:$dst, (sube GR8:$src1, imm:$src2)),
702 def SBC16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
703 "subc.w\t{$src2, $dst}",
704 [(set GR16:$dst, (sube GR16:$src1, imm:$src2)),
707 def SBC8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
708 "subc.b\t{$src2, $dst}",
709 [(set GR8:$dst, (sube GR8:$src1, (load addr:$src2))),
711 def SBC16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
712 "subc.w\t{$src2, $dst}",
713 [(set GR16:$dst, (sube GR16:$src1, (load addr:$src2))),
716 let isTwoAddress = 0 in {
717 def SBC8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
718 "subc.b\t{$src, $dst}",
719 [(store (sube (load addr:$dst), GR8:$src), addr:$dst),
721 def SBC16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
722 "subc.w\t{$src, $dst}",
723 [(store (sube (load addr:$dst), GR16:$src), addr:$dst),
726 def SBC8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
727 "subc.b\t{$src, $dst}",
728 [(store (sube (load addr:$dst), (i8 imm:$src)), addr:$dst),
730 def SBC16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
731 "subc.w\t{$src, $dst}",
732 [(store (sube (load addr:$dst), (i16 imm:$src)), addr:$dst),
735 def SBC8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
736 "subc.b\t{$src, $dst}",
737 [(store (sube (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
739 def SBC16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
740 "subc.w\t{$src, $dst}",
741 [(store (sube (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
747 // FIXME: Provide proper encoding!
748 def SAR8r1 : Pseudo<(outs GR8:$dst), (ins GR8:$src),
750 [(set GR8:$dst, (MSP430rra GR8:$src)),
752 def SAR16r1 : Pseudo<(outs GR16:$dst), (ins GR16:$src),
754 [(set GR16:$dst, (MSP430rra GR16:$src)),
757 def SHL8r1 : Pseudo<(outs GR8:$dst), (ins GR8:$src),
759 [(set GR8:$dst, (MSP430rla GR8:$src)),
761 def SHL16r1 : Pseudo<(outs GR16:$dst), (ins GR16:$src),
763 [(set GR16:$dst, (MSP430rla GR16:$src)),
766 def SAR8r1c : Pseudo<(outs GR8:$dst), (ins GR8:$src),
769 [(set GR8:$dst, (MSP430rrc GR8:$src)),
771 def SAR16r1c : Pseudo<(outs GR16:$dst), (ins GR16:$src),
774 [(set GR16:$dst, (MSP430rrc GR16:$src)),
777 def SEXT16r : Pseudo<(outs GR16:$dst), (ins GR16:$src),
779 [(set GR16:$dst, (sext_inreg GR16:$src, i8)),
784 def ZEXT16r : Pseudo<(outs GR16:$dst), (ins GR16:$src),
785 "mov.b\t{$src, $dst}",
786 [(set GR16:$dst, (zext (trunc GR16:$src)))]>;
788 def SWPB16r : Pseudo<(outs GR16:$dst), (ins GR16:$src),
790 [(set GR16:$dst, (bswap GR16:$src))]>;
792 } // isTwoAddress = 1
794 // Integer comparisons
795 let Defs = [SRW] in {
796 def CMP8rr : Pseudo<(outs), (ins GR8:$src1, GR8:$src2),
797 "cmp.b\t{$src1, $src2}",
798 [(MSP430cmp GR8:$src1, GR8:$src2), (implicit SRW)]>;
799 def CMP16rr : Pseudo<(outs), (ins GR16:$src1, GR16:$src2),
800 "cmp.w\t{$src1, $src2}",
801 [(MSP430cmp GR16:$src1, GR16:$src2), (implicit SRW)]>;
803 def CMP8ir : Pseudo<(outs), (ins i8imm:$src1, GR8:$src2),
804 "cmp.b\t{$src1, $src2}",
805 [(MSP430cmp imm:$src1, GR8:$src2), (implicit SRW)]>;
806 def CMP16ir : Pseudo<(outs), (ins i16imm:$src1, GR16:$src2),
807 "cmp.w\t{$src1, $src2}",
808 [(MSP430cmp imm:$src1, GR16:$src2), (implicit SRW)]>;
810 def CMP8im : Pseudo<(outs), (ins i8imm:$src1, memsrc:$src2),
811 "cmp.b\t{$src1, $src2}",
812 [(MSP430cmp (i8 imm:$src1), (load addr:$src2)), (implicit SRW)]>;
813 def CMP16im : Pseudo<(outs), (ins i16imm:$src1, memsrc:$src2),
814 "cmp.w\t{$src1, $src2}",
815 [(MSP430cmp (i16 imm:$src1), (load addr:$src2)), (implicit SRW)]>;
817 def CMP8rm : Pseudo<(outs), (ins GR8:$src1, memsrc:$src2),
818 "cmp.b\t{$src1, $src2}",
819 [(MSP430cmp GR8:$src1, (load addr:$src2)), (implicit SRW)]>;
820 def CMP16rm : Pseudo<(outs), (ins GR16:$src1, memsrc:$src2),
821 "cmp.w\t{$src1, $src2}",
822 [(MSP430cmp GR16:$src1, (load addr:$src2)), (implicit SRW)]>;
824 def CMP8mr : Pseudo<(outs), (ins memsrc:$src1, GR8:$src2),
825 "cmp.b\t{$src1, $src2}",
826 [(MSP430cmp (load addr:$src1), GR8:$src2), (implicit SRW)]>;
827 def CMP16mr : Pseudo<(outs), (ins memsrc:$src1, GR16:$src2),
828 "cmp.w\t{$src1, $src2}",
829 [(MSP430cmp (load addr:$src1), GR16:$src2), (implicit SRW)]>;
832 // BIT TESTS, just sets condition codes
833 // Note that the C condition is set differently than when using CMP.
834 let isCommutable = 1 in {
835 def BIT8rr : Pseudo<(outs), (ins GR8:$src1, GR8:$src2),
836 "bit.b\t{$src2, $src1}",
837 [(MSP430cmp 0, (and_su GR8:$src1, GR8:$src2)),
839 def BIT16rr : Pseudo<(outs), (ins GR16:$src1, GR16:$src2),
840 "bit.w\t{$src2, $src1}",
841 [(MSP430cmp 0, (and_su GR16:$src1, GR16:$src2)),
844 def BIT8ri : Pseudo<(outs), (ins GR8:$src1, i8imm:$src2),
845 "bit.b\t{$src2, $src1}",
846 [(MSP430cmp 0, (and_su GR8:$src1, imm:$src2)),
848 def BIT16ri : Pseudo<(outs), (ins GR16:$src1, i16imm:$src2),
849 "bit.w\t{$src2, $src1}",
850 [(MSP430cmp 0, (and_su GR16:$src1, imm:$src2)),
853 def BIT8rm : Pseudo<(outs), (ins GR8:$src1, memdst:$src2),
854 "bit.b\t{$src2, $src1}",
855 [(MSP430cmp 0, (and_su GR8:$src1, (load addr:$src2))),
857 def BIT16rm : Pseudo<(outs), (ins GR16:$src1, memdst:$src2),
858 "bit.w\t{$src2, $src1}",
859 [(MSP430cmp 0, (and_su GR16:$src1, (load addr:$src2))),
862 def BIT8mr : Pseudo<(outs), (ins memsrc:$src1, GR8:$src2),
863 "bit.b\t{$src2, $src1}",
864 [(MSP430cmp 0, (and_su (load addr:$src1), GR8:$src2)),
866 def BIT16mr : Pseudo<(outs), (ins memsrc:$src1, GR16:$src2),
867 "bit.w\t{$src2, $src1}",
868 [(MSP430cmp 0, (and_su (load addr:$src1), GR16:$src2)),
871 def BIT8mi : Pseudo<(outs), (ins memsrc:$src1, i8imm:$src2),
872 "bit.b\t{$src2, $src1}",
873 [(MSP430cmp 0, (and_su (load addr:$src1), (i8 imm:$src2))),
875 def BIT16mi : Pseudo<(outs), (ins memsrc:$src1, i16imm:$src2),
876 "bit.w\t{$src2, $src1}",
877 [(MSP430cmp 0, (and_su (load addr:$src1), (i16 imm:$src2))),
880 def BIT8mm : Pseudo<(outs), (ins memsrc:$src1, memsrc:$src2),
881 "bit.b\t{$src2, $src1}",
882 [(MSP430cmp 0, (and_su (i8 (load addr:$src1)),
885 def BIT16mm : Pseudo<(outs), (ins memsrc:$src1, memsrc:$src2),
886 "bit.w\t{$src2, $src1}",
887 [(MSP430cmp 0, (and_su (i16 (load addr:$src1)),
892 //===----------------------------------------------------------------------===//
893 // Non-Instruction Patterns
896 def : Pat<(extloadi16i8 addr:$src), (MOVZX16rm8 addr:$src)>;
899 def : Pat<(anyext addr:$src), (MOVZX16rr8 GR8:$src)>;
902 def : Pat<(i8 (trunc GR16:$src)),
903 (EXTRACT_SUBREG GR16:$src, subreg_8bit)>;
905 // GlobalAddress, ExternalSymbol
906 def : Pat<(i16 (MSP430Wrapper tglobaladdr:$dst)), (MOV16ri tglobaladdr:$dst)>;
907 def : Pat<(i16 (MSP430Wrapper texternalsym:$dst)), (MOV16ri texternalsym:$dst)>;
909 def : Pat<(add GR16:$src1, (MSP430Wrapper tglobaladdr :$src2)),
910 (ADD16ri GR16:$src1, tglobaladdr:$src2)>;
911 def : Pat<(add GR16:$src1, (MSP430Wrapper texternalsym:$src2)),
912 (ADD16ri GR16:$src1, texternalsym:$src2)>;
914 def : Pat<(store (i16 (MSP430Wrapper tglobaladdr:$src)), addr:$dst),
915 (MOV16mi addr:$dst, tglobaladdr:$src)>;
916 def : Pat<(store (i16 (MSP430Wrapper texternalsym:$src)), addr:$dst),
917 (MOV16mi addr:$dst, texternalsym:$src)>;
920 def : Pat<(MSP430call (i16 tglobaladdr:$dst)),
921 (CALLi tglobaladdr:$dst)>;
922 def : Pat<(MSP430call (i16 texternalsym:$dst)),
923 (CALLi texternalsym:$dst)>;
925 // add and sub always produce carry
926 def : Pat<(addc GR16:$src1, GR16:$src2),
927 (ADD16rr GR16:$src1, GR16:$src2)>;
928 def : Pat<(addc GR16:$src1, (load addr:$src2)),
929 (ADD16rm GR16:$src1, addr:$src2)>;
930 def : Pat<(addc GR16:$src1, imm:$src2),
931 (ADD16ri GR16:$src1, imm:$src2)>;
932 def : Pat<(store (addc (load addr:$dst), GR16:$src), addr:$dst),
933 (ADD16mr addr:$dst, GR16:$src)>;
934 def : Pat<(store (addc (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
935 (ADD16mm addr:$dst, addr:$src)>;
937 def : Pat<(addc GR8:$src1, GR8:$src2),
938 (ADD8rr GR8:$src1, GR8:$src2)>;
939 def : Pat<(addc GR8:$src1, (load addr:$src2)),
940 (ADD8rm GR8:$src1, addr:$src2)>;
941 def : Pat<(addc GR8:$src1, imm:$src2),
942 (ADD8ri GR8:$src1, imm:$src2)>;
943 def : Pat<(store (addc (load addr:$dst), GR8:$src), addr:$dst),
944 (ADD8mr addr:$dst, GR8:$src)>;
945 def : Pat<(store (addc (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
946 (ADD8mm addr:$dst, addr:$src)>;
948 def : Pat<(subc GR16:$src1, GR16:$src2),
949 (SUB16rr GR16:$src1, GR16:$src2)>;
950 def : Pat<(subc GR16:$src1, (load addr:$src2)),
951 (SUB16rm GR16:$src1, addr:$src2)>;
952 def : Pat<(subc GR16:$src1, imm:$src2),
953 (SUB16ri GR16:$src1, imm:$src2)>;
954 def : Pat<(store (subc (load addr:$dst), GR16:$src), addr:$dst),
955 (SUB16mr addr:$dst, GR16:$src)>;
956 def : Pat<(store (subc (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
957 (SUB16mm addr:$dst, addr:$src)>;
959 def : Pat<(subc GR8:$src1, GR8:$src2),
960 (SUB8rr GR8:$src1, GR8:$src2)>;
961 def : Pat<(subc GR8:$src1, (load addr:$src2)),
962 (SUB8rm GR8:$src1, addr:$src2)>;
963 def : Pat<(subc GR8:$src1, imm:$src2),
964 (SUB8ri GR8:$src1, imm:$src2)>;
965 def : Pat<(store (subc (load addr:$dst), GR8:$src), addr:$dst),
966 (SUB8mr addr:$dst, GR8:$src)>;
967 def : Pat<(store (subc (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
968 (SUB8mm addr:$dst, addr:$src)>;
971 def : Pat<(and GR16:$src, 255), (ZEXT16r GR16:$src)>;
972 def : Pat<(MSP430cmp 0, (trunc (and_su GR16:$src1, GR16:$src2))),
973 (BIT8rr (EXTRACT_SUBREG GR16:$src1, subreg_8bit),
974 (EXTRACT_SUBREG GR16:$src2, subreg_8bit))>;