summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
diff options
context:
space:
mode:
authorDaniel Sanders <daniel.sanders@imgtec.com>2014-08-13 10:07:34 +0000
committerDaniel Sanders <daniel.sanders@imgtec.com>2014-08-13 10:07:34 +0000
commitd97a634f12f16a58ce1b11feef5e9ea3a4485d03 (patch)
treef8ba837da2e1204e7dbc44bd5ac69c2c8e9f515c /llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
parentdf153c1a7e9eb487c5eb9d426abaeaf9317c6367 (diff)
downloadbcm5719-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.cpp60
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() {
OpenPOWER on IntegriCloud