2791 lines · cpp
1//===-- AVRISelLowering.cpp - AVR DAG Lowering Implementation -------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file defines the interfaces that AVR uses to lower LLVM code into a10// selection DAG.11//12//===----------------------------------------------------------------------===//13 14#include "AVRISelLowering.h"15 16#include "llvm/ADT/ArrayRef.h"17#include "llvm/ADT/StringSwitch.h"18#include "llvm/CodeGen/CallingConvLower.h"19#include "llvm/CodeGen/MachineFrameInfo.h"20#include "llvm/CodeGen/MachineInstrBuilder.h"21#include "llvm/CodeGen/MachineRegisterInfo.h"22#include "llvm/CodeGen/SelectionDAG.h"23#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"24#include "llvm/IR/Function.h"25#include "llvm/Support/ErrorHandling.h"26 27#include "AVR.h"28#include "AVRMachineFunctionInfo.h"29#include "AVRSubtarget.h"30#include "AVRTargetMachine.h"31#include "MCTargetDesc/AVRMCTargetDesc.h"32 33namespace llvm {34 35AVRTargetLowering::AVRTargetLowering(const AVRTargetMachine &TM,36 const AVRSubtarget &STI)37 : TargetLowering(TM, STI), Subtarget(STI) {38 // Set up the register classes.39 addRegisterClass(MVT::i8, &AVR::GPR8RegClass);40 addRegisterClass(MVT::i16, &AVR::DREGSRegClass);41 42 // Compute derived properties from the register classes.43 computeRegisterProperties(Subtarget.getRegisterInfo());44 45 setBooleanContents(ZeroOrOneBooleanContent);46 setBooleanVectorContents(ZeroOrOneBooleanContent);47 setSchedulingPreference(Sched::RegPressure);48 setStackPointerRegisterToSaveRestore(AVR::SP);49 setSupportsUnalignedAtomics(true);50 51 setOperationAction(ISD::GlobalAddress, MVT::i16, Custom);52 setOperationAction(ISD::BlockAddress, MVT::i16, Custom);53 54 setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);55 setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);56 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i8, Expand);57 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i16, Expand);58 59 setOperationAction(ISD::INLINEASM, MVT::Other, Custom);60 61 for (MVT VT : MVT::integer_valuetypes()) {62 for (auto N : {ISD::EXTLOAD, ISD::SEXTLOAD, ISD::ZEXTLOAD}) {63 setLoadExtAction(N, VT, MVT::i1, Promote);64 setLoadExtAction(N, VT, MVT::i8, Expand);65 }66 }67 68 setTruncStoreAction(MVT::i16, MVT::i8, Expand);69 70 for (MVT VT : MVT::integer_valuetypes()) {71 setOperationAction(ISD::ADDC, VT, Legal);72 setOperationAction(ISD::SUBC, VT, Legal);73 setOperationAction(ISD::ADDE, VT, Legal);74 setOperationAction(ISD::SUBE, VT, Legal);75 }76 77 // sub (x, imm) gets canonicalized to add (x, -imm), so for illegal types78 // revert into a sub since we don't have an add with immediate instruction.79 setOperationAction(ISD::ADD, MVT::i32, Custom);80 setOperationAction(ISD::ADD, MVT::i64, Custom);81 82 // our shift instructions are only able to shift 1 bit at a time, so handle83 // this in a custom way.84 setOperationAction(ISD::SRA, MVT::i8, Custom);85 setOperationAction(ISD::SHL, MVT::i8, Custom);86 setOperationAction(ISD::SRL, MVT::i8, Custom);87 setOperationAction(ISD::SRA, MVT::i16, Custom);88 setOperationAction(ISD::SHL, MVT::i16, Custom);89 setOperationAction(ISD::SRL, MVT::i16, Custom);90 setOperationAction(ISD::SRA, MVT::i32, Custom);91 setOperationAction(ISD::SHL, MVT::i32, Custom);92 setOperationAction(ISD::SRL, MVT::i32, Custom);93 setOperationAction(ISD::SHL_PARTS, MVT::i16, Expand);94 setOperationAction(ISD::SRA_PARTS, MVT::i16, Expand);95 setOperationAction(ISD::SRL_PARTS, MVT::i16, Expand);96 97 setOperationAction(ISD::ROTL, MVT::i8, Custom);98 setOperationAction(ISD::ROTL, MVT::i16, Expand);99 setOperationAction(ISD::ROTR, MVT::i8, Custom);100 setOperationAction(ISD::ROTR, MVT::i16, Expand);101 102 setOperationAction(ISD::BR_CC, MVT::i8, Custom);103 setOperationAction(ISD::BR_CC, MVT::i16, Custom);104 setOperationAction(ISD::BR_CC, MVT::i32, Custom);105 setOperationAction(ISD::BR_CC, MVT::i64, Custom);106 setOperationAction(ISD::BRCOND, MVT::Other, Expand);107 108 setOperationAction(ISD::SELECT_CC, MVT::i8, Custom);109 setOperationAction(ISD::SELECT_CC, MVT::i16, Custom);110 setOperationAction(ISD::SELECT_CC, MVT::i32, Expand);111 setOperationAction(ISD::SELECT_CC, MVT::i64, Expand);112 setOperationAction(ISD::SETCC, MVT::i8, Custom);113 setOperationAction(ISD::SETCC, MVT::i16, Custom);114 setOperationAction(ISD::SETCC, MVT::i32, Custom);115 setOperationAction(ISD::SETCC, MVT::i64, Custom);116 setOperationAction(ISD::SELECT, MVT::i8, Expand);117 setOperationAction(ISD::SELECT, MVT::i16, Expand);118 119 setOperationAction(ISD::BSWAP, MVT::i16, Expand);120 121 // Add support for postincrement and predecrement load/stores.122 setIndexedLoadAction(ISD::POST_INC, MVT::i8, Legal);123 setIndexedLoadAction(ISD::POST_INC, MVT::i16, Legal);124 setIndexedLoadAction(ISD::PRE_DEC, MVT::i8, Legal);125 setIndexedLoadAction(ISD::PRE_DEC, MVT::i16, Legal);126 setIndexedStoreAction(ISD::POST_INC, MVT::i8, Legal);127 setIndexedStoreAction(ISD::POST_INC, MVT::i16, Legal);128 setIndexedStoreAction(ISD::PRE_DEC, MVT::i8, Legal);129 setIndexedStoreAction(ISD::PRE_DEC, MVT::i16, Legal);130 131 setOperationAction(ISD::BR_JT, MVT::Other, Expand);132 133 setOperationAction(ISD::VASTART, MVT::Other, Custom);134 setOperationAction(ISD::VAEND, MVT::Other, Expand);135 setOperationAction(ISD::VAARG, MVT::Other, Expand);136 setOperationAction(ISD::VACOPY, MVT::Other, Expand);137 138 // Atomic operations which must be lowered to rtlib calls139 for (MVT VT : MVT::integer_valuetypes()) {140 setOperationAction(ISD::ATOMIC_SWAP, VT, Expand);141 setOperationAction(ISD::ATOMIC_CMP_SWAP, VT, Expand);142 setOperationAction(ISD::ATOMIC_LOAD_NAND, VT, Expand);143 setOperationAction(ISD::ATOMIC_LOAD_MAX, VT, Expand);144 setOperationAction(ISD::ATOMIC_LOAD_MIN, VT, Expand);145 setOperationAction(ISD::ATOMIC_LOAD_UMAX, VT, Expand);146 setOperationAction(ISD::ATOMIC_LOAD_UMIN, VT, Expand);147 }148 149 // Division/remainder150 setOperationAction(ISD::UDIV, MVT::i8, Expand);151 setOperationAction(ISD::UDIV, MVT::i16, Expand);152 setOperationAction(ISD::UREM, MVT::i8, Expand);153 setOperationAction(ISD::UREM, MVT::i16, Expand);154 setOperationAction(ISD::SDIV, MVT::i8, Expand);155 setOperationAction(ISD::SDIV, MVT::i16, Expand);156 setOperationAction(ISD::SREM, MVT::i8, Expand);157 setOperationAction(ISD::SREM, MVT::i16, Expand);158 159 // Make division and modulus custom160 setOperationAction(ISD::UDIVREM, MVT::i8, Custom);161 setOperationAction(ISD::UDIVREM, MVT::i16, Custom);162 setOperationAction(ISD::UDIVREM, MVT::i32, Custom);163 setOperationAction(ISD::SDIVREM, MVT::i8, Custom);164 setOperationAction(ISD::SDIVREM, MVT::i16, Custom);165 setOperationAction(ISD::SDIVREM, MVT::i32, Custom);166 167 // Do not use MUL. The AVR instructions are closer to SMUL_LOHI &co.168 setOperationAction(ISD::MUL, MVT::i8, Expand);169 setOperationAction(ISD::MUL, MVT::i16, Expand);170 171 // Expand 16 bit multiplications.172 setOperationAction(ISD::SMUL_LOHI, MVT::i16, Expand);173 setOperationAction(ISD::UMUL_LOHI, MVT::i16, Expand);174 175 // Expand multiplications to libcalls when there is176 // no hardware MUL.177 if (!Subtarget.supportsMultiplication()) {178 setOperationAction(ISD::SMUL_LOHI, MVT::i8, Expand);179 setOperationAction(ISD::UMUL_LOHI, MVT::i8, Expand);180 }181 182 for (MVT VT : MVT::integer_valuetypes()) {183 setOperationAction(ISD::MULHS, VT, Expand);184 setOperationAction(ISD::MULHU, VT, Expand);185 }186 187 for (MVT VT : MVT::integer_valuetypes()) {188 setOperationAction(ISD::CTPOP, VT, Expand);189 setOperationAction(ISD::CTLZ, VT, Expand);190 setOperationAction(ISD::CTTZ, VT, Expand);191 }192 193 for (MVT VT : MVT::integer_valuetypes()) {194 setOperationAction(ISD::SIGN_EXTEND_INREG, VT, Expand);195 // TODO: The generated code is pretty poor. Investigate using the196 // same "shift and subtract with carry" trick that we do for197 // extending 8-bit to 16-bit. This may require infrastructure198 // improvements in how we treat 16-bit "registers" to be feasible.199 }200 201 setMinFunctionAlignment(Align(2));202 setMinimumJumpTableEntries(UINT_MAX);203}204 205EVT AVRTargetLowering::getSetCCResultType(const DataLayout &DL, LLVMContext &,206 EVT VT) const {207 assert(!VT.isVector() && "No AVR SetCC type for vectors!");208 return MVT::i8;209}210 211SDValue AVRTargetLowering::LowerShifts(SDValue Op, SelectionDAG &DAG) const {212 unsigned Opc8;213 const SDNode *N = Op.getNode();214 EVT VT = Op.getValueType();215 SDLoc dl(N);216 assert(llvm::has_single_bit<uint32_t>(VT.getSizeInBits()) &&217 "Expected power-of-2 shift amount");218 219 if (VT.getSizeInBits() == 32) {220 if (!isa<ConstantSDNode>(N->getOperand(1))) {221 // 32-bit shifts are converted to a loop in IR.222 // This should be unreachable.223 report_fatal_error("Expected a constant shift amount!");224 }225 SDVTList ResTys = DAG.getVTList(MVT::i16, MVT::i16);226 SDValue SrcLo =227 DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i16, Op.getOperand(0),228 DAG.getConstant(0, dl, MVT::i16));229 SDValue SrcHi =230 DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i16, Op.getOperand(0),231 DAG.getConstant(1, dl, MVT::i16));232 uint64_t ShiftAmount = N->getConstantOperandVal(1);233 if (ShiftAmount == 16) {234 // Special case these two operations because they appear to be used by the235 // generic codegen parts to lower 32-bit numbers.236 // TODO: perhaps we can lower shift amounts bigger than 16 to a 16-bit237 // shift of a part of the 32-bit value?238 switch (Op.getOpcode()) {239 case ISD::SHL: {240 SDValue Zero = DAG.getConstant(0, dl, MVT::i16);241 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i32, Zero, SrcLo);242 }243 case ISD::SRL: {244 SDValue Zero = DAG.getConstant(0, dl, MVT::i16);245 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i32, SrcHi, Zero);246 }247 }248 }249 SDValue Cnt = DAG.getTargetConstant(ShiftAmount, dl, MVT::i8);250 unsigned Opc;251 switch (Op.getOpcode()) {252 default:253 llvm_unreachable("Invalid 32-bit shift opcode!");254 case ISD::SHL:255 Opc = AVRISD::LSLW;256 break;257 case ISD::SRL:258 Opc = AVRISD::LSRW;259 break;260 case ISD::SRA:261 Opc = AVRISD::ASRW;262 break;263 }264 SDValue Result = DAG.getNode(Opc, dl, ResTys, SrcLo, SrcHi, Cnt);265 return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i32, Result.getValue(0),266 Result.getValue(1));267 }268 269 // Expand non-constant shifts to loops.270 if (!isa<ConstantSDNode>(N->getOperand(1))) {271 switch (Op.getOpcode()) {272 default:273 llvm_unreachable("Invalid shift opcode!");274 case ISD::SHL:275 return DAG.getNode(AVRISD::LSLLOOP, dl, VT, N->getOperand(0),276 N->getOperand(1));277 case ISD::SRL:278 return DAG.getNode(AVRISD::LSRLOOP, dl, VT, N->getOperand(0),279 N->getOperand(1));280 case ISD::ROTL: {281 SDValue Amt = N->getOperand(1);282 EVT AmtVT = Amt.getValueType();283 Amt = DAG.getNode(ISD::AND, dl, AmtVT, Amt,284 DAG.getConstant(VT.getSizeInBits() - 1, dl, AmtVT));285 return DAG.getNode(AVRISD::ROLLOOP, dl, VT, N->getOperand(0), Amt);286 }287 case ISD::ROTR: {288 SDValue Amt = N->getOperand(1);289 EVT AmtVT = Amt.getValueType();290 Amt = DAG.getNode(ISD::AND, dl, AmtVT, Amt,291 DAG.getConstant(VT.getSizeInBits() - 1, dl, AmtVT));292 return DAG.getNode(AVRISD::RORLOOP, dl, VT, N->getOperand(0), Amt);293 }294 case ISD::SRA:295 return DAG.getNode(AVRISD::ASRLOOP, dl, VT, N->getOperand(0),296 N->getOperand(1));297 }298 }299 300 uint64_t ShiftAmount = N->getConstantOperandVal(1);301 SDValue Victim = N->getOperand(0);302 303 switch (Op.getOpcode()) {304 case ISD::SRA:305 Opc8 = AVRISD::ASR;306 break;307 case ISD::ROTL:308 Opc8 = AVRISD::ROL;309 ShiftAmount = ShiftAmount % VT.getSizeInBits();310 break;311 case ISD::ROTR:312 Opc8 = AVRISD::ROR;313 ShiftAmount = ShiftAmount % VT.getSizeInBits();314 break;315 case ISD::SRL:316 Opc8 = AVRISD::LSR;317 break;318 case ISD::SHL:319 Opc8 = AVRISD::LSL;320 break;321 default:322 llvm_unreachable("Invalid shift opcode");323 }324 325 // Optimize int8/int16 shifts.326 if (VT.getSizeInBits() == 8) {327 if (Op.getOpcode() == ISD::SHL && 4 <= ShiftAmount && ShiftAmount < 7) {328 // Optimize LSL when 4 <= ShiftAmount <= 6.329 Victim = DAG.getNode(AVRISD::SWAP, dl, VT, Victim);330 Victim =331 DAG.getNode(ISD::AND, dl, VT, Victim, DAG.getConstant(0xf0, dl, VT));332 ShiftAmount -= 4;333 } else if (Op.getOpcode() == ISD::SRL && 4 <= ShiftAmount &&334 ShiftAmount < 7) {335 // Optimize LSR when 4 <= ShiftAmount <= 6.336 Victim = DAG.getNode(AVRISD::SWAP, dl, VT, Victim);337 Victim =338 DAG.getNode(ISD::AND, dl, VT, Victim, DAG.getConstant(0x0f, dl, VT));339 ShiftAmount -= 4;340 } else if (Op.getOpcode() == ISD::SHL && ShiftAmount == 7) {341 // Optimize LSL when ShiftAmount == 7.342 Victim = DAG.getNode(AVRISD::LSLBN, dl, VT, Victim,343 DAG.getConstant(7, dl, VT));344 ShiftAmount = 0;345 } else if (Op.getOpcode() == ISD::SRL && ShiftAmount == 7) {346 // Optimize LSR when ShiftAmount == 7.347 Victim = DAG.getNode(AVRISD::LSRBN, dl, VT, Victim,348 DAG.getConstant(7, dl, VT));349 ShiftAmount = 0;350 } else if (Op.getOpcode() == ISD::SRA && ShiftAmount == 6) {351 // Optimize ASR when ShiftAmount == 6.352 Victim = DAG.getNode(AVRISD::ASRBN, dl, VT, Victim,353 DAG.getConstant(6, dl, VT));354 ShiftAmount = 0;355 } else if (Op.getOpcode() == ISD::SRA && ShiftAmount == 7) {356 // Optimize ASR when ShiftAmount == 7.357 Victim = DAG.getNode(AVRISD::ASRBN, dl, VT, Victim,358 DAG.getConstant(7, dl, VT));359 ShiftAmount = 0;360 } else if (Op.getOpcode() == ISD::ROTL && ShiftAmount == 3) {361 // Optimize left rotation 3 bits to swap then right rotation 1 bit.362 Victim = DAG.getNode(AVRISD::SWAP, dl, VT, Victim);363 Victim = DAG.getNode(AVRISD::ROR, dl, VT, Victim);364 ShiftAmount = 0;365 } else if (Op.getOpcode() == ISD::ROTR && ShiftAmount == 3) {366 // Optimize right rotation 3 bits to swap then left rotation 1 bit.367 Victim = DAG.getNode(AVRISD::SWAP, dl, VT, Victim);368 Victim = DAG.getNode(AVRISD::ROL, dl, VT, Victim);369 ShiftAmount = 0;370 } else if (Op.getOpcode() == ISD::ROTL && ShiftAmount == 7) {371 // Optimize left rotation 7 bits to right rotation 1 bit.372 Victim = DAG.getNode(AVRISD::ROR, dl, VT, Victim);373 ShiftAmount = 0;374 } else if (Op.getOpcode() == ISD::ROTR && ShiftAmount == 7) {375 // Optimize right rotation 7 bits to left rotation 1 bit.376 Victim = DAG.getNode(AVRISD::ROL, dl, VT, Victim);377 ShiftAmount = 0;378 } else if ((Op.getOpcode() == ISD::ROTR || Op.getOpcode() == ISD::ROTL) &&379 ShiftAmount >= 4) {380 // Optimize left/right rotation with the SWAP instruction.381 Victim = DAG.getNode(AVRISD::SWAP, dl, VT, Victim);382 ShiftAmount -= 4;383 }384 } else if (VT.getSizeInBits() == 16) {385 if (Op.getOpcode() == ISD::SRA)386 // Special optimization for int16 arithmetic right shift.387 switch (ShiftAmount) {388 case 15:389 Victim = DAG.getNode(AVRISD::ASRWN, dl, VT, Victim,390 DAG.getConstant(15, dl, VT));391 ShiftAmount = 0;392 break;393 case 14:394 Victim = DAG.getNode(AVRISD::ASRWN, dl, VT, Victim,395 DAG.getConstant(14, dl, VT));396 ShiftAmount = 0;397 break;398 case 7:399 Victim = DAG.getNode(AVRISD::ASRWN, dl, VT, Victim,400 DAG.getConstant(7, dl, VT));401 ShiftAmount = 0;402 break;403 default:404 break;405 }406 if (4 <= ShiftAmount && ShiftAmount < 8)407 switch (Op.getOpcode()) {408 case ISD::SHL:409 Victim = DAG.getNode(AVRISD::LSLWN, dl, VT, Victim,410 DAG.getConstant(4, dl, VT));411 ShiftAmount -= 4;412 break;413 case ISD::SRL:414 Victim = DAG.getNode(AVRISD::LSRWN, dl, VT, Victim,415 DAG.getConstant(4, dl, VT));416 ShiftAmount -= 4;417 break;418 default:419 break;420 }421 else if (8 <= ShiftAmount && ShiftAmount < 12)422 switch (Op.getOpcode()) {423 case ISD::SHL:424 Victim = DAG.getNode(AVRISD::LSLWN, dl, VT, Victim,425 DAG.getConstant(8, dl, VT));426 ShiftAmount -= 8;427 // Only operate on the higher byte for remaining shift bits.428 Opc8 = AVRISD::LSLHI;429 break;430 case ISD::SRL:431 Victim = DAG.getNode(AVRISD::LSRWN, dl, VT, Victim,432 DAG.getConstant(8, dl, VT));433 ShiftAmount -= 8;434 // Only operate on the lower byte for remaining shift bits.435 Opc8 = AVRISD::LSRLO;436 break;437 case ISD::SRA:438 Victim = DAG.getNode(AVRISD::ASRWN, dl, VT, Victim,439 DAG.getConstant(8, dl, VT));440 ShiftAmount -= 8;441 // Only operate on the lower byte for remaining shift bits.442 Opc8 = AVRISD::ASRLO;443 break;444 default:445 break;446 }447 else if (12 <= ShiftAmount)448 switch (Op.getOpcode()) {449 case ISD::SHL:450 Victim = DAG.getNode(AVRISD::LSLWN, dl, VT, Victim,451 DAG.getConstant(12, dl, VT));452 ShiftAmount -= 12;453 // Only operate on the higher byte for remaining shift bits.454 Opc8 = AVRISD::LSLHI;455 break;456 case ISD::SRL:457 Victim = DAG.getNode(AVRISD::LSRWN, dl, VT, Victim,458 DAG.getConstant(12, dl, VT));459 ShiftAmount -= 12;460 // Only operate on the lower byte for remaining shift bits.461 Opc8 = AVRISD::LSRLO;462 break;463 case ISD::SRA:464 Victim = DAG.getNode(AVRISD::ASRWN, dl, VT, Victim,465 DAG.getConstant(8, dl, VT));466 ShiftAmount -= 8;467 // Only operate on the lower byte for remaining shift bits.468 Opc8 = AVRISD::ASRLO;469 break;470 default:471 break;472 }473 }474 475 while (ShiftAmount--) {476 Victim = DAG.getNode(Opc8, dl, VT, Victim);477 }478 479 return Victim;480}481 482SDValue AVRTargetLowering::LowerDivRem(SDValue Op, SelectionDAG &DAG) const {483 unsigned Opcode = Op->getOpcode();484 assert((Opcode == ISD::SDIVREM || Opcode == ISD::UDIVREM) &&485 "Invalid opcode for Div/Rem lowering");486 bool IsSigned = (Opcode == ISD::SDIVREM);487 EVT VT = Op->getValueType(0);488 Type *Ty = VT.getTypeForEVT(*DAG.getContext());489 490 RTLIB::Libcall LC;491 switch (VT.getSimpleVT().SimpleTy) {492 default:493 llvm_unreachable("Unexpected request for libcall!");494 case MVT::i8:495 LC = IsSigned ? RTLIB::SDIVREM_I8 : RTLIB::UDIVREM_I8;496 break;497 case MVT::i16:498 LC = IsSigned ? RTLIB::SDIVREM_I16 : RTLIB::UDIVREM_I16;499 break;500 case MVT::i32:501 LC = IsSigned ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32;502 break;503 }504 505 SDValue InChain = DAG.getEntryNode();506 507 TargetLowering::ArgListTy Args;508 for (SDValue const &Value : Op->op_values()) {509 TargetLowering::ArgListEntry Entry(510 Value, Value.getValueType().getTypeForEVT(*DAG.getContext()));511 Entry.IsSExt = IsSigned;512 Entry.IsZExt = !IsSigned;513 Args.push_back(Entry);514 }515 516 SDValue Callee = DAG.getExternalSymbol(getLibcallName(LC),517 getPointerTy(DAG.getDataLayout()));518 519 Type *RetTy = (Type *)StructType::get(Ty, Ty);520 521 SDLoc dl(Op);522 TargetLowering::CallLoweringInfo CLI(DAG);523 CLI.setDebugLoc(dl)524 .setChain(InChain)525 .setLibCallee(getLibcallCallingConv(LC), RetTy, Callee, std::move(Args))526 .setInRegister()527 .setSExtResult(IsSigned)528 .setZExtResult(!IsSigned);529 530 std::pair<SDValue, SDValue> CallInfo = LowerCallTo(CLI);531 return CallInfo.first;532}533 534SDValue AVRTargetLowering::LowerGlobalAddress(SDValue Op,535 SelectionDAG &DAG) const {536 auto DL = DAG.getDataLayout();537 538 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();539 int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset();540 541 // Create the TargetGlobalAddress node, folding in the constant offset.542 SDValue Result =543 DAG.getTargetGlobalAddress(GV, SDLoc(Op), getPointerTy(DL), Offset);544 return DAG.getNode(AVRISD::WRAPPER, SDLoc(Op), getPointerTy(DL), Result);545}546 547SDValue AVRTargetLowering::LowerBlockAddress(SDValue Op,548 SelectionDAG &DAG) const {549 auto DL = DAG.getDataLayout();550 const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();551 552 SDValue Result = DAG.getTargetBlockAddress(BA, getPointerTy(DL));553 554 return DAG.getNode(AVRISD::WRAPPER, SDLoc(Op), getPointerTy(DL), Result);555}556 557/// IntCCToAVRCC - Convert a DAG integer condition code to an AVR CC.558static AVRCC::CondCodes intCCToAVRCC(ISD::CondCode CC) {559 switch (CC) {560 default:561 llvm_unreachable("Unknown condition code!");562 case ISD::SETEQ:563 return AVRCC::COND_EQ;564 case ISD::SETNE:565 return AVRCC::COND_NE;566 case ISD::SETGE:567 return AVRCC::COND_GE;568 case ISD::SETLT:569 return AVRCC::COND_LT;570 case ISD::SETUGE:571 return AVRCC::COND_SH;572 case ISD::SETULT:573 return AVRCC::COND_LO;574 }575}576 577/// Returns appropriate CP/CPI/CPC nodes code for the given 8/16-bit operands.578SDValue AVRTargetLowering::getAVRCmp(SDValue LHS, SDValue RHS,579 SelectionDAG &DAG, SDLoc DL) const {580 assert((LHS.getSimpleValueType() == RHS.getSimpleValueType()) &&581 "LHS and RHS have different types");582 assert(((LHS.getSimpleValueType() == MVT::i16) ||583 (LHS.getSimpleValueType() == MVT::i8)) &&584 "invalid comparison type");585 586 SDValue Cmp;587 588 if (LHS.getSimpleValueType() == MVT::i16 && isa<ConstantSDNode>(RHS)) {589 uint64_t Imm = RHS->getAsZExtVal();590 // Generate a CPI/CPC pair if RHS is a 16-bit constant. Use the zero591 // register for the constant RHS if its lower or higher byte is zero.592 SDValue LHSlo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, LHS,593 DAG.getIntPtrConstant(0, DL));594 SDValue LHShi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, LHS,595 DAG.getIntPtrConstant(1, DL));596 SDValue RHSlo = (Imm & 0xff) == 0597 ? DAG.getRegister(Subtarget.getZeroRegister(), MVT::i8)598 : DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, RHS,599 DAG.getIntPtrConstant(0, DL));600 SDValue RHShi = (Imm & 0xff00) == 0601 ? DAG.getRegister(Subtarget.getZeroRegister(), MVT::i8)602 : DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, RHS,603 DAG.getIntPtrConstant(1, DL));604 Cmp = DAG.getNode(AVRISD::CMP, DL, MVT::Glue, LHSlo, RHSlo);605 Cmp = DAG.getNode(AVRISD::CMPC, DL, MVT::Glue, LHShi, RHShi, Cmp);606 } else if (RHS.getSimpleValueType() == MVT::i16 && isa<ConstantSDNode>(LHS)) {607 // Generate a CPI/CPC pair if LHS is a 16-bit constant. Use the zero608 // register for the constant LHS if its lower or higher byte is zero.609 uint64_t Imm = LHS->getAsZExtVal();610 SDValue LHSlo = (Imm & 0xff) == 0611 ? DAG.getRegister(Subtarget.getZeroRegister(), MVT::i8)612 : DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, LHS,613 DAG.getIntPtrConstant(0, DL));614 SDValue LHShi = (Imm & 0xff00) == 0615 ? DAG.getRegister(Subtarget.getZeroRegister(), MVT::i8)616 : DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, LHS,617 DAG.getIntPtrConstant(1, DL));618 SDValue RHSlo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, RHS,619 DAG.getIntPtrConstant(0, DL));620 SDValue RHShi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, RHS,621 DAG.getIntPtrConstant(1, DL));622 Cmp = DAG.getNode(AVRISD::CMP, DL, MVT::Glue, LHSlo, RHSlo);623 Cmp = DAG.getNode(AVRISD::CMPC, DL, MVT::Glue, LHShi, RHShi, Cmp);624 } else {625 // Generate ordinary 16-bit comparison.626 Cmp = DAG.getNode(AVRISD::CMP, DL, MVT::Glue, LHS, RHS);627 }628 629 return Cmp;630}631 632/// Returns appropriate AVR CMP/CMPC nodes and corresponding condition code for633/// the given operands.634SDValue AVRTargetLowering::getAVRCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,635 SDValue &AVRcc, SelectionDAG &DAG,636 SDLoc DL) const {637 SDValue Cmp;638 EVT VT = LHS.getValueType();639 bool UseTest = false;640 641 switch (CC) {642 default:643 break;644 case ISD::SETLE: {645 // Swap operands and reverse the branching condition.646 std::swap(LHS, RHS);647 CC = ISD::SETGE;648 break;649 }650 case ISD::SETGT: {651 if (const ConstantSDNode *C = dyn_cast<ConstantSDNode>(RHS)) {652 switch (C->getSExtValue()) {653 case -1: {654 // When doing lhs > -1 use a tst instruction on the top part of lhs655 // and use brpl instead of using a chain of cp/cpc.656 UseTest = true;657 AVRcc = DAG.getConstant(AVRCC::COND_PL, DL, MVT::i8);658 break;659 }660 case 0: {661 // Turn lhs > 0 into 0 < lhs since 0 can be materialized with662 // __zero_reg__ in lhs.663 RHS = LHS;664 LHS = DAG.getConstant(0, DL, VT);665 CC = ISD::SETLT;666 break;667 }668 default: {669 // Turn lhs < rhs with lhs constant into rhs >= lhs+1, this allows670 // us to fold the constant into the cmp instruction.671 RHS = DAG.getSignedConstant(C->getSExtValue() + 1, DL, VT);672 CC = ISD::SETGE;673 break;674 }675 }676 break;677 }678 // Swap operands and reverse the branching condition.679 std::swap(LHS, RHS);680 CC = ISD::SETLT;681 break;682 }683 case ISD::SETLT: {684 if (const ConstantSDNode *C = dyn_cast<ConstantSDNode>(RHS)) {685 switch (C->getSExtValue()) {686 case 1: {687 // Turn lhs < 1 into 0 >= lhs since 0 can be materialized with688 // __zero_reg__ in lhs.689 RHS = LHS;690 LHS = DAG.getConstant(0, DL, VT);691 CC = ISD::SETGE;692 break;693 }694 case 0: {695 // When doing lhs < 0 use a tst instruction on the top part of lhs696 // and use brmi instead of using a chain of cp/cpc.697 UseTest = true;698 AVRcc = DAG.getConstant(AVRCC::COND_MI, DL, MVT::i8);699 break;700 }701 }702 }703 break;704 }705 case ISD::SETULE: {706 // Swap operands and reverse the branching condition.707 std::swap(LHS, RHS);708 CC = ISD::SETUGE;709 break;710 }711 case ISD::SETUGT: {712 // Turn lhs < rhs with lhs constant into rhs >= lhs+1, this allows us to713 // fold the constant into the cmp instruction.714 if (const ConstantSDNode *C = dyn_cast<ConstantSDNode>(RHS)) {715 // Doing a "icmp ugt i16 65535, %0" comparison should have been converted716 // already to something else. Assert to make sure this assumption holds.717 assert((!C->isAllOnes()) && "integer overflow in comparison transform");718 RHS = DAG.getConstant(C->getZExtValue() + 1, DL, VT);719 CC = ISD::SETUGE;720 break;721 }722 // Swap operands and reverse the branching condition.723 std::swap(LHS, RHS);724 CC = ISD::SETULT;725 break;726 }727 }728 729 // Expand 32 and 64 bit comparisons with custom CMP and CMPC nodes instead of730 // using the default and/or/xor expansion code which is much longer.731 if (VT == MVT::i32) {732 SDValue LHSlo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i16, LHS,733 DAG.getIntPtrConstant(0, DL));734 SDValue LHShi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i16, LHS,735 DAG.getIntPtrConstant(1, DL));736 SDValue RHSlo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i16, RHS,737 DAG.getIntPtrConstant(0, DL));738 SDValue RHShi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i16, RHS,739 DAG.getIntPtrConstant(1, DL));740 741 if (UseTest) {742 // When using tst we only care about the highest part.743 SDValue Top = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, LHShi,744 DAG.getIntPtrConstant(1, DL));745 Cmp = DAG.getNode(AVRISD::TST, DL, MVT::Glue, Top);746 } else {747 Cmp = getAVRCmp(LHSlo, RHSlo, DAG, DL);748 Cmp = DAG.getNode(AVRISD::CMPC, DL, MVT::Glue, LHShi, RHShi, Cmp);749 }750 } else if (VT == MVT::i64) {751 SDValue LHS_0 = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, LHS,752 DAG.getIntPtrConstant(0, DL));753 SDValue LHS_1 = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, LHS,754 DAG.getIntPtrConstant(1, DL));755 756 SDValue LHS0 = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i16, LHS_0,757 DAG.getIntPtrConstant(0, DL));758 SDValue LHS1 = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i16, LHS_0,759 DAG.getIntPtrConstant(1, DL));760 SDValue LHS2 = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i16, LHS_1,761 DAG.getIntPtrConstant(0, DL));762 SDValue LHS3 = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i16, LHS_1,763 DAG.getIntPtrConstant(1, DL));764 765 SDValue RHS_0 = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, RHS,766 DAG.getIntPtrConstant(0, DL));767 SDValue RHS_1 = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, RHS,768 DAG.getIntPtrConstant(1, DL));769 770 SDValue RHS0 = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i16, RHS_0,771 DAG.getIntPtrConstant(0, DL));772 SDValue RHS1 = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i16, RHS_0,773 DAG.getIntPtrConstant(1, DL));774 SDValue RHS2 = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i16, RHS_1,775 DAG.getIntPtrConstant(0, DL));776 SDValue RHS3 = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i16, RHS_1,777 DAG.getIntPtrConstant(1, DL));778 779 if (UseTest) {780 // When using tst we only care about the highest part.781 SDValue Top = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8, LHS3,782 DAG.getIntPtrConstant(1, DL));783 Cmp = DAG.getNode(AVRISD::TST, DL, MVT::Glue, Top);784 } else {785 Cmp = getAVRCmp(LHS0, RHS0, DAG, DL);786 Cmp = DAG.getNode(AVRISD::CMPC, DL, MVT::Glue, LHS1, RHS1, Cmp);787 Cmp = DAG.getNode(AVRISD::CMPC, DL, MVT::Glue, LHS2, RHS2, Cmp);788 Cmp = DAG.getNode(AVRISD::CMPC, DL, MVT::Glue, LHS3, RHS3, Cmp);789 }790 } else if (VT == MVT::i8 || VT == MVT::i16) {791 if (UseTest) {792 // When using tst we only care about the highest part.793 Cmp = DAG.getNode(AVRISD::TST, DL, MVT::Glue,794 (VT == MVT::i8)795 ? LHS796 : DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i8,797 LHS, DAG.getIntPtrConstant(1, DL)));798 } else {799 Cmp = getAVRCmp(LHS, RHS, DAG, DL);800 }801 } else {802 llvm_unreachable("Invalid comparison size");803 }804 805 // When using a test instruction AVRcc is already set.806 if (!UseTest) {807 AVRcc = DAG.getConstant(intCCToAVRCC(CC), DL, MVT::i8);808 }809 810 return Cmp;811}812 813SDValue AVRTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {814 SDValue Chain = Op.getOperand(0);815 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();816 SDValue LHS = Op.getOperand(2);817 SDValue RHS = Op.getOperand(3);818 SDValue Dest = Op.getOperand(4);819 SDLoc dl(Op);820 821 SDValue TargetCC;822 SDValue Cmp = getAVRCmp(LHS, RHS, CC, TargetCC, DAG, dl);823 824 return DAG.getNode(AVRISD::BRCOND, dl, MVT::Other, Chain, Dest, TargetCC,825 Cmp);826}827 828SDValue AVRTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {829 SDValue LHS = Op.getOperand(0);830 SDValue RHS = Op.getOperand(1);831 SDValue TrueV = Op.getOperand(2);832 SDValue FalseV = Op.getOperand(3);833 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();834 SDLoc dl(Op);835 836 SDValue TargetCC;837 SDValue Cmp = getAVRCmp(LHS, RHS, CC, TargetCC, DAG, dl);838 839 SDValue Ops[] = {TrueV, FalseV, TargetCC, Cmp};840 841 return DAG.getNode(AVRISD::SELECT_CC, dl, Op.getValueType(), Ops);842}843 844SDValue AVRTargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {845 SDValue LHS = Op.getOperand(0);846 SDValue RHS = Op.getOperand(1);847 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();848 SDLoc DL(Op);849 850 SDValue TargetCC;851 SDValue Cmp = getAVRCmp(LHS, RHS, CC, TargetCC, DAG, DL);852 853 SDValue TrueV = DAG.getConstant(1, DL, Op.getValueType());854 SDValue FalseV = DAG.getConstant(0, DL, Op.getValueType());855 SDValue Ops[] = {TrueV, FalseV, TargetCC, Cmp};856 857 return DAG.getNode(AVRISD::SELECT_CC, DL, Op.getValueType(), Ops);858}859 860SDValue AVRTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const {861 const MachineFunction &MF = DAG.getMachineFunction();862 const AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>();863 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();864 auto DL = DAG.getDataLayout();865 SDLoc dl(Op);866 867 // Vastart just stores the address of the VarArgsFrameIndex slot into the868 // memory location argument.869 SDValue FI = DAG.getFrameIndex(AFI->getVarArgsFrameIndex(), getPointerTy(DL));870 871 return DAG.getStore(Op.getOperand(0), dl, FI, Op.getOperand(1),872 MachinePointerInfo(SV));873}874 875// Modify the existing ISD::INLINEASM node to add the implicit zero register.876SDValue AVRTargetLowering::LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const {877 SDValue ZeroReg = DAG.getRegister(Subtarget.getZeroRegister(), MVT::i8);878 if (Op.getOperand(Op.getNumOperands() - 1) == ZeroReg ||879 Op.getOperand(Op.getNumOperands() - 2) == ZeroReg) {880 // Zero register has already been added. Don't add it again.881 // If this isn't handled, we get called over and over again.882 return Op;883 }884 885 // Get a list of operands to the new INLINEASM node. This is mostly a copy,886 // with some edits.887 // Add the following operands at the end (but before the glue node, if it's888 // there):889 // - The flags of the implicit zero register operand.890 // - The implicit zero register operand itself.891 SDLoc dl(Op);892 SmallVector<SDValue, 8> Ops;893 SDNode *N = Op.getNode();894 SDValue Glue;895 for (unsigned I = 0; I < N->getNumOperands(); I++) {896 SDValue Operand = N->getOperand(I);897 if (Operand.getValueType() == MVT::Glue) {898 // The glue operand always needs to be at the end, so we need to treat it899 // specially.900 Glue = Operand;901 } else {902 Ops.push_back(Operand);903 }904 }905 InlineAsm::Flag Flags(InlineAsm::Kind::RegUse, 1);906 Ops.push_back(DAG.getTargetConstant(Flags, dl, MVT::i32));907 Ops.push_back(ZeroReg);908 if (Glue) {909 Ops.push_back(Glue);910 }911 912 // Replace the current INLINEASM node with a new one that has the zero913 // register as implicit parameter.914 SDValue New = DAG.getNode(N->getOpcode(), dl, N->getVTList(), Ops);915 DAG.ReplaceAllUsesOfValueWith(Op, New);916 DAG.ReplaceAllUsesOfValueWith(Op.getValue(1), New.getValue(1));917 918 return New;919}920 921SDValue AVRTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {922 switch (Op.getOpcode()) {923 default:924 llvm_unreachable("Don't know how to custom lower this!");925 case ISD::SHL:926 case ISD::SRA:927 case ISD::SRL:928 case ISD::ROTL:929 case ISD::ROTR:930 return LowerShifts(Op, DAG);931 case ISD::GlobalAddress:932 return LowerGlobalAddress(Op, DAG);933 case ISD::BlockAddress:934 return LowerBlockAddress(Op, DAG);935 case ISD::BR_CC:936 return LowerBR_CC(Op, DAG);937 case ISD::SELECT_CC:938 return LowerSELECT_CC(Op, DAG);939 case ISD::SETCC:940 return LowerSETCC(Op, DAG);941 case ISD::VASTART:942 return LowerVASTART(Op, DAG);943 case ISD::SDIVREM:944 case ISD::UDIVREM:945 return LowerDivRem(Op, DAG);946 case ISD::INLINEASM:947 return LowerINLINEASM(Op, DAG);948 }949 950 return SDValue();951}952 953/// Replace a node with an illegal result type954/// with a new node built out of custom code.955void AVRTargetLowering::ReplaceNodeResults(SDNode *N,956 SmallVectorImpl<SDValue> &Results,957 SelectionDAG &DAG) const {958 SDLoc DL(N);959 960 switch (N->getOpcode()) {961 case ISD::ADD: {962 // Convert add (x, imm) into sub (x, -imm).963 if (const ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1))) {964 SDValue Sub = DAG.getNode(965 ISD::SUB, DL, N->getValueType(0), N->getOperand(0),966 DAG.getConstant(-C->getAPIntValue(), DL, C->getValueType(0)));967 Results.push_back(Sub);968 }969 break;970 }971 default: {972 SDValue Res = LowerOperation(SDValue(N, 0), DAG);973 974 for (unsigned I = 0, E = Res->getNumValues(); I != E; ++I)975 Results.push_back(Res.getValue(I));976 977 break;978 }979 }980}981 982/// Return true if the addressing mode represented983/// by AM is legal for this target, for a load/store of the specified type.984bool AVRTargetLowering::isLegalAddressingMode(const DataLayout &DL,985 const AddrMode &AM, Type *Ty,986 unsigned AS,987 Instruction *I) const {988 int64_t Offs = AM.BaseOffs;989 990 // Allow absolute addresses.991 if (AM.BaseGV && !AM.HasBaseReg && AM.Scale == 0 && Offs == 0) {992 return true;993 }994 995 // Flash memory instructions only allow zero offsets.996 if (isa<PointerType>(Ty) && AS == AVR::ProgramMemory) {997 return false;998 }999 1000 // Allow reg+<6bit> offset.1001 if (Offs < 0)1002 Offs = -Offs;1003 if (AM.BaseGV == nullptr && AM.HasBaseReg && AM.Scale == 0 &&1004 isUInt<6>(Offs)) {1005 return true;1006 }1007 1008 return false;1009}1010 1011/// Returns true by value, base pointer and1012/// offset pointer and addressing mode by reference if the node's address1013/// can be legally represented as pre-indexed load / store address.1014bool AVRTargetLowering::getPreIndexedAddressParts(SDNode *N, SDValue &Base,1015 SDValue &Offset,1016 ISD::MemIndexedMode &AM,1017 SelectionDAG &DAG) const {1018 EVT VT;1019 const SDNode *Op;1020 SDLoc DL(N);1021 1022 if (const LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {1023 VT = LD->getMemoryVT();1024 Op = LD->getBasePtr().getNode();1025 if (LD->getExtensionType() != ISD::NON_EXTLOAD)1026 return false;1027 if (AVR::isProgramMemoryAccess(LD)) {1028 return false;1029 }1030 } else if (const StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {1031 VT = ST->getMemoryVT();1032 Op = ST->getBasePtr().getNode();1033 if (AVR::isProgramMemoryAccess(ST)) {1034 return false;1035 }1036 } else {1037 return false;1038 }1039 1040 if (VT != MVT::i8 && VT != MVT::i16) {1041 return false;1042 }1043 1044 if (Op->getOpcode() != ISD::ADD && Op->getOpcode() != ISD::SUB) {1045 return false;1046 }1047 1048 if (const ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1))) {1049 int RHSC = RHS->getSExtValue();1050 if (Op->getOpcode() == ISD::SUB)1051 RHSC = -RHSC;1052 1053 if ((VT == MVT::i16 && RHSC != -2) || (VT == MVT::i8 && RHSC != -1)) {1054 return false;1055 }1056 1057 Base = Op->getOperand(0);1058 Offset = DAG.getSignedConstant(RHSC, DL, MVT::i8);1059 AM = ISD::PRE_DEC;1060 1061 return true;1062 }1063 1064 return false;1065}1066 1067/// Returns true by value, base pointer and1068/// offset pointer and addressing mode by reference if this node can be1069/// combined with a load / store to form a post-indexed load / store.1070bool AVRTargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,1071 SDValue &Base,1072 SDValue &Offset,1073 ISD::MemIndexedMode &AM,1074 SelectionDAG &DAG) const {1075 EVT VT;1076 SDValue Ptr;1077 SDLoc DL(N);1078 1079 if (const LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {1080 VT = LD->getMemoryVT();1081 Ptr = LD->getBasePtr();1082 if (LD->getExtensionType() != ISD::NON_EXTLOAD)1083 return false;1084 } else if (const StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {1085 VT = ST->getMemoryVT();1086 Ptr = ST->getBasePtr();1087 // We can not store to program memory.1088 if (AVR::isProgramMemoryAccess(ST))1089 return false;1090 // Since the high byte need to be stored first, we can not emit1091 // i16 post increment store like:1092 // st X+, r241093 // st X+, r251094 if (VT == MVT::i16 && !Subtarget.hasLowByteFirst())1095 return false;1096 } else {1097 return false;1098 }1099 1100 if (VT != MVT::i8 && VT != MVT::i16) {1101 return false;1102 }1103 1104 if (Op->getOpcode() != ISD::ADD && Op->getOpcode() != ISD::SUB) {1105 return false;1106 }1107 1108 if (const ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1))) {1109 int RHSC = RHS->getSExtValue();1110 if (Op->getOpcode() == ISD::SUB)1111 RHSC = -RHSC;1112 if ((VT == MVT::i16 && RHSC != 2) || (VT == MVT::i8 && RHSC != 1)) {1113 return false;1114 }1115 1116 // FIXME: We temporarily disable post increment load from program memory,1117 // due to bug https://github.com/llvm/llvm-project/issues/59914.1118 if (const LoadSDNode *LD = dyn_cast<LoadSDNode>(N))1119 if (AVR::isProgramMemoryAccess(LD))1120 return false;1121 1122 Base = Op->getOperand(0);1123 1124 // Post-indexing updates the base, so it's not a valid transform1125 // if that's not the same as the load's pointer.1126 if (Ptr != Base)1127 return false;1128 1129 Offset = DAG.getConstant(RHSC, DL, MVT::i8);1130 AM = ISD::POST_INC;1131 1132 return true;1133 }1134 1135 return false;1136}1137 1138bool AVRTargetLowering::isOffsetFoldingLegal(1139 const GlobalAddressSDNode *GA) const {1140 return true;1141}1142 1143//===----------------------------------------------------------------------===//1144// Formal Arguments Calling Convention Implementation1145//===----------------------------------------------------------------------===//1146 1147#include "AVRGenCallingConv.inc"1148 1149/// Registers for calling conventions, ordered in reverse as required by ABI.1150/// Both arrays must be of the same length.1151static const MCPhysReg RegList8AVR[] = {1152 AVR::R25, AVR::R24, AVR::R23, AVR::R22, AVR::R21, AVR::R20,1153 AVR::R19, AVR::R18, AVR::R17, AVR::R16, AVR::R15, AVR::R14,1154 AVR::R13, AVR::R12, AVR::R11, AVR::R10, AVR::R9, AVR::R8};1155static const MCPhysReg RegList8Tiny[] = {AVR::R25, AVR::R24, AVR::R23,1156 AVR::R22, AVR::R21, AVR::R20};1157static const MCPhysReg RegList16AVR[] = {1158 AVR::R26R25, AVR::R25R24, AVR::R24R23, AVR::R23R22, AVR::R22R21,1159 AVR::R21R20, AVR::R20R19, AVR::R19R18, AVR::R18R17, AVR::R17R16,1160 AVR::R16R15, AVR::R15R14, AVR::R14R13, AVR::R13R12, AVR::R12R11,1161 AVR::R11R10, AVR::R10R9, AVR::R9R8};1162static const MCPhysReg RegList16Tiny[] = {AVR::R26R25, AVR::R25R24,1163 AVR::R24R23, AVR::R23R22,1164 AVR::R22R21, AVR::R21R20};1165 1166static_assert(std::size(RegList8AVR) == std::size(RegList16AVR),1167 "8-bit and 16-bit register arrays must be of equal length");1168static_assert(std::size(RegList8Tiny) == std::size(RegList16Tiny),1169 "8-bit and 16-bit register arrays must be of equal length");1170 1171/// Analyze incoming and outgoing function arguments. We need custom C++ code1172/// to handle special constraints in the ABI.1173/// In addition, all pieces of a certain argument have to be passed either1174/// using registers or the stack but never mixing both.1175template <typename ArgT>1176static void analyzeArguments(TargetLowering::CallLoweringInfo *CLI,1177 const Function *F, const DataLayout *TD,1178 const SmallVectorImpl<ArgT> &Args,1179 SmallVectorImpl<CCValAssign> &ArgLocs,1180 CCState &CCInfo, bool Tiny) {1181 // Choose the proper register list for argument passing according to the ABI.1182 ArrayRef<MCPhysReg> RegList8;1183 ArrayRef<MCPhysReg> RegList16;1184 if (Tiny) {1185 RegList8 = ArrayRef(RegList8Tiny);1186 RegList16 = ArrayRef(RegList16Tiny);1187 } else {1188 RegList8 = ArrayRef(RegList8AVR);1189 RegList16 = ArrayRef(RegList16AVR);1190 }1191 1192 unsigned NumArgs = Args.size();1193 // This is the index of the last used register, in RegList*.1194 // -1 means R26 (R26 is never actually used in CC).1195 int RegLastIdx = -1;1196 // Once a value is passed to the stack it will always be used1197 bool UseStack = false;1198 for (unsigned i = 0; i != NumArgs;) {1199 MVT VT = Args[i].VT;1200 // We have to count the number of bytes for each function argument, that is1201 // those Args with the same OrigArgIndex. This is important in case the1202 // function takes an aggregate type.1203 // Current argument will be between [i..j).1204 unsigned ArgIndex = Args[i].OrigArgIndex;1205 unsigned TotalBytes = VT.getStoreSize();1206 unsigned j = i + 1;1207 for (; j != NumArgs; ++j) {1208 if (Args[j].OrigArgIndex != ArgIndex)1209 break;1210 TotalBytes += Args[j].VT.getStoreSize();1211 }1212 // Round up to even number of bytes.1213 TotalBytes = alignTo(TotalBytes, 2);1214 // Skip zero sized arguments1215 if (TotalBytes == 0)1216 continue;1217 // The index of the first register to be used1218 unsigned RegIdx = RegLastIdx + TotalBytes;1219 RegLastIdx = RegIdx;1220 // If there are not enough registers, use the stack1221 if (RegIdx >= RegList8.size()) {1222 UseStack = true;1223 }1224 for (; i != j; ++i) {1225 MVT VT = Args[i].VT;1226 1227 if (UseStack) {1228 auto evt = EVT(VT).getTypeForEVT(CCInfo.getContext());1229 unsigned Offset = CCInfo.AllocateStack(TD->getTypeAllocSize(evt),1230 TD->getABITypeAlign(evt));1231 CCInfo.addLoc(1232 CCValAssign::getMem(i, VT, Offset, VT, CCValAssign::Full));1233 } else {1234 unsigned Reg;1235 if (VT == MVT::i8) {1236 Reg = CCInfo.AllocateReg(RegList8[RegIdx]);1237 } else if (VT == MVT::i16) {1238 Reg = CCInfo.AllocateReg(RegList16[RegIdx]);1239 } else {1240 llvm_unreachable(1241 "calling convention can only manage i8 and i16 types");1242 }1243 assert(Reg && "register not available in calling convention");1244 CCInfo.addLoc(CCValAssign::getReg(i, VT, Reg, VT, CCValAssign::Full));1245 // Registers inside a particular argument are sorted in increasing order1246 // (remember the array is reversed).1247 RegIdx -= VT.getStoreSize();1248 }1249 }1250 }1251}1252 1253/// Count the total number of bytes needed to pass or return these arguments.1254template <typename ArgT>1255static unsigned1256getTotalArgumentsSizeInBytes(const SmallVectorImpl<ArgT> &Args) {1257 unsigned TotalBytes = 0;1258 1259 for (const ArgT &Arg : Args) {1260 TotalBytes += Arg.VT.getStoreSize();1261 }1262 return TotalBytes;1263}1264 1265/// Analyze incoming and outgoing value of returning from a function.1266/// The algorithm is similar to analyzeArguments, but there can only be1267/// one value, possibly an aggregate, and it is limited to 8 bytes.1268template <typename ArgT>1269static void analyzeReturnValues(const SmallVectorImpl<ArgT> &Args,1270 CCState &CCInfo, bool Tiny) {1271 unsigned NumArgs = Args.size();1272 unsigned TotalBytes = getTotalArgumentsSizeInBytes(Args);1273 // CanLowerReturn() guarantees this assertion.1274 if (Tiny)1275 assert(TotalBytes <= 4 &&1276 "return values greater than 4 bytes cannot be lowered on AVRTiny");1277 else1278 assert(TotalBytes <= 8 &&1279 "return values greater than 8 bytes cannot be lowered on AVR");1280 1281 // Choose the proper register list for argument passing according to the ABI.1282 ArrayRef<MCPhysReg> RegList8;1283 ArrayRef<MCPhysReg> RegList16;1284 if (Tiny) {1285 RegList8 = ArrayRef(RegList8Tiny);1286 RegList16 = ArrayRef(RegList16Tiny);1287 } else {1288 RegList8 = ArrayRef(RegList8AVR);1289 RegList16 = ArrayRef(RegList16AVR);1290 }1291 1292 // GCC-ABI says that the size is rounded up to the next even number,1293 // but actually once it is more than 4 it will always round up to 8.1294 if (TotalBytes > 4) {1295 TotalBytes = 8;1296 } else {1297 TotalBytes = alignTo(TotalBytes, 2);1298 }1299 1300 // The index of the first register to use.1301 int RegIdx = TotalBytes - 1;1302 for (unsigned i = 0; i != NumArgs; ++i) {1303 MVT VT = Args[i].VT;1304 unsigned Reg;1305 if (VT == MVT::i8) {1306 Reg = CCInfo.AllocateReg(RegList8[RegIdx]);1307 } else if (VT == MVT::i16) {1308 Reg = CCInfo.AllocateReg(RegList16[RegIdx]);1309 } else {1310 llvm_unreachable("calling convention can only manage i8 and i16 types");1311 }1312 assert(Reg && "register not available in calling convention");1313 CCInfo.addLoc(CCValAssign::getReg(i, VT, Reg, VT, CCValAssign::Full));1314 // Registers sort in increasing order1315 RegIdx -= VT.getStoreSize();1316 }1317}1318 1319SDValue AVRTargetLowering::LowerFormalArguments(1320 SDValue Chain, CallingConv::ID CallConv, bool isVarArg,1321 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,1322 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {1323 MachineFunction &MF = DAG.getMachineFunction();1324 MachineFrameInfo &MFI = MF.getFrameInfo();1325 auto DL = DAG.getDataLayout();1326 1327 // Assign locations to all of the incoming arguments.1328 SmallVector<CCValAssign, 16> ArgLocs;1329 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,1330 *DAG.getContext());1331 1332 // Variadic functions do not need all the analysis below.1333 if (isVarArg) {1334 CCInfo.AnalyzeFormalArguments(Ins, ArgCC_AVR_Vararg);1335 } else {1336 analyzeArguments(nullptr, &MF.getFunction(), &DL, Ins, ArgLocs, CCInfo,1337 Subtarget.hasTinyEncoding());1338 }1339 1340 SDValue ArgValue;1341 for (CCValAssign &VA : ArgLocs) {1342 1343 // Arguments stored on registers.1344 if (VA.isRegLoc()) {1345 EVT RegVT = VA.getLocVT();1346 const TargetRegisterClass *RC;1347 if (RegVT == MVT::i8) {1348 RC = &AVR::GPR8RegClass;1349 } else if (RegVT == MVT::i16) {1350 RC = &AVR::DREGSRegClass;1351 } else {1352 llvm_unreachable("Unknown argument type!");1353 }1354 1355 Register Reg = MF.addLiveIn(VA.getLocReg(), RC);1356 ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, RegVT);1357 1358 // :NOTE: Clang should not promote any i8 into i16 but for safety the1359 // following code will handle zexts or sexts generated by other1360 // front ends. Otherwise:1361 // If this is an 8 bit value, it is really passed promoted1362 // to 16 bits. Insert an assert[sz]ext to capture this, then1363 // truncate to the right size.1364 switch (VA.getLocInfo()) {1365 default:1366 llvm_unreachable("Unknown loc info!");1367 case CCValAssign::Full:1368 break;1369 case CCValAssign::BCvt:1370 ArgValue = DAG.getNode(ISD::BITCAST, dl, VA.getValVT(), ArgValue);1371 break;1372 case CCValAssign::SExt:1373 ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue,1374 DAG.getValueType(VA.getValVT()));1375 ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);1376 break;1377 case CCValAssign::ZExt:1378 ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue,1379 DAG.getValueType(VA.getValVT()));1380 ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);1381 break;1382 }1383 1384 InVals.push_back(ArgValue);1385 } else {1386 // Only arguments passed on the stack should make it here.1387 assert(VA.isMemLoc());1388 1389 EVT LocVT = VA.getLocVT();1390 1391 // Create the frame index object for this incoming parameter.1392 int FI = MFI.CreateFixedObject(LocVT.getSizeInBits() / 8,1393 VA.getLocMemOffset(), true);1394 1395 // Create the SelectionDAG nodes corresponding to a load1396 // from this parameter.1397 SDValue FIN = DAG.getFrameIndex(FI, getPointerTy(DL));1398 InVals.push_back(DAG.getLoad(LocVT, dl, Chain, FIN,1399 MachinePointerInfo::getFixedStack(MF, FI)));1400 }1401 }1402 1403 // If the function takes variable number of arguments, make a frame index for1404 // the start of the first vararg value... for expansion of llvm.va_start.1405 if (isVarArg) {1406 unsigned StackSize = CCInfo.getStackSize();1407 AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>();1408 1409 AFI->setVarArgsFrameIndex(MFI.CreateFixedObject(2, StackSize, true));1410 }1411 1412 return Chain;1413}1414 1415//===----------------------------------------------------------------------===//1416// Call Calling Convention Implementation1417//===----------------------------------------------------------------------===//1418 1419SDValue AVRTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,1420 SmallVectorImpl<SDValue> &InVals) const {1421 SelectionDAG &DAG = CLI.DAG;1422 SDLoc &DL = CLI.DL;1423 SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;1424 SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;1425 SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;1426 SDValue Chain = CLI.Chain;1427 SDValue Callee = CLI.Callee;1428 bool &isTailCall = CLI.IsTailCall;1429 CallingConv::ID CallConv = CLI.CallConv;1430 bool isVarArg = CLI.IsVarArg;1431 1432 MachineFunction &MF = DAG.getMachineFunction();1433 1434 // AVR does not yet support tail call optimization.1435 isTailCall = false;1436 1437 // Analyze operands of the call, assigning locations to each operand.1438 SmallVector<CCValAssign, 16> ArgLocs;1439 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,1440 *DAG.getContext());1441 1442 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every1443 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol1444 // node so that legalize doesn't hack it.1445 const Function *F = nullptr;1446 if (const GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {1447 const GlobalValue *GV = G->getGlobal();1448 if (isa<Function>(GV))1449 F = cast<Function>(GV);1450 Callee =1451 DAG.getTargetGlobalAddress(GV, DL, getPointerTy(DAG.getDataLayout()));1452 } else if (const ExternalSymbolSDNode *ES =1453 dyn_cast<ExternalSymbolSDNode>(Callee)) {1454 Callee = DAG.getTargetExternalSymbol(ES->getSymbol(),1455 getPointerTy(DAG.getDataLayout()));1456 }1457 1458 // Variadic functions do not need all the analysis below.1459 if (isVarArg) {1460 CCInfo.AnalyzeCallOperands(Outs, ArgCC_AVR_Vararg);1461 } else {1462 analyzeArguments(&CLI, F, &DAG.getDataLayout(), Outs, ArgLocs, CCInfo,1463 Subtarget.hasTinyEncoding());1464 }1465 1466 // Get a count of how many bytes are to be pushed on the stack.1467 unsigned NumBytes = CCInfo.getStackSize();1468 1469 Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, DL);1470 1471 SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass;1472 1473 // First, walk the register assignments, inserting copies.1474 unsigned AI, AE;1475 bool HasStackArgs = false;1476 for (AI = 0, AE = ArgLocs.size(); AI != AE; ++AI) {1477 CCValAssign &VA = ArgLocs[AI];1478 EVT RegVT = VA.getLocVT();1479 SDValue Arg = OutVals[AI];1480 1481 // Promote the value if needed. With Clang this should not happen.1482 switch (VA.getLocInfo()) {1483 default:1484 llvm_unreachable("Unknown loc info!");1485 case CCValAssign::Full:1486 break;1487 case CCValAssign::SExt:1488 Arg = DAG.getNode(ISD::SIGN_EXTEND, DL, RegVT, Arg);1489 break;1490 case CCValAssign::ZExt:1491 Arg = DAG.getNode(ISD::ZERO_EXTEND, DL, RegVT, Arg);1492 break;1493 case CCValAssign::AExt:1494 Arg = DAG.getNode(ISD::ANY_EXTEND, DL, RegVT, Arg);1495 break;1496 case CCValAssign::BCvt:1497 Arg = DAG.getNode(ISD::BITCAST, DL, RegVT, Arg);1498 break;1499 }1500 1501 // Stop when we encounter a stack argument, we need to process them1502 // in reverse order in the loop below.1503 if (VA.isMemLoc()) {1504 HasStackArgs = true;1505 break;1506 }1507 1508 // Arguments that can be passed on registers must be kept in the RegsToPass1509 // vector.1510 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));1511 }1512 1513 // Second, stack arguments have to walked.1514 // Previously this code created chained stores but those chained stores appear1515 // to be unchained in the legalization phase. Therefore, do not attempt to1516 // chain them here. In fact, chaining them here somehow causes the first and1517 // second store to be reversed which is the exact opposite of the intended1518 // effect.1519 if (HasStackArgs) {1520 SmallVector<SDValue, 8> MemOpChains;1521 for (; AI != AE; AI++) {1522 CCValAssign &VA = ArgLocs[AI];1523 SDValue Arg = OutVals[AI];1524 1525 assert(VA.isMemLoc());1526 1527 // SP points to one stack slot further so add one to adjust it.1528 SDValue PtrOff = DAG.getNode(1529 ISD::ADD, DL, getPointerTy(DAG.getDataLayout()),1530 DAG.getRegister(AVR::SP, getPointerTy(DAG.getDataLayout())),1531 DAG.getIntPtrConstant(VA.getLocMemOffset() + 1, DL));1532 1533 MemOpChains.push_back(1534 DAG.getStore(Chain, DL, Arg, PtrOff,1535 MachinePointerInfo::getStack(MF, VA.getLocMemOffset())));1536 }1537 1538 if (!MemOpChains.empty())1539 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains);1540 }1541 1542 // Build a sequence of copy-to-reg nodes chained together with token chain and1543 // flag operands which copy the outgoing args into registers. The InGlue in1544 // necessary since all emited instructions must be stuck together.1545 SDValue InGlue;1546 for (auto Reg : RegsToPass) {1547 Chain = DAG.getCopyToReg(Chain, DL, Reg.first, Reg.second, InGlue);1548 InGlue = Chain.getValue(1);1549 }1550 1551 // Returns a chain & a flag for retval copy to use.1552 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);1553 SmallVector<SDValue, 8> Ops;1554 Ops.push_back(Chain);1555 Ops.push_back(Callee);1556 1557 // Add argument registers to the end of the list so that they are known live1558 // into the call.1559 for (auto Reg : RegsToPass) {1560 Ops.push_back(DAG.getRegister(Reg.first, Reg.second.getValueType()));1561 }1562 1563 // The zero register (usually R1) must be passed as an implicit register so1564 // that this register is correctly zeroed in interrupts.1565 Ops.push_back(DAG.getRegister(Subtarget.getZeroRegister(), MVT::i8));1566 1567 // Add a register mask operand representing the call-preserved registers.1568 const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();1569 const uint32_t *Mask =1570 TRI->getCallPreservedMask(DAG.getMachineFunction(), CallConv);1571 assert(Mask && "Missing call preserved mask for calling convention");1572 Ops.push_back(DAG.getRegisterMask(Mask));1573 1574 if (InGlue.getNode()) {1575 Ops.push_back(InGlue);1576 }1577 1578 Chain = DAG.getNode(AVRISD::CALL, DL, NodeTys, Ops);1579 InGlue = Chain.getValue(1);1580 1581 // Create the CALLSEQ_END node.1582 Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, InGlue, DL);1583 1584 if (!Ins.empty()) {1585 InGlue = Chain.getValue(1);1586 }1587 1588 // Handle result values, copying them out of physregs into vregs that we1589 // return.1590 return LowerCallResult(Chain, InGlue, CallConv, isVarArg, Ins, DL, DAG,1591 InVals);1592}1593 1594/// Lower the result values of a call into the1595/// appropriate copies out of appropriate physical registers.1596///1597SDValue AVRTargetLowering::LowerCallResult(1598 SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool isVarArg,1599 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,1600 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {1601 1602 // Assign locations to each value returned by this call.1603 SmallVector<CCValAssign, 16> RVLocs;1604 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,1605 *DAG.getContext());1606 1607 // Handle runtime calling convs.1608 if (CallConv == CallingConv::AVR_BUILTIN) {1609 CCInfo.AnalyzeCallResult(Ins, RetCC_AVR_BUILTIN);1610 } else {1611 analyzeReturnValues(Ins, CCInfo, Subtarget.hasTinyEncoding());1612 }1613 1614 // Copy all of the result registers out of their specified physreg.1615 for (CCValAssign const &RVLoc : RVLocs) {1616 Chain = DAG.getCopyFromReg(Chain, dl, RVLoc.getLocReg(), RVLoc.getValVT(),1617 InGlue)1618 .getValue(1);1619 InGlue = Chain.getValue(2);1620 InVals.push_back(Chain.getValue(0));1621 }1622 1623 return Chain;1624}1625 1626//===----------------------------------------------------------------------===//1627// Return Value Calling Convention Implementation1628//===----------------------------------------------------------------------===//1629 1630bool AVRTargetLowering::CanLowerReturn(1631 CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg,1632 const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,1633 const Type *RetTy) const {1634 if (CallConv == CallingConv::AVR_BUILTIN) {1635 SmallVector<CCValAssign, 16> RVLocs;1636 CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);1637 return CCInfo.CheckReturn(Outs, RetCC_AVR_BUILTIN);1638 }1639 1640 unsigned TotalBytes = getTotalArgumentsSizeInBytes(Outs);1641 return TotalBytes <= (unsigned)(Subtarget.hasTinyEncoding() ? 4 : 8);1642}1643 1644SDValue1645AVRTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,1646 bool isVarArg,1647 const SmallVectorImpl<ISD::OutputArg> &Outs,1648 const SmallVectorImpl<SDValue> &OutVals,1649 const SDLoc &dl, SelectionDAG &DAG) const {1650 // CCValAssign - represent the assignment of the return value to locations.1651 SmallVector<CCValAssign, 16> RVLocs;1652 1653 // CCState - Info about the registers and stack slot.1654 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,1655 *DAG.getContext());1656 1657 MachineFunction &MF = DAG.getMachineFunction();1658 1659 // Analyze return values.1660 if (CallConv == CallingConv::AVR_BUILTIN) {1661 CCInfo.AnalyzeReturn(Outs, RetCC_AVR_BUILTIN);1662 } else {1663 analyzeReturnValues(Outs, CCInfo, Subtarget.hasTinyEncoding());1664 }1665 1666 SDValue Glue;1667 SmallVector<SDValue, 4> RetOps(1, Chain);1668 // Copy the result values into the output registers.1669 for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) {1670 CCValAssign &VA = RVLocs[i];1671 assert(VA.isRegLoc() && "Can only return in registers!");1672 1673 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), OutVals[i], Glue);1674 1675 // Guarantee that all emitted copies are stuck together with flags.1676 Glue = Chain.getValue(1);1677 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));1678 }1679 1680 // Don't emit the ret/reti instruction when the naked attribute is present in1681 // the function being compiled.1682 if (MF.getFunction().getAttributes().hasFnAttr(Attribute::Naked)) {1683 return Chain;1684 }1685 1686 const AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>();1687 1688 if (!AFI->isInterruptOrSignalHandler()) {1689 // The return instruction has an implicit zero register operand: it must1690 // contain zero on return.1691 // This is not needed in interrupts however, where the zero register is1692 // handled specially (only pushed/popped when needed).1693 RetOps.push_back(DAG.getRegister(Subtarget.getZeroRegister(), MVT::i8));1694 }1695 1696 unsigned RetOpc =1697 AFI->isInterruptOrSignalHandler() ? AVRISD::RETI_GLUE : AVRISD::RET_GLUE;1698 1699 RetOps[0] = Chain; // Update chain.1700 1701 if (Glue.getNode()) {1702 RetOps.push_back(Glue);1703 }1704 1705 return DAG.getNode(RetOpc, dl, MVT::Other, RetOps);1706}1707 1708//===----------------------------------------------------------------------===//1709// Custom Inserters1710//===----------------------------------------------------------------------===//1711 1712MachineBasicBlock *AVRTargetLowering::insertShift(MachineInstr &MI,1713 MachineBasicBlock *BB,1714 bool Tiny) const {1715 unsigned Opc;1716 const TargetRegisterClass *RC;1717 bool HasRepeatedOperand = false;1718 MachineFunction *F = BB->getParent();1719 MachineRegisterInfo &RI = F->getRegInfo();1720 const TargetInstrInfo &TII = *Subtarget.getInstrInfo();1721 DebugLoc dl = MI.getDebugLoc();1722 1723 switch (MI.getOpcode()) {1724 default:1725 llvm_unreachable("Invalid shift opcode!");1726 case AVR::Lsl8:1727 Opc = AVR::ADDRdRr; // LSL is an alias of ADD Rd, Rd1728 RC = &AVR::GPR8RegClass;1729 HasRepeatedOperand = true;1730 break;1731 case AVR::Lsl16:1732 Opc = AVR::LSLWRd;1733 RC = &AVR::DREGSRegClass;1734 break;1735 case AVR::Asr8:1736 Opc = AVR::ASRRd;1737 RC = &AVR::GPR8RegClass;1738 break;1739 case AVR::Asr16:1740 Opc = AVR::ASRWRd;1741 RC = &AVR::DREGSRegClass;1742 break;1743 case AVR::Lsr8:1744 Opc = AVR::LSRRd;1745 RC = &AVR::GPR8RegClass;1746 break;1747 case AVR::Lsr16:1748 Opc = AVR::LSRWRd;1749 RC = &AVR::DREGSRegClass;1750 break;1751 case AVR::Rol8:1752 Opc = Tiny ? AVR::ROLBRdR17 : AVR::ROLBRdR1;1753 RC = &AVR::GPR8RegClass;1754 break;1755 case AVR::Rol16:1756 Opc = AVR::ROLWRd;1757 RC = &AVR::DREGSRegClass;1758 break;1759 case AVR::Ror8:1760 Opc = AVR::RORBRd;1761 RC = &AVR::GPR8RegClass;1762 break;1763 case AVR::Ror16:1764 Opc = AVR::RORWRd;1765 RC = &AVR::DREGSRegClass;1766 break;1767 }1768 1769 const BasicBlock *LLVM_BB = BB->getBasicBlock();1770 1771 MachineFunction::iterator I;1772 for (I = BB->getIterator(); I != F->end() && &(*I) != BB; ++I)1773 ;1774 if (I != F->end())1775 ++I;1776 1777 // Create loop block.1778 MachineBasicBlock *LoopBB = F->CreateMachineBasicBlock(LLVM_BB);1779 MachineBasicBlock *CheckBB = F->CreateMachineBasicBlock(LLVM_BB);1780 MachineBasicBlock *RemBB = F->CreateMachineBasicBlock(LLVM_BB);1781 1782 F->insert(I, LoopBB);1783 F->insert(I, CheckBB);1784 F->insert(I, RemBB);1785 1786 // Update machine-CFG edges by transferring all successors of the current1787 // block to the block containing instructions after shift.1788 RemBB->splice(RemBB->begin(), BB, std::next(MachineBasicBlock::iterator(MI)),1789 BB->end());1790 RemBB->transferSuccessorsAndUpdatePHIs(BB);1791 1792 // Add edges BB => LoopBB => CheckBB => RemBB, CheckBB => LoopBB.1793 BB->addSuccessor(CheckBB);1794 LoopBB->addSuccessor(CheckBB);1795 CheckBB->addSuccessor(LoopBB);1796 CheckBB->addSuccessor(RemBB);1797 1798 Register ShiftAmtReg = RI.createVirtualRegister(&AVR::GPR8RegClass);1799 Register ShiftAmtReg2 = RI.createVirtualRegister(&AVR::GPR8RegClass);1800 Register ShiftReg = RI.createVirtualRegister(RC);1801 Register ShiftReg2 = RI.createVirtualRegister(RC);1802 Register ShiftAmtSrcReg = MI.getOperand(2).getReg();1803 Register SrcReg = MI.getOperand(1).getReg();1804 Register DstReg = MI.getOperand(0).getReg();1805 1806 // BB:1807 // rjmp CheckBB1808 BuildMI(BB, dl, TII.get(AVR::RJMPk)).addMBB(CheckBB);1809 1810 // LoopBB:1811 // ShiftReg2 = shift ShiftReg1812 auto ShiftMI = BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2).addReg(ShiftReg);1813 if (HasRepeatedOperand)1814 ShiftMI.addReg(ShiftReg);1815 1816 // CheckBB:1817 // ShiftReg = phi [%SrcReg, BB], [%ShiftReg2, LoopBB]1818 // ShiftAmt = phi [%N, BB], [%ShiftAmt2, LoopBB]1819 // DestReg = phi [%SrcReg, BB], [%ShiftReg, LoopBB]1820 // ShiftAmt2 = ShiftAmt - 1;1821 // if (ShiftAmt2 >= 0) goto LoopBB;1822 BuildMI(CheckBB, dl, TII.get(AVR::PHI), ShiftReg)1823 .addReg(SrcReg)1824 .addMBB(BB)1825 .addReg(ShiftReg2)1826 .addMBB(LoopBB);1827 BuildMI(CheckBB, dl, TII.get(AVR::PHI), ShiftAmtReg)1828 .addReg(ShiftAmtSrcReg)1829 .addMBB(BB)1830 .addReg(ShiftAmtReg2)1831 .addMBB(LoopBB);1832 BuildMI(CheckBB, dl, TII.get(AVR::PHI), DstReg)1833 .addReg(SrcReg)1834 .addMBB(BB)1835 .addReg(ShiftReg2)1836 .addMBB(LoopBB);1837 1838 BuildMI(CheckBB, dl, TII.get(AVR::DECRd), ShiftAmtReg2).addReg(ShiftAmtReg);1839 BuildMI(CheckBB, dl, TII.get(AVR::BRPLk)).addMBB(LoopBB);1840 1841 MI.eraseFromParent(); // The pseudo instruction is gone now.1842 return RemBB;1843}1844 1845// Do a multibyte AVR shift. Insert shift instructions and put the output1846// registers in the Regs array.1847// Because AVR does not have a normal shift instruction (only a single bit shift1848// instruction), we have to emulate this behavior with other instructions.1849// It first tries large steps (moving registers around) and then smaller steps1850// like single bit shifts.1851// Large shifts actually reduce the number of shifted registers, so the below1852// algorithms have to work independently of the number of registers that are1853// shifted.1854// For more information and background, see this blogpost:1855// https://aykevl.nl/2021/02/avr-bitshift1856static void insertMultibyteShift(MachineInstr &MI, MachineBasicBlock *BB,1857 MutableArrayRef<std::pair<Register, int>> Regs,1858 ISD::NodeType Opc, int64_t ShiftAmt) {1859 const TargetInstrInfo &TII = *BB->getParent()->getSubtarget().getInstrInfo();1860 const AVRSubtarget &STI = BB->getParent()->getSubtarget<AVRSubtarget>();1861 MachineRegisterInfo &MRI = BB->getParent()->getRegInfo();1862 const DebugLoc &dl = MI.getDebugLoc();1863 1864 const bool ShiftLeft = Opc == ISD::SHL;1865 const bool ArithmeticShift = Opc == ISD::SRA;1866 1867 // Zero a register, for use in later operations.1868 Register ZeroReg = MRI.createVirtualRegister(&AVR::GPR8RegClass);1869 BuildMI(*BB, MI, dl, TII.get(AVR::COPY), ZeroReg)1870 .addReg(STI.getZeroRegister());1871 1872 // Do a shift modulo 6 or 7. This is a bit more complicated than most shifts1873 // and is hard to compose with the rest, so these are special cased.1874 // The basic idea is to shift one or two bits in the opposite direction and1875 // then move registers around to get the correct end result.1876 if (ShiftLeft && (ShiftAmt % 8) >= 6) {1877 // Left shift modulo 6 or 7.1878 1879 // Create a slice of the registers we're going to modify, to ease working1880 // with them.1881 size_t ShiftRegsOffset = ShiftAmt / 8;1882 size_t ShiftRegsSize = Regs.size() - ShiftRegsOffset;1883 MutableArrayRef<std::pair<Register, int>> ShiftRegs =1884 Regs.slice(ShiftRegsOffset, ShiftRegsSize);1885 1886 // Shift one to the right, keeping the least significant bit as the carry1887 // bit.1888 insertMultibyteShift(MI, BB, ShiftRegs, ISD::SRL, 1);1889 1890 // Rotate the least significant bit from the carry bit into a new register1891 // (that starts out zero).1892 Register LowByte = MRI.createVirtualRegister(&AVR::GPR8RegClass);1893 BuildMI(*BB, MI, dl, TII.get(AVR::RORRd), LowByte).addReg(ZeroReg);1894 1895 // Shift one more to the right if this is a modulo-6 shift.1896 if (ShiftAmt % 8 == 6) {1897 insertMultibyteShift(MI, BB, ShiftRegs, ISD::SRL, 1);1898 Register NewLowByte = MRI.createVirtualRegister(&AVR::GPR8RegClass);1899 BuildMI(*BB, MI, dl, TII.get(AVR::RORRd), NewLowByte).addReg(LowByte);1900 LowByte = NewLowByte;1901 }1902 1903 // Move all registers to the left, zeroing the bottom registers as needed.1904 for (size_t I = 0; I < Regs.size(); I++) {1905 int ShiftRegsIdx = I + 1;1906 if (ShiftRegsIdx < (int)ShiftRegs.size()) {1907 Regs[I] = ShiftRegs[ShiftRegsIdx];1908 } else if (ShiftRegsIdx == (int)ShiftRegs.size()) {1909 Regs[I] = std::pair(LowByte, 0);1910 } else {1911 Regs[I] = std::pair(ZeroReg, 0);1912 }1913 }1914 1915 return;1916 }1917 1918 // Right shift modulo 6 or 7.1919 if (!ShiftLeft && (ShiftAmt % 8) >= 6) {1920 // Create a view on the registers we're going to modify, to ease working1921 // with them.1922 size_t ShiftRegsSize = Regs.size() - (ShiftAmt / 8);1923 MutableArrayRef<std::pair<Register, int>> ShiftRegs =1924 Regs.slice(0, ShiftRegsSize);1925 1926 // Shift one to the left.1927 insertMultibyteShift(MI, BB, ShiftRegs, ISD::SHL, 1);1928 1929 // Sign or zero extend the most significant register into a new register.1930 // The HighByte is the byte that still has one (or two) bits from the1931 // original value. The ExtByte is purely a zero/sign extend byte (all bits1932 // are either 0 or 1).1933 Register HighByte = MRI.createVirtualRegister(&AVR::GPR8RegClass);1934 Register ExtByte = 0;1935 if (ArithmeticShift) {1936 // Sign-extend bit that was shifted out last.1937 BuildMI(*BB, MI, dl, TII.get(AVR::SBCRdRr), HighByte)1938 .addReg(HighByte, RegState::Undef)1939 .addReg(HighByte, RegState::Undef);1940 ExtByte = HighByte;1941 // The highest bit of the original value is the same as the zero-extend1942 // byte, so HighByte and ExtByte are the same.1943 } else {1944 // Use the zero register for zero extending.1945 ExtByte = ZeroReg;1946 // Rotate most significant bit into a new register (that starts out zero).1947 BuildMI(*BB, MI, dl, TII.get(AVR::ADCRdRr), HighByte)1948 .addReg(ExtByte)1949 .addReg(ExtByte);1950 }1951 1952 // Shift one more to the left for modulo 6 shifts.1953 if (ShiftAmt % 8 == 6) {1954 insertMultibyteShift(MI, BB, ShiftRegs, ISD::SHL, 1);1955 // Shift the topmost bit into the HighByte.1956 Register NewExt = MRI.createVirtualRegister(&AVR::GPR8RegClass);1957 BuildMI(*BB, MI, dl, TII.get(AVR::ADCRdRr), NewExt)1958 .addReg(HighByte)1959 .addReg(HighByte);1960 HighByte = NewExt;1961 }1962 1963 // Move all to the right, while sign or zero extending.1964 for (int I = Regs.size() - 1; I >= 0; I--) {1965 int ShiftRegsIdx = I - (Regs.size() - ShiftRegs.size()) - 1;1966 if (ShiftRegsIdx >= 0) {1967 Regs[I] = ShiftRegs[ShiftRegsIdx];1968 } else if (ShiftRegsIdx == -1) {1969 Regs[I] = std::pair(HighByte, 0);1970 } else {1971 Regs[I] = std::pair(ExtByte, 0);1972 }1973 }1974 1975 return;1976 }1977 1978 // For shift amounts of at least one register, simply rename the registers and1979 // zero the bottom registers.1980 while (ShiftLeft && ShiftAmt >= 8) {1981 // Move all registers one to the left.1982 for (size_t I = 0; I < Regs.size() - 1; I++) {1983 Regs[I] = Regs[I + 1];1984 }1985 1986 // Zero the least significant register.1987 Regs[Regs.size() - 1] = std::pair(ZeroReg, 0);1988 1989 // Continue shifts with the leftover registers.1990 Regs = Regs.drop_back(1);1991 1992 ShiftAmt -= 8;1993 }1994 1995 // And again, the same for right shifts.1996 Register ShrExtendReg = 0;1997 if (!ShiftLeft && ShiftAmt >= 8) {1998 if (ArithmeticShift) {1999 // Sign extend the most significant register into ShrExtendReg.2000 ShrExtendReg = MRI.createVirtualRegister(&AVR::GPR8RegClass);2001 Register Tmp = MRI.createVirtualRegister(&AVR::GPR8RegClass);2002 BuildMI(*BB, MI, dl, TII.get(AVR::ADDRdRr), Tmp)2003 .addReg(Regs[0].first, 0, Regs[0].second)2004 .addReg(Regs[0].first, 0, Regs[0].second);2005 BuildMI(*BB, MI, dl, TII.get(AVR::SBCRdRr), ShrExtendReg)2006 .addReg(Tmp)2007 .addReg(Tmp);2008 } else {2009 ShrExtendReg = ZeroReg;2010 }2011 for (; ShiftAmt >= 8; ShiftAmt -= 8) {2012 // Move all registers one to the right.2013 for (size_t I = Regs.size() - 1; I != 0; I--) {2014 Regs[I] = Regs[I - 1];2015 }2016 2017 // Zero or sign extend the most significant register.2018 Regs[0] = std::pair(ShrExtendReg, 0);2019 2020 // Continue shifts with the leftover registers.2021 Regs = Regs.drop_front(1);2022 }2023 }2024 2025 // The bigger shifts are already handled above.2026 assert((ShiftAmt < 8) && "Unexpect shift amount");2027 2028 // Shift by four bits, using a complicated swap/eor/andi/eor sequence.2029 // It only works for logical shifts because the bits shifted in are all2030 // zeroes.2031 // To shift a single byte right, it produces code like this:2032 // swap r02033 // andi r0, 0x0f2034 // For a two-byte (16-bit) shift, it adds the following instructions to shift2035 // the upper byte into the lower byte:2036 // swap r12037 // eor r0, r12038 // andi r1, 0x0f2039 // eor r0, r12040 // For bigger shifts, it repeats the above sequence. For example, for a 3-byte2041 // (24-bit) shift it adds:2042 // swap r22043 // eor r1, r22044 // andi r2, 0x0f2045 // eor r1, r22046 if (!ArithmeticShift && ShiftAmt >= 4) {2047 Register Prev = 0;2048 for (size_t I = 0; I < Regs.size(); I++) {2049 size_t Idx = ShiftLeft ? I : Regs.size() - I - 1;2050 Register SwapReg = MRI.createVirtualRegister(&AVR::LD8RegClass);2051 BuildMI(*BB, MI, dl, TII.get(AVR::SWAPRd), SwapReg)2052 .addReg(Regs[Idx].first, 0, Regs[Idx].second);2053 if (I != 0) {2054 Register R = MRI.createVirtualRegister(&AVR::GPR8RegClass);2055 BuildMI(*BB, MI, dl, TII.get(AVR::EORRdRr), R)2056 .addReg(Prev)2057 .addReg(SwapReg);2058 Prev = R;2059 }2060 Register AndReg = MRI.createVirtualRegister(&AVR::LD8RegClass);2061 BuildMI(*BB, MI, dl, TII.get(AVR::ANDIRdK), AndReg)2062 .addReg(SwapReg)2063 .addImm(ShiftLeft ? 0xf0 : 0x0f);2064 if (I != 0) {2065 Register R = MRI.createVirtualRegister(&AVR::GPR8RegClass);2066 BuildMI(*BB, MI, dl, TII.get(AVR::EORRdRr), R)2067 .addReg(Prev)2068 .addReg(AndReg);2069 size_t PrevIdx = ShiftLeft ? Idx - 1 : Idx + 1;2070 Regs[PrevIdx] = std::pair(R, 0);2071 }2072 Prev = AndReg;2073 Regs[Idx] = std::pair(AndReg, 0);2074 }2075 ShiftAmt -= 4;2076 }2077 2078 // Shift by one. This is the fallback that always works, and the shift2079 // operation that is used for 1, 2, and 3 bit shifts.2080 while (ShiftLeft && ShiftAmt) {2081 // Shift one to the left.2082 for (ssize_t I = Regs.size() - 1; I >= 0; I--) {2083 Register Out = MRI.createVirtualRegister(&AVR::GPR8RegClass);2084 Register In = Regs[I].first;2085 Register InSubreg = Regs[I].second;2086 if (I == (ssize_t)Regs.size() - 1) { // first iteration2087 BuildMI(*BB, MI, dl, TII.get(AVR::ADDRdRr), Out)2088 .addReg(In, 0, InSubreg)2089 .addReg(In, 0, InSubreg);2090 } else {2091 BuildMI(*BB, MI, dl, TII.get(AVR::ADCRdRr), Out)2092 .addReg(In, 0, InSubreg)2093 .addReg(In, 0, InSubreg);2094 }2095 Regs[I] = std::pair(Out, 0);2096 }2097 ShiftAmt--;2098 }2099 while (!ShiftLeft && ShiftAmt) {2100 // Shift one to the right.2101 for (size_t I = 0; I < Regs.size(); I++) {2102 Register Out = MRI.createVirtualRegister(&AVR::GPR8RegClass);2103 Register In = Regs[I].first;2104 Register InSubreg = Regs[I].second;2105 if (I == 0) {2106 unsigned Opc = ArithmeticShift ? AVR::ASRRd : AVR::LSRRd;2107 BuildMI(*BB, MI, dl, TII.get(Opc), Out).addReg(In, 0, InSubreg);2108 } else {2109 BuildMI(*BB, MI, dl, TII.get(AVR::RORRd), Out).addReg(In, 0, InSubreg);2110 }2111 Regs[I] = std::pair(Out, 0);2112 }2113 ShiftAmt--;2114 }2115 2116 if (ShiftAmt != 0) {2117 llvm_unreachable("don't know how to shift!"); // sanity check2118 }2119}2120 2121// Do a wide (32-bit) shift.2122MachineBasicBlock *2123AVRTargetLowering::insertWideShift(MachineInstr &MI,2124 MachineBasicBlock *BB) const {2125 const TargetInstrInfo &TII = *Subtarget.getInstrInfo();2126 const DebugLoc &dl = MI.getDebugLoc();2127 2128 // How much to shift to the right (meaning: a negative number indicates a left2129 // shift).2130 int64_t ShiftAmt = MI.getOperand(4).getImm();2131 ISD::NodeType Opc;2132 switch (MI.getOpcode()) {2133 case AVR::Lsl32:2134 Opc = ISD::SHL;2135 break;2136 case AVR::Lsr32:2137 Opc = ISD::SRL;2138 break;2139 case AVR::Asr32:2140 Opc = ISD::SRA;2141 break;2142 }2143 2144 // Read the input registers, with the most significant register at index 0.2145 std::array<std::pair<Register, int>, 4> Registers = {2146 std::pair(MI.getOperand(3).getReg(), AVR::sub_hi),2147 std::pair(MI.getOperand(3).getReg(), AVR::sub_lo),2148 std::pair(MI.getOperand(2).getReg(), AVR::sub_hi),2149 std::pair(MI.getOperand(2).getReg(), AVR::sub_lo),2150 };2151 2152 // Do the shift. The registers are modified in-place.2153 insertMultibyteShift(MI, BB, Registers, Opc, ShiftAmt);2154 2155 // Combine the 8-bit registers into 16-bit register pairs.2156 // This done either from LSB to MSB or from MSB to LSB, depending on the2157 // shift. It's an optimization so that the register allocator will use the2158 // fewest movs possible (which order we use isn't a correctness issue, just an2159 // optimization issue).2160 // - lsl prefers starting from the most significant byte (2nd case).2161 // - lshr prefers starting from the least significant byte (1st case).2162 // - for ashr it depends on the number of shifted bytes.2163 // Some shift operations still don't get the most optimal mov sequences even2164 // with this distinction. TODO: figure out why and try to fix it (but we're2165 // already equal to or faster than avr-gcc in all cases except ashr 8).2166 if (Opc != ISD::SHL &&2167 (Opc != ISD::SRA || (ShiftAmt < 16 || ShiftAmt >= 22))) {2168 // Use the resulting registers starting with the least significant byte.2169 BuildMI(*BB, MI, dl, TII.get(AVR::REG_SEQUENCE), MI.getOperand(0).getReg())2170 .addReg(Registers[3].first, 0, Registers[3].second)2171 .addImm(AVR::sub_lo)2172 .addReg(Registers[2].first, 0, Registers[2].second)2173 .addImm(AVR::sub_hi);2174 BuildMI(*BB, MI, dl, TII.get(AVR::REG_SEQUENCE), MI.getOperand(1).getReg())2175 .addReg(Registers[1].first, 0, Registers[1].second)2176 .addImm(AVR::sub_lo)2177 .addReg(Registers[0].first, 0, Registers[0].second)2178 .addImm(AVR::sub_hi);2179 } else {2180 // Use the resulting registers starting with the most significant byte.2181 BuildMI(*BB, MI, dl, TII.get(AVR::REG_SEQUENCE), MI.getOperand(1).getReg())2182 .addReg(Registers[0].first, 0, Registers[0].second)2183 .addImm(AVR::sub_hi)2184 .addReg(Registers[1].first, 0, Registers[1].second)2185 .addImm(AVR::sub_lo);2186 BuildMI(*BB, MI, dl, TII.get(AVR::REG_SEQUENCE), MI.getOperand(0).getReg())2187 .addReg(Registers[2].first, 0, Registers[2].second)2188 .addImm(AVR::sub_hi)2189 .addReg(Registers[3].first, 0, Registers[3].second)2190 .addImm(AVR::sub_lo);2191 }2192 2193 // Remove the pseudo instruction.2194 MI.eraseFromParent();2195 return BB;2196}2197 2198static bool isCopyMulResult(MachineBasicBlock::iterator const &I) {2199 if (I->getOpcode() == AVR::COPY) {2200 Register SrcReg = I->getOperand(1).getReg();2201 return (SrcReg == AVR::R0 || SrcReg == AVR::R1);2202 }2203 2204 return false;2205}2206 2207// The mul instructions wreak havock on our zero_reg R1. We need to clear it2208// after the result has been evacuated. This is probably not the best way to do2209// it, but it works for now.2210MachineBasicBlock *AVRTargetLowering::insertMul(MachineInstr &MI,2211 MachineBasicBlock *BB) const {2212 const TargetInstrInfo &TII = *Subtarget.getInstrInfo();2213 MachineBasicBlock::iterator I(MI);2214 ++I; // in any case insert *after* the mul instruction2215 if (isCopyMulResult(I))2216 ++I;2217 if (isCopyMulResult(I))2218 ++I;2219 BuildMI(*BB, I, MI.getDebugLoc(), TII.get(AVR::EORRdRr), AVR::R1)2220 .addReg(AVR::R1)2221 .addReg(AVR::R1);2222 return BB;2223}2224 2225// Insert a read from the zero register.2226MachineBasicBlock *2227AVRTargetLowering::insertCopyZero(MachineInstr &MI,2228 MachineBasicBlock *BB) const {2229 const TargetInstrInfo &TII = *Subtarget.getInstrInfo();2230 MachineBasicBlock::iterator I(MI);2231 BuildMI(*BB, I, MI.getDebugLoc(), TII.get(AVR::COPY))2232 .add(MI.getOperand(0))2233 .addReg(Subtarget.getZeroRegister());2234 MI.eraseFromParent();2235 return BB;2236}2237 2238// Lower atomicrmw operation to disable interrupts, do operation, and restore2239// interrupts. This works because all AVR microcontrollers are single core.2240MachineBasicBlock *AVRTargetLowering::insertAtomicArithmeticOp(2241 MachineInstr &MI, MachineBasicBlock *BB, unsigned Opcode, int Width) const {2242 MachineRegisterInfo &MRI = BB->getParent()->getRegInfo();2243 const TargetInstrInfo &TII = *Subtarget.getInstrInfo();2244 MachineBasicBlock::iterator I(MI);2245 DebugLoc dl = MI.getDebugLoc();2246 2247 // Example instruction sequence, for an atomic 8-bit add:2248 // ldi r25, 52249 // in r0, SREG2250 // cli2251 // ld r24, X2252 // add r25, r242253 // st X, r252254 // out SREG, r02255 2256 const TargetRegisterClass *RC =2257 (Width == 8) ? &AVR::GPR8RegClass : &AVR::DREGSRegClass;2258 unsigned LoadOpcode = (Width == 8) ? AVR::LDRdPtr : AVR::LDWRdPtr;2259 unsigned StoreOpcode = (Width == 8) ? AVR::STPtrRr : AVR::STWPtrRr;2260 2261 // Disable interrupts.2262 BuildMI(*BB, I, dl, TII.get(AVR::INRdA), Subtarget.getTmpRegister())2263 .addImm(Subtarget.getIORegSREG());2264 BuildMI(*BB, I, dl, TII.get(AVR::BCLRs)).addImm(7);2265 2266 // Load the original value.2267 BuildMI(*BB, I, dl, TII.get(LoadOpcode), MI.getOperand(0).getReg())2268 .add(MI.getOperand(1));2269 2270 // Do the arithmetic operation.2271 Register Result = MRI.createVirtualRegister(RC);2272 BuildMI(*BB, I, dl, TII.get(Opcode), Result)2273 .addReg(MI.getOperand(0).getReg())2274 .add(MI.getOperand(2));2275 2276 // Store the result.2277 BuildMI(*BB, I, dl, TII.get(StoreOpcode))2278 .add(MI.getOperand(1))2279 .addReg(Result);2280 2281 // Restore interrupts.2282 BuildMI(*BB, I, dl, TII.get(AVR::OUTARr))2283 .addImm(Subtarget.getIORegSREG())2284 .addReg(Subtarget.getTmpRegister());2285 2286 // Remove the pseudo instruction.2287 MI.eraseFromParent();2288 return BB;2289}2290 2291MachineBasicBlock *2292AVRTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,2293 MachineBasicBlock *MBB) const {2294 int Opc = MI.getOpcode();2295 const AVRSubtarget &STI = MBB->getParent()->getSubtarget<AVRSubtarget>();2296 2297 // Pseudo shift instructions with a non constant shift amount are expanded2298 // into a loop.2299 switch (Opc) {2300 case AVR::Lsl8:2301 case AVR::Lsl16:2302 case AVR::Lsr8:2303 case AVR::Lsr16:2304 case AVR::Rol8:2305 case AVR::Rol16:2306 case AVR::Ror8:2307 case AVR::Ror16:2308 case AVR::Asr8:2309 case AVR::Asr16:2310 return insertShift(MI, MBB, STI.hasTinyEncoding());2311 case AVR::Lsl32:2312 case AVR::Lsr32:2313 case AVR::Asr32:2314 return insertWideShift(MI, MBB);2315 case AVR::MULRdRr:2316 case AVR::MULSRdRr:2317 return insertMul(MI, MBB);2318 case AVR::CopyZero:2319 return insertCopyZero(MI, MBB);2320 case AVR::AtomicLoadAdd8:2321 return insertAtomicArithmeticOp(MI, MBB, AVR::ADDRdRr, 8);2322 case AVR::AtomicLoadAdd16:2323 return insertAtomicArithmeticOp(MI, MBB, AVR::ADDWRdRr, 16);2324 case AVR::AtomicLoadSub8:2325 return insertAtomicArithmeticOp(MI, MBB, AVR::SUBRdRr, 8);2326 case AVR::AtomicLoadSub16:2327 return insertAtomicArithmeticOp(MI, MBB, AVR::SUBWRdRr, 16);2328 case AVR::AtomicLoadAnd8:2329 return insertAtomicArithmeticOp(MI, MBB, AVR::ANDRdRr, 8);2330 case AVR::AtomicLoadAnd16:2331 return insertAtomicArithmeticOp(MI, MBB, AVR::ANDWRdRr, 16);2332 case AVR::AtomicLoadOr8:2333 return insertAtomicArithmeticOp(MI, MBB, AVR::ORRdRr, 8);2334 case AVR::AtomicLoadOr16:2335 return insertAtomicArithmeticOp(MI, MBB, AVR::ORWRdRr, 16);2336 case AVR::AtomicLoadXor8:2337 return insertAtomicArithmeticOp(MI, MBB, AVR::EORRdRr, 8);2338 case AVR::AtomicLoadXor16:2339 return insertAtomicArithmeticOp(MI, MBB, AVR::EORWRdRr, 16);2340 }2341 2342 assert((Opc == AVR::Select16 || Opc == AVR::Select8) &&2343 "Unexpected instr type to insert");2344 2345 const AVRInstrInfo &TII = (const AVRInstrInfo &)*MI.getParent()2346 ->getParent()2347 ->getSubtarget()2348 .getInstrInfo();2349 DebugLoc dl = MI.getDebugLoc();2350 2351 // To "insert" a SELECT instruction, we insert the diamond2352 // control-flow pattern. The incoming instruction knows the2353 // destination vreg to set, the condition code register to branch2354 // on, the true/false values to select between, and a branch opcode2355 // to use.2356 2357 MachineFunction *MF = MBB->getParent();2358 const BasicBlock *LLVM_BB = MBB->getBasicBlock();2359 MachineBasicBlock *FallThrough = MBB->getFallThrough();2360 2361 // If the current basic block falls through to another basic block,2362 // we must insert an unconditional branch to the fallthrough destination2363 // if we are to insert basic blocks at the prior fallthrough point.2364 if (FallThrough != nullptr) {2365 BuildMI(MBB, dl, TII.get(AVR::RJMPk)).addMBB(FallThrough);2366 }2367 2368 MachineBasicBlock *trueMBB = MF->CreateMachineBasicBlock(LLVM_BB);2369 MachineBasicBlock *falseMBB = MF->CreateMachineBasicBlock(LLVM_BB);2370 2371 MachineFunction::iterator I;2372 for (I = MF->begin(); I != MF->end() && &(*I) != MBB; ++I)2373 ;2374 if (I != MF->end())2375 ++I;2376 MF->insert(I, trueMBB);2377 MF->insert(I, falseMBB);2378 2379 // Set the call frame size on entry to the new basic blocks.2380 unsigned CallFrameSize = TII.getCallFrameSizeAt(MI);2381 trueMBB->setCallFrameSize(CallFrameSize);2382 falseMBB->setCallFrameSize(CallFrameSize);2383 2384 // Transfer remaining instructions and all successors of the current2385 // block to the block which will contain the Phi node for the2386 // select.2387 trueMBB->splice(trueMBB->begin(), MBB,2388 std::next(MachineBasicBlock::iterator(MI)), MBB->end());2389 trueMBB->transferSuccessorsAndUpdatePHIs(MBB);2390 2391 AVRCC::CondCodes CC = (AVRCC::CondCodes)MI.getOperand(3).getImm();2392 BuildMI(MBB, dl, TII.getBrCond(CC)).addMBB(trueMBB);2393 BuildMI(MBB, dl, TII.get(AVR::RJMPk)).addMBB(falseMBB);2394 MBB->addSuccessor(falseMBB);2395 MBB->addSuccessor(trueMBB);2396 2397 // Unconditionally flow back to the true block2398 BuildMI(falseMBB, dl, TII.get(AVR::RJMPk)).addMBB(trueMBB);2399 falseMBB->addSuccessor(trueMBB);2400 2401 // Set up the Phi node to determine where we came from2402 BuildMI(*trueMBB, trueMBB->begin(), dl, TII.get(AVR::PHI),2403 MI.getOperand(0).getReg())2404 .addReg(MI.getOperand(1).getReg())2405 .addMBB(MBB)2406 .addReg(MI.getOperand(2).getReg())2407 .addMBB(falseMBB);2408 2409 MI.eraseFromParent(); // The pseudo instruction is gone now.2410 return trueMBB;2411}2412 2413//===----------------------------------------------------------------------===//2414// Inline Asm Support2415//===----------------------------------------------------------------------===//2416 2417AVRTargetLowering::ConstraintType2418AVRTargetLowering::getConstraintType(StringRef Constraint) const {2419 if (Constraint.size() == 1) {2420 // See http://www.nongnu.org/avr-libc/user-manual/inline_asm.html2421 switch (Constraint[0]) {2422 default:2423 break;2424 case 'a': // Simple upper registers2425 case 'b': // Base pointer registers pairs2426 case 'd': // Upper register2427 case 'l': // Lower registers2428 case 'e': // Pointer register pairs2429 case 'q': // Stack pointer register2430 case 'r': // Any register2431 case 'w': // Special upper register pairs2432 return C_RegisterClass;2433 case 't': // Temporary register2434 case 'x':2435 case 'X': // Pointer register pair X2436 case 'y':2437 case 'Y': // Pointer register pair Y2438 case 'z':2439 case 'Z': // Pointer register pair Z2440 return C_Register;2441 case 'Q': // A memory address based on Y or Z pointer with displacement.2442 return C_Memory;2443 case 'G': // Floating point constant2444 case 'I': // 6-bit positive integer constant2445 case 'J': // 6-bit negative integer constant2446 case 'K': // Integer constant (Range: 2)2447 case 'L': // Integer constant (Range: 0)2448 case 'M': // 8-bit integer constant2449 case 'N': // Integer constant (Range: -1)2450 case 'O': // Integer constant (Range: 8, 16, 24)2451 case 'P': // Integer constant (Range: 1)2452 case 'R': // Integer constant (Range: -6 to 5)x2453 return C_Immediate;2454 }2455 }2456 2457 return TargetLowering::getConstraintType(Constraint);2458}2459 2460InlineAsm::ConstraintCode2461AVRTargetLowering::getInlineAsmMemConstraint(StringRef ConstraintCode) const {2462 // Not sure if this is actually the right thing to do, but we got to do2463 // *something* [agnat]2464 switch (ConstraintCode[0]) {2465 case 'Q':2466 return InlineAsm::ConstraintCode::Q;2467 }2468 return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);2469}2470 2471AVRTargetLowering::ConstraintWeight2472AVRTargetLowering::getSingleConstraintMatchWeight(2473 AsmOperandInfo &info, const char *constraint) const {2474 ConstraintWeight weight = CW_Invalid;2475 Value *CallOperandVal = info.CallOperandVal;2476 2477 // If we don't have a value, we can't do a match,2478 // but allow it at the lowest weight.2479 // (this behaviour has been copied from the ARM backend)2480 if (!CallOperandVal) {2481 return CW_Default;2482 }2483 2484 // Look at the constraint type.2485 switch (*constraint) {2486 default:2487 weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint);2488 break;2489 case 'd':2490 case 'r':2491 case 'l':2492 weight = CW_Register;2493 break;2494 case 'a':2495 case 'b':2496 case 'e':2497 case 'q':2498 case 't':2499 case 'w':2500 case 'x':2501 case 'X':2502 case 'y':2503 case 'Y':2504 case 'z':2505 case 'Z':2506 weight = CW_SpecificReg;2507 break;2508 case 'G':2509 if (const ConstantFP *C = dyn_cast<ConstantFP>(CallOperandVal)) {2510 if (C->isZero()) {2511 weight = CW_Constant;2512 }2513 }2514 break;2515 case 'I':2516 if (const ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) {2517 if (isUInt<6>(C->getZExtValue())) {2518 weight = CW_Constant;2519 }2520 }2521 break;2522 case 'J':2523 if (const ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) {2524 if ((C->getSExtValue() >= -63) && (C->getSExtValue() <= 0)) {2525 weight = CW_Constant;2526 }2527 }2528 break;2529 case 'K':2530 if (const ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) {2531 if (C->getZExtValue() == 2) {2532 weight = CW_Constant;2533 }2534 }2535 break;2536 case 'L':2537 if (const ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) {2538 if (C->getZExtValue() == 0) {2539 weight = CW_Constant;2540 }2541 }2542 break;2543 case 'M':2544 if (const ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) {2545 if (isUInt<8>(C->getZExtValue())) {2546 weight = CW_Constant;2547 }2548 }2549 break;2550 case 'N':2551 if (const ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) {2552 if (C->getSExtValue() == -1) {2553 weight = CW_Constant;2554 }2555 }2556 break;2557 case 'O':2558 if (const ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) {2559 if ((C->getZExtValue() == 8) || (C->getZExtValue() == 16) ||2560 (C->getZExtValue() == 24)) {2561 weight = CW_Constant;2562 }2563 }2564 break;2565 case 'P':2566 if (const ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) {2567 if (C->getZExtValue() == 1) {2568 weight = CW_Constant;2569 }2570 }2571 break;2572 case 'R':2573 if (const ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) {2574 if ((C->getSExtValue() >= -6) && (C->getSExtValue() <= 5)) {2575 weight = CW_Constant;2576 }2577 }2578 break;2579 case 'Q':2580 weight = CW_Memory;2581 break;2582 }2583 2584 return weight;2585}2586 2587std::pair<unsigned, const TargetRegisterClass *>2588AVRTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,2589 StringRef Constraint,2590 MVT VT) const {2591 if (Constraint.size() == 1) {2592 switch (Constraint[0]) {2593 case 'a': // Simple upper registers r16..r23.2594 if (VT == MVT::i8)2595 return std::make_pair(0U, &AVR::LD8loRegClass);2596 else if (VT == MVT::i16)2597 return std::make_pair(0U, &AVR::DREGSLD8loRegClass);2598 break;2599 case 'b': // Base pointer registers: y, z.2600 if (VT == MVT::i8 || VT == MVT::i16)2601 return std::make_pair(0U, &AVR::PTRDISPREGSRegClass);2602 break;2603 case 'd': // Upper registers r16..r31.2604 if (VT == MVT::i8)2605 return std::make_pair(0U, &AVR::LD8RegClass);2606 else if (VT == MVT::i16)2607 return std::make_pair(0U, &AVR::DLDREGSRegClass);2608 break;2609 case 'l': // Lower registers r0..r15.2610 if (VT == MVT::i8)2611 return std::make_pair(0U, &AVR::GPR8loRegClass);2612 else if (VT == MVT::i16)2613 return std::make_pair(0U, &AVR::DREGSloRegClass);2614 break;2615 case 'e': // Pointer register pairs: x, y, z.2616 if (VT == MVT::i8 || VT == MVT::i16)2617 return std::make_pair(0U, &AVR::PTRREGSRegClass);2618 break;2619 case 'q': // Stack pointer register: SPH:SPL.2620 return std::make_pair(0U, &AVR::GPRSPRegClass);2621 case 'r': // Any register: r0..r31.2622 if (VT == MVT::i8)2623 return std::make_pair(0U, &AVR::GPR8RegClass);2624 else if (VT == MVT::i16)2625 return std::make_pair(0U, &AVR::DREGSRegClass);2626 break;2627 case 't': // Temporary register: r0.2628 if (VT == MVT::i8)2629 return std::make_pair(unsigned(Subtarget.getTmpRegister()),2630 &AVR::GPR8RegClass);2631 break;2632 case 'w': // Special upper register pairs: r24, r26, r28, r30.2633 if (VT == MVT::i8 || VT == MVT::i16)2634 return std::make_pair(0U, &AVR::IWREGSRegClass);2635 break;2636 case 'x': // Pointer register pair X: r27:r26.2637 case 'X':2638 if (VT == MVT::i8 || VT == MVT::i16)2639 return std::make_pair(unsigned(AVR::R27R26), &AVR::PTRREGSRegClass);2640 break;2641 case 'y': // Pointer register pair Y: r29:r28.2642 case 'Y':2643 if (VT == MVT::i8 || VT == MVT::i16)2644 return std::make_pair(unsigned(AVR::R29R28), &AVR::PTRREGSRegClass);2645 break;2646 case 'z': // Pointer register pair Z: r31:r30.2647 case 'Z':2648 if (VT == MVT::i8 || VT == MVT::i16)2649 return std::make_pair(unsigned(AVR::R31R30), &AVR::PTRREGSRegClass);2650 break;2651 default:2652 break;2653 }2654 }2655 2656 return TargetLowering::getRegForInlineAsmConstraint(2657 Subtarget.getRegisterInfo(), Constraint, VT);2658}2659 2660void AVRTargetLowering::LowerAsmOperandForConstraint(SDValue Op,2661 StringRef Constraint,2662 std::vector<SDValue> &Ops,2663 SelectionDAG &DAG) const {2664 SDValue Result;2665 SDLoc DL(Op);2666 EVT Ty = Op.getValueType();2667 2668 // Currently only support length 1 constraints.2669 if (Constraint.size() != 1) {2670 return;2671 }2672 2673 char ConstraintLetter = Constraint[0];2674 switch (ConstraintLetter) {2675 default:2676 break;2677 // Deal with integers first:2678 case 'I':2679 case 'J':2680 case 'K':2681 case 'L':2682 case 'M':2683 case 'N':2684 case 'O':2685 case 'P':2686 case 'R': {2687 const ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op);2688 if (!C) {2689 return;2690 }2691 2692 int64_t CVal64 = C->getSExtValue();2693 uint64_t CUVal64 = C->getZExtValue();2694 switch (ConstraintLetter) {2695 case 'I': // 0..632696 if (!isUInt<6>(CUVal64))2697 return;2698 Result = DAG.getTargetConstant(CUVal64, DL, Ty);2699 break;2700 case 'J': // -63..02701 if (CVal64 < -63 || CVal64 > 0)2702 return;2703 Result = DAG.getTargetConstant(CVal64, DL, Ty);2704 break;2705 case 'K': // 22706 if (CUVal64 != 2)2707 return;2708 Result = DAG.getTargetConstant(CUVal64, DL, Ty);2709 break;2710 case 'L': // 02711 if (CUVal64 != 0)2712 return;2713 Result = DAG.getTargetConstant(CUVal64, DL, Ty);2714 break;2715 case 'M': // 0..2552716 if (!isUInt<8>(CUVal64))2717 return;2718 // i8 type may be printed as a negative number,2719 // e.g. 254 would be printed as -2,2720 // so we force it to i16 at least.2721 if (Ty.getSimpleVT() == MVT::i8) {2722 Ty = MVT::i16;2723 }2724 Result = DAG.getTargetConstant(CUVal64, DL, Ty);2725 break;2726 case 'N': // -12727 if (CVal64 != -1)2728 return;2729 Result = DAG.getTargetConstant(CVal64, DL, Ty);2730 break;2731 case 'O': // 8, 16, 242732 if (CUVal64 != 8 && CUVal64 != 16 && CUVal64 != 24)2733 return;2734 Result = DAG.getTargetConstant(CUVal64, DL, Ty);2735 break;2736 case 'P': // 12737 if (CUVal64 != 1)2738 return;2739 Result = DAG.getTargetConstant(CUVal64, DL, Ty);2740 break;2741 case 'R': // -6..52742 if (CVal64 < -6 || CVal64 > 5)2743 return;2744 Result = DAG.getTargetConstant(CVal64, DL, Ty);2745 break;2746 }2747 2748 break;2749 }2750 case 'G':2751 const ConstantFPSDNode *FC = dyn_cast<ConstantFPSDNode>(Op);2752 if (!FC || !FC->isZero())2753 return;2754 // Soften float to i8 02755 Result = DAG.getTargetConstant(0, DL, MVT::i8);2756 break;2757 }2758 2759 if (Result.getNode()) {2760 Ops.push_back(Result);2761 return;2762 }2763 2764 return TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG);2765}2766 2767Register AVRTargetLowering::getRegisterByName(const char *RegName, LLT VT,2768 const MachineFunction &MF) const {2769 Register Reg;2770 2771 if (VT == LLT::scalar(8)) {2772 Reg = StringSwitch<unsigned>(RegName)2773 .Case("r0", AVR::R0)2774 .Case("r1", AVR::R1)2775 .Default(0);2776 } else {2777 Reg = StringSwitch<unsigned>(RegName)2778 .Case("r0", AVR::R1R0)2779 .Case("sp", AVR::SP)2780 .Default(0);2781 }2782 2783 if (Reg)2784 return Reg;2785 2786 report_fatal_error(2787 Twine("Invalid register name \"" + StringRef(RegName) + "\"."));2788}2789 2790} // end of namespace llvm2791