209 lines · c
1//===- MipsABIFlagsSection.h - Mips ELF ABI Flags Section -------*- C++ -*-===//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#ifndef LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSABIFLAGSSECTION_H10#define LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSABIFLAGSSECTION_H11 12#include "llvm/Support/ErrorHandling.h"13#include "llvm/Support/MipsABIFlags.h"14#include <cstdint>15 16namespace llvm {17 18class MCStreamer;19class StringRef;20 21struct MipsABIFlagsSection {22 // Internal representation of the fp_abi related values used in .module.23 enum class FpABIKind { ANY, XX, S32, S64, SOFT };24 25 // Version of flags structure.26 uint16_t Version = 0;27 // The level of the ISA: 1-5, 32, 64.28 uint8_t ISALevel = 0;29 // The revision of ISA: 0 for MIPS V and below, 1-n otherwise.30 uint8_t ISARevision = 0;31 // The size of general purpose registers.32 Mips::AFL_REG GPRSize = Mips::AFL_REG_NONE;33 // The size of co-processor 1 registers.34 Mips::AFL_REG CPR1Size = Mips::AFL_REG_NONE;35 // The size of co-processor 2 registers.36 Mips::AFL_REG CPR2Size = Mips::AFL_REG_NONE;37 // Processor-specific extension.38 Mips::AFL_EXT ISAExtension = Mips::AFL_EXT_NONE;39 // Mask of ASEs used.40 uint32_t ASESet = 0;41 42 bool OddSPReg = false;43 44 bool Is32BitABI = false;45 46protected:47 // The floating-point ABI.48 FpABIKind FpABI = FpABIKind::ANY;49 50public:51 MipsABIFlagsSection() = default;52 53 uint16_t getVersionValue() { return (uint16_t)Version; }54 uint8_t getISALevelValue() { return (uint8_t)ISALevel; }55 uint8_t getISARevisionValue() { return (uint8_t)ISARevision; }56 uint8_t getGPRSizeValue() { return (uint8_t)GPRSize; }57 uint8_t getCPR1SizeValue();58 uint8_t getCPR2SizeValue() { return (uint8_t)CPR2Size; }59 uint8_t getFpABIValue();60 uint32_t getISAExtensionValue() { return (uint32_t)ISAExtension; }61 uint32_t getASESetValue() { return (uint32_t)ASESet; }62 63 uint32_t getFlags1Value() {64 uint32_t Value = 0;65 66 if (OddSPReg)67 Value |= (uint32_t)Mips::AFL_FLAGS1_ODDSPREG;68 69 return Value;70 }71 72 uint32_t getFlags2Value() { return 0; }73 74 FpABIKind getFpABI() { return FpABI; }75 void setFpABI(FpABIKind Value, bool IsABI32Bit) {76 FpABI = Value;77 Is32BitABI = IsABI32Bit;78 }79 80 StringRef getFpABIString(FpABIKind Value);81 82 template <class PredicateLibrary>83 void setISALevelAndRevisionFromPredicates(const PredicateLibrary &P) {84 if (P.hasMips64()) {85 ISALevel = 64;86 if (P.hasMips64r6())87 ISARevision = 6;88 else if (P.hasMips64r5())89 ISARevision = 5;90 else if (P.hasMips64r3())91 ISARevision = 3;92 else if (P.hasMips64r2())93 ISARevision = 2;94 else95 ISARevision = 1;96 } else if (P.hasMips32()) {97 ISALevel = 32;98 if (P.hasMips32r6())99 ISARevision = 6;100 else if (P.hasMips32r5())101 ISARevision = 5;102 else if (P.hasMips32r3())103 ISARevision = 3;104 else if (P.hasMips32r2())105 ISARevision = 2;106 else107 ISARevision = 1;108 } else {109 ISARevision = 0;110 if (P.hasMips5())111 ISALevel = 5;112 else if (P.hasMips4())113 ISALevel = 4;114 else if (P.hasMips3())115 ISALevel = 3;116 else if (P.hasMips2())117 ISALevel = 2;118 else if (P.hasMips1())119 ISALevel = 1;120 else121 llvm_unreachable("Unknown ISA level!");122 }123 }124 125 template <class PredicateLibrary>126 void setGPRSizeFromPredicates(const PredicateLibrary &P) {127 GPRSize = P.isGP64bit() ? Mips::AFL_REG_64 : Mips::AFL_REG_32;128 }129 130 template <class PredicateLibrary>131 void setCPR1SizeFromPredicates(const PredicateLibrary &P) {132 if (P.useSoftFloat())133 CPR1Size = Mips::AFL_REG_NONE;134 else if (P.hasMSA())135 CPR1Size = Mips::AFL_REG_128;136 else137 CPR1Size = P.isFP64bit() ? Mips::AFL_REG_64 : Mips::AFL_REG_32;138 }139 140 template <class PredicateLibrary>141 void setISAExtensionFromPredicates(const PredicateLibrary &P) {142 if (P.hasCnMipsP())143 ISAExtension = Mips::AFL_EXT_OCTEONP;144 else if (P.hasCnMips())145 ISAExtension = Mips::AFL_EXT_OCTEON;146 else147 ISAExtension = Mips::AFL_EXT_NONE;148 }149 150 template <class PredicateLibrary>151 void setASESetFromPredicates(const PredicateLibrary &P) {152 ASESet = 0;153 if (P.hasDSP())154 ASESet |= Mips::AFL_ASE_DSP;155 if (P.hasDSPR2())156 ASESet |= Mips::AFL_ASE_DSPR2;157 if (P.hasMSA())158 ASESet |= Mips::AFL_ASE_MSA;159 if (P.inMicroMipsMode())160 ASESet |= Mips::AFL_ASE_MICROMIPS;161 if (P.inMips16Mode())162 ASESet |= Mips::AFL_ASE_MIPS16;163 if (P.hasMT())164 ASESet |= Mips::AFL_ASE_MT;165 if (P.hasCRC())166 ASESet |= Mips::AFL_ASE_CRC;167 if (P.hasVirt())168 ASESet |= Mips::AFL_ASE_VIRT;169 if (P.hasGINV())170 ASESet |= Mips::AFL_ASE_GINV;171 }172 173 template <class PredicateLibrary>174 void setFpAbiFromPredicates(const PredicateLibrary &P) {175 Is32BitABI = P.isABI_O32();176 177 FpABI = FpABIKind::ANY;178 if (P.useSoftFloat())179 FpABI = FpABIKind::SOFT;180 else if (P.isABI_N32() || P.isABI_N64())181 FpABI = FpABIKind::S64;182 else if (P.isABI_O32()) {183 if (P.isABI_FPXX())184 FpABI = FpABIKind::XX;185 else if (P.isFP64bit())186 FpABI = FpABIKind::S64;187 else188 FpABI = FpABIKind::S32;189 }190 }191 192 template <class PredicateLibrary>193 void setAllFromPredicates(const PredicateLibrary &P) {194 setISALevelAndRevisionFromPredicates(P);195 setGPRSizeFromPredicates(P);196 setCPR1SizeFromPredicates(P);197 setISAExtensionFromPredicates(P);198 setASESetFromPredicates(P);199 setFpAbiFromPredicates(P);200 OddSPReg = P.useOddSPReg();201 }202};203 204MCStreamer &operator<<(MCStreamer &OS, MipsABIFlagsSection &ABIFlagsSection);205 206} // end namespace llvm207 208#endif // LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSABIFLAGSSECTION_H209