a426b286c8
patch for r263619, and unify all the URLs to point to svnweb.
299 lines
12 KiB
Diff
299 lines
12 KiB
Diff
Pull in r198681 from upstream llvm trunk (by Venkatraman Govindaraju):
|
|
|
|
[Sparc] Add support for parsing sparc asm modifiers such as %hi, %lo etc.,
|
|
Also, correct the offsets for FixupsKindInfo.
|
|
|
|
Introduced here: http://svnweb.freebsd.org/changeset/base/262261
|
|
|
|
Index: lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
|
|
===================================================================
|
|
--- lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
|
|
+++ lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
|
|
@@ -27,11 +27,11 @@ static unsigned adjustFixupValue(unsigned Kind, ui
|
|
case FK_Data_8:
|
|
return Value;
|
|
case Sparc::fixup_sparc_call30:
|
|
- return Value & 0x3fffffff;
|
|
+ return (Value >> 2) & 0x3fffffff;
|
|
case Sparc::fixup_sparc_br22:
|
|
- return Value & 0x3fffff;
|
|
+ return (Value >> 2) & 0x3fffff;
|
|
case Sparc::fixup_sparc_br19:
|
|
- return Value & 0x1ffff;
|
|
+ return (Value >> 2) & 0x1ffff;
|
|
case Sparc::fixup_sparc_hi22:
|
|
return (Value >> 10) & 0x3fffff;
|
|
case Sparc::fixup_sparc_lo10:
|
|
@@ -45,7 +45,7 @@ static unsigned adjustFixupValue(unsigned Kind, ui
|
|
case Sparc::fixup_sparc_hh:
|
|
return (Value >> 42) & 0x3fffff;
|
|
case Sparc::fixup_sparc_hm:
|
|
- return (Value >>32) & 0x3ff;
|
|
+ return (Value >> 32) & 0x3ff;
|
|
}
|
|
}
|
|
|
|
@@ -62,16 +62,16 @@ namespace {
|
|
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const {
|
|
const static MCFixupKindInfo Infos[Sparc::NumTargetFixupKinds] = {
|
|
// name offset bits flags
|
|
- { "fixup_sparc_call30", 0, 30, MCFixupKindInfo::FKF_IsPCRel },
|
|
- { "fixup_sparc_br22", 0, 22, MCFixupKindInfo::FKF_IsPCRel },
|
|
- { "fixup_sparc_br19", 0, 19, MCFixupKindInfo::FKF_IsPCRel },
|
|
- { "fixup_sparc_hi22", 0, 22, 0 },
|
|
- { "fixup_sparc_lo10", 0, 10, 0 },
|
|
- { "fixup_sparc_h44", 0, 22, 0 },
|
|
- { "fixup_sparc_m44", 0, 10, 0 },
|
|
- { "fixup_sparc_l44", 0, 12, 0 },
|
|
- { "fixup_sparc_hh", 0, 21, 0 },
|
|
- { "fixup_sparc_hm", 0, 10, 0 },
|
|
+ { "fixup_sparc_call30", 2, 30, MCFixupKindInfo::FKF_IsPCRel },
|
|
+ { "fixup_sparc_br22", 10, 22, MCFixupKindInfo::FKF_IsPCRel },
|
|
+ { "fixup_sparc_br19", 13, 19, MCFixupKindInfo::FKF_IsPCRel },
|
|
+ { "fixup_sparc_hi22", 10, 22, 0 },
|
|
+ { "fixup_sparc_lo10", 22, 10, 0 },
|
|
+ { "fixup_sparc_h44", 10, 22, 0 },
|
|
+ { "fixup_sparc_m44", 22, 10, 0 },
|
|
+ { "fixup_sparc_l44", 20, 12, 0 },
|
|
+ { "fixup_sparc_hh", 10, 22, 0 },
|
|
+ { "fixup_sparc_hm", 22, 10, 0 },
|
|
};
|
|
|
|
if (Kind < FirstTargetFixupKind)
|
|
Index: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
|
|
===================================================================
|
|
--- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
|
|
+++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
|
|
@@ -67,6 +67,37 @@ void SparcMCExpr::PrintImpl(raw_ostream &OS) const
|
|
OS << ')';
|
|
}
|
|
|
|
+SparcMCExpr::VariantKind SparcMCExpr::parseVariantKind(StringRef name)
|
|
+{
|
|
+ return StringSwitch<SparcMCExpr::VariantKind>(name)
|
|
+ .Case("lo", VK_Sparc_LO)
|
|
+ .Case("hi", VK_Sparc_HI)
|
|
+ .Case("h44", VK_Sparc_H44)
|
|
+ .Case("m44", VK_Sparc_M44)
|
|
+ .Case("l44", VK_Sparc_L44)
|
|
+ .Case("hh", VK_Sparc_HH)
|
|
+ .Case("hm", VK_Sparc_HM)
|
|
+ .Case("tgd_hi22", VK_Sparc_TLS_GD_HI22)
|
|
+ .Case("tgd_lo10", VK_Sparc_TLS_GD_LO10)
|
|
+ .Case("tgd_add", VK_Sparc_TLS_GD_ADD)
|
|
+ .Case("tgd_call", VK_Sparc_TLS_GD_CALL)
|
|
+ .Case("tldm_hi22", VK_Sparc_TLS_LDM_HI22)
|
|
+ .Case("tldm_lo10", VK_Sparc_TLS_LDM_LO10)
|
|
+ .Case("tldm_add", VK_Sparc_TLS_LDM_ADD)
|
|
+ .Case("tldm_call", VK_Sparc_TLS_LDM_CALL)
|
|
+ .Case("tldo_hix22", VK_Sparc_TLS_LDO_HIX22)
|
|
+ .Case("tldo_lox10", VK_Sparc_TLS_LDO_LOX10)
|
|
+ .Case("tldo_add", VK_Sparc_TLS_LDO_ADD)
|
|
+ .Case("tie_hi22", VK_Sparc_TLS_IE_HI22)
|
|
+ .Case("tie_lo10", VK_Sparc_TLS_IE_LO10)
|
|
+ .Case("tie_ld", VK_Sparc_TLS_IE_LD)
|
|
+ .Case("tie_ldx", VK_Sparc_TLS_IE_LDX)
|
|
+ .Case("tie_add", VK_Sparc_TLS_IE_ADD)
|
|
+ .Case("tle_hix22", VK_Sparc_TLS_LE_HIX22)
|
|
+ .Case("tle_lox10", VK_Sparc_TLS_LE_LOX10)
|
|
+ .Default(VK_Sparc_None);
|
|
+}
|
|
+
|
|
bool
|
|
SparcMCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
|
|
const MCAsmLayout *Layout) const {
|
|
Index: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
|
|
===================================================================
|
|
--- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
|
|
+++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
|
|
@@ -19,6 +19,7 @@
|
|
|
|
namespace llvm {
|
|
|
|
+class StringRef;
|
|
class SparcMCExpr : public MCTargetExpr {
|
|
public:
|
|
enum VariantKind {
|
|
@@ -90,6 +91,7 @@ class SparcMCExpr : public MCTargetExpr {
|
|
|
|
static bool classof(const SparcMCExpr *) { return true; }
|
|
|
|
+ static VariantKind parseVariantKind(StringRef name);
|
|
|
|
};
|
|
|
|
Index: lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
|
|
===================================================================
|
|
--- lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
|
|
+++ lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
|
|
@@ -8,6 +8,7 @@
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "MCTargetDesc/SparcMCTargetDesc.h"
|
|
+#include "MCTargetDesc/SparcMCExpr.h"
|
|
#include "llvm/ADT/STLExtras.h"
|
|
#include "llvm/MC/MCContext.h"
|
|
#include "llvm/MC/MCInst.h"
|
|
@@ -68,6 +69,7 @@ class SparcAsmParser : public MCTargetAsmParser {
|
|
// returns true if Tok is matched to a register and returns register in RegNo.
|
|
bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo, bool isDFP,
|
|
bool isQFP);
|
|
+ bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc);
|
|
|
|
public:
|
|
SparcAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
|
|
@@ -536,15 +538,19 @@ SparcAsmParser::parseSparcAsmOperand(SparcOperand
|
|
unsigned RegNo;
|
|
if (matchRegisterName(Parser.getTok(), RegNo, false, false)) {
|
|
Parser.Lex(); // Eat the identifier token.
|
|
+ E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
|
|
Op = SparcOperand::CreateReg(RegNo, SparcOperand::rk_None, S, E);
|
|
break;
|
|
}
|
|
- // FIXME: Handle modifiers like %hi, %lo etc.,
|
|
+ if (matchSparcAsmModifiers(EVal, E)) {
|
|
+ E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
|
|
+ Op = SparcOperand::CreateImm(EVal, S, E);
|
|
+ }
|
|
break;
|
|
|
|
case AsmToken::Minus:
|
|
case AsmToken::Integer:
|
|
- if (!getParser().parseExpression(EVal))
|
|
+ if (!getParser().parseExpression(EVal, E))
|
|
Op = SparcOperand::CreateImm(EVal, S, E);
|
|
break;
|
|
|
|
@@ -551,13 +557,11 @@ SparcAsmParser::parseSparcAsmOperand(SparcOperand
|
|
case AsmToken::Identifier: {
|
|
StringRef Identifier;
|
|
if (!getParser().parseIdentifier(Identifier)) {
|
|
- SMLoc E = SMLoc::getFromPointer(Parser.getTok().
|
|
- getLoc().getPointer() - 1);
|
|
+ E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
|
|
MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier);
|
|
|
|
const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
|
|
getContext());
|
|
-
|
|
Op = SparcOperand::CreateImm(Res, S, E);
|
|
}
|
|
break;
|
|
@@ -675,7 +679,33 @@ bool SparcAsmParser::matchRegisterName(const AsmTo
|
|
}
|
|
|
|
|
|
+bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
|
|
+ SMLoc &EndLoc)
|
|
+{
|
|
+ AsmToken Tok = Parser.getTok();
|
|
+ if (!Tok.is(AsmToken::Identifier))
|
|
+ return false;
|
|
|
|
+ StringRef name = Tok.getString();
|
|
+
|
|
+ SparcMCExpr::VariantKind VK = SparcMCExpr::parseVariantKind(name);
|
|
+
|
|
+ if (VK == SparcMCExpr::VK_Sparc_None)
|
|
+ return false;
|
|
+
|
|
+ Parser.Lex(); // Eat the identifier.
|
|
+ if (Parser.getTok().getKind() != AsmToken::LParen)
|
|
+ return false;
|
|
+
|
|
+ Parser.Lex(); // Eat the LParen token.
|
|
+ const MCExpr *subExpr;
|
|
+ if (Parser.parseParenExpression(subExpr, EndLoc))
|
|
+ return false;
|
|
+ EVal = SparcMCExpr::Create(VK, subExpr, getContext());
|
|
+ return true;
|
|
+}
|
|
+
|
|
+
|
|
extern "C" void LLVMInitializeSparcAsmParser() {
|
|
RegisterMCAsmParser<SparcAsmParser> A(TheSparcTarget);
|
|
RegisterMCAsmParser<SparcAsmParser> B(TheSparcV9Target);
|
|
Index: test/MC/Sparc/sparc-relocations.s
|
|
===================================================================
|
|
--- test/MC/Sparc/sparc-relocations.s
|
|
+++ test/MC/Sparc/sparc-relocations.s
|
|
@@ -0,0 +1,33 @@
|
|
+! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s
|
|
+
|
|
+ ! CHECK: call foo ! encoding: [0b01AAAAAA,A,A,A]
|
|
+ ! CHECK: ! fixup A - offset: 0, value: foo, kind: fixup_sparc_call30
|
|
+ call foo
|
|
+
|
|
+ ! CHECK: or %g1, %lo(sym), %g3 ! encoding: [0x86,0x10,0b011000AA,A]
|
|
+ ! CHECK-NEXT ! fixup A - offset: 0, value: %lo(sym), kind: fixup_sparc_lo10
|
|
+ or %g1, %lo(sym), %g3
|
|
+
|
|
+ ! CHECK: sethi %hi(sym), %l0 ! encoding: [0x21,0b00AAAAAA,A,A]
|
|
+ ! CHECK-NEXT: ! fixup A - offset: 0, value: %hi(sym), kind: fixup_sparc_hi22
|
|
+ sethi %hi(sym), %l0
|
|
+
|
|
+ ! CHECK: sethi %h44(sym), %l0 ! encoding: [0x21,0b00AAAAAA,A,A]
|
|
+ ! CHECK-NEXT: ! fixup A - offset: 0, value: %h44(sym), kind: fixup_sparc_h44
|
|
+ sethi %h44(sym), %l0
|
|
+
|
|
+ ! CHECK: or %g1, %m44(sym), %g3 ! encoding: [0x86,0x10,0b011000AA,A]
|
|
+ ! CHECK-NEXT ! fixup A - offset: 0, value: %m44(sym), kind: fixup_sparc_m44
|
|
+ or %g1, %m44(sym), %g3
|
|
+
|
|
+ ! CHECK: or %g1, %l44(sym), %g3 ! encoding: [0x86,0x10,0b0110AAAA,A]
|
|
+ ! CHECK-NEXT ! fixup A - offset: 0, value: %l44(sym), kind: fixup_sparc_l44
|
|
+ or %g1, %l44(sym), %g3
|
|
+
|
|
+ ! CHECK: sethi %hh(sym), %l0 ! encoding: [0x21,0b00AAAAAA,A,A]
|
|
+ ! CHECK-NEXT: ! fixup A - offset: 0, value: %hh(sym), kind: fixup_sparc_hh
|
|
+ sethi %hh(sym), %l0
|
|
+
|
|
+ ! CHECK: or %g1, %hm(sym), %g3 ! encoding: [0x86,0x10,0b011000AA,A]
|
|
+ ! CHECK-NEXT ! fixup A - offset: 0, value: %hm(sym), kind: fixup_sparc_hm
|
|
+ or %g1, %hm(sym), %g3
|
|
Index: test/MC/Sparc/sparc-ctrl-instructions.s
|
|
===================================================================
|
|
--- test/MC/Sparc/sparc-ctrl-instructions.s
|
|
+++ test/MC/Sparc/sparc-ctrl-instructions.s
|
|
@@ -1,23 +1,33 @@
|
|
! RUN: llvm-mc %s -arch=sparc -show-encoding | FileCheck %s
|
|
! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s
|
|
|
|
- ! CHECK: call foo
|
|
+ ! CHECK: call foo ! encoding: [0b01AAAAAA,A,A,A]
|
|
+ ! CHECK: ! fixup A - offset: 0, value: foo, kind: fixup_sparc_call30
|
|
call foo
|
|
|
|
- ! CHECK: call %g1+%i2
|
|
+ ! CHECK: call %g1+%i2 ! encoding: [0x9f,0xc0,0x40,0x1a]
|
|
call %g1 + %i2
|
|
|
|
- ! CHECK: call %o1+8
|
|
+ ! CHECK: call %o1+8 ! encoding: [0x9f,0xc2,0x60,0x08]
|
|
call %o1 + 8
|
|
|
|
- ! CHECK: call %g1
|
|
+ ! CHECK: call %g1 ! encoding: [0x9f,0xc0,0x60,0x00]
|
|
call %g1
|
|
|
|
- ! CHECK: jmp %g1+%i2
|
|
+ ! CHECK: call %g1+%lo(sym) ! encoding: [0x9f,0xc0,0b011000AA,A]
|
|
+ ! CHECK-NEXT: ! fixup A - offset: 0, value: %lo(sym), kind: fixup_sparc_lo10
|
|
+ call %g1+%lo(sym)
|
|
+
|
|
+ ! CHECK: jmp %g1+%i2 ! encoding: [0x81,0xc0,0x40,0x1a]
|
|
jmp %g1 + %i2
|
|
|
|
- ! CHECK: jmp %o1+8
|
|
+ ! CHECK: jmp %o1+8 ! encoding: [0x81,0xc2,0x60,0x08]
|
|
jmp %o1 + 8
|
|
|
|
- ! CHECK: jmp %g1
|
|
+ ! CHECK: jmp %g1 ! encoding: [0x81,0xc0,0x60,0x00]
|
|
jmp %g1
|
|
+
|
|
+ ! CHECK: jmp %g1+%lo(sym) ! encoding: [0x81,0xc0,0b011000AA,A]
|
|
+ ! CHECK-NEXT: ! fixup A - offset: 0, value: %lo(sym), kind: fixup_sparc_lo10
|
|
+ jmp %g1+%lo(sym)
|
|
+
|