diff options
author | Daniel Sanders <daniel.sanders@imgtec.com> | 2014-08-13 10:07:34 +0000 |
---|---|---|
committer | Daniel Sanders <daniel.sanders@imgtec.com> | 2014-08-13 10:07:34 +0000 |
commit | d97a634f12f16a58ce1b11feef5e9ea3a4485d03 (patch) | |
tree | f8ba837da2e1204e7dbc44bd5ac69c2c8e9f515c /llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp | |
parent | df153c1a7e9eb487c5eb9d426abaeaf9317c6367 (diff) | |
download | bcm5719-llvm-d97a634f12f16a58ce1b11feef5e9ea3a4485d03.tar.gz bcm5719-llvm-d97a634f12f16a58ce1b11feef5e9ea3a4485d03.zip |
Re-commit: [mips] Implement .ent, .end, .frame, .mask and .fmask.
Patch by Matheus Almeida and Toma Tabacu
The lld test failure on the previous attempt to commit was caused by the
addition of the .pdr section causing the offsets it was checking to change.
This has been fixed by removing the .ent/.end directives from that test since
they weren't really needed.
llvm-svn: 215535
Diffstat (limited to 'llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp')
-rw-r--r-- | llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp | 60 |
1 files changed, 53 insertions, 7 deletions
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp index 7a8230fdebf..23e0d90dc0b 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -29,7 +29,9 @@ 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() {} @@ -492,11 +494,45 @@ void MipsTargetELFStreamer::emitDirectiveSetNoAt() { } void MipsTargetELFStreamer::emitDirectiveEnd(StringRef Name) { - // FIXME: implement. + MCAssembler &MCA = getStreamer().getAssembler(); + MCContext &Context = MCA.getContext(); + MCStreamer &OS = getStreamer(); + + const MCSectionELF *Sec = Context.getELFSection(".pdr", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC | ELF::SHT_REL, + SectionKind::getMetadata()); + + const MCSymbolRefExpr *ExprRef = + MCSymbolRefExpr::Create(Name, MCSymbolRefExpr::VK_None, Context); + + MCSectionData &SecData = MCA.getOrCreateSectionData(*Sec); + SecData.setAlignment(4); + + 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,18 +578,28 @@ void MipsTargetELFStreamer::emitDirectiveOptionPic2() { } 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. + FPRInfoSet = true; + FPRBitMask = FPUBitmask; + FPROffset = FPUTopSavedRegOff; } void MipsTargetELFStreamer::emitDirectiveSetMips1() { |