[mips] Add assembler support for .set msa/nomsa directive.
[oota-llvm.git] / lib / Target / Mips / MipsTargetStreamer.h
index a0edc6f85d8164f9ae9f6a863652cd41cdc3e162..8253c6225639d044299f2096248551c77a792470 100644 (file)
 
 #include "llvm/MC/MCELFStreamer.h"
 #include "llvm/MC/MCStreamer.h"
+#include "MCTargetDesc/MipsABIFlagsSection.h"
 
 namespace llvm {
-struct Elf_Internal_ABIFlags_v0 {
-  // Version of flags structure.
-  uint16_t version;
-  // The level of the ISA: 1-5, 32, 64.
-  uint8_t isa_level;
-  // The revision of ISA: 0 for MIPS V and below, 1-n otherwise.
-  uint8_t isa_rev;
-  // The size of general purpose registers.
-  uint8_t gpr_size;
-  // The size of co-processor 1 registers.
-  uint8_t cpr1_size;
-  // The size of co-processor 2 registers.
-  uint8_t cpr2_size;
-  // The floating-point ABI.
-  uint8_t fp_abi;
-  // Processor-specific extension.
-  uint32_t isa_ext;
-  // Mask of ASEs used.
-  uint32_t ases;
-  // Mask of general flags.
-  uint32_t flags1;
-  uint32_t flags2;
-
-  Elf_Internal_ABIFlags_v0()
-      : version(0), isa_level(0), isa_rev(0), gpr_size(0), cpr1_size(0),
-        cpr2_size(0), fp_abi(0), isa_ext(0), ases(0), flags1(0), flags2(0) {}
-};
-
-// Values for the xxx_size bytes of an ABI flags structure.
-enum {
-  AFL_REG_NONE = 0x00, // No registers.
-  AFL_REG_32 = 0x01,   // 32-bit registers.
-  AFL_REG_64 = 0x02,   // 64-bit registers.
-  AFL_REG_128 = 0x03   // 128-bit registers.
-};
-
-// Masks for the ases word of an ABI flags structure.
-enum {
-  AFL_ASE_DSP = 0x00000001,       // DSP ASE.
-  AFL_ASE_DSPR2 = 0x00000002,     // DSP R2 ASE.
-  AFL_ASE_EVA = 0x00000004,       // Enhanced VA Scheme.
-  AFL_ASE_MCU = 0x00000008,       // MCU (MicroController) ASE.
-  AFL_ASE_MDMX = 0x00000010,      // MDMX ASE.
-  AFL_ASE_MIPS3D = 0x00000020,    // MIPS-3D ASE.
-  AFL_ASE_MT = 0x00000040,        // MT ASE.
-  AFL_ASE_SMARTMIPS = 0x00000080, // SmartMIPS ASE.
-  AFL_ASE_VIRT = 0x00000100,      // VZ ASE.
-  AFL_ASE_MSA = 0x00000200,       // MSA ASE.
-  AFL_ASE_MIPS16 = 0x00000400,    // MIPS16 ASE.
-  AFL_ASE_MICROMIPS = 0x00000800, // MICROMIPS ASE.
-  AFL_ASE_XPA = 0x00001000        // XPA ASE.
-};
-
-// Values for the isa_ext word of an ABI flags structure.
-enum {
-  AFL_EXT_XLR = 1,          // RMI Xlr instruction.
-  AFL_EXT_OCTEON2 = 2,      // Cavium Networks Octeon2.
-  AFL_EXT_OCTEONP = 3,      // Cavium Networks OcteonP.
-  AFL_EXT_LOONGSON_3A = 4,  // Loongson 3A.
-  AFL_EXT_OCTEON = 5,       // Cavium Networks Octeon.
-  AFL_EXT_5900 = 6,         // MIPS R5900 instruction.
-  AFL_EXT_4650 = 7,         // MIPS R4650 instruction.
-  AFL_EXT_4010 = 8,         // LSI R4010 instruction.
-  AFL_EXT_4100 = 9,         // NEC VR4100 instruction.
-  AFL_EXT_3900 = 10,        // Toshiba R3900 instruction.
-  AFL_EXT_10000 = 11,       // MIPS R10000 instruction.
-  AFL_EXT_SB1 = 12,         // Broadcom SB-1 instruction.
-  AFL_EXT_4111 = 13,        // NEC VR4111/VR4181 instruction.
-  AFL_EXT_4120 = 14,        // NEC VR4120 instruction.
-  AFL_EXT_5400 = 15,        // NEC VR5400 instruction.
-  AFL_EXT_5500 = 16,        // NEC VR5500 instruction.
-  AFL_EXT_LOONGSON_2E = 17, // ST Microelectronics Loongson 2E.
-  AFL_EXT_LOONGSON_2F = 18  // ST Microelectronics Loongson 2F.
-};
 
-// Values for the fp_abi word of an ABI flags structure.
-enum {
-  Val_GNU_MIPS_ABI_FP_DOUBLE = 1,
-  Val_GNU_MIPS_ABI_FP_XX = 5,
-  Val_GNU_MIPS_ABI_FP_64 = 6
-};
+struct MipsABIFlagsSection;
 
 class MipsTargetStreamer : public MCTargetStreamer {
 public:
@@ -108,6 +30,8 @@ public:
   virtual void emitDirectiveSetNoReorder();
   virtual void emitDirectiveSetMacro();
   virtual void emitDirectiveSetNoMacro();
+  virtual void emitDirectiveSetMsa();
+  virtual void emitDirectiveSetNoMsa();
   virtual void emitDirectiveSetAt();
   virtual void emitDirectiveSetNoAt();
   virtual void emitDirectiveEnd(StringRef Name);
@@ -123,115 +47,55 @@ public:
   virtual void emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff);
   virtual void emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff);
 
+  virtual void emitDirectiveSetMips1();
+  virtual void emitDirectiveSetMips2();
+  virtual void emitDirectiveSetMips3();
+  virtual void emitDirectiveSetMips4();
+  virtual void emitDirectiveSetMips5();
+  virtual void emitDirectiveSetMips32();
   virtual void emitDirectiveSetMips32R2();
+  virtual void emitDirectiveSetMips32R6();
   virtual void emitDirectiveSetMips64();
   virtual void emitDirectiveSetMips64R2();
+  virtual void emitDirectiveSetMips64R6();
   virtual void emitDirectiveSetDsp();
 
   // PIC support
   virtual void emitDirectiveCpload(unsigned RegNo);
   virtual void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
                                     const MCSymbol &Sym, bool IsReg);
-  // ABI Flags
-  virtual void emitDirectiveModule(unsigned Value, bool is32BitAbi){};
-  virtual void emitDirectiveSetFp(unsigned Value, bool is32BitAbi){};
+
+  /// Emit a '.module fp=value' directive using the given values.
+  /// Updates the .MIPS.abiflags section
+  virtual void emitDirectiveModuleFP(MipsABIFlagsSection::FpABIKind Value,
+                                     bool Is32BitABI) {
+    ABIFlagsSection.setFpABI(Value, Is32BitABI);
+  }
+
+  /// Emit a '.module fp=value' directive using the current values of the
+  /// .MIPS.abiflags section.
+  void emitDirectiveModuleFP() {
+    emitDirectiveModuleFP(ABIFlagsSection.getFpABI(),
+                          ABIFlagsSection.Is32BitABI);
+  }
+
+  virtual void emitDirectiveModuleOddSPReg(bool Enabled, bool IsO32ABI);
+  virtual void emitDirectiveSetFp(MipsABIFlagsSection::FpABIKind Value){};
   virtual void emitMipsAbiFlags(){};
   void setCanHaveModuleDir(bool Can) { canHaveModuleDirective = Can; }
   bool getCanHaveModuleDir() { return canHaveModuleDirective; }
 
-  void setVersion(uint16_t Version) { MipsABIFlags.version = Version; }
-  void setISALevel(uint8_t Level) { MipsABIFlags.isa_level = Level; }
-  void setISARev(uint8_t Rev) { MipsABIFlags.isa_rev = Rev; }
-  void setGprSize(uint8_t Size) { MipsABIFlags.gpr_size = Size; }
-  void setCpr1Size(uint8_t Size) { MipsABIFlags.cpr1_size = Size; }
-  void setCpr2Size(uint8_t Size) { MipsABIFlags.cpr2_size = Size; }
-  void setFpABI(uint8_t Abi) { MipsABIFlags.fp_abi = Abi; }
-  void setIsaExt(uint32_t IsaExt) { MipsABIFlags.isa_ext = IsaExt; }
-  void setASEs(uint32_t Ases) { MipsABIFlags.ases = Ases; }
-  void setFlags1(uint32_t Flags) { MipsABIFlags.flags1 = Flags; }
-  void setFlags2(uint32_t Flags) { MipsABIFlags.flags2 = Flags; }
-
-  uint8_t getFPAbi() { return MipsABIFlags.fp_abi; }
   // This method enables template classes to set internal abi flags
   // structure values.
   template <class PredicateLibrary>
   void updateABIInfo(const PredicateLibrary &P) {
-    setVersion(0); // Version, default value is 0.
-
-    if (P.hasMips64()) { // isa_level
-      setISALevel(64);
-      if (P.hasMips64r6())
-        setISARev(6);
-      else if (P.hasMips64r2())
-        setISARev(2);
-      else
-        setISARev(1);
-    } else if (P.hasMips32()) {
-      setISALevel(32);
-      if (P.hasMips32r6())
-        setISARev(6);
-      else if (P.hasMips32r2())
-        setISARev(2);
-      else
-        setISARev(1);
-    } else {
-      setISARev(0);
-      if (P.hasMips5())
-        setISALevel(5);
-      else if (P.hasMips4())
-        setISALevel(4);
-      else if (P.hasMips3())
-        setISALevel(3);
-      else if (P.hasMips2())
-        setISALevel(2);
-      else if (P.hasMips1())
-        setISALevel(1);
-      else
-        llvm_unreachable("Unknown ISA level!");
-    }
-
-    if (P.isGP64bit()) // GPR size.
-      setGprSize(AFL_REG_64);
-    else
-      setGprSize(AFL_REG_32);
-
-    // TODO: check for MSA128 value.
-    if (P.mipsSEUsesSoftFloat())
-      setCpr1Size(AFL_REG_NONE);
-    else if (P.isFP64bit())
-      setCpr1Size(AFL_REG_64);
-    else
-      setCpr1Size(AFL_REG_32);
-    setCpr2Size(AFL_REG_NONE); // Default value.
-
-    // Set ASE.
-    unsigned AseFlags = 0;
-    if (P.hasDSP())
-      AseFlags |= AFL_ASE_DSP;
-    if (P.hasDSPR2())
-      AseFlags |= AFL_ASE_DSPR2;
-    if (P.hasMSA())
-      AseFlags |= AFL_ASE_MSA;
-    if (P.inMicroMipsMode())
-      AseFlags |= AFL_ASE_MICROMIPS;
-    if (P.inMips16Mode())
-      AseFlags |= AFL_ASE_MIPS16;
-
-    if (P.isABI_N32() || P.isABI_N64())
-      setFpABI(Val_GNU_MIPS_ABI_FP_DOUBLE);
-    else if (P.isABI_O32()) {
-      if (P.isFP64bit())
-        setFpABI(Val_GNU_MIPS_ABI_FP_64);
-      else if (P.isABI_FPXX())
-        setFpABI(Val_GNU_MIPS_ABI_FP_XX);
-      else
-        setFpABI(Val_GNU_MIPS_ABI_FP_DOUBLE);
-    } else
-      setFpABI(0); // Default value.
+    ABIFlagsSection.setAllFromPredicates(P);
   }
 
+  MipsABIFlagsSection &getABIFlagsSection() { return ABIFlagsSection; }
+
 protected:
-  Elf_Internal_ABIFlags_v0 MipsABIFlags;
+  MipsABIFlagsSection ABIFlagsSection;
 
 private:
   bool canHaveModuleDirective;
@@ -252,6 +116,8 @@ public:
   void emitDirectiveSetNoReorder() override;
   void emitDirectiveSetMacro() override;
   void emitDirectiveSetNoMacro() override;
+  void emitDirectiveSetMsa() override;
+  void emitDirectiveSetNoMsa() override;
   void emitDirectiveSetAt() override;
   void emitDirectiveSetNoAt() override;
   void emitDirectiveEnd(StringRef Name) override;
@@ -267,9 +133,17 @@ public:
   void emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff) override;
   void emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) override;
 
+  void emitDirectiveSetMips1() override;
+  void emitDirectiveSetMips2() override;
+  void emitDirectiveSetMips3() override;
+  void emitDirectiveSetMips4() override;
+  void emitDirectiveSetMips5() override;
+  void emitDirectiveSetMips32() override;
   void emitDirectiveSetMips32R2() override;
+  void emitDirectiveSetMips32R6() override;
   void emitDirectiveSetMips64() override;
   void emitDirectiveSetMips64R2() override;
+  void emitDirectiveSetMips64R6() override;
   void emitDirectiveSetDsp() override;
 
   // PIC support
@@ -278,8 +152,10 @@ public:
                             const MCSymbol &Sym, bool IsReg) override;
 
   // ABI Flags
-  void emitDirectiveModule(unsigned Value, bool is32BitAbi) override;
-  void emitDirectiveSetFp(unsigned Value, bool is32BitAbi) override;
+  void emitDirectiveModuleFP(MipsABIFlagsSection::FpABIKind Value,
+                             bool Is32BitABI) override;
+  void emitDirectiveModuleOddSPReg(bool Enabled, bool IsO32ABI) override;
+  void emitDirectiveSetFp(MipsABIFlagsSection::FpABIKind Value) override;
   void emitMipsAbiFlags() override;
 };
 
@@ -322,9 +198,17 @@ public:
   void emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff) override;
   void emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) override;
 
+  void emitDirectiveSetMips1() override;
+  void emitDirectiveSetMips2() override;
+  void emitDirectiveSetMips3() override;
+  void emitDirectiveSetMips4() override;
+  void emitDirectiveSetMips5() override;
+  void emitDirectiveSetMips32() override;
   void emitDirectiveSetMips32R2() override;
+  void emitDirectiveSetMips32R6() override;
   void emitDirectiveSetMips64() override;
   void emitDirectiveSetMips64R2() override;
+  void emitDirectiveSetMips64R6() override;
   void emitDirectiveSetDsp() override;
 
   // PIC support
@@ -333,6 +217,7 @@ public:
                             const MCSymbol &Sym, bool IsReg) override;
 
   // ABI Flags
+  void emitDirectiveModuleOddSPReg(bool Enabled, bool IsO32ABI) override;
   void emitMipsAbiFlags() override;
 
 protected: