140 lines · cpp
1//===-- SparcSubtarget.cpp - SPARC Subtarget Information ------------------===//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 implements the SPARC specific subclass of TargetSubtargetInfo.10//11//===----------------------------------------------------------------------===//12 13#include "SparcSubtarget.h"14#include "SparcSelectionDAGInfo.h"15#include "llvm/ADT/StringRef.h"16#include "llvm/MC/TargetRegistry.h"17#include "llvm/Support/MathExtras.h"18 19using namespace llvm;20 21#define DEBUG_TYPE "sparc-subtarget"22 23#define GET_SUBTARGETINFO_TARGET_DESC24#define GET_SUBTARGETINFO_CTOR25#include "SparcGenSubtargetInfo.inc"26 27void SparcSubtarget::anchor() { }28 29SparcSubtarget &SparcSubtarget::initializeSubtargetDependencies(30 StringRef CPU, StringRef TuneCPU, StringRef FS) {31 const Triple &TT = getTargetTriple();32 // Determine default and user specified characteristics33 std::string CPUName = std::string(CPU);34 if (CPUName.empty())35 CPUName = TT.isSPARC64() ? "v9" : "v8";36 37 if (TuneCPU.empty())38 TuneCPU = CPUName;39 40 // Parse features string.41 ParseSubtargetFeatures(CPUName, TuneCPU, FS);42 43 if (!Is64Bit && TT.isSPARC64()) {44 FeatureBitset Features = getFeatureBits();45 setFeatureBits(Features.set(Sparc::Feature64Bit));46 Is64Bit = true;47 }48 49 // Popc is a v9-only instruction.50 if (!IsV9)51 UsePopc = false;52 53 return *this;54}55 56SparcSubtarget::SparcSubtarget(const StringRef &CPU, const StringRef &TuneCPU,57 const StringRef &FS, const TargetMachine &TM)58 : SparcGenSubtargetInfo(TM.getTargetTriple(), CPU, TuneCPU, FS),59 ReserveRegister(TM.getMCRegisterInfo()->getNumRegs()),60 InstrInfo(initializeSubtargetDependencies(CPU, TuneCPU, FS)),61 TLInfo(TM, *this), FrameLowering(*this) {62 TSInfo = std::make_unique<SparcSelectionDAGInfo>();63}64 65SparcSubtarget::~SparcSubtarget() = default;66 67const SelectionDAGTargetInfo *SparcSubtarget::getSelectionDAGInfo() const {68 return TSInfo.get();69}70 71void SparcSubtarget::initLibcallLoweringInfo(LibcallLoweringInfo &Info) const {72 if (hasHardQuad())73 return;74 75 // Setup Runtime library names.76 if (is64Bit() && !useSoftFloat()) {77 Info.setLibcallImpl(RTLIB::ADD_F128, RTLIB::impl__Qp_add);78 Info.setLibcallImpl(RTLIB::SUB_F128, RTLIB::impl__Qp_sub);79 Info.setLibcallImpl(RTLIB::MUL_F128, RTLIB::impl__Qp_mul);80 Info.setLibcallImpl(RTLIB::DIV_F128, RTLIB::impl__Qp_div);81 Info.setLibcallImpl(RTLIB::SQRT_F128, RTLIB::impl__Qp_sqrt);82 Info.setLibcallImpl(RTLIB::FPTOSINT_F128_I32, RTLIB::impl__Qp_qtoi);83 Info.setLibcallImpl(RTLIB::FPTOUINT_F128_I32, RTLIB::impl__Qp_qtoui);84 Info.setLibcallImpl(RTLIB::SINTTOFP_I32_F128, RTLIB::impl__Qp_itoq);85 Info.setLibcallImpl(RTLIB::UINTTOFP_I32_F128, RTLIB::impl__Qp_uitoq);86 Info.setLibcallImpl(RTLIB::FPTOSINT_F128_I64, RTLIB::impl__Qp_qtox);87 Info.setLibcallImpl(RTLIB::FPTOUINT_F128_I64, RTLIB::impl__Qp_qtoux);88 Info.setLibcallImpl(RTLIB::SINTTOFP_I64_F128, RTLIB::impl__Qp_xtoq);89 Info.setLibcallImpl(RTLIB::UINTTOFP_I64_F128, RTLIB::impl__Qp_uxtoq);90 Info.setLibcallImpl(RTLIB::FPEXT_F32_F128, RTLIB::impl__Qp_stoq);91 Info.setLibcallImpl(RTLIB::FPEXT_F64_F128, RTLIB::impl__Qp_dtoq);92 Info.setLibcallImpl(RTLIB::FPROUND_F128_F32, RTLIB::impl__Qp_qtos);93 Info.setLibcallImpl(RTLIB::FPROUND_F128_F64, RTLIB::impl__Qp_qtod);94 } else if (!useSoftFloat()) {95 Info.setLibcallImpl(RTLIB::ADD_F128, RTLIB::impl__Q_add);96 Info.setLibcallImpl(RTLIB::SUB_F128, RTLIB::impl__Q_sub);97 Info.setLibcallImpl(RTLIB::MUL_F128, RTLIB::impl__Q_mul);98 Info.setLibcallImpl(RTLIB::DIV_F128, RTLIB::impl__Q_div);99 Info.setLibcallImpl(RTLIB::SQRT_F128, RTLIB::impl__Q_sqrt);100 Info.setLibcallImpl(RTLIB::FPTOSINT_F128_I32, RTLIB::impl__Q_qtoi);101 Info.setLibcallImpl(RTLIB::FPTOUINT_F128_I32, RTLIB::impl__Q_qtou);102 Info.setLibcallImpl(RTLIB::SINTTOFP_I32_F128, RTLIB::impl__Q_itoq);103 Info.setLibcallImpl(RTLIB::UINTTOFP_I32_F128, RTLIB::impl__Q_utoq);104 Info.setLibcallImpl(RTLIB::FPEXT_F32_F128, RTLIB::impl__Q_stoq);105 Info.setLibcallImpl(RTLIB::FPEXT_F64_F128, RTLIB::impl__Q_dtoq);106 Info.setLibcallImpl(RTLIB::FPROUND_F128_F32, RTLIB::impl__Q_qtos);107 Info.setLibcallImpl(RTLIB::FPROUND_F128_F64, RTLIB::impl__Q_qtod);108 }109}110 111int SparcSubtarget::getAdjustedFrameSize(int frameSize) const {112 113 if (is64Bit()) {114 // All 64-bit stack frames must be 16-byte aligned, and must reserve space115 // for spilling the 16 window registers at %sp+BIAS..%sp+BIAS+128.116 frameSize += 128;117 // Frames with calls must also reserve space for 6 outgoing arguments118 // whether they are used or not. LowerCall_64 takes care of that.119 frameSize = alignTo(frameSize, 16);120 } else {121 // Emit the correct save instruction based on the number of bytes in122 // the frame. Minimum stack frame size according to V8 ABI is:123 // 16 words for register window spill124 // 1 word for address of returned aggregate-value125 // + 6 words for passing parameters on the stack126 // ----------127 // 23 words * 4 bytes per word = 92 bytes128 frameSize += 92;129 130 // Round up to next doubleword boundary -- a double-word boundary131 // is required by the ABI.132 frameSize = alignTo(frameSize, 8);133 }134 return frameSize;135}136 137bool SparcSubtarget::enableMachineScheduler() const {138 return true;139}140