summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMatheus Almeida <matheus.almeida@imgtec.com>2014-05-01 10:24:46 +0000
committerMatheus Almeida <matheus.almeida@imgtec.com>2014-05-01 10:24:46 +0000
commit4c715625d964ee56ab667c502fe0c68b807a1015 (patch)
tree505eff893e9845b93ef1f73e4486f7e79140fb70 /lib
parent873f87c2dec04f03682543ef71ef286a8f2389b7 (diff)
downloadllvm-4c715625d964ee56ab667c502fe0c68b807a1015.tar.gz
llvm-4c715625d964ee56ab667c502fe0c68b807a1015.tar.bz2
llvm-4c715625d964ee56ab667c502fe0c68b807a1015.tar.xz
[mips] Move expansion of .cpsetup to target streamer.
Summary: There are two functional changes: 1) The directive is not expanded for the ASM->ASM code path. 2) If PIC is not set, there's no expansion for the ASM->OBJ code path (same behaviour as GAS). Reviewers: dsanders Reviewed By: dsanders Differential Revision: http://reviews.llvm.org/D3482 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207741 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/Mips/AsmParser/MipsAsmParser.cpp52
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp73
-rw-r--r--lib/Target/Mips/MipsTargetStreamer.h6
3 files changed, 80 insertions, 51 deletions
diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index 4449cc20c9..d8e783e92c 100644
--- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -2361,58 +2361,8 @@ bool MipsAsmParser::parseDirectiveCPSetup() {
if (Parser.parseIdentifier(Name))
reportParseError("expected identifier");
MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
- unsigned GPReg = getGPR(matchCPURegisterName("gp"));
- // FIXME: The code below this point should be in the TargetStreamers.
- // Only N32 and N64 emit anything for .cpsetup
- // FIXME: We should only emit something for PIC mode too.
- if (!isN32() && !isN64())
- return false;
-
- MCStreamer &TS = getStreamer();
- MCInst Inst;
- // Either store the old $gp in a register or on the stack
- if (SaveIsReg) {
- // move $save, $gpreg
- Inst.setOpcode(Mips::DADDu);
- Inst.addOperand(MCOperand::CreateReg(Save));
- Inst.addOperand(MCOperand::CreateReg(GPReg));
- Inst.addOperand(MCOperand::CreateReg(getGPR(0)));
- } else {
- // sd $gpreg, offset($sp)
- Inst.setOpcode(Mips::SD);
- Inst.addOperand(MCOperand::CreateReg(GPReg));
- Inst.addOperand(MCOperand::CreateReg(getGPR(matchCPURegisterName("sp"))));
- Inst.addOperand(MCOperand::CreateImm(Save));
- }
- TS.EmitInstruction(Inst, STI);
- Inst.clear();
-
- const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
- Sym->getName(), MCSymbolRefExpr::VK_Mips_GPOFF_HI, getContext());
- const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
- Sym->getName(), MCSymbolRefExpr::VK_Mips_GPOFF_LO, getContext());
- // lui $gp, %hi(%neg(%gp_rel(funcSym)))
- Inst.setOpcode(Mips::LUi);
- Inst.addOperand(MCOperand::CreateReg(GPReg));
- Inst.addOperand(MCOperand::CreateExpr(HiExpr));
- TS.EmitInstruction(Inst, STI);
- Inst.clear();
-
- // addiu $gp, $gp, %lo(%neg(%gp_rel(funcSym)))
- Inst.setOpcode(Mips::ADDiu);
- Inst.addOperand(MCOperand::CreateReg(GPReg));
- Inst.addOperand(MCOperand::CreateReg(GPReg));
- Inst.addOperand(MCOperand::CreateExpr(LoExpr));
- TS.EmitInstruction(Inst, STI);
- Inst.clear();
-
- // daddu $gp, $gp, $funcreg
- Inst.setOpcode(Mips::DADDu);
- Inst.addOperand(MCOperand::CreateReg(GPReg));
- Inst.addOperand(MCOperand::CreateReg(GPReg));
- Inst.addOperand(MCOperand::CreateReg(FuncReg));
- TS.EmitInstruction(Inst, STI);
+ getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg);
return false;
}
diff --git a/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
index ab1b1f6043..a8fa27244d 100644
--- a/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
+++ b/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
@@ -149,6 +149,24 @@ void MipsTargetAsmStreamer::emitDirectiveCpload(unsigned RegNo) {
<< StringRef(MipsInstPrinter::getRegisterName(RegNo)).lower() << "\n";
}
+void MipsTargetAsmStreamer::emitDirectiveCpsetup(unsigned RegNo,
+ int RegOrOffset,
+ const MCSymbol &Sym,
+ bool IsReg) {
+ OS << "\t.cpsetup\t$"
+ << StringRef(MipsInstPrinter::getRegisterName(RegNo)).lower() << ", ";
+
+ if (IsReg)
+ OS << "$"
+ << StringRef(MipsInstPrinter::getRegisterName(RegOrOffset)).lower();
+ else
+ OS << RegOrOffset;
+
+ OS << ", ";
+
+ OS << Sym.getName() << "\n";
+}
+
// This part is for ELF object output.
MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S,
const MCSubtargetInfo &STI)
@@ -456,3 +474,58 @@ void MipsTargetELFStreamer::emitDirectiveCpload(unsigned RegNo) {
TmpInst.addOperand(MCOperand::CreateReg(RegNo));
getStreamer().EmitInstruction(TmpInst, STI);
}
+
+void MipsTargetELFStreamer::emitDirectiveCpsetup(unsigned RegNo,
+ int RegOrOffset,
+ const MCSymbol &Sym,
+ bool IsReg) {
+ // Only N32 and N64 emit anything for .cpsetup iff PIC is set.
+ if (!Pic || !(isN32() || isN64()))
+ return;
+
+ MCAssembler &MCA = getStreamer().getAssembler();
+ MCInst Inst;
+
+ // Either store the old $gp in a register or on the stack
+ if (IsReg) {
+ // move $save, $gpreg
+ Inst.setOpcode(Mips::DADDu);
+ Inst.addOperand(MCOperand::CreateReg(RegOrOffset));
+ Inst.addOperand(MCOperand::CreateReg(Mips::GP));
+ Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
+ } else {
+ // sd $gpreg, offset($sp)
+ Inst.setOpcode(Mips::SD);
+ Inst.addOperand(MCOperand::CreateReg(Mips::GP));
+ Inst.addOperand(MCOperand::CreateReg(Mips::SP));
+ Inst.addOperand(MCOperand::CreateImm(RegOrOffset));
+ }
+ getStreamer().EmitInstruction(Inst, STI);
+ Inst.clear();
+
+ const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
+ Sym.getName(), MCSymbolRefExpr::VK_Mips_GPOFF_HI, MCA.getContext());
+ const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
+ Sym.getName(), MCSymbolRefExpr::VK_Mips_GPOFF_LO, MCA.getContext());
+ // lui $gp, %hi(%neg(%gp_rel(funcSym)))
+ Inst.setOpcode(Mips::LUi);
+ Inst.addOperand(MCOperand::CreateReg(Mips::GP));
+ Inst.addOperand(MCOperand::CreateExpr(HiExpr));
+ getStreamer().EmitInstruction(Inst, STI);
+ Inst.clear();
+
+ // addiu $gp, $gp, %lo(%neg(%gp_rel(funcSym)))
+ Inst.setOpcode(Mips::ADDiu);
+ Inst.addOperand(MCOperand::CreateReg(Mips::GP));
+ Inst.addOperand(MCOperand::CreateReg(Mips::GP));
+ Inst.addOperand(MCOperand::CreateExpr(LoExpr));
+ getStreamer().EmitInstruction(Inst, STI);
+ Inst.clear();
+
+ // daddu $gp, $gp, $funcreg
+ Inst.setOpcode(Mips::DADDu);
+ Inst.addOperand(MCOperand::CreateReg(Mips::GP));
+ Inst.addOperand(MCOperand::CreateReg(Mips::GP));
+ Inst.addOperand(MCOperand::CreateReg(RegNo));
+ getStreamer().EmitInstruction(Inst, STI);
+}
diff --git a/lib/Target/Mips/MipsTargetStreamer.h b/lib/Target/Mips/MipsTargetStreamer.h
index e649a4d14f..4ad37ac5b1 100644
--- a/lib/Target/Mips/MipsTargetStreamer.h
+++ b/lib/Target/Mips/MipsTargetStreamer.h
@@ -50,6 +50,8 @@ public:
// PIC support
virtual void emitDirectiveCpload(unsigned RegNo) = 0;
+ virtual void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
+ const MCSymbol &Sym, bool IsReg) = 0;
};
// This part is for ascii assembly output
@@ -89,6 +91,8 @@ public:
// PIC support
virtual void emitDirectiveCpload(unsigned RegNo);
+ void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
+ const MCSymbol &Sym, bool IsReg) override;
};
// This part is for ELF object output
@@ -137,6 +141,8 @@ public:
// PIC support
virtual void emitDirectiveCpload(unsigned RegNo);
+ void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
+ const MCSymbol &Sym, bool IsReg) override;
protected:
bool isO32() const { return STI.getFeatureBits() & Mips::FeatureO32; }