MSP430InstrInfo.td revision 8f8e9f08300f62db802767c9fb23b40aab66e51e
1//===- MSP430InstrInfo.td - MSP430 Instruction defs -----------*- tblgen-*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file describes the MSP430 instructions in TableGen format. 11// 12//===----------------------------------------------------------------------===// 13 14include "MSP430InstrFormats.td" 15 16//===----------------------------------------------------------------------===// 17// Type Constraints. 18//===----------------------------------------------------------------------===// 19class SDTCisI8<int OpNum> : SDTCisVT<OpNum, i8>; 20class SDTCisI16<int OpNum> : SDTCisVT<OpNum, i16>; 21 22//===----------------------------------------------------------------------===// 23// Type Profiles. 24//===----------------------------------------------------------------------===// 25def SDT_MSP430Call : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>; 26def SDT_MSP430CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i16>]>; 27def SDT_MSP430CallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i16>, SDTCisVT<1, i16>]>; 28def SDT_MSP430Wrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>; 29def SDT_MSP430Cmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>; 30def SDT_MSP430BrCC : SDTypeProfile<0, 2, [SDTCisVT<0, OtherVT>, 31 SDTCisVT<1, i8>]>; 32def SDT_MSP430SelectCC : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, 33 SDTCisVT<3, i8>]>; 34 35//===----------------------------------------------------------------------===// 36// MSP430 Specific Node Definitions. 37//===----------------------------------------------------------------------===// 38def MSP430retflag : SDNode<"MSP430ISD::RET_FLAG", SDTNone, 39 [SDNPHasChain, SDNPOptInFlag]>; 40 41def MSP430rra : SDNode<"MSP430ISD::RRA", SDTIntUnaryOp, []>; 42def MSP430rla : SDNode<"MSP430ISD::RLA", SDTIntUnaryOp, []>; 43def MSP430rrc : SDNode<"MSP430ISD::RRC", SDTIntUnaryOp, []>; 44 45def MSP430call : SDNode<"MSP430ISD::CALL", SDT_MSP430Call, 46 [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag]>; 47def MSP430callseq_start : 48 SDNode<"ISD::CALLSEQ_START", SDT_MSP430CallSeqStart, 49 [SDNPHasChain, SDNPOutFlag]>; 50def MSP430callseq_end : 51 SDNode<"ISD::CALLSEQ_END", SDT_MSP430CallSeqEnd, 52 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; 53def MSP430Wrapper : SDNode<"MSP430ISD::Wrapper", SDT_MSP430Wrapper>; 54def MSP430cmp : SDNode<"MSP430ISD::CMP", SDT_MSP430Cmp, [SDNPOutFlag]>; 55def MSP430brcc : SDNode<"MSP430ISD::BR_CC", SDT_MSP430BrCC, [SDNPHasChain, SDNPInFlag]>; 56def MSP430selectcc: SDNode<"MSP430ISD::SELECT_CC", SDT_MSP430SelectCC, [SDNPInFlag]>; 57 58//===----------------------------------------------------------------------===// 59// MSP430 Operand Definitions. 60//===----------------------------------------------------------------------===// 61 62// Address operands 63def memsrc : Operand<i16> { 64 let PrintMethod = "printSrcMemOperand"; 65 let MIOperandInfo = (ops GR16, i16imm); 66} 67 68def memdst : Operand<i16> { 69 let PrintMethod = "printSrcMemOperand"; 70 let MIOperandInfo = (ops GR16, i16imm); 71} 72 73// Branch targets have OtherVT type. 74def brtarget : Operand<OtherVT>; 75 76// Operand for printing out a condition code. 77def cc : Operand<i8> { 78 let PrintMethod = "printCCOperand"; 79} 80 81//===----------------------------------------------------------------------===// 82// MSP430 Complex Pattern Definitions. 83//===----------------------------------------------------------------------===// 84 85def addr : ComplexPattern<iPTR, 2, "SelectAddr", [], []>; 86 87//===----------------------------------------------------------------------===// 88// Pattern Fragments 89def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>; 90def extloadi16i8 : PatFrag<(ops node:$ptr), (i16 ( extloadi8 node:$ptr))>; 91 92//===----------------------------------------------------------------------===// 93// Instruction list.. 94 95// ADJCALLSTACKDOWN/UP implicitly use/def SP because they may be expanded into 96// a stack adjustment and the codegen must know that they may modify the stack 97// pointer before prolog-epilog rewriting occurs. 98// Pessimistically assume ADJCALLSTACKDOWN / ADJCALLSTACKUP will become 99// sub / add which can clobber SRW. 100let Defs = [SPW, SRW], Uses = [SPW] in { 101def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i16imm:$amt), 102 "#ADJCALLSTACKDOWN", 103 [(MSP430callseq_start timm:$amt)]>; 104def ADJCALLSTACKUP : Pseudo<(outs), (ins i16imm:$amt1, i16imm:$amt2), 105 "#ADJCALLSTACKUP", 106 [(MSP430callseq_end timm:$amt1, timm:$amt2)]>; 107} 108 109let usesCustomDAGSchedInserter = 1 in { 110 def Select8 : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2, i8imm:$cc), 111 "# Select8 PSEUDO", 112 [(set GR8:$dst, 113 (MSP430selectcc GR8:$src1, GR8:$src2, imm:$cc))]>; 114 def Select16 : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2, i8imm:$cc), 115 "# Select16 PSEUDO", 116 [(set GR16:$dst, 117 (MSP430selectcc GR16:$src1, GR16:$src2, imm:$cc))]>; 118} 119 120let neverHasSideEffects = 1 in 121def NOP : Pseudo<(outs), (ins), "nop", []>; 122 123//===----------------------------------------------------------------------===// 124// Control Flow Instructions... 125// 126 127// FIXME: Provide proper encoding! 128let isReturn = 1, isTerminator = 1 in { 129 def RET : Pseudo<(outs), (ins), "ret", [(MSP430retflag)]>; 130} 131 132let isBranch = 1, isTerminator = 1 in { 133 134// Direct branch 135let isBarrier = 1 in 136 def JMP : Pseudo<(outs), (ins brtarget:$dst), 137 "jmp\t$dst", 138 [(br bb:$dst)]>; 139 140// Conditional branches 141let Uses = [SRW] in 142 def JCC : Pseudo<(outs), (ins brtarget:$dst, cc:$cc), 143 "j$cc $dst", 144 [(MSP430brcc bb:$dst, imm:$cc)]>; 145} // isBranch, isTerminator 146 147//===----------------------------------------------------------------------===// 148// Call Instructions... 149// 150let isCall = 1 in 151 // All calls clobber the non-callee saved registers. SPW is marked as 152 // a use to prevent stack-pointer assignments that appear immediately 153 // before calls from potentially appearing dead. Uses for argument 154 // registers are added manually. 155 let Defs = [R12W, R13W, R14W, R15W, SRW], 156 Uses = [SPW] in { 157 def CALLi : Pseudo<(outs), (ins i16imm:$dst, variable_ops), 158 "call\t${dst:call}", [(MSP430call imm:$dst)]>; 159 def CALLr : Pseudo<(outs), (ins GR16:$dst, variable_ops), 160 "call\t$dst", [(MSP430call GR16:$dst)]>; 161 def CALLm : Pseudo<(outs), (ins memsrc:$dst, variable_ops), 162 "call\t${dst:mem}", [(MSP430call (load addr:$dst))]>; 163 } 164 165 166//===----------------------------------------------------------------------===// 167// Miscellaneous Instructions... 168// 169let Defs = [SPW], Uses = [SPW], neverHasSideEffects=1 in { 170let mayLoad = 1 in 171def POP16r : Pseudo<(outs GR16:$reg), (ins), "pop.w\t$reg", []>; 172 173let mayStore = 1 in 174def PUSH16r : Pseudo<(outs), (ins GR16:$reg), "push.w\t$reg",[]>; 175} 176 177//===----------------------------------------------------------------------===// 178// Move Instructions 179 180// FIXME: Provide proper encoding! 181let neverHasSideEffects = 1 in { 182def MOV8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src), 183 "mov.b\t{$src, $dst}", 184 []>; 185def MOV16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src), 186 "mov.w\t{$src, $dst}", 187 []>; 188} 189 190// FIXME: Provide proper encoding! 191let isReMaterializable = 1, isAsCheapAsAMove = 1 in { 192def MOV8ri : Pseudo<(outs GR8:$dst), (ins i8imm:$src), 193 "mov.b\t{$src, $dst}", 194 [(set GR8:$dst, imm:$src)]>; 195def MOV16ri : Pseudo<(outs GR16:$dst), (ins i16imm:$src), 196 "mov.w\t{$src, $dst}", 197 [(set GR16:$dst, imm:$src)]>; 198} 199 200let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in { 201def MOV8rm : Pseudo<(outs GR8:$dst), (ins memsrc:$src), 202 "mov.b\t{$src, $dst}", 203 [(set GR8:$dst, (load addr:$src))]>; 204def MOV16rm : Pseudo<(outs GR16:$dst), (ins memsrc:$src), 205 "mov.w\t{$src, $dst}", 206 [(set GR16:$dst, (load addr:$src))]>; 207} 208 209def MOVZX16rr8 : Pseudo<(outs GR16:$dst), (ins GR8:$src), 210 "mov.b\t{$src, $dst}", 211 [(set GR16:$dst, (zext GR8:$src))]>; 212def MOVZX16rm8 : Pseudo<(outs GR16:$dst), (ins memsrc:$src), 213 "mov.b\t{$src, $dst}", 214 [(set GR16:$dst, (zextloadi16i8 addr:$src))]>; 215 216// Any instruction that defines a 8-bit result leaves the high half of the 217// register. Truncate can be lowered to EXTRACT_SUBREG, and CopyFromReg may 218// be copying from a truncate, but any other 8-bit operation will zero-extend 219// up to 16 bits. 220def def8 : PatLeaf<(i8 GR8:$src), [{ 221 return N->getOpcode() != ISD::TRUNCATE && 222 N->getOpcode() != TargetInstrInfo::EXTRACT_SUBREG && 223 N->getOpcode() != ISD::CopyFromReg; 224}]>; 225 226// In the case of a 8-bit def that is known to implicitly zero-extend, 227// we can use a SUBREG_TO_REG. 228def : Pat<(i16 (zext def8:$src)), 229 (SUBREG_TO_REG (i16 0), GR8:$src, subreg_8bit)>; 230 231 232def MOV8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src), 233 "mov.b\t{$src, $dst}", 234 [(store (i8 imm:$src), addr:$dst)]>; 235def MOV16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src), 236 "mov.w\t{$src, $dst}", 237 [(store (i16 imm:$src), addr:$dst)]>; 238 239def MOV8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src), 240 "mov.b\t{$src, $dst}", 241 [(store GR8:$src, addr:$dst)]>; 242def MOV16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src), 243 "mov.w\t{$src, $dst}", 244 [(store GR16:$src, addr:$dst)]>; 245 246//===----------------------------------------------------------------------===// 247// Arithmetic Instructions 248 249let isTwoAddress = 1 in { 250 251let Defs = [SRW] in { 252 253let isCommutable = 1 in { // X = ADD Y, Z == X = ADD Z, Y 254// FIXME: Provide proper encoding! 255def ADD8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2), 256 "add.b\t{$src2, $dst}", 257 [(set GR8:$dst, (add GR8:$src1, GR8:$src2)), 258 (implicit SRW)]>; 259def ADD16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2), 260 "add.w\t{$src2, $dst}", 261 [(set GR16:$dst, (add GR16:$src1, GR16:$src2)), 262 (implicit SRW)]>; 263} 264 265def ADD8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2), 266 "add.b\t{$src2, $dst}", 267 [(set GR8:$dst, (add GR8:$src1, (load addr:$src2))), 268 (implicit SRW)]>; 269def ADD16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2), 270 "add.w\t{$src2, $dst}", 271 [(set GR16:$dst, (add GR16:$src1, (load addr:$src2))), 272 (implicit SRW)]>; 273 274def ADD8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2), 275 "add.b\t{$src2, $dst}", 276 [(set GR8:$dst, (add GR8:$src1, imm:$src2)), 277 (implicit SRW)]>; 278def ADD16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2), 279 "add.w\t{$src2, $dst}", 280 [(set GR16:$dst, (add GR16:$src1, imm:$src2)), 281 (implicit SRW)]>; 282 283let isTwoAddress = 0 in { 284def ADD8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src), 285 "add.b\t{$src, $dst}", 286 [(store (add (load addr:$dst), GR8:$src), addr:$dst), 287 (implicit SRW)]>; 288def ADD16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src), 289 "add.w\t{$src, $dst}", 290 [(store (add (load addr:$dst), GR16:$src), addr:$dst), 291 (implicit SRW)]>; 292 293def ADD8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src), 294 "add.b\t{$src, $dst}", 295 [(store (add (load addr:$dst), (i8 imm:$src)), addr:$dst), 296 (implicit SRW)]>; 297def ADD16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src), 298 "add.w\t{$src, $dst}", 299 [(store (add (load addr:$dst), (i16 imm:$src)), addr:$dst), 300 (implicit SRW)]>; 301 302def ADD8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src), 303 "add.b\t{$src, $dst}", 304 [(store (add (load addr:$dst), (i8 (load addr:$src))), addr:$dst), 305 (implicit SRW)]>; 306def ADD16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src), 307 "add.w\t{$src, $dst}", 308 [(store (add (load addr:$dst), (i16 (load addr:$src))), addr:$dst), 309 (implicit SRW)]>; 310} 311 312let Uses = [SRW] in { 313 314let isCommutable = 1 in { // X = ADDC Y, Z == X = ADDC Z, Y 315def ADC8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2), 316 "addc.b\t{$src2, $dst}", 317 [(set GR8:$dst, (adde GR8:$src1, GR8:$src2)), 318 (implicit SRW)]>; 319def ADC16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2), 320 "addc.w\t{$src2, $dst}", 321 [(set GR16:$dst, (adde GR16:$src1, GR16:$src2)), 322 (implicit SRW)]>; 323} // isCommutable 324 325def ADC8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2), 326 "addc.b\t{$src2, $dst}", 327 [(set GR8:$dst, (adde GR8:$src1, imm:$src2)), 328 (implicit SRW)]>; 329def ADC16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2), 330 "addc.w\t{$src2, $dst}", 331 [(set GR16:$dst, (adde GR16:$src1, imm:$src2)), 332 (implicit SRW)]>; 333 334def ADC8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2), 335 "addc.b\t{$src2, $dst}", 336 [(set GR8:$dst, (adde GR8:$src1, (load addr:$src2))), 337 (implicit SRW)]>; 338def ADC16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2), 339 "addc.w\t{$src2, $dst}", 340 [(set GR16:$dst, (adde GR16:$src1, (load addr:$src2))), 341 (implicit SRW)]>; 342 343let isTwoAddress = 0 in { 344def ADC8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src), 345 "addc.b\t{$src, $dst}", 346 [(store (adde (load addr:$dst), GR8:$src), addr:$dst), 347 (implicit SRW)]>; 348def ADC16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src), 349 "addc.w\t{$src, $dst}", 350 [(store (adde (load addr:$dst), GR16:$src), addr:$dst), 351 (implicit SRW)]>; 352 353def ADC8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src), 354 "addc.b\t{$src, $dst}", 355 [(store (adde (load addr:$dst), (i8 imm:$src)), addr:$dst), 356 (implicit SRW)]>; 357def ADC16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src), 358 "addc.w\t{$src, $dst}", 359 [(store (adde (load addr:$dst), (i16 imm:$src)), addr:$dst), 360 (implicit SRW)]>; 361 362def ADC8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src), 363 "addc.b\t{$src, $dst}", 364 [(store (adde (load addr:$dst), (i8 (load addr:$src))), addr:$dst), 365 (implicit SRW)]>; 366def ADC16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src), 367 "addc.w\t{$src, $dst}", 368 [(store (adde (load addr:$dst), (i16 (load addr:$src))), addr:$dst), 369 (implicit SRW)]>; 370} 371 372} // Uses = [SRW] 373 374let isCommutable = 1 in { // X = AND Y, Z == X = AND Z, Y 375def AND8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2), 376 "and.b\t{$src2, $dst}", 377 [(set GR8:$dst, (and GR8:$src1, GR8:$src2)), 378 (implicit SRW)]>; 379def AND16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2), 380 "and.w\t{$src2, $dst}", 381 [(set GR16:$dst, (and GR16:$src1, GR16:$src2)), 382 (implicit SRW)]>; 383} 384 385def AND8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2), 386 "and.b\t{$src2, $dst}", 387 [(set GR8:$dst, (and GR8:$src1, imm:$src2)), 388 (implicit SRW)]>; 389def AND16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2), 390 "and.w\t{$src2, $dst}", 391 [(set GR16:$dst, (and GR16:$src1, imm:$src2)), 392 (implicit SRW)]>; 393 394def AND8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2), 395 "and.b\t{$src2, $dst}", 396 [(set GR8:$dst, (and GR8:$src1, (load addr:$src2))), 397 (implicit SRW)]>; 398def AND16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2), 399 "and.w\t{$src2, $dst}", 400 [(set GR16:$dst, (and GR16:$src1, (load addr:$src2))), 401 (implicit SRW)]>; 402 403let isTwoAddress = 0 in { 404def AND8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src), 405 "and.b\t{$src, $dst}", 406 [(store (and (load addr:$dst), GR8:$src), addr:$dst), 407 (implicit SRW)]>; 408def AND16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src), 409 "and.w\t{$src, $dst}", 410 [(store (and (load addr:$dst), GR16:$src), addr:$dst), 411 (implicit SRW)]>; 412 413def AND8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src), 414 "and.b\t{$src, $dst}", 415 [(store (and (load addr:$dst), (i8 imm:$src)), addr:$dst), 416 (implicit SRW)]>; 417def AND16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src), 418 "and.w\t{$src, $dst}", 419 [(store (and (load addr:$dst), (i16 imm:$src)), addr:$dst), 420 (implicit SRW)]>; 421 422def AND8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src), 423 "and.b\t{$src, $dst}", 424 [(store (and (load addr:$dst), (i8 (load addr:$src))), addr:$dst), 425 (implicit SRW)]>; 426def AND16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src), 427 "and.w\t{$src, $dst}", 428 [(store (and (load addr:$dst), (i16 (load addr:$src))), addr:$dst), 429 (implicit SRW)]>; 430} 431 432 433let isCommutable = 1 in { // X = XOR Y, Z == X = XOR Z, Y 434def XOR8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2), 435 "xor.b\t{$src2, $dst}", 436 [(set GR8:$dst, (xor GR8:$src1, GR8:$src2)), 437 (implicit SRW)]>; 438def XOR16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2), 439 "xor.w\t{$src2, $dst}", 440 [(set GR16:$dst, (xor GR16:$src1, GR16:$src2)), 441 (implicit SRW)]>; 442} 443 444def XOR8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2), 445 "xor.b\t{$src2, $dst}", 446 [(set GR8:$dst, (xor GR8:$src1, imm:$src2)), 447 (implicit SRW)]>; 448def XOR16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2), 449 "xor.w\t{$src2, $dst}", 450 [(set GR16:$dst, (xor GR16:$src1, imm:$src2)), 451 (implicit SRW)]>; 452 453def XOR8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2), 454 "xor.b\t{$src2, $dst}", 455 [(set GR8:$dst, (xor GR8:$src1, (load addr:$src2))), 456 (implicit SRW)]>; 457def XOR16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2), 458 "xor.w\t{$src2, $dst}", 459 [(set GR16:$dst, (xor GR16:$src1, (load addr:$src2))), 460 (implicit SRW)]>; 461 462let isTwoAddress = 0 in { 463def XOR8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src), 464 "xor.b\t{$src, $dst}", 465 [(store (xor (load addr:$dst), GR8:$src), addr:$dst), 466 (implicit SRW)]>; 467def XOR16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src), 468 "xor.w\t{$src, $dst}", 469 [(store (xor (load addr:$dst), GR16:$src), addr:$dst), 470 (implicit SRW)]>; 471 472def XOR8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src), 473 "xor.b\t{$src, $dst}", 474 [(store (xor (load addr:$dst), (i8 imm:$src)), addr:$dst), 475 (implicit SRW)]>; 476def XOR16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src), 477 "xor.w\t{$src, $dst}", 478 [(store (xor (load addr:$dst), (i16 imm:$src)), addr:$dst), 479 (implicit SRW)]>; 480 481def XOR8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src), 482 "xor.b\t{$src, $dst}", 483 [(store (xor (load addr:$dst), (i8 (load addr:$src))), addr:$dst), 484 (implicit SRW)]>; 485def XOR16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src), 486 "xor.w\t{$src, $dst}", 487 [(store (xor (load addr:$dst), (i16 (load addr:$src))), addr:$dst), 488 (implicit SRW)]>; 489} 490 491 492def SUB8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2), 493 "sub.b\t{$src2, $dst}", 494 [(set GR8:$dst, (sub GR8:$src1, GR8:$src2)), 495 (implicit SRW)]>; 496def SUB16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2), 497 "sub.w\t{$src2, $dst}", 498 [(set GR16:$dst, (sub GR16:$src1, GR16:$src2)), 499 (implicit SRW)]>; 500 501def SUB8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2), 502 "sub.b\t{$src2, $dst}", 503 [(set GR8:$dst, (sub GR8:$src1, imm:$src2)), 504 (implicit SRW)]>; 505def SUB16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2), 506 "sub.w\t{$src2, $dst}", 507 [(set GR16:$dst, (sub GR16:$src1, imm:$src2)), 508 (implicit SRW)]>; 509 510def SUB8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2), 511 "sub.b\t{$src2, $dst}", 512 [(set GR8:$dst, (sub GR8:$src1, (load addr:$src2))), 513 (implicit SRW)]>; 514def SUB16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2), 515 "sub.w\t{$src2, $dst}", 516 [(set GR16:$dst, (sub GR16:$src1, (load addr:$src2))), 517 (implicit SRW)]>; 518 519let isTwoAddress = 0 in { 520def SUB8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src), 521 "sub.b\t{$src, $dst}", 522 [(store (sub (load addr:$dst), GR8:$src), addr:$dst), 523 (implicit SRW)]>; 524def SUB16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src), 525 "sub.w\t{$src, $dst}", 526 [(store (sub (load addr:$dst), GR16:$src), addr:$dst), 527 (implicit SRW)]>; 528 529def SUB8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src), 530 "sub.b\t{$src, $dst}", 531 [(store (sub (load addr:$dst), (i8 imm:$src)), addr:$dst), 532 (implicit SRW)]>; 533def SUB16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src), 534 "sub.w\t{$src, $dst}", 535 [(store (sub (load addr:$dst), (i16 imm:$src)), addr:$dst), 536 (implicit SRW)]>; 537 538def SUB8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src), 539 "sub.b\t{$src, $dst}", 540 [(store (sub (load addr:$dst), (i8 (load addr:$src))), addr:$dst), 541 (implicit SRW)]>; 542def SUB16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src), 543 "sub.w\t{$src, $dst}", 544 [(store (sub (load addr:$dst), (i16 (load addr:$src))), addr:$dst), 545 (implicit SRW)]>; 546} 547 548let Uses = [SRW] in { 549def SBC8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2), 550 "subc.b\t{$src2, $dst}", 551 [(set GR8:$dst, (sube GR8:$src1, GR8:$src2)), 552 (implicit SRW)]>; 553def SBC16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2), 554 "subc.w\t{$src2, $dst}", 555 [(set GR16:$dst, (sube GR16:$src1, GR16:$src2)), 556 (implicit SRW)]>; 557 558def SBC8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2), 559 "subc.b\t{$src2, $dst}", 560 [(set GR8:$dst, (sube GR8:$src1, imm:$src2)), 561 (implicit SRW)]>; 562def SBC16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2), 563 "subc.w\t{$src2, $dst}", 564 [(set GR16:$dst, (sube GR16:$src1, imm:$src2)), 565 (implicit SRW)]>; 566 567def SBC8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2), 568 "subc.b\t{$src2, $dst}", 569 [(set GR8:$dst, (sube GR8:$src1, (load addr:$src2))), 570 (implicit SRW)]>; 571def SBC16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2), 572 "subc.w\t{$src2, $dst}", 573 [(set GR16:$dst, (sube GR16:$src1, (load addr:$src2))), 574 (implicit SRW)]>; 575 576let isTwoAddress = 0 in { 577def SBC8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src), 578 "subc.b\t{$src, $dst}", 579 [(store (sube (load addr:$dst), GR8:$src), addr:$dst), 580 (implicit SRW)]>; 581def SBC16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src), 582 "subc.w\t{$src, $dst}", 583 [(store (sube (load addr:$dst), GR16:$src), addr:$dst), 584 (implicit SRW)]>; 585 586def SBC8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src), 587 "subc.b\t{$src, $dst}", 588 [(store (sube (load addr:$dst), (i8 imm:$src)), addr:$dst), 589 (implicit SRW)]>; 590def SBC16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src), 591 "subc.w\t{$src, $dst}", 592 [(store (sube (load addr:$dst), (i16 imm:$src)), addr:$dst), 593 (implicit SRW)]>; 594 595def SBC8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src), 596 "subc.b\t{$src, $dst}", 597 [(store (sube (load addr:$dst), (i8 (load addr:$src))), addr:$dst), 598 (implicit SRW)]>; 599def SBC16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src), 600 "subc.w\t{$src, $dst}", 601 [(store (sube (load addr:$dst), (i16 (load addr:$src))), addr:$dst), 602 (implicit SRW)]>; 603} 604 605} // Uses = [SRW] 606 607// FIXME: Provide proper encoding! 608def SAR8r1 : Pseudo<(outs GR8:$dst), (ins GR8:$src), 609 "rra.b\t$dst", 610 [(set GR8:$dst, (MSP430rra GR8:$src)), 611 (implicit SRW)]>; 612def SAR16r1 : Pseudo<(outs GR16:$dst), (ins GR16:$src), 613 "rra.w\t$dst", 614 [(set GR16:$dst, (MSP430rra GR16:$src)), 615 (implicit SRW)]>; 616 617def SHL8r1 : Pseudo<(outs GR8:$dst), (ins GR8:$src), 618 "rla.b\t$dst", 619 [(set GR8:$dst, (MSP430rla GR8:$src)), 620 (implicit SRW)]>; 621def SHL16r1 : Pseudo<(outs GR16:$dst), (ins GR16:$src), 622 "rla.w\t$dst", 623 [(set GR16:$dst, (MSP430rla GR16:$src)), 624 (implicit SRW)]>; 625 626def SAR8r1c : Pseudo<(outs GR8:$dst), (ins GR8:$src), 627 "clrc\n\t" 628 "rrc.b\t$dst", 629 [(set GR8:$dst, (MSP430rrc GR8:$src)), 630 (implicit SRW)]>; 631def SAR16r1c : Pseudo<(outs GR16:$dst), (ins GR16:$src), 632 "clrc\n\t" 633 "rrc.w\t$dst", 634 [(set GR16:$dst, (MSP430rrc GR16:$src)), 635 (implicit SRW)]>; 636 637def SEXT16r : Pseudo<(outs GR16:$dst), (ins GR16:$src), 638 "sxt\t$dst", 639 [(set GR16:$dst, (sext_inreg GR16:$src, i8)), 640 (implicit SRW)]>; 641 642} // Defs = [SRW] 643 644def SWPB16r : Pseudo<(outs GR16:$dst), (ins GR16:$src), 645 "swpb\t$dst", 646 [(set GR16:$dst, (bswap GR16:$src))]>; 647 648let isCommutable = 1 in { // X = OR Y, Z == X = OR Z, Y 649def OR8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2), 650 "bis.b\t{$src2, $dst}", 651 [(set GR8:$dst, (or GR8:$src1, GR8:$src2))]>; 652def OR16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2), 653 "bis.w\t{$src2, $dst}", 654 [(set GR16:$dst, (or GR16:$src1, GR16:$src2))]>; 655} 656 657def OR8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2), 658 "bis.b\t{$src2, $dst}", 659 [(set GR8:$dst, (or GR8:$src1, imm:$src2))]>; 660def OR16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2), 661 "bis.w\t{$src2, $dst}", 662 [(set GR16:$dst, (or GR16:$src1, imm:$src2))]>; 663 664def OR8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2), 665 "bis.b\t{$src2, $dst}", 666 [(set GR8:$dst, (or GR8:$src1, (load addr:$src2)))]>; 667def OR16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2), 668 "bis.w\t{$src2, $dst}", 669 [(set GR16:$dst, (or GR16:$src1, (load addr:$src2)))]>; 670 671let isTwoAddress = 0 in { 672def OR8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src), 673 "bis.b\t{$src, $dst}", 674 [(store (or (load addr:$dst), GR8:$src), addr:$dst)]>; 675def OR16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src), 676 "bis.w\t{$src, $dst}", 677 [(store (or (load addr:$dst), GR16:$src), addr:$dst)]>; 678 679def OR8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src), 680 "bis.b\t{$src, $dst}", 681 [(store (or (load addr:$dst), (i8 imm:$src)), addr:$dst)]>; 682def OR16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src), 683 "bis.w\t{$src, $dst}", 684 [(store (or (load addr:$dst), (i16 imm:$src)), addr:$dst)]>; 685 686def OR8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src), 687 "bis.b\t{$src, $dst}", 688 [(store (or (i8 (load addr:$dst)), 689 (i8 (load addr:$src))), addr:$dst)]>; 690def OR16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src), 691 "bis.w\t{$src, $dst}", 692 [(store (or (i16 (load addr:$dst)), 693 (i16 (load addr:$src))), addr:$dst)]>; 694} 695 696} // isTwoAddress = 1 697 698// Integer comparisons 699let Defs = [SRW] in { 700def CMP8rr : Pseudo<(outs), (ins GR8:$src1, GR8:$src2), 701 "cmp.b\t{$src1, $src2}", 702 [(MSP430cmp GR8:$src1, GR8:$src2), (implicit SRW)]>; 703def CMP16rr : Pseudo<(outs), (ins GR16:$src1, GR16:$src2), 704 "cmp.w\t{$src1, $src2}", 705 [(MSP430cmp GR16:$src1, GR16:$src2), (implicit SRW)]>; 706 707def CMP8ir : Pseudo<(outs), (ins i8imm:$src1, GR8:$src2), 708 "cmp.b\t{$src1, $src2}", 709 [(MSP430cmp imm:$src1, GR8:$src2), (implicit SRW)]>; 710def CMP16ir : Pseudo<(outs), (ins i16imm:$src1, GR16:$src2), 711 "cmp.w\t{$src1, $src2}", 712 [(MSP430cmp imm:$src1, GR16:$src2), (implicit SRW)]>; 713 714def CMP8im : Pseudo<(outs), (ins i8imm:$src1, memsrc:$src2), 715 "cmp.b\t{$src1, $src2}", 716 [(MSP430cmp (i8 imm:$src1), (load addr:$src2)), (implicit SRW)]>; 717def CMP16im : Pseudo<(outs), (ins i16imm:$src1, memsrc:$src2), 718 "cmp.w\t{$src1, $src2}", 719 [(MSP430cmp (i16 imm:$src1), (load addr:$src2)), (implicit SRW)]>; 720 721def CMP8rm : Pseudo<(outs), (ins GR8:$src1, memsrc:$src2), 722 "cmp.b\t{$src1, $src2}", 723 [(MSP430cmp GR8:$src1, (load addr:$src2)), (implicit SRW)]>; 724def CMP16rm : Pseudo<(outs), (ins GR16:$src1, memsrc:$src2), 725 "cmp.w\t{$src1, $src2}", 726 [(MSP430cmp GR16:$src1, (load addr:$src2)), (implicit SRW)]>; 727 728def CMP8mr : Pseudo<(outs), (ins memsrc:$src1, GR8:$src2), 729 "cmp.b\t{$src1, $src2}", 730 [(MSP430cmp (load addr:$src1), GR8:$src2), (implicit SRW)]>; 731def CMP16mr : Pseudo<(outs), (ins memsrc:$src1, GR16:$src2), 732 "cmp.w\t{$src1, $src2}", 733 [(MSP430cmp (load addr:$src1), GR16:$src2), (implicit SRW)]>; 734 735def CMP8mi0 : Pseudo<(outs), (ins memsrc:$src1), 736 "cmp.b\t{$src1, #0}", 737 [(MSP430cmp (load addr:$src1), (i8 0)), (implicit SRW)]>; 738def CMP16mi0: Pseudo<(outs), (ins memsrc:$src1), 739 "cmp.w\t{$src1, #0}", 740 [(MSP430cmp (load addr:$src1), (i16 0)), (implicit SRW)]>; 741def CMP8mi1 : Pseudo<(outs), (ins memsrc:$src1), 742 "cmp.b\t{$src1, #1}", 743 [(MSP430cmp (load addr:$src1), (i8 1)), (implicit SRW)]>; 744def CMP16mi1: Pseudo<(outs), (ins memsrc:$src1), 745 "cmp.w\t{$src1, #1}", 746 [(MSP430cmp (load addr:$src1), (i16 1)), (implicit SRW)]>; 747def CMP8mi2 : Pseudo<(outs), (ins memsrc:$src1), 748 "cmp.b\t{$src1, #2}", 749 [(MSP430cmp (load addr:$src1), (i8 2)), (implicit SRW)]>; 750def CMP16mi2: Pseudo<(outs), (ins memsrc:$src1), 751 "cmp.w\t{$src1, #2}", 752 [(MSP430cmp (load addr:$src1), (i16 2)), (implicit SRW)]>; 753def CMP8mi4 : Pseudo<(outs), (ins memsrc:$src1), 754 "cmp.b\t{$src1, #4}", 755 [(MSP430cmp (load addr:$src1), (i8 4)), (implicit SRW)]>; 756def CMP16mi4: Pseudo<(outs), (ins memsrc:$src1), 757 "cmp.w\t{$src1, #4}", 758 [(MSP430cmp (load addr:$src1), (i16 4)), (implicit SRW)]>; 759def CMP8mi8 : Pseudo<(outs), (ins memsrc:$src1), 760 "cmp.b\t{$src1, #8}", 761 [(MSP430cmp (load addr:$src1), (i8 8)), (implicit SRW)]>; 762def CMP16mi8: Pseudo<(outs), (ins memsrc:$src1), 763 "cmp.w\t{$src1, #8}", 764 [(MSP430cmp (load addr:$src1), (i16 8)), (implicit SRW)]>; 765 766} // Defs = [SRW] 767 768//===----------------------------------------------------------------------===// 769// Non-Instruction Patterns 770 771// extload 772def : Pat<(extloadi16i8 addr:$src), (MOVZX16rm8 addr:$src)>; 773 774// anyext 775def : Pat<(anyext addr:$src), (MOVZX16rr8 GR8:$src)>; 776 777// truncs 778def : Pat<(i8 (trunc GR16:$src)), 779 (EXTRACT_SUBREG GR16:$src, subreg_8bit)>; 780 781// GlobalAddress, ExternalSymbol 782def : Pat<(i16 (MSP430Wrapper tglobaladdr:$dst)), (MOV16ri tglobaladdr:$dst)>; 783def : Pat<(i16 (MSP430Wrapper texternalsym:$dst)), (MOV16ri texternalsym:$dst)>; 784 785def : Pat<(add GR16:$src1, (MSP430Wrapper tglobaladdr :$src2)), 786 (ADD16ri GR16:$src1, tglobaladdr:$src2)>; 787def : Pat<(add GR16:$src1, (MSP430Wrapper texternalsym:$src2)), 788 (ADD16ri GR16:$src1, texternalsym:$src2)>; 789 790def : Pat<(store (i16 (MSP430Wrapper tglobaladdr:$src)), addr:$dst), 791 (MOV16mi addr:$dst, tglobaladdr:$src)>; 792def : Pat<(store (i16 (MSP430Wrapper texternalsym:$src)), addr:$dst), 793 (MOV16mi addr:$dst, texternalsym:$src)>; 794 795// calls 796def : Pat<(MSP430call (i16 tglobaladdr:$dst)), 797 (CALLi tglobaladdr:$dst)>; 798def : Pat<(MSP430call (i16 texternalsym:$dst)), 799 (CALLi texternalsym:$dst)>; 800 801// add and sub always produce carry 802def : Pat<(addc GR16:$src1, GR16:$src2), 803 (ADD16rr GR16:$src1, GR16:$src2)>; 804def : Pat<(addc GR16:$src1, (load addr:$src2)), 805 (ADD16rm GR16:$src1, addr:$src2)>; 806def : Pat<(addc GR16:$src1, imm:$src2), 807 (ADD16ri GR16:$src1, imm:$src2)>; 808def : Pat<(store (addc (load addr:$dst), GR16:$src), addr:$dst), 809 (ADD16mr addr:$dst, GR16:$src)>; 810def : Pat<(store (addc (load addr:$dst), (i16 (load addr:$src))), addr:$dst), 811 (ADD16mm addr:$dst, addr:$src)>; 812 813def : Pat<(addc GR8:$src1, GR8:$src2), 814 (ADD8rr GR8:$src1, GR8:$src2)>; 815def : Pat<(addc GR8:$src1, (load addr:$src2)), 816 (ADD8rm GR8:$src1, addr:$src2)>; 817def : Pat<(addc GR8:$src1, imm:$src2), 818 (ADD8ri GR8:$src1, imm:$src2)>; 819def : Pat<(store (addc (load addr:$dst), GR8:$src), addr:$dst), 820 (ADD8mr addr:$dst, GR8:$src)>; 821def : Pat<(store (addc (load addr:$dst), (i8 (load addr:$src))), addr:$dst), 822 (ADD8mm addr:$dst, addr:$src)>; 823 824def : Pat<(subc GR16:$src1, GR16:$src2), 825 (SUB16rr GR16:$src1, GR16:$src2)>; 826def : Pat<(subc GR16:$src1, (load addr:$src2)), 827 (SUB16rm GR16:$src1, addr:$src2)>; 828def : Pat<(subc GR16:$src1, imm:$src2), 829 (SUB16ri GR16:$src1, imm:$src2)>; 830def : Pat<(store (subc (load addr:$dst), GR16:$src), addr:$dst), 831 (SUB16mr addr:$dst, GR16:$src)>; 832def : Pat<(store (subc (load addr:$dst), (i16 (load addr:$src))), addr:$dst), 833 (SUB16mm addr:$dst, addr:$src)>; 834 835def : Pat<(subc GR8:$src1, GR8:$src2), 836 (SUB8rr GR8:$src1, GR8:$src2)>; 837def : Pat<(subc GR8:$src1, (load addr:$src2)), 838 (SUB8rm GR8:$src1, addr:$src2)>; 839def : Pat<(subc GR8:$src1, imm:$src2), 840 (SUB8ri GR8:$src1, imm:$src2)>; 841def : Pat<(store (subc (load addr:$dst), GR8:$src), addr:$dst), 842 (SUB8mr addr:$dst, GR8:$src)>; 843def : Pat<(store (subc (load addr:$dst), (i8 (load addr:$src))), addr:$dst), 844 (SUB8mm addr:$dst, addr:$src)>; 845