1*9880d681SAndroid Build Coastguard Worker//===-- AVRInstrInfo.td - AVR Instruction defs -------------*- tablegen -*-===// 2*9880d681SAndroid Build Coastguard Worker// 3*9880d681SAndroid Build Coastguard Worker// The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker// 5*9880d681SAndroid Build Coastguard Worker// This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker// License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker// 8*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker// 10*9880d681SAndroid Build Coastguard Worker// This file describes the AVR instructions in TableGen format. 11*9880d681SAndroid Build Coastguard Worker// 12*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard Workerinclude "AVRInstrFormats.td" 15*9880d681SAndroid Build Coastguard Worker 16*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 17*9880d681SAndroid Build Coastguard Worker// AVR Type Profiles 18*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 19*9880d681SAndroid Build Coastguard Worker 20*9880d681SAndroid Build Coastguard Workerdef SDT_AVRCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i16>]>; 21*9880d681SAndroid Build Coastguard Workerdef SDT_AVRCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i16>, SDTCisVT<1, i16>]>; 22*9880d681SAndroid Build Coastguard Workerdef SDT_AVRCall : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>; 23*9880d681SAndroid Build Coastguard Workerdef SDT_AVRWrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>; 24*9880d681SAndroid Build Coastguard Workerdef SDT_AVRBrcond : SDTypeProfile<0, 2, 25*9880d681SAndroid Build Coastguard Worker [SDTCisVT<0, OtherVT>, SDTCisVT<1, i8>]>; 26*9880d681SAndroid Build Coastguard Workerdef SDT_AVRCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>; 27*9880d681SAndroid Build Coastguard Workerdef SDT_AVRTst : SDTypeProfile<0, 1, [SDTCisInt<0>]>; 28*9880d681SAndroid Build Coastguard Workerdef SDT_AVRSelectCC : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, 29*9880d681SAndroid Build Coastguard Worker SDTCisSameAs<1, 2>, SDTCisVT<3, i8>]>; 30*9880d681SAndroid Build Coastguard Worker 31*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 32*9880d681SAndroid Build Coastguard Worker// AVR Specific Node Definitions 33*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 34*9880d681SAndroid Build Coastguard Worker 35*9880d681SAndroid Build Coastguard Workerdef AVRretflag : SDNode<"AVRISD::RET_FLAG", SDTNone, 36*9880d681SAndroid Build Coastguard Worker [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 37*9880d681SAndroid Build Coastguard Workerdef AVRretiflag : SDNode<"AVRISD::RETI_FLAG", SDTNone, 38*9880d681SAndroid Build Coastguard Worker [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 39*9880d681SAndroid Build Coastguard Worker 40*9880d681SAndroid Build Coastguard Workerdef AVRcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_AVRCallSeqStart, 41*9880d681SAndroid Build Coastguard Worker [SDNPHasChain, SDNPOutGlue]>; 42*9880d681SAndroid Build Coastguard Workerdef AVRcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_AVRCallSeqEnd, 43*9880d681SAndroid Build Coastguard Worker [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 44*9880d681SAndroid Build Coastguard Worker 45*9880d681SAndroid Build Coastguard Workerdef AVRcall : SDNode<"AVRISD::CALL", SDT_AVRCall, 46*9880d681SAndroid Build Coastguard Worker [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, SDNPVariadic]>; 47*9880d681SAndroid Build Coastguard Worker 48*9880d681SAndroid Build Coastguard Workerdef AVRWrapper : SDNode<"AVRISD::WRAPPER", SDT_AVRWrapper>; 49*9880d681SAndroid Build Coastguard Worker 50*9880d681SAndroid Build Coastguard Workerdef AVRbrcond : SDNode<"AVRISD::BRCOND", SDT_AVRBrcond, 51*9880d681SAndroid Build Coastguard Worker [SDNPHasChain, SDNPInGlue]>; 52*9880d681SAndroid Build Coastguard Workerdef AVRcmp : SDNode<"AVRISD::CMP", SDT_AVRCmp, [SDNPOutGlue]>; 53*9880d681SAndroid Build Coastguard Workerdef AVRcmpc : SDNode<"AVRISD::CMPC", SDT_AVRCmp, [SDNPInGlue, SDNPOutGlue]>; 54*9880d681SAndroid Build Coastguard Workerdef AVRtst : SDNode<"AVRISD::TST", SDT_AVRTst, [SDNPOutGlue]>; 55*9880d681SAndroid Build Coastguard Workerdef AVRselectcc: SDNode<"AVRISD::SELECT_CC", SDT_AVRSelectCC, [SDNPInGlue]>; 56*9880d681SAndroid Build Coastguard Worker 57*9880d681SAndroid Build Coastguard Worker// Shift nodes. 58*9880d681SAndroid Build Coastguard Workerdef AVRlsl : SDNode<"AVRISD::LSL", SDTIntUnaryOp>; 59*9880d681SAndroid Build Coastguard Workerdef AVRlsr : SDNode<"AVRISD::LSR", SDTIntUnaryOp>; 60*9880d681SAndroid Build Coastguard Workerdef AVRrol : SDNode<"AVRISD::ROL", SDTIntUnaryOp>; 61*9880d681SAndroid Build Coastguard Workerdef AVRror : SDNode<"AVRISD::ROR", SDTIntUnaryOp>; 62*9880d681SAndroid Build Coastguard Workerdef AVRasr : SDNode<"AVRISD::ASR", SDTIntUnaryOp>; 63*9880d681SAndroid Build Coastguard Worker 64*9880d681SAndroid Build Coastguard Worker// Pseudo shift nodes for non-constant shift amounts. 65*9880d681SAndroid Build Coastguard Workerdef AVRlslLoop : SDNode<"AVRISD::LSLLOOP", SDTIntShiftOp>; 66*9880d681SAndroid Build Coastguard Workerdef AVRlsrLoop : SDNode<"AVRISD::LSRLOOP", SDTIntShiftOp>; 67*9880d681SAndroid Build Coastguard Workerdef AVRasrLoop : SDNode<"AVRISD::ASRLOOP", SDTIntShiftOp>; 68*9880d681SAndroid Build Coastguard Worker 69*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 70*9880d681SAndroid Build Coastguard Worker// AVR Operands, Complex Patterns and Transformations Definitions. 71*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 72*9880d681SAndroid Build Coastguard Worker 73*9880d681SAndroid Build Coastguard Workerdef imm8_neg_XFORM : SDNodeXForm<imm, 74*9880d681SAndroid Build Coastguard Worker[{ 75*9880d681SAndroid Build Coastguard Worker return CurDAG->getTargetConstant(-N->getAPIntValue(), SDLoc(N), MVT::i8); 76*9880d681SAndroid Build Coastguard Worker}]>; 77*9880d681SAndroid Build Coastguard Worker 78*9880d681SAndroid Build Coastguard Workerdef imm16_neg_XFORM : SDNodeXForm<imm, 79*9880d681SAndroid Build Coastguard Worker[{ 80*9880d681SAndroid Build Coastguard Worker return CurDAG->getTargetConstant(-N->getAPIntValue(), SDLoc(N), MVT::i16); 81*9880d681SAndroid Build Coastguard Worker}]>; 82*9880d681SAndroid Build Coastguard Worker 83*9880d681SAndroid Build Coastguard Workerdef imm0_63_neg : PatLeaf<(imm), 84*9880d681SAndroid Build Coastguard Worker[{ 85*9880d681SAndroid Build Coastguard Worker int64_t val = -N->getSExtValue(); 86*9880d681SAndroid Build Coastguard Worker return val >= 0 && val < 64; 87*9880d681SAndroid Build Coastguard Worker}], imm16_neg_XFORM>; 88*9880d681SAndroid Build Coastguard Worker 89*9880d681SAndroid Build Coastguard Workerdef uimm6 : PatLeaf<(imm), [{ return isUInt<6>(N->getZExtValue()); }]>; 90*9880d681SAndroid Build Coastguard Worker 91*9880d681SAndroid Build Coastguard Workerdef ioaddr_XFORM : SDNodeXForm<imm, 92*9880d681SAndroid Build Coastguard Worker[{ 93*9880d681SAndroid Build Coastguard Worker return CurDAG->getTargetConstant(uint8_t(N->getZExtValue()) - 0x20, SDLoc(N), MVT::i8); 94*9880d681SAndroid Build Coastguard Worker}]>; 95*9880d681SAndroid Build Coastguard Worker 96*9880d681SAndroid Build Coastguard Workerdef iobitpos8_XFORM : SDNodeXForm<imm, 97*9880d681SAndroid Build Coastguard Worker[{ 98*9880d681SAndroid Build Coastguard Worker return CurDAG->getTargetConstant(Log2_32(uint8_t(N->getZExtValue())), 99*9880d681SAndroid Build Coastguard Worker SDLoc(N), MVT::i8); 100*9880d681SAndroid Build Coastguard Worker}]>; 101*9880d681SAndroid Build Coastguard Worker 102*9880d681SAndroid Build Coastguard Workerdef iobitposn8_XFORM : SDNodeXForm<imm, 103*9880d681SAndroid Build Coastguard Worker[{ 104*9880d681SAndroid Build Coastguard Worker return CurDAG->getTargetConstant(Log2_32(uint8_t(~N->getZExtValue())), 105*9880d681SAndroid Build Coastguard Worker SDLoc(N), MVT::i8); 106*9880d681SAndroid Build Coastguard Worker}]>; 107*9880d681SAndroid Build Coastguard Worker 108*9880d681SAndroid Build Coastguard Workerdef ioaddr8 : PatLeaf<(imm), 109*9880d681SAndroid Build Coastguard Worker[{ 110*9880d681SAndroid Build Coastguard Worker uint64_t val = N->getZExtValue(); 111*9880d681SAndroid Build Coastguard Worker return val >= 0x20 && val < 0x60; 112*9880d681SAndroid Build Coastguard Worker}], ioaddr_XFORM>; 113*9880d681SAndroid Build Coastguard Worker 114*9880d681SAndroid Build Coastguard Workerdef lowioaddr8 : PatLeaf<(imm), 115*9880d681SAndroid Build Coastguard Worker[{ 116*9880d681SAndroid Build Coastguard Worker uint64_t val = N->getZExtValue(); 117*9880d681SAndroid Build Coastguard Worker return val >= 0x20 && val < 0x40; 118*9880d681SAndroid Build Coastguard Worker}], ioaddr_XFORM>; 119*9880d681SAndroid Build Coastguard Worker 120*9880d681SAndroid Build Coastguard Workerdef ioaddr16 : PatLeaf<(imm), 121*9880d681SAndroid Build Coastguard Worker[{ 122*9880d681SAndroid Build Coastguard Worker uint64_t val = N->getZExtValue(); 123*9880d681SAndroid Build Coastguard Worker return val >= 0x20 && val < 0x5f; 124*9880d681SAndroid Build Coastguard Worker}], ioaddr_XFORM>; 125*9880d681SAndroid Build Coastguard Worker 126*9880d681SAndroid Build Coastguard Workerdef iobitpos8 : PatLeaf<(imm), 127*9880d681SAndroid Build Coastguard Worker[{ 128*9880d681SAndroid Build Coastguard Worker return isPowerOf2_32(uint8_t(N->getZExtValue())); 129*9880d681SAndroid Build Coastguard Worker}], iobitpos8_XFORM>; 130*9880d681SAndroid Build Coastguard Worker 131*9880d681SAndroid Build Coastguard Workerdef iobitposn8 : PatLeaf<(imm), 132*9880d681SAndroid Build Coastguard Worker[{ 133*9880d681SAndroid Build Coastguard Worker return isPowerOf2_32(uint8_t(~N->getZExtValue())); 134*9880d681SAndroid Build Coastguard Worker}], iobitposn8_XFORM>; 135*9880d681SAndroid Build Coastguard Worker 136*9880d681SAndroid Build Coastguard Workerdef MemriAsmOperand : AsmOperandClass { 137*9880d681SAndroid Build Coastguard Worker let Name = "Memri"; 138*9880d681SAndroid Build Coastguard Worker let ParserMethod = "parseMemriOperand"; 139*9880d681SAndroid Build Coastguard Worker} 140*9880d681SAndroid Build Coastguard Worker 141*9880d681SAndroid Build Coastguard Worker/// Address operand for `reg+imm` used by STD and LDD. 142*9880d681SAndroid Build Coastguard Workerdef memri : Operand<iPTR> 143*9880d681SAndroid Build Coastguard Worker{ 144*9880d681SAndroid Build Coastguard Worker let MIOperandInfo = (ops PTRDISPREGS, i16imm); 145*9880d681SAndroid Build Coastguard Worker 146*9880d681SAndroid Build Coastguard Worker let PrintMethod = "printMemri"; 147*9880d681SAndroid Build Coastguard Worker let EncoderMethod = "encodeMemri"; 148*9880d681SAndroid Build Coastguard Worker 149*9880d681SAndroid Build Coastguard Worker let ParserMatchClass = MemriAsmOperand; 150*9880d681SAndroid Build Coastguard Worker} 151*9880d681SAndroid Build Coastguard Worker 152*9880d681SAndroid Build Coastguard Worker// Address operand for `SP+imm` used by STD{W}SPQRr 153*9880d681SAndroid Build Coastguard Workerdef memspi : Operand<iPTR> 154*9880d681SAndroid Build Coastguard Worker{ 155*9880d681SAndroid Build Coastguard Worker let MIOperandInfo = (ops GPRSP, i16imm); 156*9880d681SAndroid Build Coastguard Worker} 157*9880d681SAndroid Build Coastguard Worker 158*9880d681SAndroid Build Coastguard Workerdef i8imm_com : Operand<i8> 159*9880d681SAndroid Build Coastguard Worker{ 160*9880d681SAndroid Build Coastguard Worker let EncoderMethod = "encodeComplement"; 161*9880d681SAndroid Build Coastguard Worker 162*9880d681SAndroid Build Coastguard Worker let MIOperandInfo = (ops i8imm); 163*9880d681SAndroid Build Coastguard Worker} 164*9880d681SAndroid Build Coastguard Worker 165*9880d681SAndroid Build Coastguard Workerdef relbrtarget_7 : Operand<OtherVT> 166*9880d681SAndroid Build Coastguard Worker{ 167*9880d681SAndroid Build Coastguard Worker let PrintMethod = "printPCRelImm"; 168*9880d681SAndroid Build Coastguard Worker let EncoderMethod = "encodeRelCondBrTarget<AVR::fixup_7_pcrel>"; 169*9880d681SAndroid Build Coastguard Worker} 170*9880d681SAndroid Build Coastguard Worker 171*9880d681SAndroid Build Coastguard Workerdef brtarget_13 : Operand<OtherVT> 172*9880d681SAndroid Build Coastguard Worker{ 173*9880d681SAndroid Build Coastguard Worker let PrintMethod = "printPCRelImm"; 174*9880d681SAndroid Build Coastguard Worker let EncoderMethod = "encodeRelCondBrTarget<AVR::fixup_13_pcrel>"; 175*9880d681SAndroid Build Coastguard Worker} 176*9880d681SAndroid Build Coastguard Worker 177*9880d681SAndroid Build Coastguard Worker// The target of a 22 or 16-bit call/jmp instruction. 178*9880d681SAndroid Build Coastguard Workerdef call_target : Operand<iPTR> 179*9880d681SAndroid Build Coastguard Worker{ 180*9880d681SAndroid Build Coastguard Worker let EncoderMethod = "encodeCallTarget"; 181*9880d681SAndroid Build Coastguard Worker} 182*9880d681SAndroid Build Coastguard Worker 183*9880d681SAndroid Build Coastguard Worker// Addressing mode pattern reg+imm6 184*9880d681SAndroid Build Coastguard Workerdef addr : ComplexPattern<iPTR, 2, "SelectAddr", [], [SDNPWantRoot]>; 185*9880d681SAndroid Build Coastguard Worker 186*9880d681SAndroid Build Coastguard Worker// AsmOperand class for a pointer register. 187*9880d681SAndroid Build Coastguard Worker// Used with the LD/ST family of instructions. 188*9880d681SAndroid Build Coastguard Worker// See FSTLD in AVRInstrFormats.td 189*9880d681SAndroid Build Coastguard Workerdef PtrRegAsmOperand : AsmOperandClass 190*9880d681SAndroid Build Coastguard Worker{ 191*9880d681SAndroid Build Coastguard Worker let Name = "Reg"; 192*9880d681SAndroid Build Coastguard Worker} 193*9880d681SAndroid Build Coastguard Worker 194*9880d681SAndroid Build Coastguard Worker// A special operand type for the LD/ST instructions. 195*9880d681SAndroid Build Coastguard Worker// It converts the pointer register number into a two-bit field used in the 196*9880d681SAndroid Build Coastguard Worker// instruction. 197*9880d681SAndroid Build Coastguard Workerdef LDSTPtrReg : Operand<i16> 198*9880d681SAndroid Build Coastguard Worker{ 199*9880d681SAndroid Build Coastguard Worker let MIOperandInfo = (ops PTRREGS); 200*9880d681SAndroid Build Coastguard Worker let EncoderMethod = "encodeLDSTPtrReg"; 201*9880d681SAndroid Build Coastguard Worker 202*9880d681SAndroid Build Coastguard Worker let ParserMatchClass = PtrRegAsmOperand; 203*9880d681SAndroid Build Coastguard Worker} 204*9880d681SAndroid Build Coastguard Worker 205*9880d681SAndroid Build Coastguard Worker// A special operand type for the LDD/STD instructions. 206*9880d681SAndroid Build Coastguard Worker// It behaves identically to the LD/ST version, except restricts 207*9880d681SAndroid Build Coastguard Worker// the pointer registers to Y and Z. 208*9880d681SAndroid Build Coastguard Workerdef LDDSTDPtrReg : Operand<i16> 209*9880d681SAndroid Build Coastguard Worker{ 210*9880d681SAndroid Build Coastguard Worker let MIOperandInfo = (ops PTRDISPREGS); 211*9880d681SAndroid Build Coastguard Worker let EncoderMethod = "encodeLDSTPtrReg"; 212*9880d681SAndroid Build Coastguard Worker 213*9880d681SAndroid Build Coastguard Worker let ParserMatchClass = PtrRegAsmOperand; 214*9880d681SAndroid Build Coastguard Worker} 215*9880d681SAndroid Build Coastguard Worker 216*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 217*9880d681SAndroid Build Coastguard Worker// AVR predicates for subtarget features 218*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 219*9880d681SAndroid Build Coastguard Worker 220*9880d681SAndroid Build Coastguard Workerdef HasSRAM : Predicate<"Subtarget->hasSRAM()">, 221*9880d681SAndroid Build Coastguard Worker AssemblerPredicate<"FeatureSRAM">; 222*9880d681SAndroid Build Coastguard Worker 223*9880d681SAndroid Build Coastguard Workerdef HasJMPCALL : Predicate<"Subtarget->hasJMPCALL()">, 224*9880d681SAndroid Build Coastguard Worker AssemblerPredicate<"FeatureJMPCALL">; 225*9880d681SAndroid Build Coastguard Worker 226*9880d681SAndroid Build Coastguard Workerdef HasIJMPCALL : Predicate<"Subtarget->hasIJMPCALL()">, 227*9880d681SAndroid Build Coastguard Worker AssemblerPredicate<"FeatureIJMPCALL">; 228*9880d681SAndroid Build Coastguard Worker 229*9880d681SAndroid Build Coastguard Workerdef HasEIJMPCALL : Predicate<"Subtarget->hasEIJMPCALL()">, 230*9880d681SAndroid Build Coastguard Worker AssemblerPredicate<"FeatureEIJMPCALL">; 231*9880d681SAndroid Build Coastguard Worker 232*9880d681SAndroid Build Coastguard Workerdef HasADDSUBIW : Predicate<"Subtarget->hasADDSUBIW()">, 233*9880d681SAndroid Build Coastguard Worker AssemblerPredicate<"FeatureADDSUBIW">; 234*9880d681SAndroid Build Coastguard Worker 235*9880d681SAndroid Build Coastguard Workerdef HasSmallStack : Predicate<"Subtarget->HasSmallStack()">, 236*9880d681SAndroid Build Coastguard Worker AssemblerPredicate<"FeatureSmallStack">; 237*9880d681SAndroid Build Coastguard Worker 238*9880d681SAndroid Build Coastguard Workerdef HasMOVW : Predicate<"Subtarget->hasMOVW()">, 239*9880d681SAndroid Build Coastguard Worker AssemblerPredicate<"FeatureMOVW">; 240*9880d681SAndroid Build Coastguard Worker 241*9880d681SAndroid Build Coastguard Workerdef HasLPM : Predicate<"Subtarget->hasLPM()">, 242*9880d681SAndroid Build Coastguard Worker AssemblerPredicate<"FeatureLPM">; 243*9880d681SAndroid Build Coastguard Worker 244*9880d681SAndroid Build Coastguard Workerdef HasLPMX : Predicate<"Subtarget->hasLPMX()">, 245*9880d681SAndroid Build Coastguard Worker AssemblerPredicate<"FeatureLPMX">; 246*9880d681SAndroid Build Coastguard Worker 247*9880d681SAndroid Build Coastguard Workerdef HasELPM : Predicate<"Subtarget->hasELPM()">, 248*9880d681SAndroid Build Coastguard Worker AssemblerPredicate<"FeatureELPM">; 249*9880d681SAndroid Build Coastguard Worker 250*9880d681SAndroid Build Coastguard Workerdef HasELPMX : Predicate<"Subtarget->hasELPMX()">, 251*9880d681SAndroid Build Coastguard Worker AssemblerPredicate<"FeatureELPMX">; 252*9880d681SAndroid Build Coastguard Worker 253*9880d681SAndroid Build Coastguard Workerdef HasSPM : Predicate<"Subtarget->hasSPM()">, 254*9880d681SAndroid Build Coastguard Worker AssemblerPredicate<"FeatureSPM">; 255*9880d681SAndroid Build Coastguard Worker 256*9880d681SAndroid Build Coastguard Workerdef HasSPMX : Predicate<"Subtarget->hasSPMX()">, 257*9880d681SAndroid Build Coastguard Worker AssemblerPredicate<"FeatureSPMX">; 258*9880d681SAndroid Build Coastguard Worker 259*9880d681SAndroid Build Coastguard Workerdef HasDES : Predicate<"Subtarget->hasDES()">, 260*9880d681SAndroid Build Coastguard Worker AssemblerPredicate<"FeatureDES">; 261*9880d681SAndroid Build Coastguard Worker 262*9880d681SAndroid Build Coastguard Workerdef SupportsRMW : Predicate<"Subtarget->supportsRMW()">, 263*9880d681SAndroid Build Coastguard Worker AssemblerPredicate<"FeatureRMW">; 264*9880d681SAndroid Build Coastguard Worker 265*9880d681SAndroid Build Coastguard Workerdef SupportsMultiplication : Predicate<"Subtarget->supportsMultiplication()">, 266*9880d681SAndroid Build Coastguard Worker AssemblerPredicate<"FeatureMultiplication">; 267*9880d681SAndroid Build Coastguard Worker 268*9880d681SAndroid Build Coastguard Workerdef HasBREAK : Predicate<"Subtarget->hasBREAK()">, 269*9880d681SAndroid Build Coastguard Worker AssemblerPredicate<"FeatureBREAK">; 270*9880d681SAndroid Build Coastguard Worker 271*9880d681SAndroid Build Coastguard Workerdef HasTinyEncoding : Predicate<"Subtarget->hasTinyEncoding()">, 272*9880d681SAndroid Build Coastguard Worker AssemblerPredicate<"FeatureTinyEncoding">; 273*9880d681SAndroid Build Coastguard Worker 274*9880d681SAndroid Build Coastguard Worker 275*9880d681SAndroid Build Coastguard Worker// AVR specific condition code. These correspond to AVR_*_COND in 276*9880d681SAndroid Build Coastguard Worker// AVRInstrInfo.td. They must be kept in synch. 277*9880d681SAndroid Build Coastguard Workerdef AVR_COND_EQ : PatLeaf<(i8 0)>; 278*9880d681SAndroid Build Coastguard Workerdef AVR_COND_NE : PatLeaf<(i8 1)>; 279*9880d681SAndroid Build Coastguard Workerdef AVR_COND_GE : PatLeaf<(i8 2)>; 280*9880d681SAndroid Build Coastguard Workerdef AVR_COND_LT : PatLeaf<(i8 3)>; 281*9880d681SAndroid Build Coastguard Workerdef AVR_COND_SH : PatLeaf<(i8 4)>; 282*9880d681SAndroid Build Coastguard Workerdef AVR_COND_LO : PatLeaf<(i8 5)>; 283*9880d681SAndroid Build Coastguard Workerdef AVR_COND_MI : PatLeaf<(i8 6)>; 284*9880d681SAndroid Build Coastguard Workerdef AVR_COND_PL : PatLeaf<(i8 7)>; 285*9880d681SAndroid Build Coastguard Worker 286*9880d681SAndroid Build Coastguard Worker 287*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 288*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 289*9880d681SAndroid Build Coastguard Worker// AVR Instruction list 290*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 291*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 292*9880d681SAndroid Build Coastguard Worker 293*9880d681SAndroid Build Coastguard Worker// ADJCALLSTACKDOWN/UP implicitly use/def SP because they may be expanded into 294*9880d681SAndroid Build Coastguard Worker// a stack adjustment and the codegen must know that they may modify the stack 295*9880d681SAndroid Build Coastguard Worker// pointer before prolog-epilog rewriting occurs. 296*9880d681SAndroid Build Coastguard Worker// Pessimistically assume ADJCALLSTACKDOWN / ADJCALLSTACKUP will become 297*9880d681SAndroid Build Coastguard Worker// sub / add which can clobber SREG. 298*9880d681SAndroid Build Coastguard Workerlet Defs = [SP, SREG], 299*9880d681SAndroid Build Coastguard WorkerUses = [SP] in 300*9880d681SAndroid Build Coastguard Worker{ 301*9880d681SAndroid Build Coastguard Worker def ADJCALLSTACKDOWN : Pseudo<(outs), 302*9880d681SAndroid Build Coastguard Worker (ins i16imm:$amt), 303*9880d681SAndroid Build Coastguard Worker "#ADJCALLSTACKDOWN", 304*9880d681SAndroid Build Coastguard Worker [(AVRcallseq_start timm:$amt)]>; 305*9880d681SAndroid Build Coastguard Worker 306*9880d681SAndroid Build Coastguard Worker // R31R30 is used to update SP, since it is a scratch reg and this instruction 307*9880d681SAndroid Build Coastguard Worker // is placed after the function call then R31R30 should be always free. 308*9880d681SAndroid Build Coastguard Worker //let Defs = [R31R30], 309*9880d681SAndroid Build Coastguard Worker //Uses = [R31R30] in 310*9880d681SAndroid Build Coastguard Worker //:TODO: if we enable this, the pseudo is killed because it looks dead 311*9880d681SAndroid Build Coastguard Worker def ADJCALLSTACKUP : Pseudo<(outs), 312*9880d681SAndroid Build Coastguard Worker (ins i16imm:$amt1, i16imm:$amt2), 313*9880d681SAndroid Build Coastguard Worker "#ADJCALLSTACKUP", 314*9880d681SAndroid Build Coastguard Worker [(AVRcallseq_end timm:$amt1, timm:$amt2)]>; 315*9880d681SAndroid Build Coastguard Worker} 316*9880d681SAndroid Build Coastguard Worker 317*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 318*9880d681SAndroid Build Coastguard Worker// Addition 319*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 320*9880d681SAndroid Build Coastguard Workerlet isCommutable = 1, 321*9880d681SAndroid Build Coastguard WorkerConstraints = "$src = $rd", 322*9880d681SAndroid Build Coastguard WorkerDefs = [SREG] in 323*9880d681SAndroid Build Coastguard Worker{ 324*9880d681SAndroid Build Coastguard Worker // ADD Rd, Rr 325*9880d681SAndroid Build Coastguard Worker // Adds two 8-bit registers. 326*9880d681SAndroid Build Coastguard Worker def ADDRdRr : FRdRr<0b0000, 327*9880d681SAndroid Build Coastguard Worker 0b11, 328*9880d681SAndroid Build Coastguard Worker (outs GPR8:$rd), 329*9880d681SAndroid Build Coastguard Worker (ins GPR8:$src, GPR8:$rr), 330*9880d681SAndroid Build Coastguard Worker "add\t$rd, $rr", 331*9880d681SAndroid Build Coastguard Worker [(set i8:$rd, (add i8:$src, i8:$rr)), 332*9880d681SAndroid Build Coastguard Worker (implicit SREG)]>; 333*9880d681SAndroid Build Coastguard Worker 334*9880d681SAndroid Build Coastguard Worker // ADDW Rd+1:Rd, Rr+1:Rr 335*9880d681SAndroid Build Coastguard Worker // Pseudo instruction to add four 8-bit registers as two 16-bit values. 336*9880d681SAndroid Build Coastguard Worker // 337*9880d681SAndroid Build Coastguard Worker // Expands to: 338*9880d681SAndroid Build Coastguard Worker // add Rd, Rr 339*9880d681SAndroid Build Coastguard Worker // adc Rd+1, Rr+1 340*9880d681SAndroid Build Coastguard Worker def ADDWRdRr : Pseudo<(outs DREGS:$rd), 341*9880d681SAndroid Build Coastguard Worker (ins DREGS:$src, DREGS:$rr), 342*9880d681SAndroid Build Coastguard Worker "addw\t$rd, $rr", 343*9880d681SAndroid Build Coastguard Worker [(set i16:$rd, (add i16:$src, i16:$rr)), 344*9880d681SAndroid Build Coastguard Worker (implicit SREG)]>; 345*9880d681SAndroid Build Coastguard Worker 346*9880d681SAndroid Build Coastguard Worker // ADC Rd, Rr 347*9880d681SAndroid Build Coastguard Worker // Adds two 8-bit registers with carry. 348*9880d681SAndroid Build Coastguard Worker let Uses = [SREG] in 349*9880d681SAndroid Build Coastguard Worker def ADCRdRr : FRdRr<0b0001, 350*9880d681SAndroid Build Coastguard Worker 0b11, 351*9880d681SAndroid Build Coastguard Worker (outs GPR8:$rd), 352*9880d681SAndroid Build Coastguard Worker (ins GPR8:$src, GPR8:$rr), 353*9880d681SAndroid Build Coastguard Worker "adc\t$rd, $rr", 354*9880d681SAndroid Build Coastguard Worker [(set i8:$rd, (adde i8:$src, i8:$rr)), 355*9880d681SAndroid Build Coastguard Worker (implicit SREG)]>; 356*9880d681SAndroid Build Coastguard Worker 357*9880d681SAndroid Build Coastguard Worker // ADCW Rd+1:Rd, Rr+1:Rr 358*9880d681SAndroid Build Coastguard Worker // Pseudo instruction to add four 8-bit registers as two 16-bit values with 359*9880d681SAndroid Build Coastguard Worker // carry. 360*9880d681SAndroid Build Coastguard Worker // 361*9880d681SAndroid Build Coastguard Worker // Expands to: 362*9880d681SAndroid Build Coastguard Worker // adc Rd, Rr 363*9880d681SAndroid Build Coastguard Worker // adc Rd+1, Rr+1 364*9880d681SAndroid Build Coastguard Worker let Uses = [SREG] in 365*9880d681SAndroid Build Coastguard Worker def ADCWRdRr : Pseudo<(outs DREGS:$rd), 366*9880d681SAndroid Build Coastguard Worker (ins DREGS:$src, DREGS:$rr), 367*9880d681SAndroid Build Coastguard Worker "adcw\t$rd, $rr", 368*9880d681SAndroid Build Coastguard Worker [(set i16:$rd, (adde i16:$src, i16:$rr)), 369*9880d681SAndroid Build Coastguard Worker (implicit SREG)]>; 370*9880d681SAndroid Build Coastguard Worker 371*9880d681SAndroid Build Coastguard Worker // AIDW Rd, k 372*9880d681SAndroid Build Coastguard Worker // Adds an immediate 6-bit value K to Rd, placing the result in Rd. 373*9880d681SAndroid Build Coastguard Worker def ADIWRdK : FWRdK<0b0, 374*9880d681SAndroid Build Coastguard Worker (outs IWREGS:$rd), 375*9880d681SAndroid Build Coastguard Worker (ins IWREGS:$src, i16imm:$k), 376*9880d681SAndroid Build Coastguard Worker "adiw\t$rd, $k", 377*9880d681SAndroid Build Coastguard Worker [(set i16:$rd, (add i16:$src, uimm6:$k)), 378*9880d681SAndroid Build Coastguard Worker (implicit SREG)]>, 379*9880d681SAndroid Build Coastguard Worker Requires<[HasADDSUBIW]>; 380*9880d681SAndroid Build Coastguard Worker} 381*9880d681SAndroid Build Coastguard Worker 382*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 383*9880d681SAndroid Build Coastguard Worker// Subtraction 384*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 385*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src = $rd", 386*9880d681SAndroid Build Coastguard WorkerDefs = [SREG] in 387*9880d681SAndroid Build Coastguard Worker{ 388*9880d681SAndroid Build Coastguard Worker // SUB Rd, Rr 389*9880d681SAndroid Build Coastguard Worker // Subtracts the 8-bit value of Rr from Rd and places the value in Rd. 390*9880d681SAndroid Build Coastguard Worker def SUBRdRr : FRdRr<0b0001, 391*9880d681SAndroid Build Coastguard Worker 0b10, 392*9880d681SAndroid Build Coastguard Worker (outs GPR8:$rd), 393*9880d681SAndroid Build Coastguard Worker (ins GPR8:$src, GPR8:$rr), 394*9880d681SAndroid Build Coastguard Worker "sub\t$rd, $rr", 395*9880d681SAndroid Build Coastguard Worker [(set i8:$rd, (sub i8:$src, i8:$rr)), 396*9880d681SAndroid Build Coastguard Worker (implicit SREG)]>; 397*9880d681SAndroid Build Coastguard Worker 398*9880d681SAndroid Build Coastguard Worker // SUBW Rd+1:Rd, Rr+1:Rr 399*9880d681SAndroid Build Coastguard Worker // Subtracts two 16-bit values and places the result into Rd. 400*9880d681SAndroid Build Coastguard Worker // 401*9880d681SAndroid Build Coastguard Worker // Expands to: 402*9880d681SAndroid Build Coastguard Worker // sub Rd, Rr 403*9880d681SAndroid Build Coastguard Worker // sbc Rd+1, Rr+1 404*9880d681SAndroid Build Coastguard Worker def SUBWRdRr : Pseudo<(outs DREGS:$rd), 405*9880d681SAndroid Build Coastguard Worker (ins DREGS:$src, DREGS:$rr), 406*9880d681SAndroid Build Coastguard Worker "subw\t$rd, $rr", 407*9880d681SAndroid Build Coastguard Worker [(set i16:$rd, (sub i16:$src, i16:$rr)), 408*9880d681SAndroid Build Coastguard Worker (implicit SREG)]>; 409*9880d681SAndroid Build Coastguard Worker 410*9880d681SAndroid Build Coastguard Worker def SUBIRdK : FRdK<0b0101, 411*9880d681SAndroid Build Coastguard Worker (outs LD8:$rd), 412*9880d681SAndroid Build Coastguard Worker (ins LD8:$src, i8imm:$k), 413*9880d681SAndroid Build Coastguard Worker "subi\t$rd, $k", 414*9880d681SAndroid Build Coastguard Worker [(set i8:$rd, (sub i8:$src, imm:$k)), 415*9880d681SAndroid Build Coastguard Worker (implicit SREG)]>; 416*9880d681SAndroid Build Coastguard Worker 417*9880d681SAndroid Build Coastguard Worker // SUBIW Rd+1:Rd, K+1:K 418*9880d681SAndroid Build Coastguard Worker // 419*9880d681SAndroid Build Coastguard Worker // Expands to: 420*9880d681SAndroid Build Coastguard Worker // subi Rd, K 421*9880d681SAndroid Build Coastguard Worker // sbci Rd+1, K+1 422*9880d681SAndroid Build Coastguard Worker def SUBIWRdK : Pseudo<(outs DLDREGS:$rd), 423*9880d681SAndroid Build Coastguard Worker (ins DLDREGS:$src, i16imm:$rr), 424*9880d681SAndroid Build Coastguard Worker "subiw\t$rd, $rr", 425*9880d681SAndroid Build Coastguard Worker [(set i16:$rd, (sub i16:$src, imm:$rr)), 426*9880d681SAndroid Build Coastguard Worker (implicit SREG)]>; 427*9880d681SAndroid Build Coastguard Worker 428*9880d681SAndroid Build Coastguard Worker def SBIWRdK : FWRdK<0b1, 429*9880d681SAndroid Build Coastguard Worker (outs IWREGS:$rd), 430*9880d681SAndroid Build Coastguard Worker (ins IWREGS:$src, i16imm:$k), 431*9880d681SAndroid Build Coastguard Worker "sbiw\t$rd, $k", 432*9880d681SAndroid Build Coastguard Worker [(set i16:$rd, (sub i16:$src, uimm6:$k)), 433*9880d681SAndroid Build Coastguard Worker (implicit SREG)]>, 434*9880d681SAndroid Build Coastguard Worker Requires<[HasADDSUBIW]>; 435*9880d681SAndroid Build Coastguard Worker 436*9880d681SAndroid Build Coastguard Worker // Subtract with carry operations which must read the carry flag in SREG. 437*9880d681SAndroid Build Coastguard Worker let Uses = [SREG] in 438*9880d681SAndroid Build Coastguard Worker { 439*9880d681SAndroid Build Coastguard Worker def SBCRdRr : FRdRr<0b0000, 440*9880d681SAndroid Build Coastguard Worker 0b10, 441*9880d681SAndroid Build Coastguard Worker (outs GPR8:$rd), 442*9880d681SAndroid Build Coastguard Worker (ins GPR8:$src, GPR8:$rr), 443*9880d681SAndroid Build Coastguard Worker "sbc\t$rd, $rr", 444*9880d681SAndroid Build Coastguard Worker [(set i8:$rd, (sube i8:$src, i8:$rr)), 445*9880d681SAndroid Build Coastguard Worker (implicit SREG)]>; 446*9880d681SAndroid Build Coastguard Worker 447*9880d681SAndroid Build Coastguard Worker // SBCW Rd+1:Rd, Rr+1:Rr 448*9880d681SAndroid Build Coastguard Worker // 449*9880d681SAndroid Build Coastguard Worker // Expands to: 450*9880d681SAndroid Build Coastguard Worker // sbc Rd, Rr 451*9880d681SAndroid Build Coastguard Worker // sbc Rd+1, Rr+1 452*9880d681SAndroid Build Coastguard Worker def SBCWRdRr : Pseudo<(outs DREGS:$rd), 453*9880d681SAndroid Build Coastguard Worker (ins DREGS:$src, DREGS:$rr), 454*9880d681SAndroid Build Coastguard Worker "sbcw\t$rd, $rr", 455*9880d681SAndroid Build Coastguard Worker [(set i16:$rd, (sube i16:$src, i16:$rr)), 456*9880d681SAndroid Build Coastguard Worker (implicit SREG)]>; 457*9880d681SAndroid Build Coastguard Worker 458*9880d681SAndroid Build Coastguard Worker def SBCIRdK : FRdK<0b0100, 459*9880d681SAndroid Build Coastguard Worker (outs LD8:$rd), 460*9880d681SAndroid Build Coastguard Worker (ins LD8:$src, i8imm:$k), 461*9880d681SAndroid Build Coastguard Worker "sbci\t$rd, $k", 462*9880d681SAndroid Build Coastguard Worker [(set i8:$rd, (sube i8:$src, imm:$k)), 463*9880d681SAndroid Build Coastguard Worker (implicit SREG)]>; 464*9880d681SAndroid Build Coastguard Worker 465*9880d681SAndroid Build Coastguard Worker // SBCIW Rd+1:Rd, K+1:K 466*9880d681SAndroid Build Coastguard Worker // sbci Rd, K 467*9880d681SAndroid Build Coastguard Worker // sbci Rd+1, K+1 468*9880d681SAndroid Build Coastguard Worker def SBCIWRdK : Pseudo<(outs DLDREGS:$rd), 469*9880d681SAndroid Build Coastguard Worker (ins DLDREGS:$src, i16imm:$rr), 470*9880d681SAndroid Build Coastguard Worker "sbciw\t$rd, $rr", 471*9880d681SAndroid Build Coastguard Worker [(set i16:$rd, (sube i16:$src, imm:$rr)), 472*9880d681SAndroid Build Coastguard Worker (implicit SREG)]>; 473*9880d681SAndroid Build Coastguard Worker } 474*9880d681SAndroid Build Coastguard Worker} 475*9880d681SAndroid Build Coastguard Worker 476*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 477*9880d681SAndroid Build Coastguard Worker// Increment and Decrement 478*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 479*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src = $rd", 480*9880d681SAndroid Build Coastguard WorkerDefs = [SREG] in 481*9880d681SAndroid Build Coastguard Worker{ 482*9880d681SAndroid Build Coastguard Worker def INCRd : FRd<0b1001, 483*9880d681SAndroid Build Coastguard Worker 0b0100011, 484*9880d681SAndroid Build Coastguard Worker (outs GPR8:$rd), 485*9880d681SAndroid Build Coastguard Worker (ins GPR8:$src), 486*9880d681SAndroid Build Coastguard Worker "inc\t$rd", 487*9880d681SAndroid Build Coastguard Worker [(set i8:$rd, (add i8:$src, 1)), (implicit SREG)]>; 488*9880d681SAndroid Build Coastguard Worker 489*9880d681SAndroid Build Coastguard Worker def DECRd : FRd<0b1001, 490*9880d681SAndroid Build Coastguard Worker 0b0101010, 491*9880d681SAndroid Build Coastguard Worker (outs GPR8:$rd), 492*9880d681SAndroid Build Coastguard Worker (ins GPR8:$src), 493*9880d681SAndroid Build Coastguard Worker "dec\t$rd", 494*9880d681SAndroid Build Coastguard Worker [(set i8:$rd, (add i8:$src, -1)), (implicit SREG)]>; 495*9880d681SAndroid Build Coastguard Worker} 496*9880d681SAndroid Build Coastguard Worker 497*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 498*9880d681SAndroid Build Coastguard Worker// Multiplication 499*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 500*9880d681SAndroid Build Coastguard Worker 501*9880d681SAndroid Build Coastguard Workerlet isCommutable = 1, 502*9880d681SAndroid Build Coastguard WorkerDefs = [R1, R0, SREG] in 503*9880d681SAndroid Build Coastguard Worker{ 504*9880d681SAndroid Build Coastguard Worker // MUL Rd, Rr 505*9880d681SAndroid Build Coastguard Worker // Multiplies Rd by Rr and places the result into R1:R0. 506*9880d681SAndroid Build Coastguard Worker let usesCustomInserter = 1 in { 507*9880d681SAndroid Build Coastguard Worker def MULRdRr : FRdRr<0b1001, 0b11, 508*9880d681SAndroid Build Coastguard Worker (outs), 509*9880d681SAndroid Build Coastguard Worker (ins GPR8:$lhs, GPR8:$rhs), 510*9880d681SAndroid Build Coastguard Worker "mul\t$lhs, $rhs", 511*9880d681SAndroid Build Coastguard Worker [/*(set R1, R0, (smullohi i8:$lhs, i8:$rhs))*/]>, 512*9880d681SAndroid Build Coastguard Worker Requires<[SupportsMultiplication]>; 513*9880d681SAndroid Build Coastguard Worker 514*9880d681SAndroid Build Coastguard Worker def MULSRdRr : FMUL2RdRr<0, 515*9880d681SAndroid Build Coastguard Worker (outs), 516*9880d681SAndroid Build Coastguard Worker (ins GPR8:$lhs, GPR8:$rhs), 517*9880d681SAndroid Build Coastguard Worker "muls\t$lhs, $rhs", 518*9880d681SAndroid Build Coastguard Worker []>, 519*9880d681SAndroid Build Coastguard Worker Requires<[SupportsMultiplication]>; 520*9880d681SAndroid Build Coastguard Worker } 521*9880d681SAndroid Build Coastguard Worker 522*9880d681SAndroid Build Coastguard Worker def MULSURdRr : FMUL2RdRr<1, 523*9880d681SAndroid Build Coastguard Worker (outs), 524*9880d681SAndroid Build Coastguard Worker (ins GPR8:$lhs, GPR8:$rhs), 525*9880d681SAndroid Build Coastguard Worker "mulsu\t$lhs, $rhs", 526*9880d681SAndroid Build Coastguard Worker []>, 527*9880d681SAndroid Build Coastguard Worker Requires<[SupportsMultiplication]>; 528*9880d681SAndroid Build Coastguard Worker 529*9880d681SAndroid Build Coastguard Worker def FMUL : FFMULRdRr<0b01, 530*9880d681SAndroid Build Coastguard Worker (outs), 531*9880d681SAndroid Build Coastguard Worker (ins GPR8:$lhs, GPR8:$rhs), 532*9880d681SAndroid Build Coastguard Worker "fmul\t$lhs, $rhs", 533*9880d681SAndroid Build Coastguard Worker []>, 534*9880d681SAndroid Build Coastguard Worker Requires<[SupportsMultiplication]>; 535*9880d681SAndroid Build Coastguard Worker 536*9880d681SAndroid Build Coastguard Worker def FMULS : FFMULRdRr<0b10, 537*9880d681SAndroid Build Coastguard Worker (outs), 538*9880d681SAndroid Build Coastguard Worker (ins GPR8:$lhs, GPR8:$rhs), 539*9880d681SAndroid Build Coastguard Worker "fmuls\t$lhs, $rhs", 540*9880d681SAndroid Build Coastguard Worker []>, 541*9880d681SAndroid Build Coastguard Worker Requires<[SupportsMultiplication]>; 542*9880d681SAndroid Build Coastguard Worker 543*9880d681SAndroid Build Coastguard Worker def FMULSU : FFMULRdRr<0b11, 544*9880d681SAndroid Build Coastguard Worker (outs), 545*9880d681SAndroid Build Coastguard Worker (ins GPR8:$lhs, GPR8:$rhs), 546*9880d681SAndroid Build Coastguard Worker "fmulsu\t$lhs, $rhs", 547*9880d681SAndroid Build Coastguard Worker []>, 548*9880d681SAndroid Build Coastguard Worker Requires<[SupportsMultiplication]>; 549*9880d681SAndroid Build Coastguard Worker} 550*9880d681SAndroid Build Coastguard Worker 551*9880d681SAndroid Build Coastguard Workerlet Defs = [R15, R14, R13, R12, R11, R10, R9, 552*9880d681SAndroid Build Coastguard Worker R8, R7, R6, R5, R4, R3, R2, R1, R0] in 553*9880d681SAndroid Build Coastguard Workerdef DESK : FDES<(outs), 554*9880d681SAndroid Build Coastguard Worker (ins i8imm:$k), 555*9880d681SAndroid Build Coastguard Worker "des\t$k", 556*9880d681SAndroid Build Coastguard Worker []>, 557*9880d681SAndroid Build Coastguard Worker Requires<[HasDES]>; 558*9880d681SAndroid Build Coastguard Worker 559*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 560*9880d681SAndroid Build Coastguard Worker// Logic 561*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 562*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src = $rd", 563*9880d681SAndroid Build Coastguard WorkerDefs = [SREG] in 564*9880d681SAndroid Build Coastguard Worker{ 565*9880d681SAndroid Build Coastguard Worker // Register-Register logic instructions (which have the 566*9880d681SAndroid Build Coastguard Worker // property of commutativity). 567*9880d681SAndroid Build Coastguard Worker let isCommutable = 1 in 568*9880d681SAndroid Build Coastguard Worker { 569*9880d681SAndroid Build Coastguard Worker def ANDRdRr : FRdRr<0b0010, 570*9880d681SAndroid Build Coastguard Worker 0b00, 571*9880d681SAndroid Build Coastguard Worker (outs GPR8:$rd), 572*9880d681SAndroid Build Coastguard Worker (ins GPR8:$src, GPR8:$rr), 573*9880d681SAndroid Build Coastguard Worker "and\t$rd, $rr", 574*9880d681SAndroid Build Coastguard Worker [(set i8:$rd, (and i8:$src, i8:$rr)), 575*9880d681SAndroid Build Coastguard Worker (implicit SREG)]>; 576*9880d681SAndroid Build Coastguard Worker 577*9880d681SAndroid Build Coastguard Worker // ANDW Rd+1:Rd, Rr+1:Rr 578*9880d681SAndroid Build Coastguard Worker // 579*9880d681SAndroid Build Coastguard Worker // Expands to: 580*9880d681SAndroid Build Coastguard Worker // and Rd, Rr 581*9880d681SAndroid Build Coastguard Worker // and Rd+1, Rr+1 582*9880d681SAndroid Build Coastguard Worker def ANDWRdRr : Pseudo<(outs DREGS:$rd), 583*9880d681SAndroid Build Coastguard Worker (ins DREGS:$src, DREGS:$rr), 584*9880d681SAndroid Build Coastguard Worker "andw\t$rd, $rr", 585*9880d681SAndroid Build Coastguard Worker [(set i16:$rd, (and i16:$src, i16:$rr)), 586*9880d681SAndroid Build Coastguard Worker (implicit SREG)]>; 587*9880d681SAndroid Build Coastguard Worker 588*9880d681SAndroid Build Coastguard Worker def ORRdRr : FRdRr<0b0010, 589*9880d681SAndroid Build Coastguard Worker 0b10, 590*9880d681SAndroid Build Coastguard Worker (outs GPR8:$rd), 591*9880d681SAndroid Build Coastguard Worker (ins GPR8:$src, GPR8:$rr), 592*9880d681SAndroid Build Coastguard Worker "or\t$rd, $rr", 593*9880d681SAndroid Build Coastguard Worker [(set i8:$rd, (or i8:$src, i8:$rr)), 594*9880d681SAndroid Build Coastguard Worker (implicit SREG)]>; 595*9880d681SAndroid Build Coastguard Worker 596*9880d681SAndroid Build Coastguard Worker // ORW Rd+1:Rd, Rr+1:Rr 597*9880d681SAndroid Build Coastguard Worker // 598*9880d681SAndroid Build Coastguard Worker // Expands to: 599*9880d681SAndroid Build Coastguard Worker // or Rd, Rr 600*9880d681SAndroid Build Coastguard Worker // or Rd+1, Rr+1 601*9880d681SAndroid Build Coastguard Worker def ORWRdRr : Pseudo<(outs DREGS:$rd), 602*9880d681SAndroid Build Coastguard Worker (ins DREGS:$src, DREGS:$rr), 603*9880d681SAndroid Build Coastguard Worker "orw\t$rd, $rr", 604*9880d681SAndroid Build Coastguard Worker [(set i16:$rd, (or i16:$src, i16:$rr)), 605*9880d681SAndroid Build Coastguard Worker (implicit SREG)]>; 606*9880d681SAndroid Build Coastguard Worker 607*9880d681SAndroid Build Coastguard Worker def EORRdRr : FRdRr<0b0010, 608*9880d681SAndroid Build Coastguard Worker 0b01, 609*9880d681SAndroid Build Coastguard Worker (outs GPR8:$rd), 610*9880d681SAndroid Build Coastguard Worker (ins GPR8:$src, GPR8:$rr), 611*9880d681SAndroid Build Coastguard Worker "eor\t$rd, $rr", 612*9880d681SAndroid Build Coastguard Worker [(set i8:$rd, (xor i8:$src, i8:$rr)), 613*9880d681SAndroid Build Coastguard Worker (implicit SREG)]>; 614*9880d681SAndroid Build Coastguard Worker 615*9880d681SAndroid Build Coastguard Worker // EORW Rd+1:Rd, Rr+1:Rr 616*9880d681SAndroid Build Coastguard Worker // 617*9880d681SAndroid Build Coastguard Worker // Expands to: 618*9880d681SAndroid Build Coastguard Worker // eor Rd, Rr 619*9880d681SAndroid Build Coastguard Worker // eor Rd+1, Rr+1 620*9880d681SAndroid Build Coastguard Worker def EORWRdRr : Pseudo<(outs DREGS:$rd), 621*9880d681SAndroid Build Coastguard Worker (ins DREGS:$src, DREGS:$rr), 622*9880d681SAndroid Build Coastguard Worker "eorw\t$rd, $rr", 623*9880d681SAndroid Build Coastguard Worker [(set i16:$rd, (xor i16:$src, i16:$rr)), 624*9880d681SAndroid Build Coastguard Worker (implicit SREG)]>; 625*9880d681SAndroid Build Coastguard Worker } 626*9880d681SAndroid Build Coastguard Worker 627*9880d681SAndroid Build Coastguard Worker def ANDIRdK : FRdK<0b0111, 628*9880d681SAndroid Build Coastguard Worker (outs LD8:$rd), 629*9880d681SAndroid Build Coastguard Worker (ins LD8:$src, i8imm:$k), 630*9880d681SAndroid Build Coastguard Worker "andi\t$rd, $k", 631*9880d681SAndroid Build Coastguard Worker [(set i8:$rd, (and i8:$src, imm:$k)), 632*9880d681SAndroid Build Coastguard Worker (implicit SREG)]>; 633*9880d681SAndroid Build Coastguard Worker 634*9880d681SAndroid Build Coastguard Worker // ANDI Rd+1:Rd, K+1:K 635*9880d681SAndroid Build Coastguard Worker // 636*9880d681SAndroid Build Coastguard Worker // Expands to: 637*9880d681SAndroid Build Coastguard Worker // andi Rd, K 638*9880d681SAndroid Build Coastguard Worker // andi Rd+1, K+1 639*9880d681SAndroid Build Coastguard Worker def ANDIWRdK : Pseudo<(outs DLDREGS:$rd), 640*9880d681SAndroid Build Coastguard Worker (ins DLDREGS:$src, i16imm:$k), 641*9880d681SAndroid Build Coastguard Worker "andiw\t$rd, $k", 642*9880d681SAndroid Build Coastguard Worker [(set i16:$rd, (and i16:$src, imm:$k)), 643*9880d681SAndroid Build Coastguard Worker (implicit SREG)]>; 644*9880d681SAndroid Build Coastguard Worker 645*9880d681SAndroid Build Coastguard Worker def ORIRdK : FRdK<0b0110, 646*9880d681SAndroid Build Coastguard Worker (outs LD8:$rd), 647*9880d681SAndroid Build Coastguard Worker (ins LD8:$src, i8imm:$k), 648*9880d681SAndroid Build Coastguard Worker "ori\t$rd, $k", 649*9880d681SAndroid Build Coastguard Worker [(set i8:$rd, (or i8:$src, imm:$k)), 650*9880d681SAndroid Build Coastguard Worker (implicit SREG)]>; 651*9880d681SAndroid Build Coastguard Worker 652*9880d681SAndroid Build Coastguard Worker // ORIW Rd+1:Rd, K+1,K 653*9880d681SAndroid Build Coastguard Worker // 654*9880d681SAndroid Build Coastguard Worker // Expands to: 655*9880d681SAndroid Build Coastguard Worker // ori Rd, K 656*9880d681SAndroid Build Coastguard Worker // ori Rd+1, K+1 657*9880d681SAndroid Build Coastguard Worker def ORIWRdK : Pseudo<(outs DLDREGS:$rd), 658*9880d681SAndroid Build Coastguard Worker (ins DLDREGS:$src, i16imm:$rr), 659*9880d681SAndroid Build Coastguard Worker "oriw\t$rd, $rr", 660*9880d681SAndroid Build Coastguard Worker [(set i16:$rd, (or i16:$src, imm:$rr)), 661*9880d681SAndroid Build Coastguard Worker (implicit SREG)]>; 662*9880d681SAndroid Build Coastguard Worker} 663*9880d681SAndroid Build Coastguard Worker 664*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 665*9880d681SAndroid Build Coastguard Worker// One's/Two's Compliment 666*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 667*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src = $rd", 668*9880d681SAndroid Build Coastguard WorkerDefs = [SREG] in 669*9880d681SAndroid Build Coastguard Worker{ 670*9880d681SAndroid Build Coastguard Worker def COMRd : FRd<0b1001, 671*9880d681SAndroid Build Coastguard Worker 0b0100000, 672*9880d681SAndroid Build Coastguard Worker (outs GPR8:$rd), 673*9880d681SAndroid Build Coastguard Worker (ins GPR8:$src), 674*9880d681SAndroid Build Coastguard Worker "com\t$rd", 675*9880d681SAndroid Build Coastguard Worker [(set i8:$rd, (not i8:$src)), (implicit SREG)]>; 676*9880d681SAndroid Build Coastguard Worker 677*9880d681SAndroid Build Coastguard Worker // COMW Rd+1:Rd 678*9880d681SAndroid Build Coastguard Worker // 679*9880d681SAndroid Build Coastguard Worker // Expands to: 680*9880d681SAndroid Build Coastguard Worker // com Rd 681*9880d681SAndroid Build Coastguard Worker // com Rd+1 682*9880d681SAndroid Build Coastguard Worker def COMWRd : Pseudo<(outs DREGS:$rd), 683*9880d681SAndroid Build Coastguard Worker (ins DREGS:$src), 684*9880d681SAndroid Build Coastguard Worker "comw\t$rd", 685*9880d681SAndroid Build Coastguard Worker [(set i16:$rd, (not i16:$src)), (implicit SREG)]>; 686*9880d681SAndroid Build Coastguard Worker 687*9880d681SAndroid Build Coastguard Worker //:TODO: optimize NEG for wider types 688*9880d681SAndroid Build Coastguard Worker def NEGRd : FRd<0b1001, 689*9880d681SAndroid Build Coastguard Worker 0b0100001, 690*9880d681SAndroid Build Coastguard Worker (outs GPR8:$rd), 691*9880d681SAndroid Build Coastguard Worker (ins GPR8:$src), 692*9880d681SAndroid Build Coastguard Worker "neg\t$rd", 693*9880d681SAndroid Build Coastguard Worker [(set i8:$rd, (ineg i8:$src)), (implicit SREG)]>; 694*9880d681SAndroid Build Coastguard Worker} 695*9880d681SAndroid Build Coastguard Worker 696*9880d681SAndroid Build Coastguard Worker// TST Rd 697*9880d681SAndroid Build Coastguard Worker// Test for zero of minus. 698*9880d681SAndroid Build Coastguard Worker// This operation is identical to a `Rd AND Rd`. 699*9880d681SAndroid Build Coastguard Worker//def : InstAlias<"tst\t$rd", (ANDRdRr GPR8:$rd, GPR8:$rd), 1>; 700*9880d681SAndroid Build Coastguard Worker 701*9880d681SAndroid Build Coastguard Workerlet Defs = [SREG] in 702*9880d681SAndroid Build Coastguard Workerdef TSTRd : FTST<0b0010, 703*9880d681SAndroid Build Coastguard Worker 0b00, 704*9880d681SAndroid Build Coastguard Worker (outs), 705*9880d681SAndroid Build Coastguard Worker (ins GPR8:$rd), 706*9880d681SAndroid Build Coastguard Worker "tst\t$rd", 707*9880d681SAndroid Build Coastguard Worker [(AVRtst i8:$rd)]>; 708*9880d681SAndroid Build Coastguard Worker 709*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 710*9880d681SAndroid Build Coastguard Worker// Jump instructions 711*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 712*9880d681SAndroid Build Coastguard Workerlet isBarrier = 1, 713*9880d681SAndroid Build Coastguard WorkerisBranch = 1, 714*9880d681SAndroid Build Coastguard WorkerisTerminator = 1 in 715*9880d681SAndroid Build Coastguard Worker{ 716*9880d681SAndroid Build Coastguard Worker def RJMPk : FBRk<0, 717*9880d681SAndroid Build Coastguard Worker (outs), 718*9880d681SAndroid Build Coastguard Worker (ins brtarget_13:$target), 719*9880d681SAndroid Build Coastguard Worker "rjmp\t$target", 720*9880d681SAndroid Build Coastguard Worker [(br bb:$target)]>; 721*9880d681SAndroid Build Coastguard Worker 722*9880d681SAndroid Build Coastguard Worker let isIndirectBranch = 1, 723*9880d681SAndroid Build Coastguard Worker Uses = [R31R30] in 724*9880d681SAndroid Build Coastguard Worker def IJMP : F16<0b1001010000001001, 725*9880d681SAndroid Build Coastguard Worker (outs), 726*9880d681SAndroid Build Coastguard Worker (ins), 727*9880d681SAndroid Build Coastguard Worker "ijmp", 728*9880d681SAndroid Build Coastguard Worker []>, 729*9880d681SAndroid Build Coastguard Worker Requires<[HasIJMPCALL]>; 730*9880d681SAndroid Build Coastguard Worker 731*9880d681SAndroid Build Coastguard Worker let isIndirectBranch = 1, 732*9880d681SAndroid Build Coastguard Worker Uses = [R31R30] in 733*9880d681SAndroid Build Coastguard Worker def EIJMP : F16<0b1001010000011001, 734*9880d681SAndroid Build Coastguard Worker (outs), 735*9880d681SAndroid Build Coastguard Worker (ins), 736*9880d681SAndroid Build Coastguard Worker "eijmp", 737*9880d681SAndroid Build Coastguard Worker []>, 738*9880d681SAndroid Build Coastguard Worker Requires<[HasEIJMPCALL]>; 739*9880d681SAndroid Build Coastguard Worker 740*9880d681SAndroid Build Coastguard Worker def JMPk : F32BRk<0b110, 741*9880d681SAndroid Build Coastguard Worker (outs), 742*9880d681SAndroid Build Coastguard Worker (ins call_target:$k), 743*9880d681SAndroid Build Coastguard Worker "jmp\t$k", 744*9880d681SAndroid Build Coastguard Worker []>, 745*9880d681SAndroid Build Coastguard Worker Requires<[HasJMPCALL]>; 746*9880d681SAndroid Build Coastguard Worker} 747*9880d681SAndroid Build Coastguard Worker 748*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 749*9880d681SAndroid Build Coastguard Worker// Call instructions 750*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 751*9880d681SAndroid Build Coastguard Workerlet isCall = 1 in 752*9880d681SAndroid Build Coastguard Worker{ 753*9880d681SAndroid Build Coastguard Worker // SP is marked as a use to prevent stack-pointer assignments that appear 754*9880d681SAndroid Build Coastguard Worker // immediately before calls from potentially appearing dead. 755*9880d681SAndroid Build Coastguard Worker let Uses = [SP] in 756*9880d681SAndroid Build Coastguard Worker def RCALLk : FBRk<1, 757*9880d681SAndroid Build Coastguard Worker (outs), 758*9880d681SAndroid Build Coastguard Worker (ins brtarget_13:$target), 759*9880d681SAndroid Build Coastguard Worker "rcall\t$target", 760*9880d681SAndroid Build Coastguard Worker []>; 761*9880d681SAndroid Build Coastguard Worker 762*9880d681SAndroid Build Coastguard Worker // SP is marked as a use to prevent stack-pointer assignments that appear 763*9880d681SAndroid Build Coastguard Worker // immediately before calls from potentially appearing dead. 764*9880d681SAndroid Build Coastguard Worker let Uses = [SP, R31R30] in 765*9880d681SAndroid Build Coastguard Worker def ICALL : F16<0b1001010100001001, 766*9880d681SAndroid Build Coastguard Worker (outs), 767*9880d681SAndroid Build Coastguard Worker (ins variable_ops), 768*9880d681SAndroid Build Coastguard Worker "icall", 769*9880d681SAndroid Build Coastguard Worker []>, 770*9880d681SAndroid Build Coastguard Worker Requires<[HasIJMPCALL]>; 771*9880d681SAndroid Build Coastguard Worker 772*9880d681SAndroid Build Coastguard Worker // SP is marked as a use to prevent stack-pointer assignments that appear 773*9880d681SAndroid Build Coastguard Worker // immediately before calls from potentially appearing dead. 774*9880d681SAndroid Build Coastguard Worker let Uses = [SP, R31R30] in 775*9880d681SAndroid Build Coastguard Worker def EICALL : F16<0b1001010100011001, 776*9880d681SAndroid Build Coastguard Worker (outs), 777*9880d681SAndroid Build Coastguard Worker (ins variable_ops), 778*9880d681SAndroid Build Coastguard Worker "eicall", 779*9880d681SAndroid Build Coastguard Worker []>, 780*9880d681SAndroid Build Coastguard Worker Requires<[HasEIJMPCALL]>; 781*9880d681SAndroid Build Coastguard Worker 782*9880d681SAndroid Build Coastguard Worker // SP is marked as a use to prevent stack-pointer assignments that appear 783*9880d681SAndroid Build Coastguard Worker // immediately before calls from potentially appearing dead. 784*9880d681SAndroid Build Coastguard Worker // 785*9880d681SAndroid Build Coastguard Worker //:TODO: the imm field can be either 16 or 22 bits in devices with more 786*9880d681SAndroid Build Coastguard Worker // than 64k of ROM, fix it once we support the largest devices. 787*9880d681SAndroid Build Coastguard Worker let Uses = [SP] in 788*9880d681SAndroid Build Coastguard Worker def CALLk : F32BRk<0b111, 789*9880d681SAndroid Build Coastguard Worker (outs), 790*9880d681SAndroid Build Coastguard Worker (ins call_target:$k), 791*9880d681SAndroid Build Coastguard Worker "call\t$k", 792*9880d681SAndroid Build Coastguard Worker [(AVRcall imm:$k)]>, 793*9880d681SAndroid Build Coastguard Worker Requires<[HasJMPCALL]>; 794*9880d681SAndroid Build Coastguard Worker} 795*9880d681SAndroid Build Coastguard Worker 796*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 797*9880d681SAndroid Build Coastguard Worker// Return instructions. 798*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 799*9880d681SAndroid Build Coastguard Workerlet isTerminator = 1, 800*9880d681SAndroid Build Coastguard WorkerisReturn = 1, 801*9880d681SAndroid Build Coastguard WorkerisBarrier = 1 in 802*9880d681SAndroid Build Coastguard Worker{ 803*9880d681SAndroid Build Coastguard Worker def RET : F16<0b1001010100001000, 804*9880d681SAndroid Build Coastguard Worker (outs), 805*9880d681SAndroid Build Coastguard Worker (ins), 806*9880d681SAndroid Build Coastguard Worker "ret", 807*9880d681SAndroid Build Coastguard Worker [(AVRretflag)]>; 808*9880d681SAndroid Build Coastguard Worker 809*9880d681SAndroid Build Coastguard Worker def RETI : F16<0b1001010100011000, 810*9880d681SAndroid Build Coastguard Worker (outs), 811*9880d681SAndroid Build Coastguard Worker (ins), 812*9880d681SAndroid Build Coastguard Worker "reti", 813*9880d681SAndroid Build Coastguard Worker [(AVRretiflag)]>; 814*9880d681SAndroid Build Coastguard Worker} 815*9880d681SAndroid Build Coastguard Worker 816*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 817*9880d681SAndroid Build Coastguard Worker// Compare operations. 818*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 819*9880d681SAndroid Build Coastguard Workerlet Defs = [SREG] in 820*9880d681SAndroid Build Coastguard Worker{ 821*9880d681SAndroid Build Coastguard Worker // CPSE Rd, Rr 822*9880d681SAndroid Build Coastguard Worker // Compare Rd and Rr, skipping the next instruction if they are equal. 823*9880d681SAndroid Build Coastguard Worker let isBarrier = 1, 824*9880d681SAndroid Build Coastguard Worker isBranch = 1, 825*9880d681SAndroid Build Coastguard Worker isTerminator = 1 in 826*9880d681SAndroid Build Coastguard Worker def CPSE : FRdRr<0b0001, 827*9880d681SAndroid Build Coastguard Worker 0b00, 828*9880d681SAndroid Build Coastguard Worker (outs), 829*9880d681SAndroid Build Coastguard Worker (ins GPR8:$rd, GPR8:$rr), 830*9880d681SAndroid Build Coastguard Worker "cpse\t$rd, $rr", 831*9880d681SAndroid Build Coastguard Worker []>; 832*9880d681SAndroid Build Coastguard Worker 833*9880d681SAndroid Build Coastguard Worker def CPRdRr : FRdRr<0b0001, 834*9880d681SAndroid Build Coastguard Worker 0b01, 835*9880d681SAndroid Build Coastguard Worker (outs), 836*9880d681SAndroid Build Coastguard Worker (ins GPR8:$rd, GPR8:$rr), 837*9880d681SAndroid Build Coastguard Worker "cp\t$rd, $rr", 838*9880d681SAndroid Build Coastguard Worker [(AVRcmp i8:$rd, i8:$rr), (implicit SREG)]>; 839*9880d681SAndroid Build Coastguard Worker 840*9880d681SAndroid Build Coastguard Worker // CPW Rd+1:Rd, Rr+1:Rr 841*9880d681SAndroid Build Coastguard Worker // 842*9880d681SAndroid Build Coastguard Worker // Expands to: 843*9880d681SAndroid Build Coastguard Worker // cp Rd, Rr 844*9880d681SAndroid Build Coastguard Worker // cpc Rd+1, Rr+1 845*9880d681SAndroid Build Coastguard Worker def CPWRdRr : Pseudo<(outs), 846*9880d681SAndroid Build Coastguard Worker (ins DREGS:$src, DREGS:$src2), 847*9880d681SAndroid Build Coastguard Worker "cpw\t$src, $src2", 848*9880d681SAndroid Build Coastguard Worker [(AVRcmp i16:$src, i16:$src2), (implicit SREG)]>; 849*9880d681SAndroid Build Coastguard Worker 850*9880d681SAndroid Build Coastguard Worker let Uses = [SREG] in 851*9880d681SAndroid Build Coastguard Worker def CPCRdRr : FRdRr<0b0000, 852*9880d681SAndroid Build Coastguard Worker 0b01, 853*9880d681SAndroid Build Coastguard Worker (outs), 854*9880d681SAndroid Build Coastguard Worker (ins GPR8:$rd, GPR8:$rr), 855*9880d681SAndroid Build Coastguard Worker "cpc\t$rd, $rr", 856*9880d681SAndroid Build Coastguard Worker [(AVRcmpc i8:$rd, i8:$rr), (implicit SREG)]>; 857*9880d681SAndroid Build Coastguard Worker 858*9880d681SAndroid Build Coastguard Worker // CPCW Rd+1:Rd. Rr+1:Rr 859*9880d681SAndroid Build Coastguard Worker // 860*9880d681SAndroid Build Coastguard Worker // Expands to: 861*9880d681SAndroid Build Coastguard Worker // cpc Rd, Rr 862*9880d681SAndroid Build Coastguard Worker // cpc Rd+1, Rr+1 863*9880d681SAndroid Build Coastguard Worker let Uses = [SREG] in 864*9880d681SAndroid Build Coastguard Worker def CPCWRdRr : Pseudo<(outs), 865*9880d681SAndroid Build Coastguard Worker (ins DREGS:$src, DREGS:$src2), 866*9880d681SAndroid Build Coastguard Worker "cpcw\t$src, $src2", 867*9880d681SAndroid Build Coastguard Worker [(AVRcmpc i16:$src, i16:$src2), (implicit SREG)]>; 868*9880d681SAndroid Build Coastguard Worker 869*9880d681SAndroid Build Coastguard Worker // CPI Rd, K 870*9880d681SAndroid Build Coastguard Worker // Compares a register with an 8 bit immediate. 871*9880d681SAndroid Build Coastguard Worker let Uses = [SREG] in 872*9880d681SAndroid Build Coastguard Worker def CPIRdK : FRdK<0b0011, 873*9880d681SAndroid Build Coastguard Worker (outs), 874*9880d681SAndroid Build Coastguard Worker (ins GPR8:$rd, i8imm:$k), 875*9880d681SAndroid Build Coastguard Worker "cpi\t$rd, $k", 876*9880d681SAndroid Build Coastguard Worker [(AVRcmp i8:$rd, imm:$k), (implicit SREG)]>; 877*9880d681SAndroid Build Coastguard Worker} 878*9880d681SAndroid Build Coastguard Worker 879*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 880*9880d681SAndroid Build Coastguard Worker// Register conditional skipping/branching operations. 881*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 882*9880d681SAndroid Build Coastguard Workerlet isBranch = 1, 883*9880d681SAndroid Build Coastguard WorkerisTerminator = 1 in 884*9880d681SAndroid Build Coastguard Worker{ 885*9880d681SAndroid Build Coastguard Worker // Conditional skipping on GPR register bits, and 886*9880d681SAndroid Build Coastguard Worker // conditional skipping on IO register bits. 887*9880d681SAndroid Build Coastguard Worker let isBarrier = 1 in 888*9880d681SAndroid Build Coastguard Worker { 889*9880d681SAndroid Build Coastguard Worker def SBRCRrB : FRdB<0b10, 890*9880d681SAndroid Build Coastguard Worker (outs), 891*9880d681SAndroid Build Coastguard Worker (ins GPR8:$rr, i8imm:$b), 892*9880d681SAndroid Build Coastguard Worker "sbrc\t$rr, $b", 893*9880d681SAndroid Build Coastguard Worker []>; 894*9880d681SAndroid Build Coastguard Worker 895*9880d681SAndroid Build Coastguard Worker def SBRSRrB : FRdB<0b11, 896*9880d681SAndroid Build Coastguard Worker (outs), 897*9880d681SAndroid Build Coastguard Worker (ins GPR8:$rr, i8imm:$b), 898*9880d681SAndroid Build Coastguard Worker "sbrs\t$rr, $b", 899*9880d681SAndroid Build Coastguard Worker []>; 900*9880d681SAndroid Build Coastguard Worker 901*9880d681SAndroid Build Coastguard Worker def SBICAb : FIOBIT<0b01, 902*9880d681SAndroid Build Coastguard Worker (outs), 903*9880d681SAndroid Build Coastguard Worker (ins i16imm:$a, i8imm:$b), 904*9880d681SAndroid Build Coastguard Worker "sbic\t$a, $b", 905*9880d681SAndroid Build Coastguard Worker []>; 906*9880d681SAndroid Build Coastguard Worker 907*9880d681SAndroid Build Coastguard Worker def SBISAb : FIOBIT<0b11, 908*9880d681SAndroid Build Coastguard Worker (outs), 909*9880d681SAndroid Build Coastguard Worker (ins i16imm:$a, i8imm:$b), 910*9880d681SAndroid Build Coastguard Worker "sbis\t$a, $b", 911*9880d681SAndroid Build Coastguard Worker []>; 912*9880d681SAndroid Build Coastguard Worker } 913*9880d681SAndroid Build Coastguard Worker 914*9880d681SAndroid Build Coastguard Worker // Relative branches on status flag bits. 915*9880d681SAndroid Build Coastguard Worker let Uses = [SREG] in 916*9880d681SAndroid Build Coastguard Worker { 917*9880d681SAndroid Build Coastguard Worker // BRBS s, k 918*9880d681SAndroid Build Coastguard Worker // Branch if `s` flag in status register is set. 919*9880d681SAndroid Build Coastguard Worker def BRBSsk : FSK<0, 920*9880d681SAndroid Build Coastguard Worker (outs), 921*9880d681SAndroid Build Coastguard Worker (ins i8imm:$s, relbrtarget_7:$k), 922*9880d681SAndroid Build Coastguard Worker "brbs\t$s, $k", 923*9880d681SAndroid Build Coastguard Worker []>; 924*9880d681SAndroid Build Coastguard Worker 925*9880d681SAndroid Build Coastguard Worker // BRBC s, k 926*9880d681SAndroid Build Coastguard Worker // Branch if `s` flag in status register is clear. 927*9880d681SAndroid Build Coastguard Worker def BRBCsk : FSK<1, 928*9880d681SAndroid Build Coastguard Worker (outs), 929*9880d681SAndroid Build Coastguard Worker (ins i8imm:$s, relbrtarget_7:$k), 930*9880d681SAndroid Build Coastguard Worker "brbc\t$s, $k", 931*9880d681SAndroid Build Coastguard Worker []>; 932*9880d681SAndroid Build Coastguard Worker } 933*9880d681SAndroid Build Coastguard Worker} 934*9880d681SAndroid Build Coastguard Worker 935*9880d681SAndroid Build Coastguard Worker 936*9880d681SAndroid Build Coastguard Worker// BRCS k 937*9880d681SAndroid Build Coastguard Worker// Branch if carry flag is set 938*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"brcs\t$k", (BRBSsk 0, relbrtarget_7:$k)>; 939*9880d681SAndroid Build Coastguard Worker 940*9880d681SAndroid Build Coastguard Worker// BRCC k 941*9880d681SAndroid Build Coastguard Worker// Branch if carry flag is clear 942*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"brcc\t$k", (BRBCsk 0, relbrtarget_7:$k)>; 943*9880d681SAndroid Build Coastguard Worker 944*9880d681SAndroid Build Coastguard Worker// BRHS k 945*9880d681SAndroid Build Coastguard Worker// Branch if half carry flag is set 946*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"brhs\t$k", (BRBSsk 5, relbrtarget_7:$k)>; 947*9880d681SAndroid Build Coastguard Worker 948*9880d681SAndroid Build Coastguard Worker// BRHC k 949*9880d681SAndroid Build Coastguard Worker// Branch if half carry flag is clear 950*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"brhc\t$k", (BRBCsk 5, relbrtarget_7:$k)>; 951*9880d681SAndroid Build Coastguard Worker 952*9880d681SAndroid Build Coastguard Worker// BRTS k 953*9880d681SAndroid Build Coastguard Worker// Branch if the T flag is set 954*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"brts\t$k", (BRBSsk 6, relbrtarget_7:$k)>; 955*9880d681SAndroid Build Coastguard Worker 956*9880d681SAndroid Build Coastguard Worker// BRTC k 957*9880d681SAndroid Build Coastguard Worker// Branch if the T flag is clear 958*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"brtc\t$k", (BRBCsk 6, relbrtarget_7:$k)>; 959*9880d681SAndroid Build Coastguard Worker 960*9880d681SAndroid Build Coastguard Worker// BRVS k 961*9880d681SAndroid Build Coastguard Worker// Branch if the overflow flag is set 962*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"brvs\t$k", (BRBSsk 3, relbrtarget_7:$k)>; 963*9880d681SAndroid Build Coastguard Worker 964*9880d681SAndroid Build Coastguard Worker// BRVC k 965*9880d681SAndroid Build Coastguard Worker// Branch if the overflow flag is clear 966*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"brvc\t$k", (BRBCsk 3, relbrtarget_7:$k)>; 967*9880d681SAndroid Build Coastguard Worker 968*9880d681SAndroid Build Coastguard Worker// BRIE k 969*9880d681SAndroid Build Coastguard Worker// Branch if the global interrupt flag is enabled 970*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"brie\t$k", (BRBSsk 7, relbrtarget_7:$k)>; 971*9880d681SAndroid Build Coastguard Worker 972*9880d681SAndroid Build Coastguard Worker// BRID k 973*9880d681SAndroid Build Coastguard Worker// Branch if the global interrupt flag is disabled 974*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"brid\t$k", (BRBCsk 7, relbrtarget_7:$k)>; 975*9880d681SAndroid Build Coastguard Worker 976*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 977*9880d681SAndroid Build Coastguard Worker// PC-relative conditional branches 978*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 979*9880d681SAndroid Build Coastguard Worker// Based on status register. We cannot simplify these into instruction aliases 980*9880d681SAndroid Build Coastguard Worker// because we also need to be able to specify a pattern to match for ISel. 981*9880d681SAndroid Build Coastguard Workerlet isBranch = 1, 982*9880d681SAndroid Build Coastguard WorkerisTerminator = 1, 983*9880d681SAndroid Build Coastguard WorkerUses = [SREG] in 984*9880d681SAndroid Build Coastguard Worker{ 985*9880d681SAndroid Build Coastguard Worker def BREQk : FBRsk<0, 986*9880d681SAndroid Build Coastguard Worker 0b001, 987*9880d681SAndroid Build Coastguard Worker (outs), 988*9880d681SAndroid Build Coastguard Worker (ins relbrtarget_7:$target), 989*9880d681SAndroid Build Coastguard Worker "breq\t$target", 990*9880d681SAndroid Build Coastguard Worker [(AVRbrcond bb:$target, AVR_COND_EQ)]>; 991*9880d681SAndroid Build Coastguard Worker 992*9880d681SAndroid Build Coastguard Worker def BRNEk : FBRsk<1, 993*9880d681SAndroid Build Coastguard Worker 0b001, 994*9880d681SAndroid Build Coastguard Worker (outs), 995*9880d681SAndroid Build Coastguard Worker (ins relbrtarget_7:$target), 996*9880d681SAndroid Build Coastguard Worker "brne\t$target", 997*9880d681SAndroid Build Coastguard Worker [(AVRbrcond bb:$target, AVR_COND_NE)]>; 998*9880d681SAndroid Build Coastguard Worker 999*9880d681SAndroid Build Coastguard Worker 1000*9880d681SAndroid Build Coastguard Worker def BRSHk : FBRsk<1, 1001*9880d681SAndroid Build Coastguard Worker 0b000, 1002*9880d681SAndroid Build Coastguard Worker (outs), 1003*9880d681SAndroid Build Coastguard Worker (ins relbrtarget_7:$target), 1004*9880d681SAndroid Build Coastguard Worker "brsh\t$target", 1005*9880d681SAndroid Build Coastguard Worker [(AVRbrcond bb:$target, AVR_COND_SH)]>; 1006*9880d681SAndroid Build Coastguard Worker 1007*9880d681SAndroid Build Coastguard Worker def BRLOk : FBRsk<0, 1008*9880d681SAndroid Build Coastguard Worker 0b000, 1009*9880d681SAndroid Build Coastguard Worker (outs), 1010*9880d681SAndroid Build Coastguard Worker (ins relbrtarget_7:$target), 1011*9880d681SAndroid Build Coastguard Worker "brlo\t$target", 1012*9880d681SAndroid Build Coastguard Worker [(AVRbrcond bb:$target, AVR_COND_LO)]>; 1013*9880d681SAndroid Build Coastguard Worker 1014*9880d681SAndroid Build Coastguard Worker def BRMIk : FBRsk<0, 1015*9880d681SAndroid Build Coastguard Worker 0b010, 1016*9880d681SAndroid Build Coastguard Worker (outs), 1017*9880d681SAndroid Build Coastguard Worker (ins relbrtarget_7:$target), 1018*9880d681SAndroid Build Coastguard Worker "brmi\t$target", 1019*9880d681SAndroid Build Coastguard Worker [(AVRbrcond bb:$target, AVR_COND_MI)]>; 1020*9880d681SAndroid Build Coastguard Worker 1021*9880d681SAndroid Build Coastguard Worker def BRPLk : FBRsk<1, 1022*9880d681SAndroid Build Coastguard Worker 0b010, 1023*9880d681SAndroid Build Coastguard Worker (outs), 1024*9880d681SAndroid Build Coastguard Worker (ins relbrtarget_7:$target), 1025*9880d681SAndroid Build Coastguard Worker "brpl\t$target", 1026*9880d681SAndroid Build Coastguard Worker [(AVRbrcond bb:$target, AVR_COND_PL)]>; 1027*9880d681SAndroid Build Coastguard Worker 1028*9880d681SAndroid Build Coastguard Worker def BRGEk : FBRsk<1, 1029*9880d681SAndroid Build Coastguard Worker 0b100, 1030*9880d681SAndroid Build Coastguard Worker (outs), 1031*9880d681SAndroid Build Coastguard Worker (ins relbrtarget_7:$target), 1032*9880d681SAndroid Build Coastguard Worker "brge\t$target", 1033*9880d681SAndroid Build Coastguard Worker [(AVRbrcond bb:$target, AVR_COND_GE)]>; 1034*9880d681SAndroid Build Coastguard Worker 1035*9880d681SAndroid Build Coastguard Worker def BRLTk : FBRsk<0, 1036*9880d681SAndroid Build Coastguard Worker 0b100, 1037*9880d681SAndroid Build Coastguard Worker (outs), 1038*9880d681SAndroid Build Coastguard Worker (ins relbrtarget_7:$target), 1039*9880d681SAndroid Build Coastguard Worker "brlt\t$target", 1040*9880d681SAndroid Build Coastguard Worker [(AVRbrcond bb:$target, AVR_COND_LT)]>; 1041*9880d681SAndroid Build Coastguard Worker} 1042*9880d681SAndroid Build Coastguard Worker 1043*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 1044*9880d681SAndroid Build Coastguard Worker// Data transfer instructions 1045*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 1046*9880d681SAndroid Build Coastguard Worker// 8 and 16-bit register move instructions. 1047*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0 in 1048*9880d681SAndroid Build Coastguard Worker{ 1049*9880d681SAndroid Build Coastguard Worker def MOVRdRr : FRdRr<0b0010, 1050*9880d681SAndroid Build Coastguard Worker 0b11, 1051*9880d681SAndroid Build Coastguard Worker (outs GPR8:$rd), 1052*9880d681SAndroid Build Coastguard Worker (ins GPR8:$rr), 1053*9880d681SAndroid Build Coastguard Worker "mov\t$rd, $rr", 1054*9880d681SAndroid Build Coastguard Worker []>; 1055*9880d681SAndroid Build Coastguard Worker 1056*9880d681SAndroid Build Coastguard Worker def MOVWRdRr : FMOVWRdRr<(outs DREGS:$dst), 1057*9880d681SAndroid Build Coastguard Worker (ins DREGS:$src), 1058*9880d681SAndroid Build Coastguard Worker "movw\t$dst, $src", 1059*9880d681SAndroid Build Coastguard Worker []>, 1060*9880d681SAndroid Build Coastguard Worker Requires<[HasMOVW]>; 1061*9880d681SAndroid Build Coastguard Worker} 1062*9880d681SAndroid Build Coastguard Worker 1063*9880d681SAndroid Build Coastguard Worker// Load immediate values into registers. 1064*9880d681SAndroid Build Coastguard Workerlet isReMaterializable = 1 in 1065*9880d681SAndroid Build Coastguard Worker{ 1066*9880d681SAndroid Build Coastguard Worker def LDIRdK : FRdK<0b1110, 1067*9880d681SAndroid Build Coastguard Worker (outs LD8:$rd), 1068*9880d681SAndroid Build Coastguard Worker (ins i8imm:$k), 1069*9880d681SAndroid Build Coastguard Worker "ldi\t$rd, $k", 1070*9880d681SAndroid Build Coastguard Worker [(set i8:$rd, imm:$k)]>; 1071*9880d681SAndroid Build Coastguard Worker 1072*9880d681SAndroid Build Coastguard Worker // LDIW Rd+1:Rd, K+1:K 1073*9880d681SAndroid Build Coastguard Worker // 1074*9880d681SAndroid Build Coastguard Worker // Expands to: 1075*9880d681SAndroid Build Coastguard Worker // ldi Rd, K 1076*9880d681SAndroid Build Coastguard Worker // ldi Rd+1, K+1 1077*9880d681SAndroid Build Coastguard Worker def LDIWRdK : Pseudo<(outs DLDREGS:$dst), 1078*9880d681SAndroid Build Coastguard Worker (ins i16imm:$src), 1079*9880d681SAndroid Build Coastguard Worker "ldiw\t$dst, $src", 1080*9880d681SAndroid Build Coastguard Worker [(set i16:$dst, imm:$src)]>; 1081*9880d681SAndroid Build Coastguard Worker} 1082*9880d681SAndroid Build Coastguard Worker 1083*9880d681SAndroid Build Coastguard Worker// Load from data space into register. 1084*9880d681SAndroid Build Coastguard Workerlet canFoldAsLoad = 1, 1085*9880d681SAndroid Build Coastguard WorkerisReMaterializable = 1 in 1086*9880d681SAndroid Build Coastguard Worker{ 1087*9880d681SAndroid Build Coastguard Worker def LDSRdK : F32DM<0b0, 1088*9880d681SAndroid Build Coastguard Worker (outs GPR8:$rd), 1089*9880d681SAndroid Build Coastguard Worker (ins i16imm:$k), 1090*9880d681SAndroid Build Coastguard Worker "lds\t$rd, $k", 1091*9880d681SAndroid Build Coastguard Worker [(set i8:$rd, (load imm:$k))]>, 1092*9880d681SAndroid Build Coastguard Worker Requires<[HasSRAM]>; 1093*9880d681SAndroid Build Coastguard Worker 1094*9880d681SAndroid Build Coastguard Worker // LDSW Rd+1:Rd, K+1:K 1095*9880d681SAndroid Build Coastguard Worker // 1096*9880d681SAndroid Build Coastguard Worker // Expands to: 1097*9880d681SAndroid Build Coastguard Worker // lds Rd, (K+1:K) 1098*9880d681SAndroid Build Coastguard Worker // lds Rd+1 (K+1:K) + 1 1099*9880d681SAndroid Build Coastguard Worker def LDSWRdK : Pseudo<(outs DREGS:$dst), 1100*9880d681SAndroid Build Coastguard Worker (ins i16imm:$src), 1101*9880d681SAndroid Build Coastguard Worker "ldsw\t$dst, $src", 1102*9880d681SAndroid Build Coastguard Worker [(set i16:$dst, (load imm:$src))]>, 1103*9880d681SAndroid Build Coastguard Worker Requires<[HasSRAM]>; 1104*9880d681SAndroid Build Coastguard Worker} 1105*9880d681SAndroid Build Coastguard Worker 1106*9880d681SAndroid Build Coastguard Worker// Indirect loads. 1107*9880d681SAndroid Build Coastguard Workerlet canFoldAsLoad = 1, 1108*9880d681SAndroid Build Coastguard WorkerisReMaterializable = 1 in 1109*9880d681SAndroid Build Coastguard Worker{ 1110*9880d681SAndroid Build Coastguard Worker def LDRdPtr : FSTLD<0, 1111*9880d681SAndroid Build Coastguard Worker 0b00, 1112*9880d681SAndroid Build Coastguard Worker (outs GPR8:$reg), 1113*9880d681SAndroid Build Coastguard Worker (ins LDSTPtrReg:$ptrreg), 1114*9880d681SAndroid Build Coastguard Worker "ld\t$reg, $ptrreg", 1115*9880d681SAndroid Build Coastguard Worker [(set GPR8:$reg, (load i16:$ptrreg))]>, 1116*9880d681SAndroid Build Coastguard Worker Requires<[HasSRAM]>; 1117*9880d681SAndroid Build Coastguard Worker 1118*9880d681SAndroid Build Coastguard Worker // LDW Rd+1:Rd, P 1119*9880d681SAndroid Build Coastguard Worker // 1120*9880d681SAndroid Build Coastguard Worker // Expands to: 1121*9880d681SAndroid Build Coastguard Worker // ld Rd, P+ 1122*9880d681SAndroid Build Coastguard Worker // ld Rd+1, P+ 1123*9880d681SAndroid Build Coastguard Worker let Constraints = "@earlyclobber $reg" in 1124*9880d681SAndroid Build Coastguard Worker def LDWRdPtr : Pseudo<(outs DREGS:$reg), 1125*9880d681SAndroid Build Coastguard Worker (ins PTRDISPREGS:$ptrreg), 1126*9880d681SAndroid Build Coastguard Worker "ldw\t$reg, $ptrreg", 1127*9880d681SAndroid Build Coastguard Worker [(set i16:$reg, (load i16:$ptrreg))]>, 1128*9880d681SAndroid Build Coastguard Worker Requires<[HasSRAM]>; 1129*9880d681SAndroid Build Coastguard Worker} 1130*9880d681SAndroid Build Coastguard Worker 1131*9880d681SAndroid Build Coastguard Worker// Indirect loads (with postincrement or predecrement). 1132*9880d681SAndroid Build Coastguard Workerlet mayLoad = 1, 1133*9880d681SAndroid Build Coastguard WorkerhasSideEffects = 0, 1134*9880d681SAndroid Build Coastguard WorkerConstraints = "$ptrreg = $base_wb,@earlyclobber $reg,@earlyclobber $base_wb" in 1135*9880d681SAndroid Build Coastguard Worker{ 1136*9880d681SAndroid Build Coastguard Worker def LDRdPtrPi : FSTLD<0, 1137*9880d681SAndroid Build Coastguard Worker 0b01, 1138*9880d681SAndroid Build Coastguard Worker (outs GPR8:$reg, PTRREGS:$base_wb), 1139*9880d681SAndroid Build Coastguard Worker (ins LDSTPtrReg:$ptrreg), 1140*9880d681SAndroid Build Coastguard Worker "ld\t$reg, $ptrreg+", 1141*9880d681SAndroid Build Coastguard Worker []>, 1142*9880d681SAndroid Build Coastguard Worker Requires<[HasSRAM]>; 1143*9880d681SAndroid Build Coastguard Worker 1144*9880d681SAndroid Build Coastguard Worker // LDW Rd+1:Rd, P+ 1145*9880d681SAndroid Build Coastguard Worker // Expands to: 1146*9880d681SAndroid Build Coastguard Worker // ld Rd, P+ 1147*9880d681SAndroid Build Coastguard Worker // ld Rd+1, P+ 1148*9880d681SAndroid Build Coastguard Worker def LDWRdPtrPi : Pseudo<(outs DREGS:$reg, PTRREGS:$base_wb), 1149*9880d681SAndroid Build Coastguard Worker (ins PTRREGS:$ptrreg), 1150*9880d681SAndroid Build Coastguard Worker "ldw\t$reg, $ptrreg+", 1151*9880d681SAndroid Build Coastguard Worker []>, 1152*9880d681SAndroid Build Coastguard Worker Requires<[HasSRAM]>; 1153*9880d681SAndroid Build Coastguard Worker 1154*9880d681SAndroid Build Coastguard Worker def LDRdPtrPd : FSTLD<0, 1155*9880d681SAndroid Build Coastguard Worker 0b10, 1156*9880d681SAndroid Build Coastguard Worker (outs GPR8:$reg, PTRREGS:$base_wb), 1157*9880d681SAndroid Build Coastguard Worker (ins LDSTPtrReg:$ptrreg), 1158*9880d681SAndroid Build Coastguard Worker "ld\t$reg, -$ptrreg", 1159*9880d681SAndroid Build Coastguard Worker []>, 1160*9880d681SAndroid Build Coastguard Worker Requires<[HasSRAM]>; 1161*9880d681SAndroid Build Coastguard Worker 1162*9880d681SAndroid Build Coastguard Worker // LDW Rd+1:Rd, -P 1163*9880d681SAndroid Build Coastguard Worker // 1164*9880d681SAndroid Build Coastguard Worker // Expands to: 1165*9880d681SAndroid Build Coastguard Worker // ld Rd+1, -P 1166*9880d681SAndroid Build Coastguard Worker // ld Rd, -P 1167*9880d681SAndroid Build Coastguard Worker def LDWRdPtrPd : Pseudo<(outs DREGS:$reg, PTRREGS:$base_wb), 1168*9880d681SAndroid Build Coastguard Worker (ins PTRREGS:$ptrreg), 1169*9880d681SAndroid Build Coastguard Worker "ldw\t$reg, -$ptrreg", 1170*9880d681SAndroid Build Coastguard Worker []>, 1171*9880d681SAndroid Build Coastguard Worker Requires<[HasSRAM]>; 1172*9880d681SAndroid Build Coastguard Worker} 1173*9880d681SAndroid Build Coastguard Worker 1174*9880d681SAndroid Build Coastguard Worker// Load indirect with displacement operations. 1175*9880d681SAndroid Build Coastguard Workerlet canFoldAsLoad = 1, 1176*9880d681SAndroid Build Coastguard WorkerisReMaterializable = 1 in 1177*9880d681SAndroid Build Coastguard Worker{ 1178*9880d681SAndroid Build Coastguard Worker def LDDRdPtrQ : FSTDLDD<0, 1179*9880d681SAndroid Build Coastguard Worker (outs GPR8:$reg), 1180*9880d681SAndroid Build Coastguard Worker (ins memri:$memri), 1181*9880d681SAndroid Build Coastguard Worker "ldd\t$reg, $memri", 1182*9880d681SAndroid Build Coastguard Worker [(set i8:$reg, (load addr:$memri))]>, 1183*9880d681SAndroid Build Coastguard Worker Requires<[HasSRAM]>; 1184*9880d681SAndroid Build Coastguard Worker 1185*9880d681SAndroid Build Coastguard Worker // LDDW Rd+1:Rd, P+q 1186*9880d681SAndroid Build Coastguard Worker // 1187*9880d681SAndroid Build Coastguard Worker // Expands to: 1188*9880d681SAndroid Build Coastguard Worker // ldd Rd, P+q 1189*9880d681SAndroid Build Coastguard Worker // ldd Rd+1, P+q+1 1190*9880d681SAndroid Build Coastguard Worker let Constraints = "@earlyclobber $dst" in 1191*9880d681SAndroid Build Coastguard Worker def LDDWRdPtrQ : Pseudo<(outs DREGS:$dst), 1192*9880d681SAndroid Build Coastguard Worker (ins memri:$memri), 1193*9880d681SAndroid Build Coastguard Worker "lddw\t$dst, $memri", 1194*9880d681SAndroid Build Coastguard Worker [(set i16:$dst, (load addr:$memri))]>, 1195*9880d681SAndroid Build Coastguard Worker Requires<[HasSRAM]>; 1196*9880d681SAndroid Build Coastguard Worker 1197*9880d681SAndroid Build Coastguard Worker //:FIXME: remove this once PR13375 gets fixed 1198*9880d681SAndroid Build Coastguard Worker // Bug report: https://llvm.org/bugs/show_bug.cgi?id=13375 1199*9880d681SAndroid Build Coastguard Worker let mayLoad = 1, 1200*9880d681SAndroid Build Coastguard Worker hasSideEffects = 0 in 1201*9880d681SAndroid Build Coastguard Worker def LDDWRdYQ : Pseudo<(outs DREGS:$dst), 1202*9880d681SAndroid Build Coastguard Worker (ins memri:$memri), 1203*9880d681SAndroid Build Coastguard Worker "lddw\t$dst, $memri", 1204*9880d681SAndroid Build Coastguard Worker []>, 1205*9880d681SAndroid Build Coastguard Worker Requires<[HasSRAM]>; 1206*9880d681SAndroid Build Coastguard Worker} 1207*9880d681SAndroid Build Coastguard Worker 1208*9880d681SAndroid Build Coastguard Worker// Indirect store from register to data space. 1209*9880d681SAndroid Build Coastguard Workerdef STSKRr : F32DM<0b1, 1210*9880d681SAndroid Build Coastguard Worker (outs), 1211*9880d681SAndroid Build Coastguard Worker (ins i16imm:$k, GPR8:$rd), 1212*9880d681SAndroid Build Coastguard Worker "sts\t$k, $rd", 1213*9880d681SAndroid Build Coastguard Worker [(store i8:$rd, imm:$k)]>, 1214*9880d681SAndroid Build Coastguard Worker Requires<[HasSRAM]>; 1215*9880d681SAndroid Build Coastguard Worker 1216*9880d681SAndroid Build Coastguard Worker// STSW K+1:K, Rr+1:Rr 1217*9880d681SAndroid Build Coastguard Worker// 1218*9880d681SAndroid Build Coastguard Worker// Expands to: 1219*9880d681SAndroid Build Coastguard Worker// sts Rr+1, (K+1:K) + 1 1220*9880d681SAndroid Build Coastguard Worker// sts Rr, (K+1:K) 1221*9880d681SAndroid Build Coastguard Workerdef STSWKRr : Pseudo<(outs), 1222*9880d681SAndroid Build Coastguard Worker (ins i16imm:$dst, DREGS:$src), 1223*9880d681SAndroid Build Coastguard Worker "stsw\t$dst, $src", 1224*9880d681SAndroid Build Coastguard Worker [(store i16:$src, imm:$dst)]>, 1225*9880d681SAndroid Build Coastguard Worker Requires<[HasSRAM]>; 1226*9880d681SAndroid Build Coastguard Worker 1227*9880d681SAndroid Build Coastguard Worker// Indirect stores. 1228*9880d681SAndroid Build Coastguard Worker// ST P, Rr 1229*9880d681SAndroid Build Coastguard Worker// Stores the value of Rr into the location addressed by pointer P. 1230*9880d681SAndroid Build Coastguard Workerdef STPtrRr : FSTLD<1, 1231*9880d681SAndroid Build Coastguard Worker 0b00, 1232*9880d681SAndroid Build Coastguard Worker (outs), 1233*9880d681SAndroid Build Coastguard Worker (ins LDSTPtrReg:$ptrreg, GPR8:$reg), 1234*9880d681SAndroid Build Coastguard Worker "st\t$ptrreg, $reg", 1235*9880d681SAndroid Build Coastguard Worker [(store GPR8:$reg, i16:$ptrreg)]>, 1236*9880d681SAndroid Build Coastguard Worker Requires<[HasSRAM]>; 1237*9880d681SAndroid Build Coastguard Worker 1238*9880d681SAndroid Build Coastguard Worker// STW P, Rr+1:Rr 1239*9880d681SAndroid Build Coastguard Worker// Stores the value of Rr into the location addressed by pointer P. 1240*9880d681SAndroid Build Coastguard Worker// 1241*9880d681SAndroid Build Coastguard Worker// Expands to: 1242*9880d681SAndroid Build Coastguard Worker// st P, Rr 1243*9880d681SAndroid Build Coastguard Worker// std P+1, Rr+1 1244*9880d681SAndroid Build Coastguard Workerdef STWPtrRr : Pseudo<(outs), 1245*9880d681SAndroid Build Coastguard Worker (ins PTRDISPREGS:$ptrreg, DREGS:$reg), 1246*9880d681SAndroid Build Coastguard Worker "stw\t$ptrreg, $reg", 1247*9880d681SAndroid Build Coastguard Worker [(store i16:$reg, i16:$ptrreg)]>, 1248*9880d681SAndroid Build Coastguard Worker Requires<[HasSRAM]>; 1249*9880d681SAndroid Build Coastguard Worker 1250*9880d681SAndroid Build Coastguard Worker// Indirect stores (with postincrement or predecrement). 1251*9880d681SAndroid Build Coastguard Workerlet Constraints = "$ptrreg = $base_wb,@earlyclobber $base_wb" in 1252*9880d681SAndroid Build Coastguard Worker{ 1253*9880d681SAndroid Build Coastguard Worker 1254*9880d681SAndroid Build Coastguard Worker // ST P+, Rr 1255*9880d681SAndroid Build Coastguard Worker // Stores the value of Rr into the location addressed by pointer P. 1256*9880d681SAndroid Build Coastguard Worker // Post increments P. 1257*9880d681SAndroid Build Coastguard Worker def STPtrPiRr : FSTLD<1, 1258*9880d681SAndroid Build Coastguard Worker 0b01, 1259*9880d681SAndroid Build Coastguard Worker (outs LDSTPtrReg:$base_wb), 1260*9880d681SAndroid Build Coastguard Worker (ins LDSTPtrReg:$ptrreg, GPR8:$reg, i8imm:$offs), 1261*9880d681SAndroid Build Coastguard Worker "st\t$ptrreg+, $reg", 1262*9880d681SAndroid Build Coastguard Worker [(set i16:$base_wb, 1263*9880d681SAndroid Build Coastguard Worker (post_store GPR8:$reg, i16:$ptrreg, imm:$offs))]>, 1264*9880d681SAndroid Build Coastguard Worker Requires<[HasSRAM]>; 1265*9880d681SAndroid Build Coastguard Worker 1266*9880d681SAndroid Build Coastguard Worker // STW P+, Rr+1:Rr 1267*9880d681SAndroid Build Coastguard Worker // Stores the value of Rr into the location addressed by pointer P. 1268*9880d681SAndroid Build Coastguard Worker // Post increments P. 1269*9880d681SAndroid Build Coastguard Worker // 1270*9880d681SAndroid Build Coastguard Worker // Expands to: 1271*9880d681SAndroid Build Coastguard Worker // st P+, Rr 1272*9880d681SAndroid Build Coastguard Worker // st P+, Rr+1 1273*9880d681SAndroid Build Coastguard Worker def STWPtrPiRr : Pseudo<(outs PTRREGS:$base_wb), 1274*9880d681SAndroid Build Coastguard Worker (ins PTRREGS:$ptrreg, DREGS:$trh, i8imm:$offs), 1275*9880d681SAndroid Build Coastguard Worker "stw\t$ptrreg+, $trh", 1276*9880d681SAndroid Build Coastguard Worker [(set PTRREGS:$base_wb, 1277*9880d681SAndroid Build Coastguard Worker (post_store DREGS:$trh, PTRREGS:$ptrreg, imm:$offs))]>, 1278*9880d681SAndroid Build Coastguard Worker Requires<[HasSRAM]>; 1279*9880d681SAndroid Build Coastguard Worker 1280*9880d681SAndroid Build Coastguard Worker // ST -P, Rr 1281*9880d681SAndroid Build Coastguard Worker // Stores the value of Rr into the location addressed by pointer P. 1282*9880d681SAndroid Build Coastguard Worker // Pre decrements P. 1283*9880d681SAndroid Build Coastguard Worker def STPtrPdRr : FSTLD<1, 1284*9880d681SAndroid Build Coastguard Worker 0b10, 1285*9880d681SAndroid Build Coastguard Worker (outs LDSTPtrReg:$base_wb), 1286*9880d681SAndroid Build Coastguard Worker (ins LDSTPtrReg:$ptrreg, GPR8:$reg, i8imm:$offs), 1287*9880d681SAndroid Build Coastguard Worker "st\t-$ptrreg, $reg", 1288*9880d681SAndroid Build Coastguard Worker [(set i16:$base_wb, 1289*9880d681SAndroid Build Coastguard Worker (pre_store GPR8:$reg, i16:$ptrreg, imm:$offs))]>, 1290*9880d681SAndroid Build Coastguard Worker Requires<[HasSRAM]>; 1291*9880d681SAndroid Build Coastguard Worker 1292*9880d681SAndroid Build Coastguard Worker // STW -P, Rr+1:Rr 1293*9880d681SAndroid Build Coastguard Worker // Stores the value of Rr into the location addressed by pointer P. 1294*9880d681SAndroid Build Coastguard Worker // Pre decrements P. 1295*9880d681SAndroid Build Coastguard Worker // 1296*9880d681SAndroid Build Coastguard Worker // Expands to: 1297*9880d681SAndroid Build Coastguard Worker // st -P, Rr+1 1298*9880d681SAndroid Build Coastguard Worker // st -P, Rr 1299*9880d681SAndroid Build Coastguard Worker def STWPtrPdRr : Pseudo<(outs PTRREGS:$base_wb), 1300*9880d681SAndroid Build Coastguard Worker (ins PTRREGS:$ptrreg, DREGS:$reg, i8imm:$offs), 1301*9880d681SAndroid Build Coastguard Worker "stw\t-$ptrreg, $reg", 1302*9880d681SAndroid Build Coastguard Worker [(set PTRREGS:$base_wb, 1303*9880d681SAndroid Build Coastguard Worker (pre_store i16:$reg, i16:$ptrreg, imm:$offs))]>, 1304*9880d681SAndroid Build Coastguard Worker Requires<[HasSRAM]>; 1305*9880d681SAndroid Build Coastguard Worker} 1306*9880d681SAndroid Build Coastguard Worker 1307*9880d681SAndroid Build Coastguard Worker// Store indirect with displacement operations. 1308*9880d681SAndroid Build Coastguard Worker// STD P+q, Rr 1309*9880d681SAndroid Build Coastguard Worker// Stores the value of Rr into the location addressed by pointer P with a 1310*9880d681SAndroid Build Coastguard Worker// displacement of q. Does not modify P. 1311*9880d681SAndroid Build Coastguard Workerdef STDPtrQRr : FSTDLDD<1, 1312*9880d681SAndroid Build Coastguard Worker (outs), 1313*9880d681SAndroid Build Coastguard Worker (ins memri:$memri, GPR8:$reg), 1314*9880d681SAndroid Build Coastguard Worker "std\t$memri, $reg", 1315*9880d681SAndroid Build Coastguard Worker [(store i8:$reg, addr:$memri)]>, 1316*9880d681SAndroid Build Coastguard Worker Requires<[HasSRAM]>; 1317*9880d681SAndroid Build Coastguard Worker 1318*9880d681SAndroid Build Coastguard Worker// STDW P+q, Rr+1:Rr 1319*9880d681SAndroid Build Coastguard Worker// Stores the value of Rr into the location addressed by pointer P with a 1320*9880d681SAndroid Build Coastguard Worker// displacement of q. Does not modify P. 1321*9880d681SAndroid Build Coastguard Worker// 1322*9880d681SAndroid Build Coastguard Worker// Expands to: 1323*9880d681SAndroid Build Coastguard Worker// std P+q, Rr 1324*9880d681SAndroid Build Coastguard Worker// std P+q+1, Rr+1 1325*9880d681SAndroid Build Coastguard Workerdef STDWPtrQRr : Pseudo<(outs), 1326*9880d681SAndroid Build Coastguard Worker (ins memri:$memri, DREGS:$src), 1327*9880d681SAndroid Build Coastguard Worker "stdw\t$memri, $src", 1328*9880d681SAndroid Build Coastguard Worker [(store i16:$src, addr:$memri)]>, 1329*9880d681SAndroid Build Coastguard Worker Requires<[HasSRAM]>; 1330*9880d681SAndroid Build Coastguard Worker 1331*9880d681SAndroid Build Coastguard Worker 1332*9880d681SAndroid Build Coastguard Worker// Load program memory operations. 1333*9880d681SAndroid Build Coastguard Workerlet canFoldAsLoad = 1, 1334*9880d681SAndroid Build Coastguard WorkerisReMaterializable = 1, 1335*9880d681SAndroid Build Coastguard WorkerhasSideEffects = 0 in 1336*9880d681SAndroid Build Coastguard Worker{ 1337*9880d681SAndroid Build Coastguard Worker let Defs = [R0], 1338*9880d681SAndroid Build Coastguard Worker Uses = [R31R30] in 1339*9880d681SAndroid Build Coastguard Worker def LPM : F16<0b1001010111001000, 1340*9880d681SAndroid Build Coastguard Worker (outs), 1341*9880d681SAndroid Build Coastguard Worker (ins), 1342*9880d681SAndroid Build Coastguard Worker "lpm", 1343*9880d681SAndroid Build Coastguard Worker []>, 1344*9880d681SAndroid Build Coastguard Worker Requires<[HasLPM]>; 1345*9880d681SAndroid Build Coastguard Worker 1346*9880d681SAndroid Build Coastguard Worker def LPMRdZ : FLPMX<0, 1347*9880d681SAndroid Build Coastguard Worker 0, 1348*9880d681SAndroid Build Coastguard Worker (outs GPR8:$dst), 1349*9880d681SAndroid Build Coastguard Worker (ins ZREGS:$z), 1350*9880d681SAndroid Build Coastguard Worker "lpm\t$dst, $z", 1351*9880d681SAndroid Build Coastguard Worker []>, 1352*9880d681SAndroid Build Coastguard Worker Requires<[HasLPMX]>; 1353*9880d681SAndroid Build Coastguard Worker 1354*9880d681SAndroid Build Coastguard Worker def LPMWRdZ : Pseudo<(outs DREGS:$dst), 1355*9880d681SAndroid Build Coastguard Worker (ins ZREGS:$z), 1356*9880d681SAndroid Build Coastguard Worker "lpmw\t$dst, $z", 1357*9880d681SAndroid Build Coastguard Worker []>, 1358*9880d681SAndroid Build Coastguard Worker Requires<[HasLPMX]>; 1359*9880d681SAndroid Build Coastguard Worker 1360*9880d681SAndroid Build Coastguard Worker // Load program memory, while postincrementing the Z register. 1361*9880d681SAndroid Build Coastguard Worker let mayLoad = 1, 1362*9880d681SAndroid Build Coastguard Worker Defs = [R31R30] in 1363*9880d681SAndroid Build Coastguard Worker { 1364*9880d681SAndroid Build Coastguard Worker def LPMRdZPi : FLPMX<0, 1365*9880d681SAndroid Build Coastguard Worker 1, 1366*9880d681SAndroid Build Coastguard Worker (outs GPR8:$dst), 1367*9880d681SAndroid Build Coastguard Worker (ins ZREGS:$z), 1368*9880d681SAndroid Build Coastguard Worker "lpm\t$dst, $z+", 1369*9880d681SAndroid Build Coastguard Worker []>, 1370*9880d681SAndroid Build Coastguard Worker Requires<[HasLPMX]>; 1371*9880d681SAndroid Build Coastguard Worker 1372*9880d681SAndroid Build Coastguard Worker def LPMWRdZPi : Pseudo<(outs DREGS:$dst), 1373*9880d681SAndroid Build Coastguard Worker (ins ZREGS:$z), 1374*9880d681SAndroid Build Coastguard Worker "lpmw\t$dst, $z+", 1375*9880d681SAndroid Build Coastguard Worker []>, 1376*9880d681SAndroid Build Coastguard Worker Requires<[HasLPMX]>; 1377*9880d681SAndroid Build Coastguard Worker } 1378*9880d681SAndroid Build Coastguard Worker} 1379*9880d681SAndroid Build Coastguard Worker 1380*9880d681SAndroid Build Coastguard Worker// Extended load program memory operations. 1381*9880d681SAndroid Build Coastguard Workerlet mayLoad = 1, 1382*9880d681SAndroid Build Coastguard WorkerhasSideEffects = 0 in 1383*9880d681SAndroid Build Coastguard Worker{ 1384*9880d681SAndroid Build Coastguard Worker let Defs = [R0], 1385*9880d681SAndroid Build Coastguard Worker Uses = [R31R30] in 1386*9880d681SAndroid Build Coastguard Worker def ELPM : F16<0b1001010111011000, 1387*9880d681SAndroid Build Coastguard Worker (outs), 1388*9880d681SAndroid Build Coastguard Worker (ins), 1389*9880d681SAndroid Build Coastguard Worker "elpm", 1390*9880d681SAndroid Build Coastguard Worker []>, 1391*9880d681SAndroid Build Coastguard Worker Requires<[HasELPM]>; 1392*9880d681SAndroid Build Coastguard Worker 1393*9880d681SAndroid Build Coastguard Worker def ELPMRdZ : FLPMX<1, 1394*9880d681SAndroid Build Coastguard Worker 0, 1395*9880d681SAndroid Build Coastguard Worker (outs GPR8:$dst), 1396*9880d681SAndroid Build Coastguard Worker (ins ZREGS:$z), 1397*9880d681SAndroid Build Coastguard Worker "elpm\t$dst, $z", 1398*9880d681SAndroid Build Coastguard Worker []>, 1399*9880d681SAndroid Build Coastguard Worker Requires<[HasELPMX]>; 1400*9880d681SAndroid Build Coastguard Worker 1401*9880d681SAndroid Build Coastguard Worker let Defs = [R31R30] in 1402*9880d681SAndroid Build Coastguard Worker def ELPMRdZPi : FLPMX<1, 1403*9880d681SAndroid Build Coastguard Worker 1, 1404*9880d681SAndroid Build Coastguard Worker (outs GPR8:$dst), 1405*9880d681SAndroid Build Coastguard Worker (ins ZREGS: $z), 1406*9880d681SAndroid Build Coastguard Worker "elpm\t$dst, $z+", 1407*9880d681SAndroid Build Coastguard Worker []>, 1408*9880d681SAndroid Build Coastguard Worker Requires<[HasELPMX]>; 1409*9880d681SAndroid Build Coastguard Worker} 1410*9880d681SAndroid Build Coastguard Worker 1411*9880d681SAndroid Build Coastguard Worker// Store program memory operations. 1412*9880d681SAndroid Build Coastguard Workerlet Uses = [R1, R0] in 1413*9880d681SAndroid Build Coastguard Worker{ 1414*9880d681SAndroid Build Coastguard Worker let Uses = [R31R30, R1, R0] in 1415*9880d681SAndroid Build Coastguard Worker def SPM : F16<0b1001010111101000, 1416*9880d681SAndroid Build Coastguard Worker (outs), 1417*9880d681SAndroid Build Coastguard Worker (ins), 1418*9880d681SAndroid Build Coastguard Worker "spm", 1419*9880d681SAndroid Build Coastguard Worker []>, 1420*9880d681SAndroid Build Coastguard Worker Requires<[HasSPM]>; 1421*9880d681SAndroid Build Coastguard Worker 1422*9880d681SAndroid Build Coastguard Worker let Defs = [R31R30] in 1423*9880d681SAndroid Build Coastguard Worker def SPMZPi : F16<0b1001010111111000, 1424*9880d681SAndroid Build Coastguard Worker (outs), 1425*9880d681SAndroid Build Coastguard Worker (ins ZREGS:$z), 1426*9880d681SAndroid Build Coastguard Worker "spm $z+", 1427*9880d681SAndroid Build Coastguard Worker []>, 1428*9880d681SAndroid Build Coastguard Worker Requires<[HasSPMX]>; 1429*9880d681SAndroid Build Coastguard Worker} 1430*9880d681SAndroid Build Coastguard Worker 1431*9880d681SAndroid Build Coastguard Worker// Read data from IO location operations. 1432*9880d681SAndroid Build Coastguard Workerlet canFoldAsLoad = 1, 1433*9880d681SAndroid Build Coastguard WorkerisReMaterializable = 1 in 1434*9880d681SAndroid Build Coastguard Worker{ 1435*9880d681SAndroid Build Coastguard Worker def INRdA : FIORdA<(outs GPR8:$dst), 1436*9880d681SAndroid Build Coastguard Worker (ins i16imm:$src), 1437*9880d681SAndroid Build Coastguard Worker "in\t$dst, $src", 1438*9880d681SAndroid Build Coastguard Worker [(set i8:$dst, (load ioaddr8:$src))]>; 1439*9880d681SAndroid Build Coastguard Worker 1440*9880d681SAndroid Build Coastguard Worker def INWRdA : Pseudo<(outs DREGS:$dst), 1441*9880d681SAndroid Build Coastguard Worker (ins i16imm:$src), 1442*9880d681SAndroid Build Coastguard Worker "inw\t$dst, $src", 1443*9880d681SAndroid Build Coastguard Worker [(set i16:$dst, (load ioaddr16:$src))]>; 1444*9880d681SAndroid Build Coastguard Worker} 1445*9880d681SAndroid Build Coastguard Worker 1446*9880d681SAndroid Build Coastguard Worker// Write data to IO location operations. 1447*9880d681SAndroid Build Coastguard Workerdef OUTARr : FIOARr<(outs), 1448*9880d681SAndroid Build Coastguard Worker (ins i16imm:$dst, GPR8:$src), 1449*9880d681SAndroid Build Coastguard Worker "out\t$dst, $src", 1450*9880d681SAndroid Build Coastguard Worker [(store i8:$src, ioaddr8:$dst)]>; 1451*9880d681SAndroid Build Coastguard Worker 1452*9880d681SAndroid Build Coastguard Workerdef OUTWARr : Pseudo<(outs), 1453*9880d681SAndroid Build Coastguard Worker (ins i16imm:$dst, DREGS:$src), 1454*9880d681SAndroid Build Coastguard Worker "outw\t$dst, $src", 1455*9880d681SAndroid Build Coastguard Worker [(store i16:$src, ioaddr16:$dst)]>; 1456*9880d681SAndroid Build Coastguard Worker 1457*9880d681SAndroid Build Coastguard Worker// Stack push/pop operations. 1458*9880d681SAndroid Build Coastguard Workerlet Defs = [SP], 1459*9880d681SAndroid Build Coastguard WorkerUses = [SP], 1460*9880d681SAndroid Build Coastguard WorkerhasSideEffects = 0 in 1461*9880d681SAndroid Build Coastguard Worker{ 1462*9880d681SAndroid Build Coastguard Worker // Stack push operations. 1463*9880d681SAndroid Build Coastguard Worker let mayStore = 1 in 1464*9880d681SAndroid Build Coastguard Worker { 1465*9880d681SAndroid Build Coastguard Worker def PUSHRr : FRd<0b1001, 1466*9880d681SAndroid Build Coastguard Worker 0b0011111, 1467*9880d681SAndroid Build Coastguard Worker (outs), 1468*9880d681SAndroid Build Coastguard Worker (ins GPR8:$reg), 1469*9880d681SAndroid Build Coastguard Worker "push\t$reg", 1470*9880d681SAndroid Build Coastguard Worker []>, 1471*9880d681SAndroid Build Coastguard Worker Requires<[HasSRAM]>; 1472*9880d681SAndroid Build Coastguard Worker 1473*9880d681SAndroid Build Coastguard Worker def PUSHWRr : Pseudo<(outs), 1474*9880d681SAndroid Build Coastguard Worker (ins DREGS:$reg), 1475*9880d681SAndroid Build Coastguard Worker "pushw\t$reg", 1476*9880d681SAndroid Build Coastguard Worker []>, 1477*9880d681SAndroid Build Coastguard Worker Requires<[HasSRAM]>; 1478*9880d681SAndroid Build Coastguard Worker } 1479*9880d681SAndroid Build Coastguard Worker 1480*9880d681SAndroid Build Coastguard Worker // Stack pop operations. 1481*9880d681SAndroid Build Coastguard Worker let mayLoad = 1 in 1482*9880d681SAndroid Build Coastguard Worker { 1483*9880d681SAndroid Build Coastguard Worker def POPRd : FRd<0b1001, 1484*9880d681SAndroid Build Coastguard Worker 0b0001111, 1485*9880d681SAndroid Build Coastguard Worker (outs GPR8:$reg), 1486*9880d681SAndroid Build Coastguard Worker (ins), 1487*9880d681SAndroid Build Coastguard Worker "pop\t$reg", 1488*9880d681SAndroid Build Coastguard Worker []>, 1489*9880d681SAndroid Build Coastguard Worker Requires<[HasSRAM]>; 1490*9880d681SAndroid Build Coastguard Worker 1491*9880d681SAndroid Build Coastguard Worker def POPWRd : Pseudo<(outs DREGS:$reg), 1492*9880d681SAndroid Build Coastguard Worker (ins), 1493*9880d681SAndroid Build Coastguard Worker "popw\t$reg", 1494*9880d681SAndroid Build Coastguard Worker []>, 1495*9880d681SAndroid Build Coastguard Worker Requires<[HasSRAM]>; 1496*9880d681SAndroid Build Coastguard Worker } 1497*9880d681SAndroid Build Coastguard Worker} 1498*9880d681SAndroid Build Coastguard Worker 1499*9880d681SAndroid Build Coastguard Worker// Read-Write-Modify (RMW) instructions. 1500*9880d681SAndroid Build Coastguard Workerdef XCHZRd : FZRd<0b100, 1501*9880d681SAndroid Build Coastguard Worker (outs GPR8:$rd), 1502*9880d681SAndroid Build Coastguard Worker (ins ZREGS:$z), 1503*9880d681SAndroid Build Coastguard Worker "xch\t$z, $rd", 1504*9880d681SAndroid Build Coastguard Worker []>, 1505*9880d681SAndroid Build Coastguard Worker Requires<[SupportsRMW]>; 1506*9880d681SAndroid Build Coastguard Worker 1507*9880d681SAndroid Build Coastguard Workerdef LASZRd : FZRd<0b101, 1508*9880d681SAndroid Build Coastguard Worker (outs GPR8:$rd), 1509*9880d681SAndroid Build Coastguard Worker (ins ZREGS:$z), 1510*9880d681SAndroid Build Coastguard Worker "las\t$z, $rd", 1511*9880d681SAndroid Build Coastguard Worker []>, 1512*9880d681SAndroid Build Coastguard Worker Requires<[SupportsRMW]>; 1513*9880d681SAndroid Build Coastguard Worker 1514*9880d681SAndroid Build Coastguard Workerdef LACZRd : FZRd<0b110, 1515*9880d681SAndroid Build Coastguard Worker (outs GPR8:$rd), 1516*9880d681SAndroid Build Coastguard Worker (ins ZREGS:$z), 1517*9880d681SAndroid Build Coastguard Worker "lac\t$z, $rd", 1518*9880d681SAndroid Build Coastguard Worker []>, 1519*9880d681SAndroid Build Coastguard Worker Requires<[SupportsRMW]>; 1520*9880d681SAndroid Build Coastguard Worker 1521*9880d681SAndroid Build Coastguard Workerdef LATZRd : FZRd<0b111, 1522*9880d681SAndroid Build Coastguard Worker (outs GPR8:$rd), 1523*9880d681SAndroid Build Coastguard Worker (ins ZREGS:$z), 1524*9880d681SAndroid Build Coastguard Worker "lat\t$z, $rd", 1525*9880d681SAndroid Build Coastguard Worker []>, 1526*9880d681SAndroid Build Coastguard Worker Requires<[SupportsRMW]>; 1527*9880d681SAndroid Build Coastguard Worker 1528*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 1529*9880d681SAndroid Build Coastguard Worker// Bit and bit-test instructions 1530*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 1531*9880d681SAndroid Build Coastguard Worker 1532*9880d681SAndroid Build Coastguard Worker// Bit shift/rotate operations. 1533*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src = $rd", 1534*9880d681SAndroid Build Coastguard WorkerDefs = [SREG] in 1535*9880d681SAndroid Build Coastguard Worker{ 1536*9880d681SAndroid Build Coastguard Worker def LSLRd : FRdRr<0b0000, 1537*9880d681SAndroid Build Coastguard Worker 0b11, 1538*9880d681SAndroid Build Coastguard Worker (outs GPR8:$rd), 1539*9880d681SAndroid Build Coastguard Worker (ins GPR8:$src), 1540*9880d681SAndroid Build Coastguard Worker "lsl\t$rd", 1541*9880d681SAndroid Build Coastguard Worker [(set i8:$rd, (AVRlsl i8:$src)), (implicit SREG)]>; 1542*9880d681SAndroid Build Coastguard Worker 1543*9880d681SAndroid Build Coastguard Worker def LSLWRd : Pseudo<(outs DREGS:$rd), 1544*9880d681SAndroid Build Coastguard Worker (ins DREGS:$src), 1545*9880d681SAndroid Build Coastguard Worker "lslw\t$rd", 1546*9880d681SAndroid Build Coastguard Worker [(set i16:$rd, (AVRlsl i16:$src)), (implicit SREG)]>; 1547*9880d681SAndroid Build Coastguard Worker 1548*9880d681SAndroid Build Coastguard Worker def LSRRd : FRd<0b1001, 1549*9880d681SAndroid Build Coastguard Worker 0b0100110, 1550*9880d681SAndroid Build Coastguard Worker (outs GPR8:$rd), 1551*9880d681SAndroid Build Coastguard Worker (ins GPR8:$src), 1552*9880d681SAndroid Build Coastguard Worker "lsr\t$rd", 1553*9880d681SAndroid Build Coastguard Worker [(set i8:$rd, (AVRlsr i8:$src)), (implicit SREG)]>; 1554*9880d681SAndroid Build Coastguard Worker 1555*9880d681SAndroid Build Coastguard Worker def LSRWRd : Pseudo<(outs DREGS:$rd), 1556*9880d681SAndroid Build Coastguard Worker (ins DREGS:$src), 1557*9880d681SAndroid Build Coastguard Worker "lsrw\t$rd", 1558*9880d681SAndroid Build Coastguard Worker [(set i16:$rd, (AVRlsr i16:$src)), (implicit SREG)]>; 1559*9880d681SAndroid Build Coastguard Worker 1560*9880d681SAndroid Build Coastguard Worker def ASRRd : FRd<0b1001, 1561*9880d681SAndroid Build Coastguard Worker 0b0100101, 1562*9880d681SAndroid Build Coastguard Worker (outs GPR8:$rd), 1563*9880d681SAndroid Build Coastguard Worker (ins GPR8:$src), 1564*9880d681SAndroid Build Coastguard Worker "asr\t$rd", 1565*9880d681SAndroid Build Coastguard Worker [(set i8:$rd, (AVRasr i8:$src)), (implicit SREG)]>; 1566*9880d681SAndroid Build Coastguard Worker 1567*9880d681SAndroid Build Coastguard Worker def ASRWRd : Pseudo<(outs DREGS:$rd), 1568*9880d681SAndroid Build Coastguard Worker (ins DREGS:$src), 1569*9880d681SAndroid Build Coastguard Worker "asrw\t$rd", 1570*9880d681SAndroid Build Coastguard Worker [(set i16:$rd, (AVRasr i16:$src)), (implicit SREG)]>; 1571*9880d681SAndroid Build Coastguard Worker 1572*9880d681SAndroid Build Coastguard Worker // Bit rotate operations. 1573*9880d681SAndroid Build Coastguard Worker let Uses = [SREG] in 1574*9880d681SAndroid Build Coastguard Worker { 1575*9880d681SAndroid Build Coastguard Worker def ROLRd : FRdRr<0b0001, 1576*9880d681SAndroid Build Coastguard Worker 0b11, 1577*9880d681SAndroid Build Coastguard Worker (outs GPR8:$rd), 1578*9880d681SAndroid Build Coastguard Worker (ins GPR8:$src), 1579*9880d681SAndroid Build Coastguard Worker "rol\t$rd", 1580*9880d681SAndroid Build Coastguard Worker [(set i8:$rd, (AVRrol i8:$src)), (implicit SREG)]>; 1581*9880d681SAndroid Build Coastguard Worker 1582*9880d681SAndroid Build Coastguard Worker def ROLWRd : Pseudo<(outs DREGS:$rd), 1583*9880d681SAndroid Build Coastguard Worker (ins DREGS:$src), 1584*9880d681SAndroid Build Coastguard Worker "rolw\t$rd", 1585*9880d681SAndroid Build Coastguard Worker [(set i16:$rd, (AVRrol i16:$src)), (implicit SREG)]>; 1586*9880d681SAndroid Build Coastguard Worker 1587*9880d681SAndroid Build Coastguard Worker def RORRd : FRd<0b1001, 1588*9880d681SAndroid Build Coastguard Worker 0b0100111, 1589*9880d681SAndroid Build Coastguard Worker (outs GPR8:$rd), 1590*9880d681SAndroid Build Coastguard Worker (ins GPR8:$src), 1591*9880d681SAndroid Build Coastguard Worker "ror\t$rd", 1592*9880d681SAndroid Build Coastguard Worker [(set i8:$rd, (AVRror i8:$src)), (implicit SREG)]>; 1593*9880d681SAndroid Build Coastguard Worker 1594*9880d681SAndroid Build Coastguard Worker def RORWRd : Pseudo<(outs DREGS:$rd), 1595*9880d681SAndroid Build Coastguard Worker (ins DREGS:$src), 1596*9880d681SAndroid Build Coastguard Worker "rorw\t$rd", 1597*9880d681SAndroid Build Coastguard Worker [(set i16:$rd, (AVRror i16:$src)), (implicit SREG)]>; 1598*9880d681SAndroid Build Coastguard Worker } 1599*9880d681SAndroid Build Coastguard Worker} 1600*9880d681SAndroid Build Coastguard Worker 1601*9880d681SAndroid Build Coastguard Worker// SWAP Rd 1602*9880d681SAndroid Build Coastguard Worker// Swaps the high and low nibbles in a register. 1603*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src = $rd" in 1604*9880d681SAndroid Build Coastguard Workerdef SWAPRd : FRd<0b1001, 1605*9880d681SAndroid Build Coastguard Worker 0b0100010, 1606*9880d681SAndroid Build Coastguard Worker (outs GPR8:$rd), 1607*9880d681SAndroid Build Coastguard Worker (ins GPR8:$src), 1608*9880d681SAndroid Build Coastguard Worker "swap\t$rd", 1609*9880d681SAndroid Build Coastguard Worker [(set i8:$rd, (bswap i8:$src))]>; 1610*9880d681SAndroid Build Coastguard Worker 1611*9880d681SAndroid Build Coastguard Worker// IO register bit set/clear operations. 1612*9880d681SAndroid Build Coastguard Worker//:TODO: add patterns when popcount(imm)==2 to be expanded with 2 sbi/cbi 1613*9880d681SAndroid Build Coastguard Worker// instead of in+ori+out which requires one more instr. 1614*9880d681SAndroid Build Coastguard Workerdef SBIAb : FIOBIT<0b10, 1615*9880d681SAndroid Build Coastguard Worker (outs), 1616*9880d681SAndroid Build Coastguard Worker (ins i16imm:$addr, i8imm:$bit), 1617*9880d681SAndroid Build Coastguard Worker "sbi\t$addr, $bit", 1618*9880d681SAndroid Build Coastguard Worker [(store (or (i8 (load lowioaddr8:$addr)), iobitpos8:$bit), 1619*9880d681SAndroid Build Coastguard Worker lowioaddr8:$addr)]>; 1620*9880d681SAndroid Build Coastguard Worker 1621*9880d681SAndroid Build Coastguard Workerdef CBIAb : FIOBIT<0b00, 1622*9880d681SAndroid Build Coastguard Worker (outs), 1623*9880d681SAndroid Build Coastguard Worker (ins i16imm:$addr, i8imm:$bit), 1624*9880d681SAndroid Build Coastguard Worker "cbi\t$addr, $bit", 1625*9880d681SAndroid Build Coastguard Worker [(store (and (i8 (load lowioaddr8:$addr)), iobitposn8:$bit), 1626*9880d681SAndroid Build Coastguard Worker lowioaddr8:$addr)]>; 1627*9880d681SAndroid Build Coastguard Worker 1628*9880d681SAndroid Build Coastguard Worker// Status register bit load/store operations. 1629*9880d681SAndroid Build Coastguard Workerlet Defs = [SREG] in 1630*9880d681SAndroid Build Coastguard Workerdef BST : FRdB<0b01, 1631*9880d681SAndroid Build Coastguard Worker (outs), 1632*9880d681SAndroid Build Coastguard Worker (ins GPR8:$rd, i8imm:$b), 1633*9880d681SAndroid Build Coastguard Worker "bst\t$rd, $b", 1634*9880d681SAndroid Build Coastguard Worker []>; 1635*9880d681SAndroid Build Coastguard Worker 1636*9880d681SAndroid Build Coastguard Workerlet Uses = [SREG] in 1637*9880d681SAndroid Build Coastguard Workerdef BLD : FRdB<0b00, 1638*9880d681SAndroid Build Coastguard Worker (outs), 1639*9880d681SAndroid Build Coastguard Worker (ins GPR8:$rd, i8imm:$b), 1640*9880d681SAndroid Build Coastguard Worker "bld\t$rd, $b", 1641*9880d681SAndroid Build Coastguard Worker []>; 1642*9880d681SAndroid Build Coastguard Worker 1643*9880d681SAndroid Build Coastguard Worker// Set/clear bit in register operations. 1644*9880d681SAndroid Build Coastguard Workerlet Constraints = "$src = $rd", 1645*9880d681SAndroid Build Coastguard WorkerDefs = [SREG] in 1646*9880d681SAndroid Build Coastguard Worker{ 1647*9880d681SAndroid Build Coastguard Worker // SBR Rd, K 1648*9880d681SAndroid Build Coastguard Worker // Alias for ORI Rd, K 1649*9880d681SAndroid Build Coastguard Worker def SBRRdK : FRdK<0b0110, 1650*9880d681SAndroid Build Coastguard Worker (outs LD8:$rd), 1651*9880d681SAndroid Build Coastguard Worker (ins LD8:$src, i8imm:$k), 1652*9880d681SAndroid Build Coastguard Worker "sbr\t$rd, $k", 1653*9880d681SAndroid Build Coastguard Worker [(set i8:$rd, (or i8:$src, imm:$k)), 1654*9880d681SAndroid Build Coastguard Worker (implicit SREG)]>; 1655*9880d681SAndroid Build Coastguard Worker 1656*9880d681SAndroid Build Coastguard Worker // CBR Rd, K 1657*9880d681SAndroid Build Coastguard Worker // Alias for `ANDI Rd, COM(K)` where COM(K) is the compliment of K. 1658*9880d681SAndroid Build Coastguard Worker def CBRRdK : FRdK<0b0111, 1659*9880d681SAndroid Build Coastguard Worker (outs LD8:$rd), 1660*9880d681SAndroid Build Coastguard Worker (ins LD8:$src, i8imm_com:$k), 1661*9880d681SAndroid Build Coastguard Worker "cbr\t$rd, $k", 1662*9880d681SAndroid Build Coastguard Worker []>; 1663*9880d681SAndroid Build Coastguard Worker} 1664*9880d681SAndroid Build Coastguard Worker 1665*9880d681SAndroid Build Coastguard Worker// CLR Rd 1666*9880d681SAndroid Build Coastguard Worker// Alias for EOR Rd, Rd 1667*9880d681SAndroid Build Coastguard Worker// ------------- 1668*9880d681SAndroid Build Coastguard Worker// Clears all bits in a register. 1669*9880d681SAndroid Build Coastguard Workerdef CLR : InstAlias<"clr\t$rd", (EORRdRr GPR8:$rd, GPR8:$rd)>; 1670*9880d681SAndroid Build Coastguard Worker 1671*9880d681SAndroid Build Coastguard Worker// SER Rd 1672*9880d681SAndroid Build Coastguard Worker// Alias for LDI Rd, 0xff 1673*9880d681SAndroid Build Coastguard Worker// --------- 1674*9880d681SAndroid Build Coastguard Worker// Sets all bits in a register. 1675*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"ser\t$rd", (LDIRdK LD8:$rd, 0xff), 0>; 1676*9880d681SAndroid Build Coastguard Worker 1677*9880d681SAndroid Build Coastguard Workerlet Defs = [SREG] in 1678*9880d681SAndroid Build Coastguard Workerdef BSETs : FS<0, 1679*9880d681SAndroid Build Coastguard Worker (outs), 1680*9880d681SAndroid Build Coastguard Worker (ins i8imm:$s), 1681*9880d681SAndroid Build Coastguard Worker "bset\t$s", 1682*9880d681SAndroid Build Coastguard Worker []>; 1683*9880d681SAndroid Build Coastguard Worker 1684*9880d681SAndroid Build Coastguard Workerlet Defs = [SREG] in 1685*9880d681SAndroid Build Coastguard Workerdef BCLRs : FS<1, 1686*9880d681SAndroid Build Coastguard Worker (outs), 1687*9880d681SAndroid Build Coastguard Worker (ins i8imm:$s), 1688*9880d681SAndroid Build Coastguard Worker "bclr\t$s", 1689*9880d681SAndroid Build Coastguard Worker []>; 1690*9880d681SAndroid Build Coastguard Worker 1691*9880d681SAndroid Build Coastguard Worker// Set/clear aliases for the carry (C) status flag (bit 0). 1692*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"sec", (BSETs 0)>; 1693*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"clc", (BCLRs 0)>; 1694*9880d681SAndroid Build Coastguard Worker 1695*9880d681SAndroid Build Coastguard Worker// Set/clear aliases for the zero (Z) status flag (bit 1). 1696*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"sez", (BSETs 1)>; 1697*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"clz", (BCLRs 1)>; 1698*9880d681SAndroid Build Coastguard Worker 1699*9880d681SAndroid Build Coastguard Worker// Set/clear aliases for the negative (N) status flag (bit 2). 1700*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"sen", (BSETs 2)>; 1701*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"cln", (BCLRs 2)>; 1702*9880d681SAndroid Build Coastguard Worker 1703*9880d681SAndroid Build Coastguard Worker// Set/clear aliases for the overflow (V) status flag (bit 3). 1704*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"sev", (BSETs 3)>; 1705*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"clv", (BCLRs 3)>; 1706*9880d681SAndroid Build Coastguard Worker 1707*9880d681SAndroid Build Coastguard Worker// Set/clear aliases for the signed (S) status flag (bit 4). 1708*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"ses", (BSETs 4)>; 1709*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"cls", (BCLRs 4)>; 1710*9880d681SAndroid Build Coastguard Worker 1711*9880d681SAndroid Build Coastguard Worker// Set/clear aliases for the half-carry (H) status flag (bit 5). 1712*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"seh", (BSETs 5)>; 1713*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"clh", (BCLRs 5)>; 1714*9880d681SAndroid Build Coastguard Worker 1715*9880d681SAndroid Build Coastguard Worker// Set/clear aliases for the T status flag (bit 6). 1716*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"set", (BSETs 6)>; 1717*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"clt", (BCLRs 6)>; 1718*9880d681SAndroid Build Coastguard Worker 1719*9880d681SAndroid Build Coastguard Worker// Set/clear aliases for the interrupt (I) status flag (bit 7). 1720*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"sei", (BSETs 7)>; 1721*9880d681SAndroid Build Coastguard Workerdef : InstAlias<"cli", (BCLRs 7)>; 1722*9880d681SAndroid Build Coastguard Worker 1723*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 1724*9880d681SAndroid Build Coastguard Worker// Special/Control instructions 1725*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 1726*9880d681SAndroid Build Coastguard Worker 1727*9880d681SAndroid Build Coastguard Worker// BREAK 1728*9880d681SAndroid Build Coastguard Worker// Breakpoint instruction 1729*9880d681SAndroid Build Coastguard Worker// --------- 1730*9880d681SAndroid Build Coastguard Worker// <|1001|0101|1001|1000> 1731*9880d681SAndroid Build Coastguard Workerdef BREAK : F16<0b1001010110011000, 1732*9880d681SAndroid Build Coastguard Worker (outs), 1733*9880d681SAndroid Build Coastguard Worker (ins), 1734*9880d681SAndroid Build Coastguard Worker "break", 1735*9880d681SAndroid Build Coastguard Worker []>, 1736*9880d681SAndroid Build Coastguard Worker Requires<[HasBREAK]>; 1737*9880d681SAndroid Build Coastguard Worker 1738*9880d681SAndroid Build Coastguard Worker// NOP 1739*9880d681SAndroid Build Coastguard Worker// No-operation instruction 1740*9880d681SAndroid Build Coastguard Worker// --------- 1741*9880d681SAndroid Build Coastguard Worker// <|0000|0000|0000|0000> 1742*9880d681SAndroid Build Coastguard Workerdef NOP : F16<0b0000000000000000, 1743*9880d681SAndroid Build Coastguard Worker (outs), 1744*9880d681SAndroid Build Coastguard Worker (ins), 1745*9880d681SAndroid Build Coastguard Worker "nop", 1746*9880d681SAndroid Build Coastguard Worker []>; 1747*9880d681SAndroid Build Coastguard Worker 1748*9880d681SAndroid Build Coastguard Worker// SLEEP 1749*9880d681SAndroid Build Coastguard Worker// Sleep instruction 1750*9880d681SAndroid Build Coastguard Worker// --------- 1751*9880d681SAndroid Build Coastguard Worker// <|1001|0101|1000|1000> 1752*9880d681SAndroid Build Coastguard Workerdef SLEEP : F16<0b1001010110001000, 1753*9880d681SAndroid Build Coastguard Worker (outs), 1754*9880d681SAndroid Build Coastguard Worker (ins), 1755*9880d681SAndroid Build Coastguard Worker "sleep", 1756*9880d681SAndroid Build Coastguard Worker []>; 1757*9880d681SAndroid Build Coastguard Worker 1758*9880d681SAndroid Build Coastguard Worker// WDR 1759*9880d681SAndroid Build Coastguard Worker// Watchdog reset 1760*9880d681SAndroid Build Coastguard Worker// --------- 1761*9880d681SAndroid Build Coastguard Worker// <|1001|0101|1010|1000> 1762*9880d681SAndroid Build Coastguard Workerdef WDR : F16<0b1001010110101000, 1763*9880d681SAndroid Build Coastguard Worker (outs), 1764*9880d681SAndroid Build Coastguard Worker (ins), 1765*9880d681SAndroid Build Coastguard Worker "wdr", 1766*9880d681SAndroid Build Coastguard Worker []>; 1767*9880d681SAndroid Build Coastguard Worker 1768*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 1769*9880d681SAndroid Build Coastguard Worker// Pseudo instructions for later expansion 1770*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 1771*9880d681SAndroid Build Coastguard Worker 1772*9880d681SAndroid Build Coastguard Worker//:TODO: Optimize this for wider types AND optimize the following code 1773*9880d681SAndroid Build Coastguard Worker// compile int foo(char a, char b, char c, char d) {return d+b;} 1774*9880d681SAndroid Build Coastguard Worker// looks like a missed sext_inreg opportunity. 1775*9880d681SAndroid Build Coastguard Workerdef SEXT : ExtensionPseudo< 1776*9880d681SAndroid Build Coastguard Worker (outs DREGS:$dst), 1777*9880d681SAndroid Build Coastguard Worker (ins GPR8:$src), 1778*9880d681SAndroid Build Coastguard Worker "sext\t$dst, $src", 1779*9880d681SAndroid Build Coastguard Worker [(set i16:$dst, (sext i8:$src)), (implicit SREG)] 1780*9880d681SAndroid Build Coastguard Worker>; 1781*9880d681SAndroid Build Coastguard Worker 1782*9880d681SAndroid Build Coastguard Workerdef ZEXT : ExtensionPseudo< 1783*9880d681SAndroid Build Coastguard Worker (outs DREGS:$dst), 1784*9880d681SAndroid Build Coastguard Worker (ins GPR8:$src), 1785*9880d681SAndroid Build Coastguard Worker "zext\t$dst, $src", 1786*9880d681SAndroid Build Coastguard Worker [(set i16:$dst, (zext i8:$src)), (implicit SREG)] 1787*9880d681SAndroid Build Coastguard Worker>; 1788*9880d681SAndroid Build Coastguard Worker 1789*9880d681SAndroid Build Coastguard Worker// This pseudo gets expanded into a movw+adiw thus it clobbers SREG. 1790*9880d681SAndroid Build Coastguard Workerlet Defs = [SREG], 1791*9880d681SAndroid Build Coastguard Worker hasSideEffects = 0 in 1792*9880d681SAndroid Build Coastguard Workerdef FRMIDX : Pseudo<(outs DLDREGS:$dst), 1793*9880d681SAndroid Build Coastguard Worker (ins DLDREGS:$src, i16imm:$src2), 1794*9880d681SAndroid Build Coastguard Worker "frmidx\t$dst, $src, $src2", 1795*9880d681SAndroid Build Coastguard Worker []>; 1796*9880d681SAndroid Build Coastguard Worker 1797*9880d681SAndroid Build Coastguard Worker// This pseudo is either converted to a regular store or a push which clobbers 1798*9880d681SAndroid Build Coastguard Worker// SP. 1799*9880d681SAndroid Build Coastguard Workerdef STDSPQRr : StorePseudo< 1800*9880d681SAndroid Build Coastguard Worker (outs), 1801*9880d681SAndroid Build Coastguard Worker (ins memspi:$dst, GPR8:$src), 1802*9880d681SAndroid Build Coastguard Worker "stdstk\t$dst, $src", 1803*9880d681SAndroid Build Coastguard Worker [(store i8:$src, addr:$dst)] 1804*9880d681SAndroid Build Coastguard Worker>; 1805*9880d681SAndroid Build Coastguard Worker 1806*9880d681SAndroid Build Coastguard Worker// This pseudo is either converted to a regular store or a push which clobbers 1807*9880d681SAndroid Build Coastguard Worker// SP. 1808*9880d681SAndroid Build Coastguard Workerdef STDWSPQRr : StorePseudo< 1809*9880d681SAndroid Build Coastguard Worker (outs), 1810*9880d681SAndroid Build Coastguard Worker (ins memspi:$dst, DREGS:$src), 1811*9880d681SAndroid Build Coastguard Worker "stdwstk\t$dst, $src", 1812*9880d681SAndroid Build Coastguard Worker [(store i16:$src, addr:$dst)] 1813*9880d681SAndroid Build Coastguard Worker>; 1814*9880d681SAndroid Build Coastguard Worker 1815*9880d681SAndroid Build Coastguard Worker// SP read/write pseudos. 1816*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0 in 1817*9880d681SAndroid Build Coastguard Worker{ 1818*9880d681SAndroid Build Coastguard Worker let Uses = [SP] in 1819*9880d681SAndroid Build Coastguard Worker def SPREAD : Pseudo< 1820*9880d681SAndroid Build Coastguard Worker (outs DREGS:$dst), 1821*9880d681SAndroid Build Coastguard Worker (ins GPRSP:$src), 1822*9880d681SAndroid Build Coastguard Worker "spread\t$dst, $src", 1823*9880d681SAndroid Build Coastguard Worker [] 1824*9880d681SAndroid Build Coastguard Worker >; 1825*9880d681SAndroid Build Coastguard Worker 1826*9880d681SAndroid Build Coastguard Worker let Defs = [SP] in 1827*9880d681SAndroid Build Coastguard Worker def SPWRITE : Pseudo< 1828*9880d681SAndroid Build Coastguard Worker (outs GPRSP:$dst), 1829*9880d681SAndroid Build Coastguard Worker (ins DREGS:$src), 1830*9880d681SAndroid Build Coastguard Worker "spwrite\t$dst, $src", 1831*9880d681SAndroid Build Coastguard Worker []>; 1832*9880d681SAndroid Build Coastguard Worker} 1833*9880d681SAndroid Build Coastguard Worker 1834*9880d681SAndroid Build Coastguard Workerdef Select8 : SelectPseudo< 1835*9880d681SAndroid Build Coastguard Worker (outs GPR8:$dst), 1836*9880d681SAndroid Build Coastguard Worker (ins GPR8:$src, GPR8:$src2, i8imm:$cc), 1837*9880d681SAndroid Build Coastguard Worker "# Select8 PSEUDO", 1838*9880d681SAndroid Build Coastguard Worker [(set i8:$dst, (AVRselectcc i8:$src, i8:$src2, imm:$cc))] 1839*9880d681SAndroid Build Coastguard Worker>; 1840*9880d681SAndroid Build Coastguard Worker 1841*9880d681SAndroid Build Coastguard Workerdef Select16 : SelectPseudo< 1842*9880d681SAndroid Build Coastguard Worker (outs DREGS:$dst), 1843*9880d681SAndroid Build Coastguard Worker (ins DREGS:$src, DREGS:$src2, i8imm:$cc), 1844*9880d681SAndroid Build Coastguard Worker "# Select16 PSEUDO", 1845*9880d681SAndroid Build Coastguard Worker [(set i16:$dst, (AVRselectcc i16:$src, i16:$src2, imm:$cc))] 1846*9880d681SAndroid Build Coastguard Worker>; 1847*9880d681SAndroid Build Coastguard Worker 1848*9880d681SAndroid Build Coastguard Workerdef Lsl8 : ShiftPseudo< 1849*9880d681SAndroid Build Coastguard Worker (outs GPR8:$dst), 1850*9880d681SAndroid Build Coastguard Worker (ins GPR8:$src, GPR8:$cnt), 1851*9880d681SAndroid Build Coastguard Worker "# Lsl8 PSEUDO", 1852*9880d681SAndroid Build Coastguard Worker [(set i8:$dst, (AVRlslLoop i8:$src, i8:$cnt))] 1853*9880d681SAndroid Build Coastguard Worker>; 1854*9880d681SAndroid Build Coastguard Worker 1855*9880d681SAndroid Build Coastguard Workerdef Lsl16 : ShiftPseudo< 1856*9880d681SAndroid Build Coastguard Worker (outs DREGS:$dst), 1857*9880d681SAndroid Build Coastguard Worker (ins DREGS:$src, GPR8:$cnt), 1858*9880d681SAndroid Build Coastguard Worker "# Lsl16 PSEUDO", 1859*9880d681SAndroid Build Coastguard Worker [(set i16:$dst, (AVRlslLoop i16:$src, i8:$cnt))] 1860*9880d681SAndroid Build Coastguard Worker>; 1861*9880d681SAndroid Build Coastguard Worker 1862*9880d681SAndroid Build Coastguard Workerdef Lsr8 : ShiftPseudo< 1863*9880d681SAndroid Build Coastguard Worker (outs GPR8:$dst), 1864*9880d681SAndroid Build Coastguard Worker (ins GPR8:$src, GPR8:$cnt), 1865*9880d681SAndroid Build Coastguard Worker "# Lsr8 PSEUDO", 1866*9880d681SAndroid Build Coastguard Worker [(set i8:$dst, (AVRlsrLoop i8:$src, i8:$cnt))] 1867*9880d681SAndroid Build Coastguard Worker>; 1868*9880d681SAndroid Build Coastguard Worker 1869*9880d681SAndroid Build Coastguard Worker 1870*9880d681SAndroid Build Coastguard Workerdef Lsr16 : ShiftPseudo< 1871*9880d681SAndroid Build Coastguard Worker (outs DREGS:$dst), 1872*9880d681SAndroid Build Coastguard Worker (ins DREGS:$src, GPR8:$cnt), 1873*9880d681SAndroid Build Coastguard Worker "# Lsr16 PSEUDO", 1874*9880d681SAndroid Build Coastguard Worker [(set i16:$dst, (AVRlsrLoop i16:$src, i8:$cnt))] 1875*9880d681SAndroid Build Coastguard Worker>; 1876*9880d681SAndroid Build Coastguard Worker 1877*9880d681SAndroid Build Coastguard Workerdef Asr8 : ShiftPseudo< 1878*9880d681SAndroid Build Coastguard Worker (outs GPR8:$dst), 1879*9880d681SAndroid Build Coastguard Worker (ins GPR8:$src, GPR8:$cnt), 1880*9880d681SAndroid Build Coastguard Worker "# Asr8 PSEUDO", 1881*9880d681SAndroid Build Coastguard Worker [(set i8:$dst, (AVRasrLoop i8:$src, i8:$cnt))] 1882*9880d681SAndroid Build Coastguard Worker>; 1883*9880d681SAndroid Build Coastguard Worker 1884*9880d681SAndroid Build Coastguard Workerdef Asr16 : ShiftPseudo< 1885*9880d681SAndroid Build Coastguard Worker (outs DREGS:$dst), 1886*9880d681SAndroid Build Coastguard Worker (ins DREGS:$src, GPR8:$cnt), 1887*9880d681SAndroid Build Coastguard Worker "# Asr16 PSEUDO", 1888*9880d681SAndroid Build Coastguard Worker [(set i16:$dst, (AVRasrLoop i16:$src, i8:$cnt))] 1889*9880d681SAndroid Build Coastguard Worker>; 1890*9880d681SAndroid Build Coastguard Worker 1891*9880d681SAndroid Build Coastguard Worker 1892*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 1893*9880d681SAndroid Build Coastguard Worker// Non-Instruction Patterns 1894*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 1895*9880d681SAndroid Build Coastguard Worker 1896*9880d681SAndroid Build Coastguard Worker//:TODO: look in x86InstrCompiler.td for odd encoding trick related to 1897*9880d681SAndroid Build Coastguard Worker// add x, 128 -> sub x, -128. Clang is emitting an eor for this (ldi+eor) 1898*9880d681SAndroid Build Coastguard Worker 1899*9880d681SAndroid Build Coastguard Worker// the add instruction always writes the carry flag 1900*9880d681SAndroid Build Coastguard Workerdef : Pat<(addc i8:$src, i8:$src2), 1901*9880d681SAndroid Build Coastguard Worker (ADDRdRr i8:$src, i8:$src2)>; 1902*9880d681SAndroid Build Coastguard Workerdef : Pat<(addc DREGS:$src, DREGS:$src2), 1903*9880d681SAndroid Build Coastguard Worker (ADDWRdRr DREGS:$src, DREGS:$src2)>; 1904*9880d681SAndroid Build Coastguard Worker 1905*9880d681SAndroid Build Coastguard Worker// all sub instruction variants always writes the carry flag 1906*9880d681SAndroid Build Coastguard Workerdef : Pat<(subc i8:$src, i8:$src2), 1907*9880d681SAndroid Build Coastguard Worker (SUBRdRr i8:$src, i8:$src2)>; 1908*9880d681SAndroid Build Coastguard Workerdef : Pat<(subc i16:$src, i16:$src2), 1909*9880d681SAndroid Build Coastguard Worker (SUBWRdRr i16:$src, i16:$src2)>; 1910*9880d681SAndroid Build Coastguard Workerdef : Pat<(subc i8:$src, imm:$src2), 1911*9880d681SAndroid Build Coastguard Worker (SUBIRdK i8:$src, imm:$src2)>; 1912*9880d681SAndroid Build Coastguard Workerdef : Pat<(subc i16:$src, imm:$src2), 1913*9880d681SAndroid Build Coastguard Worker (SUBIWRdK i16:$src, imm:$src2)>; 1914*9880d681SAndroid Build Coastguard Worker 1915*9880d681SAndroid Build Coastguard Worker// These patterns convert add (x, -imm) to sub (x, imm) since we dont have 1916*9880d681SAndroid Build Coastguard Worker// any add with imm instructions. Also take care of the adiw/sbiw instructions. 1917*9880d681SAndroid Build Coastguard Workerdef : Pat<(add i16:$src1, imm0_63_neg:$src2), 1918*9880d681SAndroid Build Coastguard Worker (SBIWRdK i16:$src1, (imm0_63_neg:$src2))>; 1919*9880d681SAndroid Build Coastguard Workerdef : Pat<(add i16:$src1, imm:$src2), 1920*9880d681SAndroid Build Coastguard Worker (SUBIWRdK i16:$src1, (imm16_neg_XFORM imm:$src2))>; 1921*9880d681SAndroid Build Coastguard Workerdef : Pat<(addc i16:$src1, imm:$src2), 1922*9880d681SAndroid Build Coastguard Worker (SUBIWRdK i16:$src1, (imm16_neg_XFORM imm:$src2))>; 1923*9880d681SAndroid Build Coastguard Workerdef : Pat<(adde i16:$src1, imm:$src2), 1924*9880d681SAndroid Build Coastguard Worker (SBCIWRdK i16:$src1, (imm16_neg_XFORM imm:$src2))>; 1925*9880d681SAndroid Build Coastguard Worker 1926*9880d681SAndroid Build Coastguard Workerdef : Pat<(add i8:$src1, imm:$src2), 1927*9880d681SAndroid Build Coastguard Worker (SUBIRdK i8:$src1, (imm8_neg_XFORM imm:$src2))>; 1928*9880d681SAndroid Build Coastguard Workerdef : Pat<(addc i8:$src1, imm:$src2), 1929*9880d681SAndroid Build Coastguard Worker (SUBIRdK i8:$src1, (imm8_neg_XFORM imm:$src2))>; 1930*9880d681SAndroid Build Coastguard Workerdef : Pat<(adde i8:$src1, imm:$src2), 1931*9880d681SAndroid Build Coastguard Worker (SBCIRdK i8:$src1, (imm8_neg_XFORM imm:$src2))>; 1932*9880d681SAndroid Build Coastguard Worker 1933*9880d681SAndroid Build Coastguard Worker// Calls. 1934*9880d681SAndroid Build Coastguard Workerdef : Pat<(AVRcall (i16 tglobaladdr:$dst)), 1935*9880d681SAndroid Build Coastguard Worker (CALLk tglobaladdr:$dst)>; 1936*9880d681SAndroid Build Coastguard Workerdef : Pat<(AVRcall (i16 texternalsym:$dst)), 1937*9880d681SAndroid Build Coastguard Worker (CALLk texternalsym:$dst)>; 1938*9880d681SAndroid Build Coastguard Worker 1939*9880d681SAndroid Build Coastguard Worker// `anyext` 1940*9880d681SAndroid Build Coastguard Workerdef : Pat<(i16 (anyext i8:$src)), 1941*9880d681SAndroid Build Coastguard Worker (INSERT_SUBREG (i16 (IMPLICIT_DEF)), i8:$src, sub_lo)>; 1942*9880d681SAndroid Build Coastguard Worker 1943*9880d681SAndroid Build Coastguard Worker// `trunc` 1944*9880d681SAndroid Build Coastguard Workerdef : Pat<(i8 (trunc i16:$src)), 1945*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG i16:$src, sub_lo)>; 1946*9880d681SAndroid Build Coastguard Worker 1947*9880d681SAndroid Build Coastguard Worker// sext_inreg 1948*9880d681SAndroid Build Coastguard Workerdef : Pat<(sext_inreg i16:$src, i8), 1949*9880d681SAndroid Build Coastguard Worker (SEXT (i8 (EXTRACT_SUBREG i16:$src, sub_lo)))>; 1950*9880d681SAndroid Build Coastguard Worker 1951*9880d681SAndroid Build Coastguard Worker// GlobalAddress 1952*9880d681SAndroid Build Coastguard Workerdef : Pat<(i16 (AVRWrapper tglobaladdr:$dst)), 1953*9880d681SAndroid Build Coastguard Worker (LDIWRdK tglobaladdr:$dst)>; 1954*9880d681SAndroid Build Coastguard Workerdef : Pat<(add i16:$src, (AVRWrapper tglobaladdr:$src2)), 1955*9880d681SAndroid Build Coastguard Worker (SUBIWRdK i16:$src, tglobaladdr:$src2)>; 1956*9880d681SAndroid Build Coastguard Workerdef : Pat<(i8 (load (AVRWrapper tglobaladdr:$dst))), 1957*9880d681SAndroid Build Coastguard Worker (LDSRdK tglobaladdr:$dst)>; 1958*9880d681SAndroid Build Coastguard Workerdef : Pat<(i16 (load (AVRWrapper tglobaladdr:$dst))), 1959*9880d681SAndroid Build Coastguard Worker (LDSWRdK tglobaladdr:$dst)>; 1960*9880d681SAndroid Build Coastguard Workerdef : Pat<(store i8:$src, (i16 (AVRWrapper tglobaladdr:$dst))), 1961*9880d681SAndroid Build Coastguard Worker (STSKRr tglobaladdr:$dst, i8:$src)>; 1962*9880d681SAndroid Build Coastguard Workerdef : Pat<(store i16:$src, (i16 (AVRWrapper tglobaladdr:$dst))), 1963*9880d681SAndroid Build Coastguard Worker (STSWKRr tglobaladdr:$dst, i16:$src)>; 1964*9880d681SAndroid Build Coastguard Worker 1965*9880d681SAndroid Build Coastguard Worker// BlockAddress 1966*9880d681SAndroid Build Coastguard Workerdef : Pat<(i16 (AVRWrapper tblockaddress:$dst)), 1967*9880d681SAndroid Build Coastguard Worker (LDIWRdK tblockaddress:$dst)>; 1968*9880d681SAndroid Build Coastguard Worker 1969*9880d681SAndroid Build Coastguard Worker// hi-reg truncation : trunc(int16 >> 8) 1970*9880d681SAndroid Build Coastguard Worker//:FIXME: i think it's better to emit an extract subreg node in the DAG than 1971*9880d681SAndroid Build Coastguard Worker// all this mess once we get optimal shift code 1972*9880d681SAndroid Build Coastguard Worker// lol... I think so, too. [@agnat] 1973*9880d681SAndroid Build Coastguard Workerdef : Pat<(i8 (trunc (AVRlsr (AVRlsr (AVRlsr (AVRlsr (AVRlsr (AVRlsr (AVRlsr 1974*9880d681SAndroid Build Coastguard Worker (AVRlsr DREGS:$src)))))))))), 1975*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG DREGS:$src, sub_hi)>; 1976*9880d681SAndroid Build Coastguard Worker 1977*9880d681SAndroid Build Coastguard Worker// :FIXME: DAGCombiner produces an shl node after legalization from these seq: 1978*9880d681SAndroid Build Coastguard Worker// BR_JT -> (mul x, 2) -> (shl x, 1) 1979*9880d681SAndroid Build Coastguard Workerdef : Pat<(shl i16:$src1, (i8 1)), 1980*9880d681SAndroid Build Coastguard Worker (LSLWRd i16:$src1)>; 1981*9880d681SAndroid Build Coastguard Worker 1982