brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.5 KiB · 1d72d0b Raw
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