1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
//===-- RISCVSubtarget.cpp - RISCV Subtarget Information ------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the RISCV specific subclass of TargetSubtargetInfo.
//
//===----------------------------------------------------------------------===//
#include "RISCVSubtarget.h"
#include "RISCV.h"
#include "RISCVCallLowering.h"
#include "RISCVFrameLowering.h"
#include "RISCVLegalizerInfo.h"
#include "RISCVRegisterBankInfo.h"
#include "RISCVTargetMachine.h"
#include "llvm/Support/TargetRegistry.h"
using namespace llvm;
#define DEBUG_TYPE "riscv-subtarget"
#define GET_SUBTARGETINFO_TARGET_DESC
#define GET_SUBTARGETINFO_CTOR
#include "RISCVGenSubtargetInfo.inc"
static cl::opt<unsigned> RVVVectorBitsMax(
"riscv-v-vector-bits-max",
cl::desc("Assume V extension vector registers are at most this big, "
"with zero meaning no maximum size is assumed."),
cl::init(0), cl::Hidden);
static cl::opt<unsigned> RVVVectorBitsMin(
"riscv-v-vector-bits-min",
cl::desc("Assume V extension vector registers are at least this big, "
"with zero meaning no minimum size is assumed."),
cl::init(0), cl::Hidden);
static cl::opt<unsigned> RVVVectorLMULMax(
"riscv-v-fixed-length-vector-lmul-max",
cl::desc("The maximum LMUL value to use for fixed length vectors. "
"Fractional LMUL values are not supported."),
cl::init(8), cl::Hidden);
void RISCVSubtarget::anchor() {}
RISCVSubtarget &
RISCVSubtarget::initializeSubtargetDependencies(const Triple &TT, StringRef CPU,
StringRef TuneCPU, StringRef FS,
StringRef ABIName) {
// Determine default and user-specified characteristics
bool Is64Bit = TT.isArch64Bit();
if (CPU.empty())
CPU = Is64Bit ? "generic-rv64" : "generic-rv32";
if (CPU == "generic")
report_fatal_error(Twine("CPU 'generic' is not supported. Use ") +
(Is64Bit ? "generic-rv64" : "generic-rv32"));
if (TuneCPU.empty())
TuneCPU = CPU;
ParseSubtargetFeatures(CPU, TuneCPU, FS);
if (Is64Bit) {
XLenVT = MVT::i64;
XLen = 64;
}
TargetABI = RISCVABI::computeTargetABI(TT, getFeatureBits(), ABIName);
RISCVFeatures::validate(TT, getFeatureBits());
return *this;
}
RISCVSubtarget::RISCVSubtarget(const Triple &TT, StringRef CPU,
StringRef TuneCPU, StringRef FS,
StringRef ABIName, const TargetMachine &TM)
: RISCVGenSubtargetInfo(TT, CPU, TuneCPU, FS),
UserReservedRegister(RISCV::NUM_TARGET_REGS),
FrameLowering(initializeSubtargetDependencies(TT, CPU, TuneCPU, FS, ABIName)),
InstrInfo(*this), RegInfo(getHwMode()), TLInfo(TM, *this) {
CallLoweringInfo.reset(new RISCVCallLowering(*getTargetLowering()));
Legalizer.reset(new RISCVLegalizerInfo(*this));
auto *RBI = new RISCVRegisterBankInfo(*getRegisterInfo());
RegBankInfo.reset(RBI);
InstSelector.reset(createRISCVInstructionSelector(
*static_cast<const RISCVTargetMachine *>(&TM), *this, *RBI));
}
const CallLowering *RISCVSubtarget::getCallLowering() const {
return CallLoweringInfo.get();
}
InstructionSelector *RISCVSubtarget::getInstructionSelector() const {
return InstSelector.get();
}
const LegalizerInfo *RISCVSubtarget::getLegalizerInfo() const {
return Legalizer.get();
}
const RegisterBankInfo *RISCVSubtarget::getRegBankInfo() const {
return RegBankInfo.get();
}
unsigned RISCVSubtarget::getMaxRVVVectorSizeInBits() const {
assert(hasStdExtV() && "Tried to get vector length without V support!");
if (RVVVectorBitsMax == 0)
return 0;
assert(RVVVectorBitsMax >= 128 && RVVVectorBitsMax <= 65536 &&
isPowerOf2_32(RVVVectorBitsMax) &&
"V extension requires vector length to be in the range of 128 to "
"65536 and a power of 2!");
assert(RVVVectorBitsMax >= RVVVectorBitsMin &&
"Minimum V extension vector length should not be larger than its "
"maximum!");
unsigned Max = std::max(RVVVectorBitsMin, RVVVectorBitsMax);
return PowerOf2Floor((Max < 128 || Max > 65536) ? 0 : Max);
}
unsigned RISCVSubtarget::getMinRVVVectorSizeInBits() const {
assert(hasStdExtV() &&
"Tried to get vector length without V extension support!");
assert((RVVVectorBitsMin == 0 ||
(RVVVectorBitsMin >= 128 && RVVVectorBitsMax <= 65536 &&
isPowerOf2_32(RVVVectorBitsMin))) &&
"V extension requires vector length to be in the range of 128 to "
"65536 and a power of 2!");
assert((RVVVectorBitsMax >= RVVVectorBitsMin || RVVVectorBitsMax == 0) &&
"Minimum V extension vector length should not be larger than its "
"maximum!");
unsigned Min = RVVVectorBitsMin;
if (RVVVectorBitsMax != 0)
Min = std::min(RVVVectorBitsMin, RVVVectorBitsMax);
return PowerOf2Floor((Min < 128 || Min > 65536) ? 0 : Min);
}
unsigned RISCVSubtarget::getMaxLMULForFixedLengthVectors() const {
assert(hasStdExtV() &&
"Tried to get maximum LMUL without V extension support!");
assert(RVVVectorLMULMax <= 8 && isPowerOf2_32(RVVVectorLMULMax) &&
"V extension requires a LMUL to be at most 8 and a power of 2!");
return PowerOf2Floor(std::max<unsigned>(RVVVectorLMULMax, 1));
}
bool RISCVSubtarget::useRVVForFixedLengthVectors() const {
return hasStdExtV() && getMinRVVVectorSizeInBits() != 0;
}
|