diff options
author | Daniel Sanders <daniel.sanders@imgtec.com> | 2016-05-03 13:35:44 +0000 |
---|---|---|
committer | Daniel Sanders <daniel.sanders@imgtec.com> | 2016-05-03 13:35:44 +0000 |
commit | fe98b2f54b0478537b9869708a6d87eafb326a1f (patch) | |
tree | 6f460d58e338449f0e77f032087596f7460d3c97 /llvm/lib/Target/Mips/MipsMCInstLower.cpp | |
parent | 32e78c3ff7172bacc6759518c3167014938c3dda (diff) | |
download | bcm5719-llvm-fe98b2f54b0478537b9869708a6d87eafb326a1f.tar.gz bcm5719-llvm-fe98b2f54b0478537b9869708a6d87eafb326a1f.zip |
[mips] Use MipsMCExpr instead of MCSymbolRefExpr for all relocations.
Summary:
This is much closer to the way MIPS relocation expressions work
(%hi(foo + 2) rather than %hi(foo) + 2) and removes the need for the
various bodges in MipsAsmParser::evaluateRelocExpr().
Removing those bodges ensures that the constant stored in MCValue is the
full 32 or 64-bit (depending on ABI) offset from the symbol. This will be used
to correct the %hi/%lo matching needed to sort the relocation table correctly.
As part of this:
* Gave MCExpr::print() the ability to omit parenthesis when emitting a
symbol reference inside a MipsMCExpr operator like %hi(X). Without this
we print things like %lo(($L1)).
* %hi(%neg(%gprel(X))) is now three MipsMCExpr's instead of one. Most of
the related special cases have been removed or moved to MipsMCExpr. We
can remove the rest as we gain support for the less common relocations
when they are not part of this specific combination.
* Renamed MipsMCExpr::VariantKind and the enum prefix ('VK_') to avoid confusion
with MCSymbolRefExpr::VariantKind and its prefix (also 'VK_').
* fixup_Mips_GOT_Local and fixup_Mips_GOT_Global were found to be identical
and merged into fixup_Mips_GOT.
* MO_GOT16 and MO_GOT turned out to be identical and have been merged into
MO_GOT.
* VK_Mips_GOT and VK_Mips_GOT16 turned out to be the same thing so they
have been merged into MEK_GOT
Reviewers: sdardis
Subscribers: dsanders, sdardis, llvm-commits
Differential Revision: http://reviews.llvm.org/D19716
llvm-svn: 268379
Diffstat (limited to 'llvm/lib/Target/Mips/MipsMCInstLower.cpp')
-rw-r--r-- | llvm/lib/Target/Mips/MipsMCInstLower.cpp | 155 |
1 files changed, 98 insertions, 57 deletions
diff --git a/llvm/lib/Target/Mips/MipsMCInstLower.cpp b/llvm/lib/Target/Mips/MipsMCInstLower.cpp index 80d9b75b85b..d5bc4e537c3 100644 --- a/llvm/lib/Target/Mips/MipsMCInstLower.cpp +++ b/llvm/lib/Target/Mips/MipsMCInstLower.cpp @@ -36,36 +36,87 @@ void MipsMCInstLower::Initialize(MCContext *C) { MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO, MachineOperandType MOTy, unsigned Offset) const { - MCSymbolRefExpr::VariantKind Kind; + MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None; + MipsMCExpr::MipsExprKind TargetKind = MipsMCExpr::MEK_None; + bool IsGpOff = false; const MCSymbol *Symbol; switch(MO.getTargetFlags()) { - default: llvm_unreachable("Invalid target flag!"); - case MipsII::MO_NO_FLAG: Kind = MCSymbolRefExpr::VK_None; break; - case MipsII::MO_GPREL: Kind = MCSymbolRefExpr::VK_Mips_GPREL; break; - case MipsII::MO_GOT_CALL: Kind = MCSymbolRefExpr::VK_Mips_GOT_CALL; break; - case MipsII::MO_GOT16: Kind = MCSymbolRefExpr::VK_Mips_GOT16; break; - case MipsII::MO_GOT: Kind = MCSymbolRefExpr::VK_Mips_GOT; break; - case MipsII::MO_ABS_HI: Kind = MCSymbolRefExpr::VK_Mips_ABS_HI; break; - case MipsII::MO_ABS_LO: Kind = MCSymbolRefExpr::VK_Mips_ABS_LO; break; - case MipsII::MO_TLSGD: Kind = MCSymbolRefExpr::VK_Mips_TLSGD; break; - case MipsII::MO_TLSLDM: Kind = MCSymbolRefExpr::VK_Mips_TLSLDM; break; - case MipsII::MO_DTPREL_HI: Kind = MCSymbolRefExpr::VK_Mips_DTPREL_HI; break; - case MipsII::MO_DTPREL_LO: Kind = MCSymbolRefExpr::VK_Mips_DTPREL_LO; break; - case MipsII::MO_GOTTPREL: Kind = MCSymbolRefExpr::VK_Mips_GOTTPREL; break; - case MipsII::MO_TPREL_HI: Kind = MCSymbolRefExpr::VK_Mips_TPREL_HI; break; - case MipsII::MO_TPREL_LO: Kind = MCSymbolRefExpr::VK_Mips_TPREL_LO; break; - case MipsII::MO_GPOFF_HI: Kind = MCSymbolRefExpr::VK_Mips_GPOFF_HI; break; - case MipsII::MO_GPOFF_LO: Kind = MCSymbolRefExpr::VK_Mips_GPOFF_LO; break; - case MipsII::MO_GOT_DISP: Kind = MCSymbolRefExpr::VK_Mips_GOT_DISP; break; - case MipsII::MO_GOT_PAGE: Kind = MCSymbolRefExpr::VK_Mips_GOT_PAGE; break; - case MipsII::MO_GOT_OFST: Kind = MCSymbolRefExpr::VK_Mips_GOT_OFST; break; - case MipsII::MO_HIGHER: Kind = MCSymbolRefExpr::VK_Mips_HIGHER; break; - case MipsII::MO_HIGHEST: Kind = MCSymbolRefExpr::VK_Mips_HIGHEST; break; - case MipsII::MO_GOT_HI16: Kind = MCSymbolRefExpr::VK_Mips_GOT_HI16; break; - case MipsII::MO_GOT_LO16: Kind = MCSymbolRefExpr::VK_Mips_GOT_LO16; break; - case MipsII::MO_CALL_HI16: Kind = MCSymbolRefExpr::VK_Mips_CALL_HI16; break; - case MipsII::MO_CALL_LO16: Kind = MCSymbolRefExpr::VK_Mips_CALL_LO16; break; + default: + llvm_unreachable("Invalid target flag!"); + case MipsII::MO_NO_FLAG: + break; + case MipsII::MO_GPREL: + TargetKind = MipsMCExpr::MEK_GPREL; + break; + case MipsII::MO_GOT_CALL: + TargetKind = MipsMCExpr::MEK_GOT_CALL; + break; + case MipsII::MO_GOT: + TargetKind = MipsMCExpr::MEK_GOT; + break; + case MipsII::MO_ABS_HI: + TargetKind = MipsMCExpr::MEK_HI; + break; + case MipsII::MO_ABS_LO: + TargetKind = MipsMCExpr::MEK_LO; + break; + case MipsII::MO_TLSGD: + TargetKind = MipsMCExpr::MEK_TLSGD; + break; + case MipsII::MO_TLSLDM: + TargetKind = MipsMCExpr::MEK_TLSLDM; + break; + case MipsII::MO_DTPREL_HI: + TargetKind = MipsMCExpr::MEK_DTPREL_HI; + break; + case MipsII::MO_DTPREL_LO: + TargetKind = MipsMCExpr::MEK_DTPREL_LO; + break; + case MipsII::MO_GOTTPREL: + TargetKind = MipsMCExpr::MEK_GOTTPREL; + break; + case MipsII::MO_TPREL_HI: + TargetKind = MipsMCExpr::MEK_TPREL_HI; + break; + case MipsII::MO_TPREL_LO: + TargetKind = MipsMCExpr::MEK_TPREL_LO; + break; + case MipsII::MO_GPOFF_HI: + TargetKind = MipsMCExpr::MEK_HI; + IsGpOff = true; + break; + case MipsII::MO_GPOFF_LO: + TargetKind = MipsMCExpr::MEK_LO; + IsGpOff = true; + break; + case MipsII::MO_GOT_DISP: + TargetKind = MipsMCExpr::MEK_GOT_DISP; + break; + case MipsII::MO_GOT_HI16: + TargetKind = MipsMCExpr::MEK_GOT_HI16; + break; + case MipsII::MO_GOT_LO16: + TargetKind = MipsMCExpr::MEK_GOT_LO16; + break; + case MipsII::MO_GOT_PAGE: + TargetKind = MipsMCExpr::MEK_GOT_PAGE; + break; + case MipsII::MO_GOT_OFST: + TargetKind = MipsMCExpr::MEK_GOT_OFST; + break; + case MipsII::MO_HIGHER: + TargetKind = MipsMCExpr::MEK_HIGHER; + break; + case MipsII::MO_HIGHEST: + TargetKind = MipsMCExpr::MEK_HIGHEST; + break; + case MipsII::MO_CALL_HI16: + TargetKind = MipsMCExpr::MEK_CALL_HI16; + break; + case MipsII::MO_CALL_LO16: + TargetKind = MipsMCExpr::MEK_CALL_LO16; + break; } switch (MOTy) { @@ -106,30 +157,23 @@ MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO, llvm_unreachable("<unknown operand type>"); } - const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::create(Symbol, Kind, *Ctx); + const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, Kind, *Ctx); - if (!Offset) - return MCOperand::createExpr(MCSym); + if (Offset) { + // Assume offset is never negative. + assert(Offset > 0); - // Assume offset is never negative. - assert(Offset > 0); + Expr = MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(Offset, *Ctx), + *Ctx); + } - const MCConstantExpr *OffsetExpr = MCConstantExpr::create(Offset, *Ctx); - const MCBinaryExpr *Add = MCBinaryExpr::createAdd(MCSym, OffsetExpr, *Ctx); - return MCOperand::createExpr(Add); -} + if (IsGpOff) + Expr = MipsMCExpr::createGpOff(TargetKind, Expr, *Ctx); + else if (TargetKind != MipsMCExpr::MEK_None) + Expr = MipsMCExpr::create(TargetKind, Expr, *Ctx); -/* -static void CreateMCInst(MCInst& Inst, unsigned Opc, const MCOperand &Opnd0, - const MCOperand &Opnd1, - const MCOperand &Opnd2 = MCOperand()) { - Inst.setOpcode(Opc); - Inst.addOperand(Opnd0); - Inst.addOperand(Opnd1); - if (Opnd2.isValid()) - Inst.addOperand(Opnd2); + return MCOperand::createExpr(Expr); } -*/ MCOperand MipsMCInstLower::LowerOperand(const MachineOperand &MO, unsigned offset) const { @@ -160,7 +204,7 @@ MCOperand MipsMCInstLower::LowerOperand(const MachineOperand &MO, MCOperand MipsMCInstLower::createSub(MachineBasicBlock *BB1, MachineBasicBlock *BB2, - MCSymbolRefExpr::VariantKind Kind) const { + MipsMCExpr::MipsExprKind Kind) const { const MCSymbolRefExpr *Sym1 = MCSymbolRefExpr::create(BB1->getSymbol(), *Ctx); const MCSymbolRefExpr *Sym2 = MCSymbolRefExpr::create(BB2->getSymbol(), *Ctx); const MCBinaryExpr *Sub = MCBinaryExpr::createSub(Sym1, Sym2, *Ctx); @@ -178,12 +222,12 @@ lowerLongBranchLUi(const MachineInstr *MI, MCInst &OutMI) const { // Create %hi($tgt-$baltgt). OutMI.addOperand(createSub(MI->getOperand(1).getMBB(), MI->getOperand(2).getMBB(), - MCSymbolRefExpr::VK_Mips_ABS_HI)); + MipsMCExpr::MEK_HI)); } -void MipsMCInstLower:: -lowerLongBranchADDiu(const MachineInstr *MI, MCInst &OutMI, int Opcode, - MCSymbolRefExpr::VariantKind Kind) const { +void MipsMCInstLower::lowerLongBranchADDiu( + const MachineInstr *MI, MCInst &OutMI, int Opcode, + MipsMCExpr::MipsExprKind Kind) const { OutMI.setOpcode(Opcode); // Lower two register operands. @@ -206,17 +250,14 @@ bool MipsMCInstLower::lowerLongBranch(const MachineInstr *MI, lowerLongBranchLUi(MI, OutMI); return true; case Mips::LONG_BRANCH_ADDiu: - lowerLongBranchADDiu(MI, OutMI, Mips::ADDiu, - MCSymbolRefExpr::VK_Mips_ABS_LO); + lowerLongBranchADDiu(MI, OutMI, Mips::ADDiu, MipsMCExpr::MEK_LO); return true; case Mips::LONG_BRANCH_DADDiu: unsigned TargetFlags = MI->getOperand(2).getTargetFlags(); if (TargetFlags == MipsII::MO_ABS_HI) - lowerLongBranchADDiu(MI, OutMI, Mips::DADDiu, - MCSymbolRefExpr::VK_Mips_ABS_HI); + lowerLongBranchADDiu(MI, OutMI, Mips::DADDiu, MipsMCExpr::MEK_HI); else if (TargetFlags == MipsII::MO_ABS_LO) - lowerLongBranchADDiu(MI, OutMI, Mips::DADDiu, - MCSymbolRefExpr::VK_Mips_ABS_LO); + lowerLongBranchADDiu(MI, OutMI, Mips::DADDiu, MipsMCExpr::MEK_LO); else report_fatal_error("Unexpected flags for LONG_BRANCH_DADDiu"); return true; |