diff options
author | Sasa Stankovic <Sasa.Stankovic@imgtec.com> | 2014-04-03 10:37:45 +0000 |
---|---|---|
committer | Sasa Stankovic <Sasa.Stankovic@imgtec.com> | 2014-04-03 10:37:45 +0000 |
commit | 06c4780311df28e9f230889fc04f63f5acb795d6 (patch) | |
tree | f92bf3999cd0851a546b707cc139c4f4ec2c7942 /llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp | |
parent | 3ba640d7aef9fb3f9be143853a48d44053f0b5f3 (diff) | |
download | bcm5719-llvm-06c4780311df28e9f230889fc04f63f5acb795d6.tar.gz bcm5719-llvm-06c4780311df28e9f230889fc04f63f5acb795d6.zip |
[mips] Extend MipsMCExpr class to handle %higher(sym1 - sym2 + const) and
%highest(sym1 - sym2 + const) relocations. Remove "ABS_" from VK_Mips_HI
and VK_Mips_LO enums in MipsMCExpr, to be consistent with VK_Mips_HIGHER
and VK_Mips_HIGHEST.
This change also deletes test file test/MC/Mips/higher_highest.ll and moves
its CHECK's to the new test file test/MC/Mips/higher-highest-addressing.s.
The deleted file tests that R_MIPS_HIGHER and R_MIPS_HIGHEST relocations are
emitted in the .o file. Since it uses -force-mips-long-branch option, it was
created when MipsLongBranch's implementation was emitting R_MIPS_HIGHER and
R_MIPS_HIGHEST relocations in the .o file. It was disabled when MipsLongBranch
started to directly calculate offsets.
Differential Revision: http://llvm-reviews.chandlerc.com/D3230
llvm-svn: 205522
Diffstat (limited to 'llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp')
-rw-r--r-- | llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp index 22ce41100a0..c7ba12d0417 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp @@ -15,17 +15,60 @@ using namespace llvm; +bool MipsMCExpr::isSupportedBinaryExpr(MCSymbolRefExpr::VariantKind VK, + const MCBinaryExpr *BE) { + switch (VK) { + case MCSymbolRefExpr::VK_Mips_ABS_LO: + case MCSymbolRefExpr::VK_Mips_ABS_HI: + case MCSymbolRefExpr::VK_Mips_HIGHER: + case MCSymbolRefExpr::VK_Mips_HIGHEST: + break; + default: + return false; + } + + // We support expressions of the form "(sym1 binop1 sym2) binop2 const", + // where "binop2 const" is optional. + if (isa<MCBinaryExpr>(BE->getLHS())) { + if (!isa<MCConstantExpr>(BE->getRHS())) + return false; + BE = cast<MCBinaryExpr>(BE->getLHS()); + } + return (isa<MCSymbolRefExpr>(BE->getLHS()) + && isa<MCSymbolRefExpr>(BE->getRHS())); +} + const MipsMCExpr* -MipsMCExpr::Create(VariantKind Kind, const MCExpr *Expr, +MipsMCExpr::Create(MCSymbolRefExpr::VariantKind VK, const MCExpr *Expr, MCContext &Ctx) { + VariantKind Kind; + switch (VK) { + case MCSymbolRefExpr::VK_Mips_ABS_LO: + Kind = VK_Mips_LO; + break; + case MCSymbolRefExpr::VK_Mips_ABS_HI: + Kind = VK_Mips_HI; + break; + case MCSymbolRefExpr::VK_Mips_HIGHER: + Kind = VK_Mips_HIGHER; + break; + case MCSymbolRefExpr::VK_Mips_HIGHEST: + Kind = VK_Mips_HIGHEST; + break; + default: + llvm_unreachable("Invalid kind!"); + } + return new (Ctx) MipsMCExpr(Kind, Expr); } void MipsMCExpr::PrintImpl(raw_ostream &OS) const { switch (Kind) { default: llvm_unreachable("Invalid kind!"); - case VK_Mips_ABS_LO: OS << "%lo"; break; - case VK_Mips_ABS_HI: OS << "%hi"; break; + case VK_Mips_LO: OS << "%lo"; break; + case VK_Mips_HI: OS << "%hi"; break; + case VK_Mips_HIGHER: OS << "%higher"; break; + case VK_Mips_HIGHEST: OS << "%highest"; break; } OS << '('; |