Index: llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -4703,6 +4703,8 @@ /// ::= .module oddspreg /// ::= .module nooddspreg /// ::= .module fp=value +/// ::= .module softfloat +/// ::= .module hardfloat bool MipsAsmParser::parseDirectiveModule() { MCAsmParser &Parser = getParser(); MCAsmLexer &Lexer = getLexer(); @@ -4765,6 +4767,44 @@ return false; // parseDirectiveModule has finished successfully. } else if (Option == "fp") { return parseDirectiveModuleFP(); + } else if (Option == "softfloat") { + setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float"); + + // Synchronize the ABI Flags information with the FeatureBits information we + // updated above. + getTargetStreamer().updateABIInfo(*this); + + // If printing assembly, use the recently updated ABI Flags information. + // If generating ELF, don't do anything (the .MIPS.abiflags section gets + // emitted later). + getTargetStreamer().emitDirectiveModuleSoftFloat(); + + // If this is not the end of the statement, report an error. + if (getLexer().isNot(AsmToken::EndOfStatement)) { + reportParseError("unexpected token, expected end of statement"); + return false; + } + + return false; // parseDirectiveModule has finished successfully. + } else if (Option == "hardfloat") { + clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float"); + + // Synchronize the ABI Flags information with the FeatureBits information we + // updated above. + getTargetStreamer().updateABIInfo(*this); + + // If printing assembly, use the recently updated ABI Flags information. + // If generating ELF, don't do anything (the .MIPS.abiflags section gets + // emitted later). + getTargetStreamer().emitDirectiveModuleHardFloat(); + + // If this is not the end of the statement, report an error. + if (getLexer().isNot(AsmToken::EndOfStatement)) { + reportParseError("unexpected token, expected end of statement"); + return false; + } + + return false; // parseDirectiveModule has finished successfully. } else { return Error(L, "'" + Twine(Option) + "' is not a valid .module option."); } Index: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -99,6 +99,8 @@ if (!ABIFlagsSection.OddSPReg && !ABIFlagsSection.Is32BitABI) report_fatal_error("+nooddspreg is only valid for O32"); } +void MipsTargetStreamer::emitDirectiveModuleSoftFloat() {} +void MipsTargetStreamer::emitDirectiveModuleHardFloat() {} void MipsTargetStreamer::emitDirectiveSetFp( MipsABIFlagsSection::FpABIKind Value) { forbidModuleDirective(); @@ -404,6 +406,14 @@ OS << "\t.set\tnooddspreg\n"; } +void MipsTargetAsmStreamer::emitDirectiveModuleSoftFloat() { + OS << "\t.module\tsoftfloat\n"; +} + +void MipsTargetAsmStreamer::emitDirectiveModuleHardFloat() { + OS << "\t.module\thardfloat\n"; +} + // This part is for ELF object output. MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI) Index: llvm/trunk/lib/Target/Mips/MipsTargetStreamer.h =================================================================== --- llvm/trunk/lib/Target/Mips/MipsTargetStreamer.h +++ llvm/trunk/lib/Target/Mips/MipsTargetStreamer.h @@ -83,6 +83,8 @@ // FP abiflags directives virtual void emitDirectiveModuleFP(); virtual void emitDirectiveModuleOddSPReg(); + virtual void emitDirectiveModuleSoftFloat(); + virtual void emitDirectiveModuleHardFloat(); virtual void emitDirectiveSetFp(MipsABIFlagsSection::FpABIKind Value); virtual void emitDirectiveSetOddSPReg(); virtual void emitDirectiveSetNoOddSPReg(); @@ -192,6 +194,8 @@ // FP abiflags directives void emitDirectiveModuleFP() override; void emitDirectiveModuleOddSPReg() override; + void emitDirectiveModuleSoftFloat() override; + void emitDirectiveModuleHardFloat() override; void emitDirectiveSetFp(MipsABIFlagsSection::FpABIKind Value) override; void emitDirectiveSetOddSPReg() override; void emitDirectiveSetNoOddSPReg() override; Index: llvm/trunk/test/MC/Mips/module-hardfloat.s =================================================================== --- llvm/trunk/test/MC/Mips/module-hardfloat.s +++ llvm/trunk/test/MC/Mips/module-hardfloat.s @@ -0,0 +1,26 @@ +# RUN: llvm-mc %s -arch=mips -mcpu=mips32 | \ +# RUN: FileCheck %s -check-prefix=CHECK-ASM +# +# RUN: llvm-mc %s -arch=mips -mcpu=mips32 -filetype=obj -o - | \ +# RUN: llvm-readobj -mips-abi-flags - | \ +# RUN: FileCheck %s -check-prefix=CHECK-OBJ + +# CHECK-ASM: .module hardfloat + +# Check if the MIPS.abiflags section was correctly emitted: +# CHECK-OBJ: MIPS ABI Flags { +# CHECK-OBJ: FP ABI: Hard float (32-bit CPU, Any FPU) (0x5) +# CHECK-OBJ: CPR1 size: 32 +# CHECK-OBJ: Flags 1 [ (0x1) +# CHECK-OBJ: ODDSPREG (0x1) +# CHECK-OBJ: ] +# CHECK-OBJ: } + + .module fp=xx + .module oddspreg + .module softfloat + .module hardfloat + +# FIXME: Test should include gnu_attributes directive when implemented. +# An explicit .gnu_attribute must be checked against the effective +# command line options and any inconsistencies reported via a warning. Index: llvm/trunk/test/MC/Mips/module-softfloat.s =================================================================== --- llvm/trunk/test/MC/Mips/module-softfloat.s +++ llvm/trunk/test/MC/Mips/module-softfloat.s @@ -0,0 +1,20 @@ +# RUN: llvm-mc %s -arch=mips -mcpu=mips32 | \ +# RUN: FileCheck %s -check-prefix=CHECK-ASM +# +# RUN: llvm-mc %s -arch=mips -mcpu=mips32 -filetype=obj -o - | \ +# RUN: llvm-readobj -mips-abi-flags - | \ +# RUN: FileCheck %s -check-prefix=CHECK-OBJ + +# CHECK-ASM: .module softfloat + +# Check if the MIPS.abiflags section was correctly emitted: +# CHECK-OBJ: MIPS ABI Flags { +# CHECK-OBJ: FP ABI: Soft float (0x3) +# CHECK-OBJ: CPR1 size: 0 +# CHECK-OBJ: } + + .module softfloat + +# FIXME: Test should include gnu_attributes directive when implemented. +# An explicit .gnu_attribute must be checked against the effective +# command line options and any inconsistencies reported via a warning.