Home | History | Annotate | Line # | Download | only in MCTargetDesc
      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-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 
      9 #ifndef LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSABIFLAGSSECTION_H
     10 #define LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSABIFLAGSSECTION_H
     11 
     12 #include "llvm/ADT/StringRef.h"
     13 #include "llvm/Support/ErrorHandling.h"
     14 #include "llvm/Support/MipsABIFlags.h"
     15 #include <cstdint>
     16 
     17 namespace llvm {
     18 
     19 class MCStreamer;
     20 
     21 struct 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 
     46 protected:
     47   // The floating-point ABI.
     48   FpABIKind FpABI = FpABIKind::ANY;
     49 
     50 public:
     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       else
     95         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       else
    107         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       else
    121         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     else
    137       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     else
    147       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       else
    188         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 
    204 MCStreamer &operator<<(MCStreamer &OS, MipsABIFlagsSection &ABIFlagsSection);
    205 
    206 } // end namespace llvm
    207 
    208 #endif // LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSABIFLAGSSECTION_H
    209