mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 04:30:12 +00:00
[Sparc] Teach SparcAsmParser to emit correct relocations for PIC code.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202571 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
79ac85be0b
commit
e0c7e3d139
@ -12,9 +12,11 @@
|
|||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
#include "llvm/MC/MCContext.h"
|
#include "llvm/MC/MCContext.h"
|
||||||
#include "llvm/MC/MCInst.h"
|
#include "llvm/MC/MCInst.h"
|
||||||
|
#include "llvm/MC/MCObjectFileInfo.h"
|
||||||
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
|
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
|
||||||
#include "llvm/MC/MCStreamer.h"
|
#include "llvm/MC/MCStreamer.h"
|
||||||
#include "llvm/MC/MCSubtargetInfo.h"
|
#include "llvm/MC/MCSubtargetInfo.h"
|
||||||
|
#include "llvm/MC/MCSymbol.h"
|
||||||
#include "llvm/MC/MCTargetAsmParser.h"
|
#include "llvm/MC/MCTargetAsmParser.h"
|
||||||
#include "llvm/Support/TargetRegistry.h"
|
#include "llvm/Support/TargetRegistry.h"
|
||||||
|
|
||||||
@ -66,7 +68,7 @@ class SparcAsmParser : public MCTargetAsmParser {
|
|||||||
StringRef Name);
|
StringRef Name);
|
||||||
|
|
||||||
OperandMatchResultTy
|
OperandMatchResultTy
|
||||||
parseSparcAsmOperand(SparcOperand *&Operand);
|
parseSparcAsmOperand(SparcOperand *&Operand, bool isCall = false);
|
||||||
|
|
||||||
// returns true if Tok is matched to a register and returns register in RegNo.
|
// returns true if Tok is matched to a register and returns register in RegNo.
|
||||||
bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo,
|
bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo,
|
||||||
@ -623,7 +625,7 @@ parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
|||||||
}
|
}
|
||||||
|
|
||||||
SparcOperand *Op = 0;
|
SparcOperand *Op = 0;
|
||||||
ResTy = parseSparcAsmOperand(Op);
|
ResTy = parseSparcAsmOperand(Op, (Mnemonic == "call"));
|
||||||
if (ResTy != MatchOperand_Success || !Op)
|
if (ResTy != MatchOperand_Success || !Op)
|
||||||
return MatchOperand_ParseFail;
|
return MatchOperand_ParseFail;
|
||||||
|
|
||||||
@ -634,7 +636,7 @@ parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
|||||||
}
|
}
|
||||||
|
|
||||||
SparcAsmParser::OperandMatchResultTy
|
SparcAsmParser::OperandMatchResultTy
|
||||||
SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op)
|
SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op, bool isCall)
|
||||||
{
|
{
|
||||||
|
|
||||||
SMLoc S = Parser.getTok().getLoc();
|
SMLoc S = Parser.getTok().getLoc();
|
||||||
@ -695,6 +697,10 @@ SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op)
|
|||||||
|
|
||||||
const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
|
const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
|
||||||
getContext());
|
getContext());
|
||||||
|
if (isCall &&
|
||||||
|
getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_)
|
||||||
|
Res = SparcMCExpr::Create(SparcMCExpr::VK_Sparc_WPLT30, Res,
|
||||||
|
getContext());
|
||||||
Op = SparcOperand::CreateImm(Res, S, E);
|
Op = SparcOperand::CreateImm(Res, S, E);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -813,6 +819,31 @@ bool SparcAsmParser::matchRegisterName(const AsmToken &Tok,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool hasGOTReference(const MCExpr *Expr) {
|
||||||
|
switch (Expr->getKind()) {
|
||||||
|
case MCExpr::Target:
|
||||||
|
if (const SparcMCExpr *SE = dyn_cast<SparcMCExpr>(Expr))
|
||||||
|
return hasGOTReference(SE->getSubExpr());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MCExpr::Constant:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MCExpr::Binary: {
|
||||||
|
const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
|
||||||
|
return hasGOTReference(BE->getLHS()) || hasGOTReference(BE->getRHS());
|
||||||
|
}
|
||||||
|
|
||||||
|
case MCExpr::SymbolRef: {
|
||||||
|
const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
|
||||||
|
return (SymRef.getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_");
|
||||||
|
}
|
||||||
|
|
||||||
|
case MCExpr::Unary:
|
||||||
|
return hasGOTReference(cast<MCUnaryExpr>(Expr)->getSubExpr());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
|
bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
|
||||||
SMLoc &EndLoc)
|
SMLoc &EndLoc)
|
||||||
@ -836,6 +867,23 @@ bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
|
|||||||
const MCExpr *subExpr;
|
const MCExpr *subExpr;
|
||||||
if (Parser.parseParenExpression(subExpr, EndLoc))
|
if (Parser.parseParenExpression(subExpr, EndLoc))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
bool isPIC = getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_;
|
||||||
|
|
||||||
|
switch(VK) {
|
||||||
|
default: break;
|
||||||
|
case SparcMCExpr::VK_Sparc_LO:
|
||||||
|
VK = (hasGOTReference(subExpr)
|
||||||
|
? SparcMCExpr::VK_Sparc_PC10
|
||||||
|
: (isPIC ? SparcMCExpr::VK_Sparc_GOT10 : VK));
|
||||||
|
break;
|
||||||
|
case SparcMCExpr::VK_Sparc_HI:
|
||||||
|
VK = (hasGOTReference(subExpr)
|
||||||
|
? SparcMCExpr::VK_Sparc_PC22
|
||||||
|
: (isPIC ? SparcMCExpr::VK_Sparc_GOT22 : VK));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
EVal = SparcMCExpr::Create(VK, subExpr, getContext());
|
EVal = SparcMCExpr::Create(VK, subExpr, getContext());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,10 @@
|
|||||||
#include "MCTargetDesc/SparcFixupKinds.h"
|
#include "MCTargetDesc/SparcFixupKinds.h"
|
||||||
#include "MCTargetDesc/SparcMCTargetDesc.h"
|
#include "MCTargetDesc/SparcMCTargetDesc.h"
|
||||||
#include "llvm/MC/MCELFObjectWriter.h"
|
#include "llvm/MC/MCELFObjectWriter.h"
|
||||||
|
#include "llvm/MC/MCExpr.h"
|
||||||
#include "llvm/MC/MCFixupKindInfo.h"
|
#include "llvm/MC/MCFixupKindInfo.h"
|
||||||
#include "llvm/MC/MCObjectWriter.h"
|
#include "llvm/MC/MCObjectWriter.h"
|
||||||
|
#include "llvm/MC/MCValue.h"
|
||||||
#include "llvm/Support/TargetRegistry.h"
|
#include "llvm/Support/TargetRegistry.h"
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
@ -154,6 +156,8 @@ namespace {
|
|||||||
switch ((Sparc::Fixups)Fixup.getKind()) {
|
switch ((Sparc::Fixups)Fixup.getKind()) {
|
||||||
default: break;
|
default: break;
|
||||||
case Sparc::fixup_sparc_wplt30:
|
case Sparc::fixup_sparc_wplt30:
|
||||||
|
if (Target.getSymA()->getSymbol().isTemporary())
|
||||||
|
return;
|
||||||
case Sparc::fixup_sparc_tls_gd_hi22:
|
case Sparc::fixup_sparc_tls_gd_hi22:
|
||||||
case Sparc::fixup_sparc_tls_gd_lo10:
|
case Sparc::fixup_sparc_tls_gd_lo10:
|
||||||
case Sparc::fixup_sparc_tls_gd_add:
|
case Sparc::fixup_sparc_tls_gd_add:
|
||||||
|
49
test/MC/Sparc/sparc-pic.s
Normal file
49
test/MC/Sparc/sparc-pic.s
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
! RUN: llvm-mc %s -arch=sparcv9 --relocation-model=pic -filetype=obj | llvm-readobj -r | FileCheck %s
|
||||||
|
|
||||||
|
|
||||||
|
! CHECK: Relocations [
|
||||||
|
! CHECK-NOT: 0x{{[0-9,A-F]+}} R_SPARC_WPLT30 .text 0xC
|
||||||
|
! CHECK: 0x{{[0-9,A-F]+}} R_SPARC_PC22 _GLOBAL_OFFSET_TABLE_ 0x4
|
||||||
|
! CHECK-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_PC10 _GLOBAL_OFFSET_TABLE_ 0x8
|
||||||
|
! CHECK-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_GOT22 AGlobalVar 0x0
|
||||||
|
! CHECK-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_GOT10 AGlobalVar 0x0
|
||||||
|
! CHECK-NEXT: 0x{{[0-9,A-F]+}} R_SPARC_WPLT30 bar 0x0
|
||||||
|
! CHECK: ]
|
||||||
|
|
||||||
|
.text
|
||||||
|
.globl foo
|
||||||
|
.align 4
|
||||||
|
.type foo,@function
|
||||||
|
foo:
|
||||||
|
.cfi_startproc
|
||||||
|
save %sp, -176, %sp
|
||||||
|
.cfi_def_cfa_register %fp
|
||||||
|
.cfi_window_save
|
||||||
|
.cfi_register 15, 31
|
||||||
|
.Ltmp4:
|
||||||
|
call .Ltmp5
|
||||||
|
.Ltmp6:
|
||||||
|
sethi %hi(_GLOBAL_OFFSET_TABLE_+(.Ltmp6-.Ltmp4)), %i1
|
||||||
|
.Ltmp5:
|
||||||
|
or %i1, %lo(_GLOBAL_OFFSET_TABLE_+(.Ltmp5-.Ltmp4)), %i1
|
||||||
|
add %i1, %o7, %i1
|
||||||
|
sethi %hi(AGlobalVar), %i2
|
||||||
|
add %i2, %lo(AGlobalVar), %i2
|
||||||
|
ldx [%i1+%i2], %i1
|
||||||
|
ldx [%i1], %i1
|
||||||
|
call bar
|
||||||
|
add %i0, %i1, %o0
|
||||||
|
ret
|
||||||
|
restore %g0, %o0, %o0
|
||||||
|
.Ltmp7:
|
||||||
|
.size foo, .Ltmp7-foo
|
||||||
|
.cfi_endproc
|
||||||
|
|
||||||
|
.type AGlobalVar,@object ! @AGlobalVar
|
||||||
|
.section .bss
|
||||||
|
.globl AGlobalVar
|
||||||
|
.align 8
|
||||||
|
AGlobalVar:
|
||||||
|
.xword 0 ! 0x0
|
||||||
|
.size AGlobalVar, 8
|
||||||
|
|
Loading…
Reference in New Issue
Block a user