Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -82,6 +82,10 @@ MCSubtargetInfo &STI; MCAsmParser &Parser; MipsAssemblerOptions Options; + MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be NULL + // which indicates no function is currently selected. + // This usually happens after an '.end function' + // directive. #define GET_ASSEMBLER_HEADER #include "MipsGenAsmMatcher.inc" @@ -285,6 +289,8 @@ if (!isABI_O32() && !useOddSPReg() != 0) report_fatal_error("-mno-odd-spreg requires the O32 ABI"); + + CurrentFn = nullptr; } MCAsmParser &getParser() const { return Parser; } @@ -3055,22 +3061,146 @@ parseDataDirective(8, DirectiveID.getLoc()); return false; } - if (IDVal == ".ent") { - // Ignore this directive for now. - Parser.Lex(); + StringRef SymbolName; + + if (Parser.parseIdentifier(SymbolName)) { + reportParseError("expected identifier after .ent"); + return false; + } + + // There's an undocumented extension that allows an integer to + // follow the name of the procedure which AFAICS is ignored by GAS. + // Example: .ent foo,2 + if (getLexer().isNot(AsmToken::EndOfStatement)) { + if (getLexer().isNot(AsmToken::Comma)) { + // Treat the directive as if it were the normal version, + // not the undocumented extended version + reportParseError("unexpected token, expected end of statement"); + return false; + } + Parser.Lex(); // Eat the comma. + const MCExpr *DummyNumber; + int64_t DummyNumberVal; + if (Parser.parseExpression(DummyNumber)) { + reportParseError("expected number after comma"); + return false; + } + if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) { + reportParseError("expected an absolute expression after comma"); + return false; + } + } + + // 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; + } + + MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName); + + getTargetStreamer().emitDirectiveEnt(*Sym); + CurrentFn = Sym; return false; } if (IDVal == ".end") { - // Ignore this directive for now. - Parser.Lex(); + StringRef SymbolName; + + if (Parser.parseIdentifier(SymbolName)) { + reportParseError("expected identifier after .end"); + return false; + } + + if (getLexer().isNot(AsmToken::EndOfStatement)) { + reportParseError("unexpected token, expected end of statement"); + return false; + } + + if (CurrentFn == nullptr) { + reportParseError(".end used without .ent"); + return false; + } + + if ((SymbolName != CurrentFn->getName())) { + reportParseError(".end symbol does not match .ent symbol"); + return false; + } + + getTargetStreamer().emitDirectiveEnd(SymbolName); + CurrentFn = nullptr; return false; } if (IDVal == ".frame") { - // Ignore this directive for now. - Parser.eatToEndOfStatement(); + // .frame $stack_reg, frame_size_in_bytes, $return_reg + SmallVector, 1> TmpReg; + OperandMatchResultTy ResTy = ParseAnyRegister(TmpReg); + if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) { + reportParseError("expected stack register"); + return false; + } + + MipsOperand &StackRegOpnd = static_cast(*TmpReg[0]); + if (!StackRegOpnd.isGPRAsmReg()) { + reportParseError(StackRegOpnd.getStartLoc(), + "expected general purpose register"); + return false; + } + unsigned StackReg = StackRegOpnd.getGPR32Reg(); + + if (Parser.getTok().is(AsmToken::Comma)) + Parser.Lex(); + else { + reportParseError("unexpected token, expected comma"); + return false; + } + + // Parse the frame size. + const MCExpr *FrameSize; + int64_t FrameSizeVal; + + if (Parser.parseExpression(FrameSize)) { + reportParseError("expected frame size value"); + return false; + } + + if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) { + reportParseError("frame size not an absolute expression"); + return false; + } + + if (Parser.getTok().is(AsmToken::Comma)) + Parser.Lex(); + else { + reportParseError("unexpected token, expected comma"); + return false; + } + + // Parse the return register. + TmpReg.clear(); + ResTy = ParseAnyRegister(TmpReg); + if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) { + reportParseError("expected return register"); + return false; + } + + MipsOperand &ReturnRegOpnd = static_cast(*TmpReg[0]); + if (!ReturnRegOpnd.isGPRAsmReg()) { + reportParseError(ReturnRegOpnd.getStartLoc(), + "expected general purpose register"); + return false; + } + + // 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; + } + + getTargetStreamer().emitFrame(StackReg, FrameSizeVal, + ReturnRegOpnd.getGPR32Reg()); return false; } @@ -3078,15 +3208,61 @@ return parseDirectiveSet(); } - if (IDVal == ".fmask") { - // Ignore this directive for now. - Parser.eatToEndOfStatement(); - return false; - } + if (IDVal == ".mask" || IDVal == ".fmask") { + // .mask bitmask, frame_offset + // bitmask: One bit for each register used. + // frame_offset: Offset from Canonical Frame Address ($sp on entry) where + // first register is expected to be saved. + // Examples: + // .mask 0x80000000, -4 + // .fmask 0x80000000, -4 + // - if (IDVal == ".mask") { - // Ignore this directive for now. - Parser.eatToEndOfStatement(); + // Parse the bitmask + const MCExpr *BitMask; + int64_t BitMaskVal; + + if (Parser.parseExpression(BitMask)) { + reportParseError("expected bitmask value"); + return false; + } + + if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) { + reportParseError("bitmask not an absolute expression"); + return false; + } + + if (Parser.getTok().is(AsmToken::Comma)) + Parser.Lex(); + else { + reportParseError("unexpected token, expected comma"); + return false; + } + + // Parse the frame_offset + const MCExpr *FrameOffset; + int64_t FrameOffsetVal; + + if (Parser.parseExpression(FrameOffset)) { + reportParseError("expected frame offset value"); + return false; + } + + if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) { + reportParseError("frame offset not an absolute expression"); + return false; + } + + // 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; + } + + if (IDVal == ".mask") + getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal); + else + getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal); return false; } Index: lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -29,19 +29,27 @@ using namespace llvm; MipsTargetStreamer::MipsTargetStreamer(MCStreamer &S) - : MCTargetStreamer(S), canHaveModuleDirective(true) {} + : MCTargetStreamer(S), canHaveModuleDirective(true) { + GPRInfoSet = FPRInfoSet = FrameInfoSet = false; +} void MipsTargetStreamer::emitDirectiveSetMicroMips() {} void MipsTargetStreamer::emitDirectiveSetNoMicroMips() {} void MipsTargetStreamer::emitDirectiveSetMips16() {} -void MipsTargetStreamer::emitDirectiveSetNoMips16() {} -void MipsTargetStreamer::emitDirectiveSetReorder() {} +void MipsTargetStreamer::emitDirectiveSetNoMips16() { + setCanHaveModuleDir(false); +} +void MipsTargetStreamer::emitDirectiveSetReorder() { + setCanHaveModuleDir(false); +} void MipsTargetStreamer::emitDirectiveSetNoReorder() {} -void MipsTargetStreamer::emitDirectiveSetMacro() {} -void MipsTargetStreamer::emitDirectiveSetNoMacro() {} +void MipsTargetStreamer::emitDirectiveSetMacro() { setCanHaveModuleDir(false); } +void MipsTargetStreamer::emitDirectiveSetNoMacro() { + setCanHaveModuleDir(false); +} void MipsTargetStreamer::emitDirectiveSetMsa() { setCanHaveModuleDir(false); } void MipsTargetStreamer::emitDirectiveSetNoMsa() { setCanHaveModuleDir(false); } -void MipsTargetStreamer::emitDirectiveSetAt() {} -void MipsTargetStreamer::emitDirectiveSetNoAt() {} +void MipsTargetStreamer::emitDirectiveSetAt() { setCanHaveModuleDir(false); } +void MipsTargetStreamer::emitDirectiveSetNoAt() { setCanHaveModuleDir(false); } void MipsTargetStreamer::emitDirectiveEnd(StringRef Name) {} void MipsTargetStreamer::emitDirectiveEnt(const MCSymbol &Symbol) {} void MipsTargetStreamer::emitDirectiveAbiCalls() {} @@ -54,18 +62,30 @@ void MipsTargetStreamer::emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff) {} void MipsTargetStreamer::emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) { } -void MipsTargetStreamer::emitDirectiveSetMips1() {} -void MipsTargetStreamer::emitDirectiveSetMips2() {} -void MipsTargetStreamer::emitDirectiveSetMips3() {} -void MipsTargetStreamer::emitDirectiveSetMips4() {} -void MipsTargetStreamer::emitDirectiveSetMips5() {} -void MipsTargetStreamer::emitDirectiveSetMips32() {} -void MipsTargetStreamer::emitDirectiveSetMips32R2() {} -void MipsTargetStreamer::emitDirectiveSetMips32R6() {} -void MipsTargetStreamer::emitDirectiveSetMips64() {} -void MipsTargetStreamer::emitDirectiveSetMips64R2() {} -void MipsTargetStreamer::emitDirectiveSetMips64R6() {} -void MipsTargetStreamer::emitDirectiveSetDsp() {} +void MipsTargetStreamer::emitDirectiveSetMips1() { setCanHaveModuleDir(false); } +void MipsTargetStreamer::emitDirectiveSetMips2() { setCanHaveModuleDir(false); } +void MipsTargetStreamer::emitDirectiveSetMips3() { setCanHaveModuleDir(false); } +void MipsTargetStreamer::emitDirectiveSetMips4() { setCanHaveModuleDir(false); } +void MipsTargetStreamer::emitDirectiveSetMips5() { setCanHaveModuleDir(false); } +void MipsTargetStreamer::emitDirectiveSetMips32() { + setCanHaveModuleDir(false); +} +void MipsTargetStreamer::emitDirectiveSetMips32R2() { + setCanHaveModuleDir(false); +} +void MipsTargetStreamer::emitDirectiveSetMips32R6() { + setCanHaveModuleDir(false); +} +void MipsTargetStreamer::emitDirectiveSetMips64() { + setCanHaveModuleDir(false); +} +void MipsTargetStreamer::emitDirectiveSetMips64R2() { + setCanHaveModuleDir(false); +} +void MipsTargetStreamer::emitDirectiveSetMips64R6() { + setCanHaveModuleDir(false); +} +void MipsTargetStreamer::emitDirectiveSetDsp() { setCanHaveModuleDir(false); } void MipsTargetStreamer::emitDirectiveCpload(unsigned RegNo) {} void MipsTargetStreamer::emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset, const MCSymbol &Sym, bool IsReg) { @@ -97,12 +117,12 @@ void MipsTargetAsmStreamer::emitDirectiveSetNoMips16() { OS << "\t.set\tnomips16\n"; - setCanHaveModuleDir(false); + MipsTargetStreamer::emitDirectiveSetNoMips16(); } void MipsTargetAsmStreamer::emitDirectiveSetReorder() { OS << "\t.set\treorder\n"; - setCanHaveModuleDir(false); + MipsTargetStreamer::emitDirectiveSetReorder(); } void MipsTargetAsmStreamer::emitDirectiveSetNoReorder() { @@ -112,12 +132,12 @@ void MipsTargetAsmStreamer::emitDirectiveSetMacro() { OS << "\t.set\tmacro\n"; - setCanHaveModuleDir(false); + MipsTargetStreamer::emitDirectiveSetMacro(); } void MipsTargetAsmStreamer::emitDirectiveSetNoMacro() { OS << "\t.set\tnomacro\n"; - setCanHaveModuleDir(false); + MipsTargetStreamer::emitDirectiveSetNoMacro(); } void MipsTargetAsmStreamer::emitDirectiveSetMsa() { @@ -132,12 +152,12 @@ void MipsTargetAsmStreamer::emitDirectiveSetAt() { OS << "\t.set\tat\n"; - setCanHaveModuleDir(false); + MipsTargetStreamer::emitDirectiveSetAt(); } void MipsTargetAsmStreamer::emitDirectiveSetNoAt() { OS << "\t.set\tnoat\n"; - setCanHaveModuleDir(false); + MipsTargetStreamer::emitDirectiveSetNoAt(); } void MipsTargetAsmStreamer::emitDirectiveEnd(StringRef Name) { @@ -174,62 +194,62 @@ void MipsTargetAsmStreamer::emitDirectiveSetMips1() { OS << "\t.set\tmips1\n"; - setCanHaveModuleDir(false); + MipsTargetStreamer::emitDirectiveSetMips1(); } void MipsTargetAsmStreamer::emitDirectiveSetMips2() { OS << "\t.set\tmips2\n"; - setCanHaveModuleDir(false); + MipsTargetStreamer::emitDirectiveSetMips2(); } void MipsTargetAsmStreamer::emitDirectiveSetMips3() { OS << "\t.set\tmips3\n"; - setCanHaveModuleDir(false); + MipsTargetStreamer::emitDirectiveSetMips3(); } void MipsTargetAsmStreamer::emitDirectiveSetMips4() { OS << "\t.set\tmips4\n"; - setCanHaveModuleDir(false); + MipsTargetStreamer::emitDirectiveSetMips4(); } void MipsTargetAsmStreamer::emitDirectiveSetMips5() { OS << "\t.set\tmips5\n"; - setCanHaveModuleDir(false); + MipsTargetStreamer::emitDirectiveSetMips5(); } void MipsTargetAsmStreamer::emitDirectiveSetMips32() { OS << "\t.set\tmips32\n"; - setCanHaveModuleDir(false); + MipsTargetStreamer::emitDirectiveSetMips32(); } void MipsTargetAsmStreamer::emitDirectiveSetMips32R2() { OS << "\t.set\tmips32r2\n"; - setCanHaveModuleDir(false); + MipsTargetStreamer::emitDirectiveSetMips32R2(); } void MipsTargetAsmStreamer::emitDirectiveSetMips32R6() { OS << "\t.set\tmips32r6\n"; - setCanHaveModuleDir(false); + MipsTargetStreamer::emitDirectiveSetMips32R6(); } void MipsTargetAsmStreamer::emitDirectiveSetMips64() { OS << "\t.set\tmips64\n"; - setCanHaveModuleDir(false); + MipsTargetStreamer::emitDirectiveSetMips64(); } void MipsTargetAsmStreamer::emitDirectiveSetMips64R2() { OS << "\t.set\tmips64r2\n"; - setCanHaveModuleDir(false); + MipsTargetStreamer::emitDirectiveSetMips64R2(); } void MipsTargetAsmStreamer::emitDirectiveSetMips64R6() { OS << "\t.set\tmips64r6\n"; - setCanHaveModuleDir(false); + MipsTargetStreamer::emitDirectiveSetMips64R6(); } void MipsTargetAsmStreamer::emitDirectiveSetDsp() { OS << "\t.set\tdsp\n"; - setCanHaveModuleDir(false); + MipsTargetStreamer::emitDirectiveSetDsp(); } // Print a 32 bit hex number with all numbers. static void printHex32(unsigned Value, raw_ostream &OS) { @@ -438,6 +458,7 @@ unsigned Flags = MCA.getELFHeaderEFlags(); Flags |= ELF::EF_MIPS_MICROMIPS; MCA.setELFHeaderEFlags(Flags); + setCanHaveModuleDir(false); } void MipsTargetELFStreamer::emitDirectiveSetNoMicroMips() { @@ -453,16 +474,6 @@ setCanHaveModuleDir(false); } -void MipsTargetELFStreamer::emitDirectiveSetNoMips16() { - // FIXME: implement. - setCanHaveModuleDir(false); -} - -void MipsTargetELFStreamer::emitDirectiveSetReorder() { - // FIXME: implement. - setCanHaveModuleDir(false); -} - void MipsTargetELFStreamer::emitDirectiveSetNoReorder() { MCAssembler &MCA = getStreamer().getAssembler(); unsigned Flags = MCA.getELFHeaderEFlags(); @@ -471,32 +482,46 @@ setCanHaveModuleDir(false); } -void MipsTargetELFStreamer::emitDirectiveSetMacro() { - // FIXME: implement. - setCanHaveModuleDir(false); -} +void MipsTargetELFStreamer::emitDirectiveEnd(StringRef Name) { + MCAssembler &MCA = getStreamer().getAssembler(); + MCContext &Context = MCA.getContext(); + MCStreamer &OS = getStreamer(); -void MipsTargetELFStreamer::emitDirectiveSetNoMacro() { - // FIXME: implement. - setCanHaveModuleDir(false); -} + const MCSectionELF *Sec = Context.getELFSection(".pdr", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC | ELF::SHT_REL, + SectionKind::getMetadata()); -void MipsTargetELFStreamer::emitDirectiveSetAt() { - // FIXME: implement. - setCanHaveModuleDir(false); -} + const MCSymbolRefExpr *ExprRef = + MCSymbolRefExpr::Create(Name, MCSymbolRefExpr::VK_None, Context); -void MipsTargetELFStreamer::emitDirectiveSetNoAt() { - // FIXME: implement. - setCanHaveModuleDir(false); -} + MCSectionData &SecData = MCA.getOrCreateSectionData(*Sec); + SecData.setAlignment(4); -void MipsTargetELFStreamer::emitDirectiveEnd(StringRef Name) { - // FIXME: implement. + OS.PushSection(); + + OS.SwitchSection(Sec); + + OS.EmitValueImpl(ExprRef, 4); + + OS.EmitIntValue(GPRInfoSet ? GPRBitMask : 0, 4); // reg_mask + OS.EmitIntValue(GPRInfoSet ? GPROffset : 0, 4); // reg_offset + + OS.EmitIntValue(FPRInfoSet ? FPRBitMask : 0, 4); // fpreg_mask + OS.EmitIntValue(FPRInfoSet ? FPROffset : 0, 4); // fpreg_offset + + OS.EmitIntValue(FrameInfoSet ? FrameOffset : 0, 4); // frame_offset + OS.EmitIntValue(FrameInfoSet ? FrameReg : 0, 4); // frame_reg + OS.EmitIntValue(FrameInfoSet ? ReturnReg : 0, 4); // return_reg + + // The .end directive marks the end of a procedure. Invalidate + // the information gathered up until this point. + GPRInfoSet = FPRInfoSet = FrameInfoSet = false; + + OS.PopSection(); } void MipsTargetELFStreamer::emitDirectiveEnt(const MCSymbol &Symbol) { - // FIXME: implement. + GPRInfoSet = FPRInfoSet = FrameInfoSet = false; } void MipsTargetELFStreamer::emitDirectiveAbiCalls() { @@ -542,66 +567,28 @@ } void MipsTargetELFStreamer::emitFrame(unsigned StackReg, unsigned StackSize, - unsigned ReturnReg) { - // FIXME: implement. + unsigned ReturnReg_) { + MCContext &Context = getStreamer().getAssembler().getContext(); + const MCRegisterInfo *RegInfo = Context.getRegisterInfo(); + + FrameInfoSet = true; + FrameReg = RegInfo->getEncodingValue(StackReg); + FrameOffset = StackSize; + ReturnReg = RegInfo->getEncodingValue(ReturnReg_); } void MipsTargetELFStreamer::emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff) { - // FIXME: implement. + GPRInfoSet = true; + GPRBitMask = CPUBitmask; + GPROffset = CPUTopSavedRegOff; } void MipsTargetELFStreamer::emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) { - // FIXME: implement. -} - -void MipsTargetELFStreamer::emitDirectiveSetMips1() { - setCanHaveModuleDir(false); -} - -void MipsTargetELFStreamer::emitDirectiveSetMips2() { - setCanHaveModuleDir(false); -} - -void MipsTargetELFStreamer::emitDirectiveSetMips3() { - setCanHaveModuleDir(false); -} - -void MipsTargetELFStreamer::emitDirectiveSetMips4() { - setCanHaveModuleDir(false); -} - -void MipsTargetELFStreamer::emitDirectiveSetMips5() { - setCanHaveModuleDir(false); -} - -void MipsTargetELFStreamer::emitDirectiveSetMips32() { - setCanHaveModuleDir(false); -} - -void MipsTargetELFStreamer::emitDirectiveSetMips32R2() { - setCanHaveModuleDir(false); -} - -void MipsTargetELFStreamer::emitDirectiveSetMips32R6() { - setCanHaveModuleDir(false); -} - -void MipsTargetELFStreamer::emitDirectiveSetMips64() { - setCanHaveModuleDir(false); -} - -void MipsTargetELFStreamer::emitDirectiveSetMips64R2() { - setCanHaveModuleDir(false); -} - -void MipsTargetELFStreamer::emitDirectiveSetMips64R6() { - setCanHaveModuleDir(false); -} - -void MipsTargetELFStreamer::emitDirectiveSetDsp() { - setCanHaveModuleDir(false); + FPRInfoSet = true; + FPRBitMask = FPUBitmask; + FPROffset = FPUTopSavedRegOff; } void MipsTargetELFStreamer::emitDirectiveCpload(unsigned RegNo) { Index: lib/Target/Mips/MipsTargetStreamer.h =================================================================== --- lib/Target/Mips/MipsTargetStreamer.h +++ lib/Target/Mips/MipsTargetStreamer.h @@ -11,6 +11,7 @@ #define MIPSTARGETSTREAMER_H #include "llvm/MC/MCELFStreamer.h" +#include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCStreamer.h" #include "MCTargetDesc/MipsABIFlagsSection.h" @@ -97,6 +98,19 @@ protected: MipsABIFlagsSection ABIFlagsSection; + bool GPRInfoSet; + unsigned GPRBitMask; + int GPROffset; + + bool FPRInfoSet; + unsigned FPRBitMask; + int FPROffset; + + bool FrameInfoSet; + int FrameOffset; + unsigned FrameReg; + unsigned ReturnReg; + private: bool canHaveModuleDirective; }; @@ -177,14 +191,8 @@ void emitDirectiveSetMicroMips() override; void emitDirectiveSetNoMicroMips() override; void emitDirectiveSetMips16() override; - void emitDirectiveSetNoMips16() override; - void emitDirectiveSetReorder() override; void emitDirectiveSetNoReorder() override; - void emitDirectiveSetMacro() override; - void emitDirectiveSetNoMacro() override; - void emitDirectiveSetAt() override; - void emitDirectiveSetNoAt() override; void emitDirectiveEnd(StringRef Name) override; void emitDirectiveEnt(const MCSymbol &Symbol) override; @@ -198,19 +206,6 @@ 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 virtual void emitDirectiveCpload(unsigned RegNo); void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset, Index: test/MC/Mips/mips-pdr-bad.s =================================================================== --- /dev/null +++ test/MC/Mips/mips-pdr-bad.s @@ -0,0 +1,42 @@ +# RUN: not llvm-mc %s -arch=mips -mcpu=mips32r2 2>%t1 +# RUN: FileCheck %s < %t1 -check-prefix=ASM + + .text + + .ent # ASM: :[[@LINE]]:14: error: expected identifier after .ent + .ent bar, # ASM: :[[@LINE]]:19: error: expected number after comma + .ent foo, bar # AMS: :[[@LINE]]:23: error: expected an absolute expression after comma + .ent foo, 5, bar # AMS: :[[@LINE]]:20: error: unexpected token, expected end of statement + + .frame # ASM: :[[@LINE]]:16: error: expected stack register + .frame bar # ASM: :[[@LINE]]:16: error: expected stack register + .frame $f1, 8, # ASM: :[[@LINE]]:16: error: expected general purpose register + .frame $sp # ASM: :[[@LINE]]:20: error: unexpected token, expected comma + .frame $sp, # ASM: :[[@LINE]]:21: error: expected frame size value + .frame $sp, bar # ASM: :[[@LINE]]:25: error: frame size not an absolute expression + .frame $sp, 8 # ASM: :[[@LINE]]:23: error: unexpected token, expected comma + .frame $sp, 8, # ASM: :[[@LINE]]:24: error: expected return register + .frame $sp, 8, $f1 # ASM: :[[@LINE]]:24: error: expected general purpose register + .frame $sp, 8, $ra, foo # ASM: :[[@LINE]]:27: error: unexpected token, expected end of statement + + .mask # ASM: :[[@LINE]]:16: error: expected bitmask value + .mask foo # ASM: :[[@LINE]]:19: error: bitmask not an absolute expression + .mask 0x80000000 # ASM: :[[@LINE]]:26: error: unexpected token, expected comma + .mask 0x80000000, # ASM: :[[@LINE]]:27: error: expected frame offset value + .mask 0x80000000, foo # ASM: :[[@LINE]]:31: error: frame offset not an absolute expression + .mask 0x80000000, -4, bar # ASM: :[[@LINE]]:29: error: unexpected token, expected end of statement + + .fmask # ASM: :[[@LINE]]:17: error: expected bitmask value + .fmask foo # ASM: :[[@LINE]]:20: error: bitmask not an absolute expression + .fmask 0x80000000 # ASM: :[[@LINE]]:27: error: unexpected token, expected comma + .fmask 0x80000000, # ASM: :[[@LINE]]:28: error: expected frame offset value + .fmask 0x80000000, foo # ASM: :[[@LINE]]:32: error: frame offset not an absolute expression + .fmask 0x80000000, -4, bar # ASM: :[[@LINE]]:30: error: unexpected token, expected end of statement + + .end # ASM: :[[@LINE]]:14: error: expected identifier after .end + .ent _local_foo_bar + .end _local_foo_bar, foo # ASM: :[[@LINE]]:28: error: unexpected token, expected end of statement + .end _local_foo_bar + .end _local_foo # ASM: :[[@LINE]]:25: error: .end used without .ent + .ent _local_foo, 2 + .end _local_foo_bar # ASM: :[[@LINE]]:29: error: .end symbol does not match .ent symbol Index: test/MC/Mips/mips-pdr.s =================================================================== --- /dev/null +++ test/MC/Mips/mips-pdr.s @@ -0,0 +1,64 @@ +# RUN: llvm-mc %s -arch=mips -mcpu=mips32r2 -filetype=asm | \ +# RUN: FileCheck %s -check-prefix=ASMOUT + +# RUN: llvm-mc %s -arch=mips -mcpu=mips32r2 -filetype=obj -o - | \ +# RUN: llvm-readobj -s -section-data | \ +# RUN: FileCheck %s -check-prefix=OBJOUT + +# ASMOUT: .text +# ASMOUT: .type _local_foo,@function +# ASMOUT: .ent _local_foo +# ASMOUT:_local_foo: +# ASMOUT: .frame $fp,16,$ra +# ASMOUT: .mask 0x10101010,-4 +# ASMOUT: .fmask 0x01010101,-8 +# ASMOUT: .end _local_foo +# ASMOUT: .size local_foo, + +# OBJOUT: Section { +# OBJOUT: Name: .pdr +# OBJOUT: Type: SHT_PROGBITS (0x1) +# OBJOUT: Flags [ (0xB) +# OBJOUT: SHF_ALLOC (0x2) +# OBJOUT: SHF_WRITE (0x1) +# OBJOUT: ] +# OBJOUT: Size: 64 +# OBJOUT: SectionData ( +# OBJOUT: 0000: 00000000 10101010 FFFFFFFC 01010101 +# OBJOUT: 0010: FFFFFFF8 00000010 0000001E 0000001F +# OBJOUT: 0020: 00000000 10101010 FFFFFFFC 01010101 +# OBJOUT: 0030: FFFFFFF8 00000010 0000001E 0000001F +# OBJOUT: ) +# OBJOUT: } + +# We should also check if relocation information was correctly generated. +# OBJOUT: Section { +# OBJOUT: Name: .rel.pdr +# OBJOUT: Type: SHT_REL (0x9) +# OBJOUT: Flags [ (0x0) +# OBJOUT: ] +# OBJOUT: Size: 16 +# OBJOUT: SectionData ( +# OBJOUT: 0000: 00000000 00000202 00000020 00000802 +# OBJOUT: ) +# OBJOUT: } + +.text + .type _local_foo,@function + .ent _local_foo +_local_foo: + .frame $fp,16,$ra + .mask 0x10101010,-4 + .fmask 0x01010101,-8 + .end _local_foo + .size local_foo,.-_local_foo + + .globl _global_foo + .type _global_foo,@function + .ent _global_foo +_global_foo: + .frame $fp,16,$ra + .mask 0x10101010,-4 + .fmask 0x01010101,-8 + .end _global_foo + .size global_foo,.-_global_foo