From 7f15e90281c9862e9084ff2197f8fe8f06823fb2 Mon Sep 17 00:00:00 2001 From: Petar Jovanovic Date: Tue, 4 Feb 2014 18:41:57 +0000 Subject: [mips] Implement %hi(sym1 - sym2) and %lo(sym1 - sym2) expressions Patch implements %hi(sym1 - sym2) and %lo(sym1 - sym2) expressions for MIPS by creating target expression class MipsMCExpr. Patch by Sasa Stankovic. Differential Revision: http://llvm-reviews.chandlerc.com/D2592 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200783 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 17 ++++- lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp | 7 ++- lib/Target/Mips/MCTargetDesc/CMakeLists.txt | 1 + lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 21 +++++++ lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp | 73 ++++++++++++++++++++++ lib/Target/Mips/MCTargetDesc/MipsMCExpr.h | 69 ++++++++++++++++++++ 6 files changed, 184 insertions(+), 4 deletions(-) create mode 100644 lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp create mode 100644 lib/Target/Mips/MCTargetDesc/MipsMCExpr.h (limited to 'lib/Target') diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index b0e699064e..e99de13077 100644 --- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "MCTargetDesc/MipsMCExpr.h" #include "MCTargetDesc/MipsMCTargetDesc.h" #include "MipsRegisterInfo.h" #include "MipsTargetStreamer.h" @@ -1313,6 +1314,18 @@ const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr, } if (const MCBinaryExpr *BE = dyn_cast(Expr)) { + MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr); + + // Check for %hi(sym1-sym2) and %lo(sym1-sym2) expressions. + if (isa(BE->getLHS()) && isa(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()); + } + const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr); const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr); Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext()); @@ -1343,8 +1356,8 @@ bool MipsAsmParser::isEvaluated(const MCExpr *Expr) { } case MCExpr::Unary: return isEvaluated(cast(Expr)->getSubExpr()); - default: - return false; + case MCExpr::Target: + return true; } return false; } diff --git a/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp b/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp index 82deec1a1e..de724d33cf 100644 --- a/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp +++ b/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp @@ -14,6 +14,7 @@ #define DEBUG_TYPE "asm-printer" #include "MipsInstPrinter.h" #include "MipsInstrInfo.h" +#include "MCTargetDesc/MipsMCExpr.h" #include "llvm/ADT/StringExtras.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" @@ -129,8 +130,10 @@ static void printExpr(const MCExpr *Expr, raw_ostream &OS) { const MCConstantExpr *CE = dyn_cast(BE->getRHS()); assert(SRE && CE && "Binary expression must be sym+const."); Offset = CE->getValue(); - } - else if (!(SRE = dyn_cast(Expr))) + } else if (const MipsMCExpr *ME = dyn_cast(Expr)) { + ME->print(OS); + return; + } else if (!(SRE = dyn_cast(Expr))) assert(false && "Unexpected MCExpr type."); MCSymbolRefExpr::VariantKind Kind = SRE->getKind(); diff --git a/lib/Target/Mips/MCTargetDesc/CMakeLists.txt b/lib/Target/Mips/MCTargetDesc/CMakeLists.txt index cf64f4a0a2..43053e896e 100644 --- a/lib/Target/Mips/MCTargetDesc/CMakeLists.txt +++ b/lib/Target/Mips/MCTargetDesc/CMakeLists.txt @@ -2,6 +2,7 @@ add_llvm_library(LLVMMipsDesc MipsAsmBackend.cpp MipsMCAsmInfo.cpp MipsMCCodeEmitter.cpp + MipsMCExpr.cpp MipsMCTargetDesc.cpp MipsELFObjectWriter.cpp MipsTargetStreamer.cpp diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index dced8255ee..d47440bda7 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -14,6 +14,7 @@ #define DEBUG_TYPE "mccodeemitter" #include "MCTargetDesc/MipsBaseInfo.h" #include "MCTargetDesc/MipsFixupKinds.h" +#include "MCTargetDesc/MipsMCExpr.h" #include "MCTargetDesc/MipsMCTargetDesc.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/Statistic.h" @@ -385,6 +386,26 @@ getExprOpValue(const MCExpr *Expr,SmallVectorImpl &Fixups, Res += getExprOpValue(cast(Expr)->getRHS(), Fixups, STI); return Res; } + + if (Kind == MCExpr::Target) { + const MipsMCExpr *MipsExpr = cast(Expr); + + Mips::Fixups FixupKind = Mips::Fixups(0); + switch (MipsExpr->getKind()) { + default: llvm_unreachable("Unsupported fixup kind for target expression!"); + case MipsMCExpr::VK_Mips_ABS_HI: + FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16 + : Mips::fixup_Mips_HI16; + break; + case MipsMCExpr::VK_Mips_ABS_LO: + FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16 + : Mips::fixup_Mips_LO16; + break; + } + Fixups.push_back(MCFixup::Create(0, MipsExpr, MCFixupKind(FixupKind))); + return 0; + } + if (Kind == MCExpr::SymbolRef) { Mips::Fixups FixupKind = Mips::Fixups(0); diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp new file mode 100644 index 0000000000..3b2ced624a --- /dev/null +++ b/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp @@ -0,0 +1,73 @@ +//===-- MipsMCExpr.cpp - Mips specific MC expression classes --------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "mipsmcexpr" +#include "MipsMCExpr.h" +#include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCAsmInfo.h" + +using namespace llvm; + +const MipsMCExpr* +MipsMCExpr::Create(VariantKind Kind, const MCExpr *Expr, + MCContext &Ctx) { + 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; + } + + OS << '('; + Expr->print(OS); + OS << ')'; +} + +bool +MipsMCExpr::EvaluateAsRelocatableImpl(MCValue &Res, + const MCAsmLayout *Layout) const { + if (!Layout) + return false; + return getSubExpr()->EvaluateAsRelocatable(Res, *Layout); +} + +// FIXME: This basically copies MCObjectStreamer::AddValueSymbols. Perhaps +// that method should be made public? +static void AddValueSymbolsImpl(const MCExpr *Value, MCAssembler *Asm) { + switch (Value->getKind()) { + case MCExpr::Target: + llvm_unreachable("Can't handle nested target expr!"); + + case MCExpr::Constant: + break; + + case MCExpr::Binary: { + const MCBinaryExpr *BE = cast(Value); + AddValueSymbolsImpl(BE->getLHS(), Asm); + AddValueSymbolsImpl(BE->getRHS(), Asm); + break; + } + + case MCExpr::SymbolRef: + Asm->getOrCreateSymbolData(cast(Value)->getSymbol()); + break; + + case MCExpr::Unary: + AddValueSymbolsImpl(cast(Value)->getSubExpr(), Asm); + break; + } +} + +void MipsMCExpr::AddValueSymbols(MCAssembler *Asm) const { + AddValueSymbolsImpl(getSubExpr(), Asm); +} diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h b/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h new file mode 100644 index 0000000000..6c4ce482a5 --- /dev/null +++ b/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h @@ -0,0 +1,69 @@ +//===-- MipsMCExpr.h - Mips specific MC expression classes ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef MIPSMCEXPR_H +#define MIPSMCEXPR_H + +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCValue.h" +#include "llvm/MC/MCAsmLayout.h" + +namespace llvm { + +class MipsMCExpr : public MCTargetExpr { +public: + enum VariantKind { + VK_Mips_None, + VK_Mips_ABS_LO, + VK_Mips_ABS_HI + }; + +private: + const VariantKind Kind; + const MCExpr *Expr; + + explicit MipsMCExpr(VariantKind Kind, const MCExpr *Expr) + : Kind(Kind), Expr(Expr) {} + +public: + static const MipsMCExpr *Create(VariantKind Kind, const MCExpr *Expr, + MCContext &Ctx); + + 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); + } + + /// getOpcode - Get the kind of this expression. + VariantKind getKind() const { return Kind; } + + /// getSubExpr - Get the child of this expression. + const MCExpr *getSubExpr() const { return Expr; } + + void PrintImpl(raw_ostream &OS) const; + bool EvaluateAsRelocatableImpl(MCValue &Res, + const MCAsmLayout *Layout) const; + void AddValueSymbols(MCAssembler *) const; + const MCSection *FindAssociatedSection() const { + return getSubExpr()->FindAssociatedSection(); + } + + // There are no TLS MipsMCExprs at the moment. + void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {} + + static bool classof(const MCExpr *E) { + return E->getKind() == MCExpr::Target; + } +}; +} // end namespace llvm + +#endif -- cgit v1.2.3