diff options
Diffstat (limited to 'lib/Target/Mips')
-rw-r--r-- | lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 24 | ||||
-rw-r--r-- | lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp | 26 | ||||
-rw-r--r-- | lib/Target/Mips/Mips.td | 2 | ||||
-rw-r--r-- | lib/Target/Mips/MipsAsmPrinter.cpp | 6 | ||||
-rw-r--r-- | lib/Target/Mips/MipsSubtarget.cpp | 21 | ||||
-rw-r--r-- | lib/Target/Mips/MipsSubtarget.h | 4 | ||||
-rw-r--r-- | lib/Target/Mips/MipsTargetStreamer.h | 6 |
7 files changed, 78 insertions, 11 deletions
diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index e1ebd7661c..41662d3f97 100644 --- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -144,6 +144,7 @@ class MipsAsmParser : public MCTargetAsmParser { bool isEvaluated(const MCExpr *Expr); bool parseSetFeature(uint64_t Feature); bool parseDirectiveCPSetup(); + bool parseDirectiveNaN(); bool parseDirectiveSet(); bool parseDirectiveOption(); @@ -2383,6 +2384,26 @@ bool MipsAsmParser::parseDirectiveCPSetup() { return false; } +bool MipsAsmParser::parseDirectiveNaN() { + if (getLexer().isNot(AsmToken::EndOfStatement)) { + const AsmToken &Tok = Parser.getTok(); + + if (Tok.getString() == "2008") { + Parser.Lex(); + getTargetStreamer().emitDirectiveNaN2008(); + return false; + } else if (Tok.getString() == "legacy") { + Parser.Lex(); + getTargetStreamer().emitDirectiveNaNLegacy(); + return false; + } + } + // If we don't recognize the option passed to the .nan + // directive (e.g. no option or unknown option), emit an error. + reportParseError("invalid option in .nan directive"); + return false; +} + bool MipsAsmParser::parseDirectiveSet() { // Get the next token. @@ -2566,6 +2587,9 @@ bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { return false; } + if (IDVal == ".nan") + return parseDirectiveNaN(); + if (IDVal == ".gpword") { parseDirectiveGpWord(); return false; diff --git a/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp index fb6aff2b0d..053e13e556 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -85,6 +85,13 @@ void MipsTargetAsmStreamer::emitDirectiveEnt(const MCSymbol &Symbol) { } void MipsTargetAsmStreamer::emitDirectiveAbiCalls() { OS << "\t.abicalls\n"; } + +void MipsTargetAsmStreamer::emitDirectiveNaN2008() { OS << "\t.nan\t2008\n"; } + +void MipsTargetAsmStreamer::emitDirectiveNaNLegacy() { + OS << "\t.nan\tlegacy\n"; +} + void MipsTargetAsmStreamer::emitDirectiveOptionPic0() { OS << "\t.option\tpic0\n"; } @@ -180,6 +187,10 @@ MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S, EFlags |= ELF::EF_MIPS_ABI_O32; } + // Other options. + if (Features & Mips::FeatureNaN2008) + EFlags |= ELF::EF_MIPS_NAN2008; + MCA.setELFHeaderEFlags(EFlags); } @@ -325,6 +336,21 @@ void MipsTargetELFStreamer::emitDirectiveAbiCalls() { Flags |= ELF::EF_MIPS_CPIC | ELF::EF_MIPS_PIC; MCA.setELFHeaderEFlags(Flags); } + +void MipsTargetELFStreamer::emitDirectiveNaN2008() { + MCAssembler &MCA = getStreamer().getAssembler(); + unsigned Flags = MCA.getELFHeaderEFlags(); + Flags |= ELF::EF_MIPS_NAN2008; + MCA.setELFHeaderEFlags(Flags); +} + +void MipsTargetELFStreamer::emitDirectiveNaNLegacy() { + MCAssembler &MCA = getStreamer().getAssembler(); + unsigned Flags = MCA.getELFHeaderEFlags(); + Flags &= ~ELF::EF_MIPS_NAN2008; + MCA.setELFHeaderEFlags(Flags); +} + void MipsTargetELFStreamer::emitDirectiveOptionPic0() { MCAssembler &MCA = getStreamer().getAssembler(); unsigned Flags = MCA.getELFHeaderEFlags(); diff --git a/lib/Target/Mips/Mips.td b/lib/Target/Mips/Mips.td index 7a8198c150..f0ada2b63f 100644 --- a/lib/Target/Mips/Mips.td +++ b/lib/Target/Mips/Mips.td @@ -34,6 +34,8 @@ def FeatureGP64Bit : SubtargetFeature<"gp64", "IsGP64bit", "true", "General Purpose Registers are 64-bit wide.">; def FeatureFP64Bit : SubtargetFeature<"fp64", "IsFP64bit", "true", "Support 64-bit FP registers.">; +def FeatureNaN2008 : SubtargetFeature<"nan2008", "IsNaN2008bit", "true", + "IEEE 754-2008 NaN encoding.">; def FeatureSingleFloat : SubtargetFeature<"single-float", "IsSingleFloat", "true", "Only supports single precision float">; def FeatureO32 : SubtargetFeature<"o32", "MipsABI", "O32", diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp index c9b56aa635..1ad7e00fdc 100644 --- a/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/lib/Target/Mips/MipsAsmPrinter.cpp @@ -637,6 +637,12 @@ void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) { OutStreamer.SwitchSection(OutContext.getELFSection( SectionName, ELF::SHT_PROGBITS, 0, SectionKind::getDataRel())); + // NaN: At the moment we only support: + // 1. .nan legacy (default) + // 2. .nan 2008 + Subtarget->isNaN2008() ? getTargetStreamer().emitDirectiveNaN2008() + : getTargetStreamer().emitDirectiveNaNLegacy(); + // TODO: handle O64 ABI if (Subtarget->isABI_EABI()) { diff --git a/lib/Target/Mips/MipsSubtarget.cpp b/lib/Target/Mips/MipsSubtarget.cpp index ffc3d2f46d..601467b72e 100644 --- a/lib/Target/Mips/MipsSubtarget.cpp +++ b/lib/Target/Mips/MipsSubtarget.cpp @@ -77,17 +77,16 @@ void MipsSubtarget::anchor() { } MipsSubtarget::MipsSubtarget(const std::string &TT, const std::string &CPU, const std::string &FS, bool little, - Reloc::Model _RM, MipsTargetMachine *_TM) : - MipsGenSubtargetInfo(TT, CPU, FS), - MipsArchVersion(Mips32), MipsABI(UnknownABI), IsLittle(little), - IsSingleFloat(false), IsFP64bit(false), IsGP64bit(false), HasVFPU(false), - HasCnMips(false), IsLinux(true), HasSEInReg(false), HasCondMov(false), - HasSwap(false), HasBitCount(false), HasFPIdx(false), - InMips16Mode(false), InMips16HardFloat(Mips16HardFloat), - InMicroMipsMode(false), HasDSP(false), HasDSPR2(false), - AllowMixed16_32(Mixed16_32 | Mips_Os16), Os16(Mips_Os16), HasMSA(false), - RM(_RM), OverrideMode(NoOverride), TM(_TM), TargetTriple(TT) -{ + Reloc::Model _RM, MipsTargetMachine *_TM) + : MipsGenSubtargetInfo(TT, CPU, FS), MipsArchVersion(Mips32), + MipsABI(UnknownABI), IsLittle(little), IsSingleFloat(false), + IsFP64bit(false), IsNaN2008bit(false), IsGP64bit(false), HasVFPU(false), + HasCnMips(false), IsLinux(true), HasSEInReg(false), HasCondMov(false), + HasSwap(false), HasBitCount(false), HasFPIdx(false), InMips16Mode(false), + InMips16HardFloat(Mips16HardFloat), InMicroMipsMode(false), HasDSP(false), + HasDSPR2(false), AllowMixed16_32(Mixed16_32 | Mips_Os16), Os16(Mips_Os16), + HasMSA(false), RM(_RM), OverrideMode(NoOverride), TM(_TM), + TargetTriple(TT) { std::string CPUName = CPU; CPUName = selectMipsCPU(TT, CPUName); diff --git a/lib/Target/Mips/MipsSubtarget.h b/lib/Target/Mips/MipsSubtarget.h index a4246e980b..c739f91817 100644 --- a/lib/Target/Mips/MipsSubtarget.h +++ b/lib/Target/Mips/MipsSubtarget.h @@ -56,6 +56,9 @@ protected: // IsFP64bit - The target processor has 64-bit floating point registers. bool IsFP64bit; + // IsNan2008 - IEEE 754-2008 NaN encoding. + bool IsNaN2008bit; + // IsFP64bit - General-purpose registers are 64 bits wide bool IsGP64bit; @@ -158,6 +161,7 @@ public: bool isLittle() const { return IsLittle; } bool isFP64bit() const { return IsFP64bit; } + bool isNaN2008() const { return IsNaN2008bit; } bool isNotFP64bit() const { return !IsFP64bit; } bool isGP64bit() const { return IsGP64bit; } bool isGP32bit() const { return !IsGP64bit; } diff --git a/lib/Target/Mips/MipsTargetStreamer.h b/lib/Target/Mips/MipsTargetStreamer.h index 5f4b74b3ba..198888cf52 100644 --- a/lib/Target/Mips/MipsTargetStreamer.h +++ b/lib/Target/Mips/MipsTargetStreamer.h @@ -34,6 +34,8 @@ public: virtual void emitDirectiveEnt(const MCSymbol &Symbol) = 0; virtual void emitDirectiveAbiCalls() = 0; + virtual void emitDirectiveNaN2008() = 0; + virtual void emitDirectiveNaNLegacy() = 0; virtual void emitDirectiveOptionPic0() = 0; virtual void emitDirectiveOptionPic2() = 0; virtual void emitFrame(unsigned StackReg, unsigned StackSize, @@ -68,6 +70,8 @@ public: virtual void emitDirectiveEnt(const MCSymbol &Symbol); virtual void emitDirectiveAbiCalls(); + virtual void emitDirectiveNaN2008(); + virtual void emitDirectiveNaNLegacy(); virtual void emitDirectiveOptionPic0(); virtual void emitDirectiveOptionPic2(); virtual void emitFrame(unsigned StackReg, unsigned StackSize, @@ -111,6 +115,8 @@ public: virtual void emitDirectiveEnt(const MCSymbol &Symbol); virtual void emitDirectiveAbiCalls(); + virtual void emitDirectiveNaN2008(); + virtual void emitDirectiveNaNLegacy(); virtual void emitDirectiveOptionPic0(); virtual void emitDirectiveOptionPic2(); virtual void emitFrame(unsigned StackReg, unsigned StackSize, |