[llvm] r205522 - [mips] Extend MipsMCExpr class to handle %higher(sym1 - sym2 + const) and
Sasa Stankovic
Sasa.Stankovic at imgtec.com
Thu Apr 3 03:37:45 PDT 2014
Author: sstankovic
Date: Thu Apr 3 05:37:45 2014
New Revision: 205522
URL: http://llvm.org/viewvc/llvm-project?rev=205522&view=rev
Log:
[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
Added:
llvm/trunk/test/MC/Mips/higher-highest-addressing.s
Removed:
llvm/trunk/test/MC/Mips/higher_highest.ll
Modified:
llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp
llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h
Modified: llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp?rev=205522&r1=205521&r2=205522&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp Thu Apr 3 05:37:45 2014
@@ -1448,23 +1448,30 @@ const MCExpr *MipsAsmParser::evaluateRel
const MCExpr *Res;
// Check the type of the expression.
if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
- // It's a constant, evaluate lo or hi value.
- if (RelocStr == "lo") {
- short Val = MCE->getValue();
- Res = MCConstantExpr::Create(Val, getContext());
- } else if (RelocStr == "hi") {
- int Val = MCE->getValue();
- int LoSign = Val & 0x8000;
- Val = (Val & 0xffff0000) >> 16;
- // Lower part is treated as a signed int, so if it is negative
- // we must add 1 to the hi part to compensate.
- if (LoSign)
- Val++;
- Res = MCConstantExpr::Create(Val, getContext());
- } else {
- llvm_unreachable("Invalid RelocStr value");
+ // It's a constant, evaluate reloc value.
+ int16_t Val;
+ switch (getVariantKind(RelocStr)) {
+ case MCSymbolRefExpr::VK_Mips_ABS_LO:
+ // Get the 1st 16-bits.
+ Val = MCE->getValue() & 0xffff;
+ break;
+ case MCSymbolRefExpr::VK_Mips_ABS_HI:
+ // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
+ // 16 bits being negative.
+ Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
+ break;
+ case MCSymbolRefExpr::VK_Mips_HIGHER:
+ // Get the 3rd 16-bits.
+ Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
+ break;
+ case MCSymbolRefExpr::VK_Mips_HIGHEST:
+ // Get the 4th 16-bits.
+ Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
+ break;
+ default:
+ report_fatal_error("Unsupported reloc value!");
}
- return Res;
+ return MCConstantExpr::Create(Val, getContext());
}
if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
@@ -1478,15 +1485,9 @@ const MCExpr *MipsAsmParser::evaluateRel
if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
- // Check for %hi(sym1-sym2) and %lo(sym1-sym2) expressions.
- if (isa<MCSymbolRefExpr>(BE->getLHS()) && isa<MCSymbolRefExpr>(BE->getRHS())
- && (VK == MCSymbolRefExpr::VK_Mips_ABS_HI
- || VK == MCSymbolRefExpr::VK_Mips_ABS_LO)) {
- // Create target expression for %hi(sym1-sym2) and %lo(sym1-sym2).
- if (VK == MCSymbolRefExpr::VK_Mips_ABS_HI)
- return MipsMCExpr::CreateHi(Expr, getContext());
- return MipsMCExpr::CreateLo(Expr, getContext());
- }
+ // Try to create target expression.
+ if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
+ return MipsMCExpr::Create(VK, Expr, getContext());
const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
Modified: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp?rev=205522&r1=205521&r2=205522&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp Thu Apr 3 05:37:45 2014
@@ -306,11 +306,17 @@ getExprOpValue(const MCExpr *Expr,SmallV
Mips::Fixups FixupKind = Mips::Fixups(0);
switch (MipsExpr->getKind()) {
default: llvm_unreachable("Unsupported fixup kind for target expression!");
- case MipsMCExpr::VK_Mips_ABS_HI:
+ case MipsMCExpr::VK_Mips_HIGHEST:
+ FixupKind = Mips::fixup_Mips_HIGHEST;
+ break;
+ case MipsMCExpr::VK_Mips_HIGHER:
+ FixupKind = Mips::fixup_Mips_HIGHER;
+ break;
+ case MipsMCExpr::VK_Mips_HI:
FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16
: Mips::fixup_Mips_HI16;
break;
- case MipsMCExpr::VK_Mips_ABS_LO:
+ case MipsMCExpr::VK_Mips_LO:
FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16
: Mips::fixup_Mips_LO16;
break;
Modified: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp?rev=205522&r1=205521&r2=205522&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp Thu Apr 3 05:37:45 2014
@@ -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 << '(';
Modified: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h?rev=205522&r1=205521&r2=205522&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h (original)
+++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h Thu Apr 3 05:37:45 2014
@@ -20,8 +20,10 @@ class MipsMCExpr : public MCTargetExpr {
public:
enum VariantKind {
VK_Mips_None,
- VK_Mips_ABS_LO,
- VK_Mips_ABS_HI
+ VK_Mips_LO,
+ VK_Mips_HI,
+ VK_Mips_HIGHER,
+ VK_Mips_HIGHEST
};
private:
@@ -32,16 +34,11 @@ private:
: Kind(Kind), Expr(Expr) {}
public:
- static const MipsMCExpr *Create(VariantKind Kind, const MCExpr *Expr,
- MCContext &Ctx);
+ static bool isSupportedBinaryExpr(MCSymbolRefExpr::VariantKind VK,
+ const MCBinaryExpr *BE);
- static const MipsMCExpr *CreateLo(const MCExpr *Expr, MCContext &Ctx) {
- return Create(VK_Mips_ABS_LO, Expr, Ctx);
- }
-
- static const MipsMCExpr *CreateHi(const MCExpr *Expr, MCContext &Ctx) {
- return Create(VK_Mips_ABS_HI, Expr, Ctx);
- }
+ static const MipsMCExpr *Create(MCSymbolRefExpr::VariantKind VK,
+ const MCExpr *Expr, MCContext &Ctx);
/// getOpcode - Get the kind of this expression.
VariantKind getKind() const { return Kind; }
Added: llvm/trunk/test/MC/Mips/higher-highest-addressing.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/higher-highest-addressing.s?rev=205522&view=auto
==============================================================================
--- llvm/trunk/test/MC/Mips/higher-highest-addressing.s (added)
+++ llvm/trunk/test/MC/Mips/higher-highest-addressing.s Thu Apr 3 05:37:45 2014
@@ -0,0 +1,54 @@
+# RUN: llvm-mc -filetype=obj -triple=mips64el-unknown-linux -mcpu=mips64r2 %s \
+# RUN: | llvm-objdump -disassemble -triple mips64el - | FileCheck %s
+
+# RUN: llvm-mc -filetype=obj -triple=mips64el-unknown-linux -mcpu=mips64r2 %s \
+# RUN: | llvm-readobj -r | FileCheck %s -check-prefix=CHECK-REL
+
+
+# Test that R_MIPS_HIGHER and R_MIPS_HIGHEST relocations are created. By using
+# NEXT we also test that none of the expressions from the test2 generates
+# relocations.
+
+test1:
+# CHECK-LABEL: test1:
+
+ lui $5, %highest(func)
+ daddiu $5, $5, %higher(func)
+
+# CHECK-REL: Relocations [
+# CHECK-REL-NEXT: {
+# CHECK-REL-NEXT: 0x{{[0-9,A-F]+}} R_MIPS_HIGHEST
+# CHECK-REL-NEXT: 0x{{[0-9,A-F]+}} R_MIPS_HIGHER
+# CHECK-REL-NEXT: }
+
+
+# Test the calculation of %higher and %highest:
+# ((x + 0x80008000) >> 32) & 0xffff (higher)
+# ((x + 0x800080008000) >> 48) & 0xffff (highest).
+
+test2:
+# CHECK-LABEL: test2:
+
+# Check the case where relocations are not modified by adding +1. The constant
+# is chosen so that it is just below the value that triggers the addition of +1
+# to %higher.
+$L1:
+ lui $6, %highest($L2-$L1+0x300047FFF7FF7)
+ daddiu $6, $6, %higher($L2-$L1+0x300047FFF7FF7)
+$L2:
+# CHECK: lui $6, 3
+# CHECK: daddiu $6, $6, 4
+
+
+# Check the case where %higher is modified by adding +1.
+ lui $7, %highest($L2-$L1+0x300047FFF7FF8)
+ ld $7, %higher ($L2-$L1+0x300047FFF7FF8)($7)
+# CHECK: lui $7, 3
+# CHECK: ld $7, 5($7)
+
+
+# Check the case where both %higher and %highest are modified by adding +1.
+ lui $8, %highest(0x37FFF7FFF8000)
+ ld $8, %higher (0x37FFF7FFF8000)($8)
+# CHECK: lui $8, 4
+# CHECK: ld $8, -32768($8)
Removed: llvm/trunk/test/MC/Mips/higher_highest.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/higher_highest.ll?rev=205521&view=auto
==============================================================================
--- llvm/trunk/test/MC/Mips/higher_highest.ll (original)
+++ llvm/trunk/test/MC/Mips/higher_highest.ll (removed)
@@ -1,32 +0,0 @@
-; DISABLE: llc -march=mips64el -mcpu=mips64 -mattr=n64 -force-mips-long-branch -filetype=obj < %s -o - | llvm-readobj -r | FileCheck %s
-; RUN: false
-; XFAIL: *
-; Disabled because currently we don't have a way to generate these relocations.
-;
-; Check that the R_MIPS_HIGHER and R_MIPS_HIGHEST relocations were created.
-
-; CHECK: Relocations [
-; CHECK: 0x{{[0-9,A-F]+}} R_MIPS_HIGHEST
-; CHECK: 0x{{[0-9,A-F]+}} R_MIPS_HIGHEST
-; CHECK: 0x{{[0-9,A-F]+}} R_MIPS_HIGHER
-; CHECK: 0x{{[0-9,A-F]+}} R_MIPS_HIGHER
-; CHECK: ]
-
- at g0 = external global i32
-
-define void @foo1(i32 %s) nounwind {
-entry:
-
- %tobool = icmp eq i32 %s, 0
- br i1 %tobool, label %if.end, label %if.then
-
-if.then: ; preds = %entry
- %0 = load i32* @g0, align 4
- %add = add nsw i32 %0, 12
- store i32 %add, i32* @g0, align 4
- br label %if.end
-
-if.end: ; preds = %entry, %if.then
- ret void
-}
-
More information about the llvm-commits
mailing list