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))>;
96 //===----------------------------------------------------------------------===//
99 // ADJCALLSTACKDOWN/UP implicitly use/def SP because they may be expanded into
100 // a stack adjustment and the codegen must know that they may modify the stack
101 // pointer before prolog-epilog rewriting occurs.
102 // Pessimistically assume ADJCALLSTACKDOWN / ADJCALLSTACKUP will become
103 // sub / add which can clobber SRW.
104 let Defs = [SPW, SRW], Uses = [SPW] in {
105 def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i16imm:$amt),
107 [(MSP430callseq_start timm:$amt)]>;
108 def ADJCALLSTACKUP : Pseudo<(outs), (ins i16imm:$amt1, i16imm:$amt2),
110 [(MSP430callseq_end timm:$amt1, timm:$amt2)]>;
113 let usesCustomInserter = 1 in {
114 def Select8 : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2, i8imm:$cc),
117 (MSP430selectcc GR8:$src1, GR8:$src2, imm:$cc))]>;
118 def Select16 : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2, i8imm:$cc),
121 (MSP430selectcc GR16:$src1, GR16:$src2, imm:$cc))]>;
124 let neverHasSideEffects = 1 in
125 def NOP : Pseudo<(outs), (ins), "nop", []>;
127 //===----------------------------------------------------------------------===//
128 // Control Flow Instructions...
131 // FIXME: Provide proper encoding!
132 let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
133 def RET : Pseudo<(outs), (ins), "ret", [(MSP430retflag)]>;
134 def RETI : Pseudo<(outs), (ins), "reti", [(MSP430retiflag)]>;
137 let isBranch = 1, isTerminator = 1 in {
141 def JMP : Pseudo<(outs), (ins brtarget:$dst),
145 // Conditional branches
147 def JCC : Pseudo<(outs), (ins brtarget:$dst, cc:$cc),
149 [(MSP430brcc bb:$dst, imm:$cc)]>;
150 } // isBranch, isTerminator
152 //===----------------------------------------------------------------------===//
153 // Call Instructions...
156 // All calls clobber the non-callee saved registers. SPW is marked as
157 // a use to prevent stack-pointer assignments that appear immediately
158 // before calls from potentially appearing dead. Uses for argument
159 // registers are added manually.
160 let Defs = [R12W, R13W, R14W, R15W, SRW],
162 def CALLi : Pseudo<(outs), (ins i16imm:$dst, variable_ops),
163 "call\t$dst", [(MSP430call imm:$dst)]>;
164 def CALLr : Pseudo<(outs), (ins GR16:$dst, variable_ops),
165 "call\t$dst", [(MSP430call GR16:$dst)]>;
166 def CALLm : Pseudo<(outs), (ins memsrc:$dst, variable_ops),
167 "call\t${dst:mem}", [(MSP430call (load addr:$dst))]>;
171 //===----------------------------------------------------------------------===//
172 // Miscellaneous Instructions...
174 let Defs = [SPW], Uses = [SPW], neverHasSideEffects=1 in {
176 def POP16r : Pseudo<(outs GR16:$reg), (ins), "pop.w\t$reg", []>;
179 def PUSH16r : Pseudo<(outs), (ins GR16:$reg), "push.w\t$reg",[]>;
182 //===----------------------------------------------------------------------===//
185 // FIXME: Provide proper encoding!
186 let neverHasSideEffects = 1 in {
187 def MOV8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src),
188 "mov.b\t{$src, $dst}",
190 def MOV16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src),
191 "mov.w\t{$src, $dst}",
195 // FIXME: Provide proper encoding!
196 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
197 def MOV8ri : Pseudo<(outs GR8:$dst), (ins i8imm:$src),
198 "mov.b\t{$src, $dst}",
199 [(set GR8:$dst, imm:$src)]>;
200 def MOV16ri : Pseudo<(outs GR16:$dst), (ins i16imm:$src),
201 "mov.w\t{$src, $dst}",
202 [(set GR16:$dst, imm:$src)]>;
205 let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in {
206 def MOV8rm : Pseudo<(outs GR8:$dst), (ins memsrc:$src),
207 "mov.b\t{$src, $dst}",
208 [(set GR8:$dst, (load addr:$src))]>;
209 def MOV16rm : Pseudo<(outs GR16:$dst), (ins memsrc:$src),
210 "mov.w\t{$src, $dst}",
211 [(set GR16:$dst, (load addr:$src))]>;
214 def MOVZX16rr8 : Pseudo<(outs GR16:$dst), (ins GR8:$src),
215 "mov.b\t{$src, $dst}",
216 [(set GR16:$dst, (zext GR8:$src))]>;
217 def MOVZX16rm8 : Pseudo<(outs GR16:$dst), (ins memsrc:$src),
218 "mov.b\t{$src, $dst}",
219 [(set GR16:$dst, (zextloadi16i8 addr:$src))]>;
221 let mayLoad = 1, hasExtraDefRegAllocReq = 1, Constraints = "$base = $base_wb" in {
222 def MOV8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR16:$base),
223 "mov.b\t{@$base+, $dst}", []>;
224 def MOV16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$base),
225 "mov.w\t{@$base+, $dst}", []>;
228 // Any instruction that defines a 8-bit result leaves the high half of the
229 // register. Truncate can be lowered to EXTRACT_SUBREG, and CopyFromReg may
230 // be copying from a truncate, but any other 8-bit operation will zero-extend
232 def def8 : PatLeaf<(i8 GR8:$src), [{
233 return N->getOpcode() != ISD::TRUNCATE &&
234 N->getOpcode() != TargetInstrInfo::EXTRACT_SUBREG &&
235 N->getOpcode() != ISD::CopyFromReg;
238 // In the case of a 8-bit def that is known to implicitly zero-extend,
239 // we can use a SUBREG_TO_REG.
240 def : Pat<(i16 (zext def8:$src)),
241 (SUBREG_TO_REG (i16 0), GR8:$src, subreg_8bit)>;
244 def MOV8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
245 "mov.b\t{$src, $dst}",
246 [(store (i8 imm:$src), addr:$dst)]>;
247 def MOV16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
248 "mov.w\t{$src, $dst}",
249 [(store (i16 imm:$src), addr:$dst)]>;
251 def MOV8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
252 "mov.b\t{$src, $dst}",
253 [(store GR8:$src, addr:$dst)]>;
254 def MOV16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
255 "mov.w\t{$src, $dst}",
256 [(store GR16:$src, addr:$dst)]>;
258 def MOV8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
259 "mov.b\t{$src, $dst}",
260 [(store (i8 (load addr:$src)), addr:$dst)]>;
261 def MOV16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
262 "mov.w\t{$src, $dst}",
263 [(store (i16 (load addr:$src)), addr:$dst)]>;
265 //===----------------------------------------------------------------------===//
266 // Arithmetic Instructions
268 let isTwoAddress = 1 in {
270 let Defs = [SRW] in {
272 let isCommutable = 1 in { // X = ADD Y, Z == X = ADD Z, Y
273 // FIXME: Provide proper encoding!
274 def ADD8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
275 "add.b\t{$src2, $dst}",
276 [(set GR8:$dst, (add GR8:$src1, GR8:$src2)),
278 def ADD16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
279 "add.w\t{$src2, $dst}",
280 [(set GR16:$dst, (add GR16:$src1, GR16:$src2)),
284 def ADD8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
285 "add.b\t{$src2, $dst}",
286 [(set GR8:$dst, (add GR8:$src1, (load addr:$src2))),
288 def ADD16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
289 "add.w\t{$src2, $dst}",
290 [(set GR16:$dst, (add GR16:$src1, (load addr:$src2))),
293 let mayLoad = 1, hasExtraDefRegAllocReq = 1,
294 Constraints = "$base = $base_wb, $src1 = $dst" in {
295 def ADD8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR8:$src1, GR16:$base),
296 "add.b\t{@$base+, $dst}", []>;
297 def ADD16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$src1, GR16:$base),
298 "add.w\t{@$base+, $dst}", []>;
302 def ADD8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
303 "add.b\t{$src2, $dst}",
304 [(set GR8:$dst, (add GR8:$src1, imm:$src2)),
306 def ADD16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
307 "add.w\t{$src2, $dst}",
308 [(set GR16:$dst, (add GR16:$src1, imm:$src2)),
311 let isTwoAddress = 0 in {
312 def ADD8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
313 "add.b\t{$src, $dst}",
314 [(store (add (load addr:$dst), GR8:$src), addr:$dst),
316 def ADD16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
317 "add.w\t{$src, $dst}",
318 [(store (add (load addr:$dst), GR16:$src), addr:$dst),
321 def ADD8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
322 "add.b\t{$src, $dst}",
323 [(store (add (load addr:$dst), (i8 imm:$src)), addr:$dst),
325 def ADD16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
326 "add.w\t{$src, $dst}",
327 [(store (add (load addr:$dst), (i16 imm:$src)), addr:$dst),
330 def ADD8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
331 "add.b\t{$src, $dst}",
332 [(store (add (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
334 def ADD16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
335 "add.w\t{$src, $dst}",
336 [(store (add (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
340 let Uses = [SRW] in {
342 let isCommutable = 1 in { // X = ADDC Y, Z == X = ADDC Z, Y
343 def ADC8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
344 "addc.b\t{$src2, $dst}",
345 [(set GR8:$dst, (adde GR8:$src1, GR8:$src2)),
347 def ADC16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
348 "addc.w\t{$src2, $dst}",
349 [(set GR16:$dst, (adde GR16:$src1, GR16:$src2)),
353 def ADC8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
354 "addc.b\t{$src2, $dst}",
355 [(set GR8:$dst, (adde GR8:$src1, imm:$src2)),
357 def ADC16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
358 "addc.w\t{$src2, $dst}",
359 [(set GR16:$dst, (adde GR16:$src1, imm:$src2)),
362 def ADC8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
363 "addc.b\t{$src2, $dst}",
364 [(set GR8:$dst, (adde GR8:$src1, (load addr:$src2))),
366 def ADC16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
367 "addc.w\t{$src2, $dst}",
368 [(set GR16:$dst, (adde GR16:$src1, (load addr:$src2))),
371 let isTwoAddress = 0 in {
372 def ADC8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
373 "addc.b\t{$src, $dst}",
374 [(store (adde (load addr:$dst), GR8:$src), addr:$dst),
376 def ADC16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
377 "addc.w\t{$src, $dst}",
378 [(store (adde (load addr:$dst), GR16:$src), addr:$dst),
381 def ADC8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
382 "addc.b\t{$src, $dst}",
383 [(store (adde (load addr:$dst), (i8 imm:$src)), addr:$dst),
385 def ADC16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
386 "addc.w\t{$src, $dst}",
387 [(store (adde (load addr:$dst), (i16 imm:$src)), addr:$dst),
390 def ADC8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
391 "addc.b\t{$src, $dst}",
392 [(store (adde (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
394 def ADC16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
395 "addc.w\t{$src, $dst}",
396 [(store (adde (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
402 let isCommutable = 1 in { // X = AND Y, Z == X = AND Z, Y
403 def AND8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
404 "and.b\t{$src2, $dst}",
405 [(set GR8:$dst, (and GR8:$src1, GR8:$src2)),
407 def AND16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
408 "and.w\t{$src2, $dst}",
409 [(set GR16:$dst, (and GR16:$src1, GR16:$src2)),
413 def AND8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
414 "and.b\t{$src2, $dst}",
415 [(set GR8:$dst, (and GR8:$src1, imm:$src2)),
417 def AND16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
418 "and.w\t{$src2, $dst}",
419 [(set GR16:$dst, (and GR16:$src1, imm:$src2)),
422 def AND8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
423 "and.b\t{$src2, $dst}",
424 [(set GR8:$dst, (and GR8:$src1, (load addr:$src2))),
426 def AND16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
427 "and.w\t{$src2, $dst}",
428 [(set GR16:$dst, (and GR16:$src1, (load addr:$src2))),
431 let mayLoad = 1, hasExtraDefRegAllocReq = 1,
432 Constraints = "$base = $base_wb, $src1 = $dst" in {
433 def AND8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR8:$src1, GR16:$base),
434 "and.b\t{@$base+, $dst}", []>;
435 def AND16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$src1, GR16:$base),
436 "and.w\t{@$base+, $dst}", []>;
439 let isTwoAddress = 0 in {
440 def AND8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
441 "and.b\t{$src, $dst}",
442 [(store (and (load addr:$dst), GR8:$src), addr:$dst),
444 def AND16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
445 "and.w\t{$src, $dst}",
446 [(store (and (load addr:$dst), GR16:$src), addr:$dst),
449 def AND8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
450 "and.b\t{$src, $dst}",
451 [(store (and (load addr:$dst), (i8 imm:$src)), addr:$dst),
453 def AND16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
454 "and.w\t{$src, $dst}",
455 [(store (and (load addr:$dst), (i16 imm:$src)), addr:$dst),
458 def AND8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
459 "and.b\t{$src, $dst}",
460 [(store (and (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
462 def AND16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
463 "and.w\t{$src, $dst}",
464 [(store (and (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
468 let isCommutable = 1 in { // X = OR Y, Z == X = OR Z, Y
469 def OR8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
470 "bis.b\t{$src2, $dst}",
471 [(set GR8:$dst, (or GR8:$src1, GR8:$src2))]>;
472 def OR16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
473 "bis.w\t{$src2, $dst}",
474 [(set GR16:$dst, (or GR16:$src1, GR16:$src2))]>;
477 def OR8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
478 "bis.b\t{$src2, $dst}",
479 [(set GR8:$dst, (or GR8:$src1, imm:$src2))]>;
480 def OR16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
481 "bis.w\t{$src2, $dst}",
482 [(set GR16:$dst, (or GR16:$src1, imm:$src2))]>;
484 def OR8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
485 "bis.b\t{$src2, $dst}",
486 [(set GR8:$dst, (or GR8:$src1, (load addr:$src2)))]>;
487 def OR16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
488 "bis.w\t{$src2, $dst}",
489 [(set GR16:$dst, (or GR16:$src1, (load addr:$src2)))]>;
491 let mayLoad = 1, hasExtraDefRegAllocReq = 1,
492 Constraints = "$base = $base_wb, $src1 = $dst" in {
493 def OR8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR8:$src1, GR16:$base),
494 "bis.b\t{@$base+, $dst}", []>;
495 def OR16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$src1, GR16:$base),
496 "bis.w\t{@$base+, $dst}", []>;
499 let isTwoAddress = 0 in {
500 def OR8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
501 "bis.b\t{$src, $dst}",
502 [(store (or (load addr:$dst), GR8:$src), addr:$dst)]>;
503 def OR16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
504 "bis.w\t{$src, $dst}",
505 [(store (or (load addr:$dst), GR16:$src), addr:$dst)]>;
507 def OR8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
508 "bis.b\t{$src, $dst}",
509 [(store (or (load addr:$dst), (i8 imm:$src)), addr:$dst)]>;
510 def OR16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
511 "bis.w\t{$src, $dst}",
512 [(store (or (load addr:$dst), (i16 imm:$src)), addr:$dst)]>;
514 def OR8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
515 "bis.b\t{$src, $dst}",
516 [(store (or (i8 (load addr:$dst)),
517 (i8 (load addr:$src))), addr:$dst)]>;
518 def OR16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
519 "bis.w\t{$src, $dst}",
520 [(store (or (i16 (load addr:$dst)),
521 (i16 (load addr:$src))), addr:$dst)]>;
524 // bic does not modify condition codes
525 def BIC8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
526 "bic.b\t{$src2, $dst}",
527 [(set GR8:$dst, (and GR8:$src1, (not GR8:$src2)))]>;
528 def BIC16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
529 "bic.w\t{$src2, $dst}",
530 [(set GR16:$dst, (and GR16:$src1, (not GR16:$src2)))]>;
532 def BIC8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
533 "bic.b\t{$src2, $dst}",
534 [(set GR8:$dst, (and GR8:$src1, (not (i8 (load addr:$src2)))))]>;
535 def BIC16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
536 "bic.w\t{$src2, $dst}",
537 [(set GR16:$dst, (and GR16:$src1, (not (i16 (load addr:$src2)))))]>;
539 let isTwoAddress = 0 in {
540 def BIC8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
541 "bic.b\t{$src, $dst}",
542 [(store (and (load addr:$dst), (not GR8:$src)), addr:$dst)]>;
543 def BIC16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
544 "bic.w\t{$src, $dst}",
545 [(store (and (load addr:$dst), (not GR16:$src)), addr:$dst)]>;
547 def BIC8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
548 "bic.b\t{$src, $dst}",
549 [(store (and (load addr:$dst), (not (i8 (load addr:$src)))), addr:$dst)]>;
550 def BIC16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
551 "bic.w\t{$src, $dst}",
552 [(store (and (load addr:$dst), (not (i16 (load addr:$src)))), addr:$dst)]>;
555 let isCommutable = 1 in { // X = XOR Y, Z == X = XOR Z, Y
556 def XOR8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
557 "xor.b\t{$src2, $dst}",
558 [(set GR8:$dst, (xor GR8:$src1, GR8:$src2)),
560 def XOR16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
561 "xor.w\t{$src2, $dst}",
562 [(set GR16:$dst, (xor GR16:$src1, GR16:$src2)),
566 def XOR8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
567 "xor.b\t{$src2, $dst}",
568 [(set GR8:$dst, (xor GR8:$src1, imm:$src2)),
570 def XOR16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
571 "xor.w\t{$src2, $dst}",
572 [(set GR16:$dst, (xor GR16:$src1, imm:$src2)),
575 def XOR8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
576 "xor.b\t{$src2, $dst}",
577 [(set GR8:$dst, (xor GR8:$src1, (load addr:$src2))),
579 def XOR16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
580 "xor.w\t{$src2, $dst}",
581 [(set GR16:$dst, (xor GR16:$src1, (load addr:$src2))),
584 let mayLoad = 1, hasExtraDefRegAllocReq = 1,
585 Constraints = "$base = $base_wb, $src1 = $dst" in {
586 def XOR8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR8:$src1, GR16:$base),
587 "xor.b\t{@$base+, $dst}", []>;
588 def XOR16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$src1, GR16:$base),
589 "xor.w\t{@$base+, $dst}", []>;
592 let isTwoAddress = 0 in {
593 def XOR8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
594 "xor.b\t{$src, $dst}",
595 [(store (xor (load addr:$dst), GR8:$src), addr:$dst),
597 def XOR16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
598 "xor.w\t{$src, $dst}",
599 [(store (xor (load addr:$dst), GR16:$src), addr:$dst),
602 def XOR8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
603 "xor.b\t{$src, $dst}",
604 [(store (xor (load addr:$dst), (i8 imm:$src)), addr:$dst),
606 def XOR16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
607 "xor.w\t{$src, $dst}",
608 [(store (xor (load addr:$dst), (i16 imm:$src)), addr:$dst),
611 def XOR8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
612 "xor.b\t{$src, $dst}",
613 [(store (xor (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
615 def XOR16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
616 "xor.w\t{$src, $dst}",
617 [(store (xor (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
622 def SUB8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
623 "sub.b\t{$src2, $dst}",
624 [(set GR8:$dst, (sub GR8:$src1, GR8:$src2)),
626 def SUB16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
627 "sub.w\t{$src2, $dst}",
628 [(set GR16:$dst, (sub GR16:$src1, GR16:$src2)),
631 def SUB8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
632 "sub.b\t{$src2, $dst}",
633 [(set GR8:$dst, (sub GR8:$src1, imm:$src2)),
635 def SUB16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
636 "sub.w\t{$src2, $dst}",
637 [(set GR16:$dst, (sub GR16:$src1, imm:$src2)),
640 def SUB8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
641 "sub.b\t{$src2, $dst}",
642 [(set GR8:$dst, (sub GR8:$src1, (load addr:$src2))),
644 def SUB16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
645 "sub.w\t{$src2, $dst}",
646 [(set GR16:$dst, (sub GR16:$src1, (load addr:$src2))),
649 let mayLoad = 1, hasExtraDefRegAllocReq = 1,
650 Constraints = "$base = $base_wb, $src1 = $dst" in {
651 def SUB8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR8:$src1, GR16:$base),
652 "sub.b\t{@$base+, $dst}", []>;
653 def SUB16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$src1, GR16:$base),
654 "sub.w\t{@$base+, $dst}", []>;
657 let isTwoAddress = 0 in {
658 def SUB8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
659 "sub.b\t{$src, $dst}",
660 [(store (sub (load addr:$dst), GR8:$src), addr:$dst),
662 def SUB16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
663 "sub.w\t{$src, $dst}",
664 [(store (sub (load addr:$dst), GR16:$src), addr:$dst),
667 def SUB8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
668 "sub.b\t{$src, $dst}",
669 [(store (sub (load addr:$dst), (i8 imm:$src)), addr:$dst),
671 def SUB16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
672 "sub.w\t{$src, $dst}",
673 [(store (sub (load addr:$dst), (i16 imm:$src)), addr:$dst),
676 def SUB8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
677 "sub.b\t{$src, $dst}",
678 [(store (sub (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
680 def SUB16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
681 "sub.w\t{$src, $dst}",
682 [(store (sub (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
686 let Uses = [SRW] in {
687 def SBC8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
688 "subc.b\t{$src2, $dst}",
689 [(set GR8:$dst, (sube GR8:$src1, GR8:$src2)),
691 def SBC16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
692 "subc.w\t{$src2, $dst}",
693 [(set GR16:$dst, (sube GR16:$src1, GR16:$src2)),
696 def SBC8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
697 "subc.b\t{$src2, $dst}",
698 [(set GR8:$dst, (sube GR8:$src1, imm:$src2)),
700 def SBC16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
701 "subc.w\t{$src2, $dst}",
702 [(set GR16:$dst, (sube GR16:$src1, imm:$src2)),
705 def SBC8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
706 "subc.b\t{$src2, $dst}",
707 [(set GR8:$dst, (sube GR8:$src1, (load addr:$src2))),
709 def SBC16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
710 "subc.w\t{$src2, $dst}",
711 [(set GR16:$dst, (sube GR16:$src1, (load addr:$src2))),
714 let isTwoAddress = 0 in {
715 def SBC8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
716 "subc.b\t{$src, $dst}",
717 [(store (sube (load addr:$dst), GR8:$src), addr:$dst),
719 def SBC16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
720 "subc.w\t{$src, $dst}",
721 [(store (sube (load addr:$dst), GR16:$src), addr:$dst),
724 def SBC8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
725 "subc.b\t{$src, $dst}",
726 [(store (sube (load addr:$dst), (i8 imm:$src)), addr:$dst),
728 def SBC16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
729 "subc.w\t{$src, $dst}",
730 [(store (sube (load addr:$dst), (i16 imm:$src)), addr:$dst),
733 def SBC8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
734 "subc.b\t{$src, $dst}",
735 [(store (sube (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
737 def SBC16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
738 "subc.w\t{$src, $dst}",
739 [(store (sube (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
745 // FIXME: Provide proper encoding!
746 def SAR8r1 : Pseudo<(outs GR8:$dst), (ins GR8:$src),
748 [(set GR8:$dst, (MSP430rra GR8:$src)),
750 def SAR16r1 : Pseudo<(outs GR16:$dst), (ins GR16:$src),
752 [(set GR16:$dst, (MSP430rra GR16:$src)),
755 def SHL8r1 : Pseudo<(outs GR8:$dst), (ins GR8:$src),
757 [(set GR8:$dst, (MSP430rla GR8:$src)),
759 def SHL16r1 : Pseudo<(outs GR16:$dst), (ins GR16:$src),
761 [(set GR16:$dst, (MSP430rla GR16:$src)),
764 def SAR8r1c : Pseudo<(outs GR8:$dst), (ins GR8:$src),
767 [(set GR8:$dst, (MSP430rrc GR8:$src)),
769 def SAR16r1c : Pseudo<(outs GR16:$dst), (ins GR16:$src),
772 [(set GR16:$dst, (MSP430rrc GR16:$src)),
775 def SEXT16r : Pseudo<(outs GR16:$dst), (ins GR16:$src),
777 [(set GR16:$dst, (sext_inreg GR16:$src, i8)),
782 def ZEXT16r : Pseudo<(outs GR16:$dst), (ins GR16:$src),
783 "mov.b\t{$src, $dst}",
784 [(set GR16:$dst, (zext (trunc GR16:$src)))]>;
786 def SWPB16r : Pseudo<(outs GR16:$dst), (ins GR16:$src),
788 [(set GR16:$dst, (bswap GR16:$src))]>;
790 } // isTwoAddress = 1
792 // Integer comparisons
793 let Defs = [SRW] in {
794 def CMP8rr : Pseudo<(outs), (ins GR8:$src1, GR8:$src2),
795 "cmp.b\t{$src1, $src2}",
796 [(MSP430cmp GR8:$src1, GR8:$src2), (implicit SRW)]>;
797 def CMP16rr : Pseudo<(outs), (ins GR16:$src1, GR16:$src2),
798 "cmp.w\t{$src1, $src2}",
799 [(MSP430cmp GR16:$src1, GR16:$src2), (implicit SRW)]>;
801 def CMP8ir : Pseudo<(outs), (ins i8imm:$src1, GR8:$src2),
802 "cmp.b\t{$src1, $src2}",
803 [(MSP430cmp imm:$src1, GR8:$src2), (implicit SRW)]>;
804 def CMP16ir : Pseudo<(outs), (ins i16imm:$src1, GR16:$src2),
805 "cmp.w\t{$src1, $src2}",
806 [(MSP430cmp imm:$src1, GR16:$src2), (implicit SRW)]>;
808 def CMP8im : Pseudo<(outs), (ins i8imm:$src1, memsrc:$src2),
809 "cmp.b\t{$src1, $src2}",
810 [(MSP430cmp (i8 imm:$src1), (load addr:$src2)), (implicit SRW)]>;
811 def CMP16im : Pseudo<(outs), (ins i16imm:$src1, memsrc:$src2),
812 "cmp.w\t{$src1, $src2}",
813 [(MSP430cmp (i16 imm:$src1), (load addr:$src2)), (implicit SRW)]>;
815 def CMP8rm : Pseudo<(outs), (ins GR8:$src1, memsrc:$src2),
816 "cmp.b\t{$src1, $src2}",
817 [(MSP430cmp GR8:$src1, (load addr:$src2)), (implicit SRW)]>;
818 def CMP16rm : Pseudo<(outs), (ins GR16:$src1, memsrc:$src2),
819 "cmp.w\t{$src1, $src2}",
820 [(MSP430cmp GR16:$src1, (load addr:$src2)), (implicit SRW)]>;
822 def CMP8mr : Pseudo<(outs), (ins memsrc:$src1, GR8:$src2),
823 "cmp.b\t{$src1, $src2}",
824 [(MSP430cmp (load addr:$src1), GR8:$src2), (implicit SRW)]>;
825 def CMP16mr : Pseudo<(outs), (ins memsrc:$src1, GR16:$src2),
826 "cmp.w\t{$src1, $src2}",
827 [(MSP430cmp (load addr:$src1), GR16:$src2), (implicit SRW)]>;
831 //===----------------------------------------------------------------------===//
832 // Non-Instruction Patterns
835 def : Pat<(extloadi16i8 addr:$src), (MOVZX16rm8 addr:$src)>;
838 def : Pat<(anyext addr:$src), (MOVZX16rr8 GR8:$src)>;
841 def : Pat<(i8 (trunc GR16:$src)),
842 (EXTRACT_SUBREG GR16:$src, subreg_8bit)>;
844 // GlobalAddress, ExternalSymbol
845 def : Pat<(i16 (MSP430Wrapper tglobaladdr:$dst)), (MOV16ri tglobaladdr:$dst)>;
846 def : Pat<(i16 (MSP430Wrapper texternalsym:$dst)), (MOV16ri texternalsym:$dst)>;
848 def : Pat<(add GR16:$src1, (MSP430Wrapper tglobaladdr :$src2)),
849 (ADD16ri GR16:$src1, tglobaladdr:$src2)>;
850 def : Pat<(add GR16:$src1, (MSP430Wrapper texternalsym:$src2)),
851 (ADD16ri GR16:$src1, texternalsym:$src2)>;
853 def : Pat<(store (i16 (MSP430Wrapper tglobaladdr:$src)), addr:$dst),
854 (MOV16mi addr:$dst, tglobaladdr:$src)>;
855 def : Pat<(store (i16 (MSP430Wrapper texternalsym:$src)), addr:$dst),
856 (MOV16mi addr:$dst, texternalsym:$src)>;
859 def : Pat<(MSP430call (i16 tglobaladdr:$dst)),
860 (CALLi tglobaladdr:$dst)>;
861 def : Pat<(MSP430call (i16 texternalsym:$dst)),
862 (CALLi texternalsym:$dst)>;
864 // add and sub always produce carry
865 def : Pat<(addc GR16:$src1, GR16:$src2),
866 (ADD16rr GR16:$src1, GR16:$src2)>;
867 def : Pat<(addc GR16:$src1, (load addr:$src2)),
868 (ADD16rm GR16:$src1, addr:$src2)>;
869 def : Pat<(addc GR16:$src1, imm:$src2),
870 (ADD16ri GR16:$src1, imm:$src2)>;
871 def : Pat<(store (addc (load addr:$dst), GR16:$src), addr:$dst),
872 (ADD16mr addr:$dst, GR16:$src)>;
873 def : Pat<(store (addc (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
874 (ADD16mm addr:$dst, addr:$src)>;
876 def : Pat<(addc GR8:$src1, GR8:$src2),
877 (ADD8rr GR8:$src1, GR8:$src2)>;
878 def : Pat<(addc GR8:$src1, (load addr:$src2)),
879 (ADD8rm GR8:$src1, addr:$src2)>;
880 def : Pat<(addc GR8:$src1, imm:$src2),
881 (ADD8ri GR8:$src1, imm:$src2)>;
882 def : Pat<(store (addc (load addr:$dst), GR8:$src), addr:$dst),
883 (ADD8mr addr:$dst, GR8:$src)>;
884 def : Pat<(store (addc (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
885 (ADD8mm addr:$dst, addr:$src)>;
887 def : Pat<(subc GR16:$src1, GR16:$src2),
888 (SUB16rr GR16:$src1, GR16:$src2)>;
889 def : Pat<(subc GR16:$src1, (load addr:$src2)),
890 (SUB16rm GR16:$src1, addr:$src2)>;
891 def : Pat<(subc GR16:$src1, imm:$src2),
892 (SUB16ri GR16:$src1, imm:$src2)>;
893 def : Pat<(store (subc (load addr:$dst), GR16:$src), addr:$dst),
894 (SUB16mr addr:$dst, GR16:$src)>;
895 def : Pat<(store (subc (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
896 (SUB16mm addr:$dst, addr:$src)>;
898 def : Pat<(subc GR8:$src1, GR8:$src2),
899 (SUB8rr GR8:$src1, GR8:$src2)>;
900 def : Pat<(subc GR8:$src1, (load addr:$src2)),
901 (SUB8rm GR8:$src1, addr:$src2)>;
902 def : Pat<(subc GR8:$src1, imm:$src2),
903 (SUB8ri GR8:$src1, imm:$src2)>;
904 def : Pat<(store (subc (load addr:$dst), GR8:$src), addr:$dst),
905 (SUB8mr addr:$dst, GR8:$src)>;
906 def : Pat<(store (subc (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
907 (SUB8mm addr:$dst, addr:$src)>;
910 def : Pat<(and GR16:$src, 255), (ZEXT16r GR16:$src)>;