summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVenkatraman Govindaraju <venkatra@cs.wisc.edu>2014-01-07 08:00:49 +0000
committerVenkatraman Govindaraju <venkatra@cs.wisc.edu>2014-01-07 08:00:49 +0000
commitdff38618c62600e912f4d39d9dfe9b547fa4749e (patch)
tree864975f2670d1954d88f7138eb163a1bb5a90b60
parent9c15f4c9c98d884ff5427df69f9859a95b75c2fb (diff)
downloadllvm-dff38618c62600e912f4d39d9dfe9b547fa4749e.tar.gz
llvm-dff38618c62600e912f4d39d9dfe9b547fa4749e.tar.bz2
llvm-dff38618c62600e912f4d39d9dfe9b547fa4749e.tar.xz
[Sparc] Add support for parsing sparc asm modifiers such as %hi, %lo etc.,
Also, correct the offsets for FixupsKindInfo. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@198681 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/Sparc/AsmParser/SparcAsmParser.cpp40
-rw-r--r--lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp28
-rw-r--r--lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp31
-rw-r--r--lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h2
-rw-r--r--test/MC/Sparc/sparc-ctrl-instructions.s24
-rw-r--r--test/MC/Sparc/sparc-relocations.s33
6 files changed, 132 insertions, 26 deletions
diff --git a/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp b/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
index 13f62666fc..8ae10c801c 100644
--- a/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
+++ b/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,28 +538,30 @@ SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op)
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;
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,6 +679,32 @@ bool SparcAsmParser::matchRegisterName(const AsmToken &Tok,
}
+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);
diff --git a/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp b/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
index 41b31e8374..66aae57d0f 100644
--- a/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
+++ b/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
@@ -27,11 +27,11 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
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, uint64_t Value) {
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)
diff --git a/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp b/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
index bc395b97a9..28d2afe46b 100644
--- a/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
+++ b/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 {
diff --git a/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h b/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
index 244c14395e..c156ea0351 100644
--- a/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
+++ b/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 @@ public:
static bool classof(const SparcMCExpr *) { return true; }
+ static VariantKind parseVariantKind(StringRef name);
};
diff --git a/test/MC/Sparc/sparc-ctrl-instructions.s b/test/MC/Sparc/sparc-ctrl-instructions.s
index 5a2c5975f6..b6ea1131ca 100644
--- a/test/MC/Sparc/sparc-ctrl-instructions.s
+++ b/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)
+
diff --git a/test/MC/Sparc/sparc-relocations.s b/test/MC/Sparc/sparc-relocations.s
new file mode 100644
index 0000000000..9b1d722baf
--- /dev/null
+++ b/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