brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.0 KiB · 5abb546 Raw
259 lines · cpp
1//===-- RISCVBaseInfo.cpp - Top level definitions for RISC-V MC -----------===//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 contains small standalone enum definitions for the RISC-V target10// useful for the compiler back-end and the MC libraries.11//12//===----------------------------------------------------------------------===//13 14#include "RISCVBaseInfo.h"15#include "llvm/MC/MCInst.h"16#include "llvm/MC/MCRegisterInfo.h"17#include "llvm/MC/MCSubtargetInfo.h"18#include "llvm/Support/raw_ostream.h"19#include "llvm/TargetParser/TargetParser.h"20#include "llvm/TargetParser/Triple.h"21 22namespace llvm {23 24extern const SubtargetFeatureKV RISCVFeatureKV[RISCV::NumSubtargetFeatures];25 26namespace RISCVSysReg {27#define GET_SysRegsList_IMPL28#include "RISCVGenSearchableTables.inc"29} // namespace RISCVSysReg30 31namespace RISCVInsnOpcode {32#define GET_RISCVOpcodesList_IMPL33#include "RISCVGenSearchableTables.inc"34} // namespace RISCVInsnOpcode35 36namespace RISCVVInversePseudosTable {37using namespace RISCV;38#define GET_RISCVVInversePseudosTable_IMPL39#include "RISCVGenSearchableTables.inc"40} // namespace RISCVVInversePseudosTable41 42namespace RISCV {43#define GET_RISCVVSSEGTable_IMPL44#define GET_RISCVVLSEGTable_IMPL45#define GET_RISCVVLXSEGTable_IMPL46#define GET_RISCVVSXSEGTable_IMPL47#define GET_RISCVVLETable_IMPL48#define GET_RISCVVSETable_IMPL49#define GET_RISCVVLXTable_IMPL50#define GET_RISCVVSXTable_IMPL51#define GET_RISCVNDSVLNTable_IMPL52#include "RISCVGenSearchableTables.inc"53} // namespace RISCV54 55namespace RISCVABI {56ABI computeTargetABI(const Triple &TT, const FeatureBitset &FeatureBits,57                     StringRef ABIName) {58  auto TargetABI = getTargetABI(ABIName);59  bool IsRV64 = TT.isArch64Bit();60  bool IsRVE = FeatureBits[RISCV::FeatureStdExtE];61 62  if (!ABIName.empty() && TargetABI == ABI_Unknown) {63    errs()64        << "'" << ABIName65        << "' is not a recognized ABI for this target (ignoring target-abi)\n";66  } else if (ABIName.starts_with("ilp32") && IsRV64) {67    errs() << "32-bit ABIs are not supported for 64-bit targets (ignoring "68              "target-abi)\n";69    TargetABI = ABI_Unknown;70  } else if (ABIName.starts_with("lp64") && !IsRV64) {71    errs() << "64-bit ABIs are not supported for 32-bit targets (ignoring "72              "target-abi)\n";73    TargetABI = ABI_Unknown;74  } else if (!IsRV64 && IsRVE && TargetABI != ABI_ILP32E &&75             TargetABI != ABI_Unknown) {76    // TODO: move this checking to RISCVTargetLowering and RISCVAsmParser77    errs()78        << "Only the ilp32e ABI is supported for RV32E (ignoring target-abi)\n";79    TargetABI = ABI_Unknown;80  } else if (IsRV64 && IsRVE && TargetABI != ABI_LP64E &&81             TargetABI != ABI_Unknown) {82    // TODO: move this checking to RISCVTargetLowering and RISCVAsmParser83    errs()84        << "Only the lp64e ABI is supported for RV64E (ignoring target-abi)\n";85    TargetABI = ABI_Unknown;86  }87 88  if ((TargetABI == RISCVABI::ABI::ABI_ILP32E ||89       (TargetABI == ABI_Unknown && IsRVE && !IsRV64)) &&90      FeatureBits[RISCV::FeatureStdExtD])91    reportFatalUsageError("ILP32E cannot be used with the D ISA extension");92 93  if (TargetABI != ABI_Unknown)94    return TargetABI;95 96  // If no explicit ABI is given, try to compute the default ABI.97  auto ISAInfo = RISCVFeatures::parseFeatureBits(IsRV64, FeatureBits);98  if (!ISAInfo)99    reportFatalUsageError(ISAInfo.takeError());100  return getTargetABI((*ISAInfo)->computeDefaultABI());101}102 103ABI getTargetABI(StringRef ABIName) {104  auto TargetABI = StringSwitch<ABI>(ABIName)105                       .Case("ilp32", ABI_ILP32)106                       .Case("ilp32f", ABI_ILP32F)107                       .Case("ilp32d", ABI_ILP32D)108                       .Case("ilp32e", ABI_ILP32E)109                       .Case("lp64", ABI_LP64)110                       .Case("lp64f", ABI_LP64F)111                       .Case("lp64d", ABI_LP64D)112                       .Case("lp64e", ABI_LP64E)113                       .Default(ABI_Unknown);114  return TargetABI;115}116 117// To avoid the BP value clobbered by a function call, we need to choose a118// callee saved register to save the value. RV32E only has X8 and X9 as callee119// saved registers and X8 will be used as fp. So we choose X9 as bp.120MCRegister getBPReg() { return RISCV::X9; }121 122// Returns the register holding shadow call stack pointer.123MCRegister getSCSPReg() { return RISCV::X3; }124 125} // namespace RISCVABI126 127namespace RISCVFeatures {128 129void validate(const Triple &TT, const FeatureBitset &FeatureBits) {130  if (TT.isArch64Bit() && !FeatureBits[RISCV::Feature64Bit])131    reportFatalUsageError("RV64 target requires an RV64 CPU");132  if (!TT.isArch64Bit() && !FeatureBits[RISCV::Feature32Bit])133    reportFatalUsageError("RV32 target requires an RV32 CPU");134  if (FeatureBits[RISCV::Feature32Bit] &&135      FeatureBits[RISCV::Feature64Bit])136    reportFatalUsageError("RV32 and RV64 can't be combined");137}138 139llvm::Expected<std::unique_ptr<RISCVISAInfo>>140parseFeatureBits(bool IsRV64, const FeatureBitset &FeatureBits) {141  unsigned XLen = IsRV64 ? 64 : 32;142  std::vector<std::string> FeatureVector;143  // Convert FeatureBitset to FeatureVector.144  for (auto Feature : RISCVFeatureKV) {145    if (FeatureBits[Feature.Value] &&146        llvm::RISCVISAInfo::isSupportedExtensionFeature(Feature.Key))147      FeatureVector.push_back(std::string("+") + Feature.Key);148  }149  return llvm::RISCVISAInfo::parseFeatures(XLen, FeatureVector);150}151 152} // namespace RISCVFeatures153 154// Include the auto-generated portion of the compress emitter.155#define GEN_UNCOMPRESS_INSTR156#define GEN_COMPRESS_INSTR157#include "RISCVGenCompressInstEmitter.inc"158 159bool RISCVRVC::compress(MCInst &OutInst, const MCInst &MI,160                        const MCSubtargetInfo &STI) {161  return compressInst(OutInst, MI, STI);162}163 164bool RISCVRVC::uncompress(MCInst &OutInst, const MCInst &MI,165                          const MCSubtargetInfo &STI) {166  return uncompressInst(OutInst, MI, STI);167}168 169// Lookup table for fli.s for entries 2-31.170static constexpr std::pair<uint8_t, uint8_t> LoadFP32ImmArr[] = {171    {0b01101111, 0b00}, {0b01110000, 0b00}, {0b01110111, 0b00},172    {0b01111000, 0b00}, {0b01111011, 0b00}, {0b01111100, 0b00},173    {0b01111101, 0b00}, {0b01111101, 0b01}, {0b01111101, 0b10},174    {0b01111101, 0b11}, {0b01111110, 0b00}, {0b01111110, 0b01},175    {0b01111110, 0b10}, {0b01111110, 0b11}, {0b01111111, 0b00},176    {0b01111111, 0b01}, {0b01111111, 0b10}, {0b01111111, 0b11},177    {0b10000000, 0b00}, {0b10000000, 0b01}, {0b10000000, 0b10},178    {0b10000001, 0b00}, {0b10000010, 0b00}, {0b10000011, 0b00},179    {0b10000110, 0b00}, {0b10000111, 0b00}, {0b10001110, 0b00},180    {0b10001111, 0b00}, {0b11111111, 0b00}, {0b11111111, 0b10},181};182 183int RISCVLoadFPImm::getLoadFPImm(APFloat FPImm) {184  assert((&FPImm.getSemantics() == &APFloat::IEEEsingle() ||185          &FPImm.getSemantics() == &APFloat::IEEEdouble() ||186          &FPImm.getSemantics() == &APFloat::IEEEhalf()) &&187         "Unexpected semantics");188 189  // Handle the minimum normalized value which is different for each type.190  if (FPImm.isSmallestNormalized() && !FPImm.isNegative())191    return 1;192 193  // Convert to single precision to use its lookup table.194  bool LosesInfo;195  APFloat::opStatus Status = FPImm.convert(196      APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &LosesInfo);197  if (Status != APFloat::opOK || LosesInfo)198    return -1;199 200  APInt Imm = FPImm.bitcastToAPInt();201 202  if (Imm.extractBitsAsZExtValue(21, 0) != 0)203    return -1;204 205  bool Sign = Imm.extractBitsAsZExtValue(1, 31);206  uint8_t Mantissa = Imm.extractBitsAsZExtValue(2, 21);207  uint8_t Exp = Imm.extractBitsAsZExtValue(8, 23);208 209  auto EMI = llvm::lower_bound(LoadFP32ImmArr, std::make_pair(Exp, Mantissa));210  if (EMI == std::end(LoadFP32ImmArr) || EMI->first != Exp ||211      EMI->second != Mantissa)212    return -1;213 214  // Table doesn't have entry 0 or 1.215  int Entry = std::distance(std::begin(LoadFP32ImmArr), EMI) + 2;216 217  // The only legal negative value is -1.0(entry 0). 1.0 is entry 16.218  if (Sign) {219    if (Entry == 16)220      return 0;221    return -1;222  }223 224  return Entry;225}226 227float RISCVLoadFPImm::getFPImm(unsigned Imm) {228  assert(Imm != 1 && Imm != 30 && Imm != 31 && "Unsupported immediate");229 230  // Entry 0 is -1.0, the only negative value. Entry 16 is 1.0.231  uint32_t Sign = 0;232  if (Imm == 0) {233    Sign = 0b1;234    Imm = 16;235  }236 237  uint32_t Exp = LoadFP32ImmArr[Imm - 2].first;238  uint32_t Mantissa = LoadFP32ImmArr[Imm - 2].second;239 240  uint32_t I = Sign << 31 | Exp << 23 | Mantissa << 21;241  return bit_cast<float>(I);242}243 244void RISCVZC::printRegList(unsigned RlistEncode, raw_ostream &OS) {245  assert(RlistEncode >= RLISTENCODE::RA &&246         RlistEncode <= RLISTENCODE::RA_S0_S11 && "Invalid Rlist");247  OS << "{ra";248  if (RlistEncode > RISCVZC::RA) {249    OS << ", s0";250    if (RlistEncode == RISCVZC::RA_S0_S11)251      OS << "-s11";252    else if (RlistEncode > RISCVZC::RA_S0 && RlistEncode <= RISCVZC::RA_S0_S11)253      OS << "-s" << (RlistEncode - RISCVZC::RA_S0);254  }255  OS << "}";256}257 258} // namespace llvm259