1c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines//===-- MipsABIFlagsSection.h - Mips ELF ABI Flags Section -----*- C++ -*--===//
2c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines//
3c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines//                     The LLVM Compiler Infrastructure
4c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines//
5c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines// This file is distributed under the University of Illinois Open Source
6c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines// License. See LICENSE.TXT for details.
7c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines//
8c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines//===----------------------------------------------------------------------===//
9c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#ifndef LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSABIFLAGSSECTION_H
1137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#define LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSABIFLAGSSECTION_H
12c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
13c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/MC/MCStreamer.h"
146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/Support/ErrorHandling.h"
156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/Support/MipsABIFlags.h"
16c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
17c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesnamespace llvm {
18c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
19c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesclass MCStreamer;
20c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
21c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstruct MipsABIFlagsSection {
226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // Internal representation of the fp_abi related values used in .module.
236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  enum class FpABIKind { ANY, XX, S32, S64, SOFT };
24c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
25c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // Version of flags structure.
26c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  uint16_t Version;
27c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // The level of the ISA: 1-5, 32, 64.
28c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  uint8_t ISALevel;
29c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // The revision of ISA: 0 for MIPS V and below, 1-n otherwise.
30c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  uint8_t ISARevision;
31c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // The size of general purpose registers.
326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  Mips::AFL_REG GPRSize;
33c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // The size of co-processor 1 registers.
346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  Mips::AFL_REG CPR1Size;
35c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // The size of co-processor 2 registers.
366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  Mips::AFL_REG CPR2Size;
37c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // Processor-specific extension.
38de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  Mips::AFL_EXT ISAExtension;
39c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // Mask of ASEs used.
40c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  uint32_t ASESet;
41c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
42c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  bool OddSPReg;
43c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
44c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  bool Is32BitABI;
45c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
46c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesprotected:
47c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // The floating-point ABI.
48c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  FpABIKind FpABI;
49c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
50c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinespublic:
51c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  MipsABIFlagsSection()
526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      : Version(0), ISALevel(0), ISARevision(0), GPRSize(Mips::AFL_REG_NONE),
536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        CPR1Size(Mips::AFL_REG_NONE), CPR2Size(Mips::AFL_REG_NONE),
54de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        ISAExtension(Mips::AFL_EXT_NONE), ASESet(0), OddSPReg(false),
55de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        Is32BitABI(false), FpABI(FpABIKind::ANY) {}
56c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
57c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  uint16_t getVersionValue() { return (uint16_t)Version; }
58c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  uint8_t getISALevelValue() { return (uint8_t)ISALevel; }
59c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  uint8_t getISARevisionValue() { return (uint8_t)ISARevision; }
60c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  uint8_t getGPRSizeValue() { return (uint8_t)GPRSize; }
6137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint8_t getCPR1SizeValue();
62c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  uint8_t getCPR2SizeValue() { return (uint8_t)CPR2Size; }
63c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  uint8_t getFpABIValue();
64de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  uint32_t getISAExtensionValue() { return (uint32_t)ISAExtension; }
65c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  uint32_t getASESetValue() { return (uint32_t)ASESet; }
66c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
67c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  uint32_t getFlags1Value() {
68c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    uint32_t Value = 0;
69c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
70c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (OddSPReg)
716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Value |= (uint32_t)Mips::AFL_FLAGS1_ODDSPREG;
72c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
73c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return Value;
74c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
75c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
76c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  uint32_t getFlags2Value() { return 0; }
77c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
78c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  FpABIKind getFpABI() { return FpABI; }
79c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  void setFpABI(FpABIKind Value, bool IsABI32Bit) {
80c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    FpABI = Value;
81c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    Is32BitABI = IsABI32Bit;
82c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
83c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  StringRef getFpABIString(FpABIKind Value);
84c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
85c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  template <class PredicateLibrary>
86c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  void setISALevelAndRevisionFromPredicates(const PredicateLibrary &P) {
87c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (P.hasMips64()) {
88c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      ISALevel = 64;
89c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      if (P.hasMips64r6())
90c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines        ISARevision = 6;
91ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      else if (P.hasMips64r5())
92ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        ISARevision = 5;
93ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      else if (P.hasMips64r3())
94ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        ISARevision = 3;
95c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      else if (P.hasMips64r2())
96c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines        ISARevision = 2;
97c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      else
98c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines        ISARevision = 1;
99c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    } else if (P.hasMips32()) {
100c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      ISALevel = 32;
101c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      if (P.hasMips32r6())
102c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines        ISARevision = 6;
103ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      else if (P.hasMips32r5())
104ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        ISARevision = 5;
105ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      else if (P.hasMips32r3())
106ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        ISARevision = 3;
107c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      else if (P.hasMips32r2())
108c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines        ISARevision = 2;
109c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      else
110c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines        ISARevision = 1;
111c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    } else {
112c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      ISARevision = 0;
113c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      if (P.hasMips5())
114c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines        ISALevel = 5;
115c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      else if (P.hasMips4())
116c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines        ISALevel = 4;
117c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      else if (P.hasMips3())
118c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines        ISALevel = 3;
119c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      else if (P.hasMips2())
120c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines        ISALevel = 2;
121c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      else if (P.hasMips1())
122c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines        ISALevel = 1;
123c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      else
124c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines        llvm_unreachable("Unknown ISA level!");
125c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    }
126c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
127c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
128c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  template <class PredicateLibrary>
129c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  void setGPRSizeFromPredicates(const PredicateLibrary &P) {
1306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    GPRSize = P.isGP64bit() ? Mips::AFL_REG_64 : Mips::AFL_REG_32;
131c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
132c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
133c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  template <class PredicateLibrary>
134c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  void setCPR1SizeFromPredicates(const PredicateLibrary &P) {
1356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (P.useSoftFloat())
1366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      CPR1Size = Mips::AFL_REG_NONE;
137c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    else if (P.hasMSA())
1386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      CPR1Size = Mips::AFL_REG_128;
139c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    else
1406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      CPR1Size = P.isFP64bit() ? Mips::AFL_REG_64 : Mips::AFL_REG_32;
141c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
142c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
143c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  template <class PredicateLibrary>
144de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void setISAExtensionFromPredicates(const PredicateLibrary &P) {
145de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (P.hasCnMips())
146de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      ISAExtension = Mips::AFL_EXT_OCTEON;
147de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    else
148de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      ISAExtension = Mips::AFL_EXT_NONE;
149de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
150de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
151de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  template <class PredicateLibrary>
152c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  void setASESetFromPredicates(const PredicateLibrary &P) {
153c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    ASESet = 0;
154c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (P.hasDSP())
1556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      ASESet |= Mips::AFL_ASE_DSP;
156c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (P.hasDSPR2())
1576948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      ASESet |= Mips::AFL_ASE_DSPR2;
158c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (P.hasMSA())
1596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      ASESet |= Mips::AFL_ASE_MSA;
160c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (P.inMicroMipsMode())
1616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      ASESet |= Mips::AFL_ASE_MICROMIPS;
162c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (P.inMips16Mode())
1636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      ASESet |= Mips::AFL_ASE_MIPS16;
164c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
165c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
166c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  template <class PredicateLibrary>
167c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  void setFpAbiFromPredicates(const PredicateLibrary &P) {
168c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    Is32BitABI = P.isABI_O32();
169c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
170c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    FpABI = FpABIKind::ANY;
1716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (P.useSoftFloat())
1726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      FpABI = FpABIKind::SOFT;
1736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    else if (P.isABI_N32() || P.isABI_N64())
174c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      FpABI = FpABIKind::S64;
175c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    else if (P.isABI_O32()) {
17637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (P.isABI_FPXX())
177c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines        FpABI = FpABIKind::XX;
17837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      else if (P.isFP64bit())
17937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        FpABI = FpABIKind::S64;
180c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      else
181c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines        FpABI = FpABIKind::S32;
182c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    }
183c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
184c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
185c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  template <class PredicateLibrary>
186c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  void setAllFromPredicates(const PredicateLibrary &P) {
187c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    setISALevelAndRevisionFromPredicates(P);
188c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    setGPRSizeFromPredicates(P);
189c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    setCPR1SizeFromPredicates(P);
190de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    setISAExtensionFromPredicates(P);
191c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    setASESetFromPredicates(P);
192c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    setFpAbiFromPredicates(P);
19337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    OddSPReg = P.useOddSPReg();
194c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
195c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines};
196c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
197c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesMCStreamer &operator<<(MCStreamer &OS, MipsABIFlagsSection &ABIFlagsSection);
198c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines}
199c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
200c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#endif
201