Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit dff3861

Browse files
committed
[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
1 parent 9c15f4c commit dff3861

File tree

6 files changed

+132
-26
lines changed

6 files changed

+132
-26
lines changed

lib/Target/Sparc/AsmParser/SparcAsmParser.cpp

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
//===----------------------------------------------------------------------===//
99

1010
#include "MCTargetDesc/SparcMCTargetDesc.h"
11+
#include "MCTargetDesc/SparcMCExpr.h"
1112
#include "llvm/ADT/STLExtras.h"
1213
#include "llvm/MC/MCContext.h"
1314
#include "llvm/MC/MCInst.h"
@@ -68,6 +69,7 @@ class SparcAsmParser : public MCTargetAsmParser {
6869
// returns true if Tok is matched to a register and returns register in RegNo.
6970
bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo, bool isDFP,
7071
bool isQFP);
72+
bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc);
7173

7274
public:
7375
SparcAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
@@ -536,28 +538,30 @@ SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op)
536538
unsigned RegNo;
537539
if (matchRegisterName(Parser.getTok(), RegNo, false, false)) {
538540
Parser.Lex(); // Eat the identifier token.
541+
E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
539542
Op = SparcOperand::CreateReg(RegNo, SparcOperand::rk_None, S, E);
540543
break;
541544
}
542-
// FIXME: Handle modifiers like %hi, %lo etc.,
545+
if (matchSparcAsmModifiers(EVal, E)) {
546+
E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
547+
Op = SparcOperand::CreateImm(EVal, S, E);
548+
}
543549
break;
544550

545551
case AsmToken::Minus:
546552
case AsmToken::Integer:
547-
if (!getParser().parseExpression(EVal))
553+
if (!getParser().parseExpression(EVal, E))
548554
Op = SparcOperand::CreateImm(EVal, S, E);
549555
break;
550556

551557
case AsmToken::Identifier: {
552558
StringRef Identifier;
553559
if (!getParser().parseIdentifier(Identifier)) {
554-
SMLoc E = SMLoc::getFromPointer(Parser.getTok().
555-
getLoc().getPointer() - 1);
560+
E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
556561
MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier);
557562

558563
const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
559564
getContext());
560-
561565
Op = SparcOperand::CreateImm(Res, S, E);
562566
}
563567
break;
@@ -675,6 +679,32 @@ bool SparcAsmParser::matchRegisterName(const AsmToken &Tok,
675679
}
676680

677681

682+
bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
683+
SMLoc &EndLoc)
684+
{
685+
AsmToken Tok = Parser.getTok();
686+
if (!Tok.is(AsmToken::Identifier))
687+
return false;
688+
689+
StringRef name = Tok.getString();
690+
691+
SparcMCExpr::VariantKind VK = SparcMCExpr::parseVariantKind(name);
692+
693+
if (VK == SparcMCExpr::VK_Sparc_None)
694+
return false;
695+
696+
Parser.Lex(); // Eat the identifier.
697+
if (Parser.getTok().getKind() != AsmToken::LParen)
698+
return false;
699+
700+
Parser.Lex(); // Eat the LParen token.
701+
const MCExpr *subExpr;
702+
if (Parser.parseParenExpression(subExpr, EndLoc))
703+
return false;
704+
EVal = SparcMCExpr::Create(VK, subExpr, getContext());
705+
return true;
706+
}
707+
678708

679709
extern "C" void LLVMInitializeSparcAsmParser() {
680710
RegisterMCAsmParser<SparcAsmParser> A(TheSparcTarget);

lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
2727
case FK_Data_8:
2828
return Value;
2929
case Sparc::fixup_sparc_call30:
30-
return Value & 0x3fffffff;
30+
return (Value >> 2) & 0x3fffffff;
3131
case Sparc::fixup_sparc_br22:
32-
return Value & 0x3fffff;
32+
return (Value >> 2) & 0x3fffff;
3333
case Sparc::fixup_sparc_br19:
34-
return Value & 0x1ffff;
34+
return (Value >> 2) & 0x1ffff;
3535
case Sparc::fixup_sparc_hi22:
3636
return (Value >> 10) & 0x3fffff;
3737
case Sparc::fixup_sparc_lo10:
@@ -45,7 +45,7 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
4545
case Sparc::fixup_sparc_hh:
4646
return (Value >> 42) & 0x3fffff;
4747
case Sparc::fixup_sparc_hm:
48-
return (Value >>32) & 0x3ff;
48+
return (Value >> 32) & 0x3ff;
4949
}
5050
}
5151

@@ -62,16 +62,16 @@ namespace {
6262
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const {
6363
const static MCFixupKindInfo Infos[Sparc::NumTargetFixupKinds] = {
6464
// name offset bits flags
65-
{ "fixup_sparc_call30", 0, 30, MCFixupKindInfo::FKF_IsPCRel },
66-
{ "fixup_sparc_br22", 0, 22, MCFixupKindInfo::FKF_IsPCRel },
67-
{ "fixup_sparc_br19", 0, 19, MCFixupKindInfo::FKF_IsPCRel },
68-
{ "fixup_sparc_hi22", 0, 22, 0 },
69-
{ "fixup_sparc_lo10", 0, 10, 0 },
70-
{ "fixup_sparc_h44", 0, 22, 0 },
71-
{ "fixup_sparc_m44", 0, 10, 0 },
72-
{ "fixup_sparc_l44", 0, 12, 0 },
73-
{ "fixup_sparc_hh", 0, 21, 0 },
74-
{ "fixup_sparc_hm", 0, 10, 0 },
65+
{ "fixup_sparc_call30", 2, 30, MCFixupKindInfo::FKF_IsPCRel },
66+
{ "fixup_sparc_br22", 10, 22, MCFixupKindInfo::FKF_IsPCRel },
67+
{ "fixup_sparc_br19", 13, 19, MCFixupKindInfo::FKF_IsPCRel },
68+
{ "fixup_sparc_hi22", 10, 22, 0 },
69+
{ "fixup_sparc_lo10", 22, 10, 0 },
70+
{ "fixup_sparc_h44", 10, 22, 0 },
71+
{ "fixup_sparc_m44", 22, 10, 0 },
72+
{ "fixup_sparc_l44", 20, 12, 0 },
73+
{ "fixup_sparc_hh", 10, 22, 0 },
74+
{ "fixup_sparc_hm", 22, 10, 0 },
7575
};
7676

7777
if (Kind < FirstTargetFixupKind)

lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,37 @@ void SparcMCExpr::PrintImpl(raw_ostream &OS) const
6767
OS << ')';
6868
}
6969

70+
SparcMCExpr::VariantKind SparcMCExpr::parseVariantKind(StringRef name)
71+
{
72+
return StringSwitch<SparcMCExpr::VariantKind>(name)
73+
.Case("lo", VK_Sparc_LO)
74+
.Case("hi", VK_Sparc_HI)
75+
.Case("h44", VK_Sparc_H44)
76+
.Case("m44", VK_Sparc_M44)
77+
.Case("l44", VK_Sparc_L44)
78+
.Case("hh", VK_Sparc_HH)
79+
.Case("hm", VK_Sparc_HM)
80+
.Case("tgd_hi22", VK_Sparc_TLS_GD_HI22)
81+
.Case("tgd_lo10", VK_Sparc_TLS_GD_LO10)
82+
.Case("tgd_add", VK_Sparc_TLS_GD_ADD)
83+
.Case("tgd_call", VK_Sparc_TLS_GD_CALL)
84+
.Case("tldm_hi22", VK_Sparc_TLS_LDM_HI22)
85+
.Case("tldm_lo10", VK_Sparc_TLS_LDM_LO10)
86+
.Case("tldm_add", VK_Sparc_TLS_LDM_ADD)
87+
.Case("tldm_call", VK_Sparc_TLS_LDM_CALL)
88+
.Case("tldo_hix22", VK_Sparc_TLS_LDO_HIX22)
89+
.Case("tldo_lox10", VK_Sparc_TLS_LDO_LOX10)
90+
.Case("tldo_add", VK_Sparc_TLS_LDO_ADD)
91+
.Case("tie_hi22", VK_Sparc_TLS_IE_HI22)
92+
.Case("tie_lo10", VK_Sparc_TLS_IE_LO10)
93+
.Case("tie_ld", VK_Sparc_TLS_IE_LD)
94+
.Case("tie_ldx", VK_Sparc_TLS_IE_LDX)
95+
.Case("tie_add", VK_Sparc_TLS_IE_ADD)
96+
.Case("tle_hix22", VK_Sparc_TLS_LE_HIX22)
97+
.Case("tle_lox10", VK_Sparc_TLS_LE_LOX10)
98+
.Default(VK_Sparc_None);
99+
}
100+
70101
bool
71102
SparcMCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
72103
const MCAsmLayout *Layout) const {

lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
namespace llvm {
2121

22+
class StringRef;
2223
class SparcMCExpr : public MCTargetExpr {
2324
public:
2425
enum VariantKind {
@@ -90,6 +91,7 @@ class SparcMCExpr : public MCTargetExpr {
9091

9192
static bool classof(const SparcMCExpr *) { return true; }
9293

94+
static VariantKind parseVariantKind(StringRef name);
9395

9496
};
9597

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,33 @@
11
! RUN: llvm-mc %s -arch=sparc -show-encoding | FileCheck %s
22
! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s
33

4-
! CHECK: call foo
4+
! CHECK: call foo ! encoding: [0b01AAAAAA,A,A,A]
5+
! CHECK: ! fixup A - offset: 0, value: foo, kind: fixup_sparc_call30
56
call foo
67

7-
! CHECK: call %g1+%i2
8+
! CHECK: call %g1+%i2 ! encoding: [0x9f,0xc0,0x40,0x1a]
89
call %g1 + %i2
910

10-
! CHECK: call %o1+8
11+
! CHECK: call %o1+8 ! encoding: [0x9f,0xc2,0x60,0x08]
1112
call %o1 + 8
1213

13-
! CHECK: call %g1
14+
! CHECK: call %g1 ! encoding: [0x9f,0xc0,0x60,0x00]
1415
call %g1
1516

16-
! CHECK: jmp %g1+%i2
17+
! CHECK: call %g1+%lo(sym) ! encoding: [0x9f,0xc0,0b011000AA,A]
18+
! CHECK-NEXT: ! fixup A - offset: 0, value: %lo(sym), kind: fixup_sparc_lo10
19+
call %g1+%lo(sym)
20+
21+
! CHECK: jmp %g1+%i2 ! encoding: [0x81,0xc0,0x40,0x1a]
1722
jmp %g1 + %i2
1823

19-
! CHECK: jmp %o1+8
24+
! CHECK: jmp %o1+8 ! encoding: [0x81,0xc2,0x60,0x08]
2025
jmp %o1 + 8
2126

22-
! CHECK: jmp %g1
27+
! CHECK: jmp %g1 ! encoding: [0x81,0xc0,0x60,0x00]
2328
jmp %g1
29+
30+
! CHECK: jmp %g1+%lo(sym) ! encoding: [0x81,0xc0,0b011000AA,A]
31+
! CHECK-NEXT: ! fixup A - offset: 0, value: %lo(sym), kind: fixup_sparc_lo10
32+
jmp %g1+%lo(sym)
33+

test/MC/Sparc/sparc-relocations.s

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s
2+
3+
! CHECK: call foo ! encoding: [0b01AAAAAA,A,A,A]
4+
! CHECK: ! fixup A - offset: 0, value: foo, kind: fixup_sparc_call30
5+
call foo
6+
7+
! CHECK: or %g1, %lo(sym), %g3 ! encoding: [0x86,0x10,0b011000AA,A]
8+
! CHECK-NEXT ! fixup A - offset: 0, value: %lo(sym), kind: fixup_sparc_lo10
9+
or %g1, %lo(sym), %g3
10+
11+
! CHECK: sethi %hi(sym), %l0 ! encoding: [0x21,0b00AAAAAA,A,A]
12+
! CHECK-NEXT: ! fixup A - offset: 0, value: %hi(sym), kind: fixup_sparc_hi22
13+
sethi %hi(sym), %l0
14+
15+
! CHECK: sethi %h44(sym), %l0 ! encoding: [0x21,0b00AAAAAA,A,A]
16+
! CHECK-NEXT: ! fixup A - offset: 0, value: %h44(sym), kind: fixup_sparc_h44
17+
sethi %h44(sym), %l0
18+
19+
! CHECK: or %g1, %m44(sym), %g3 ! encoding: [0x86,0x10,0b011000AA,A]
20+
! CHECK-NEXT ! fixup A - offset: 0, value: %m44(sym), kind: fixup_sparc_m44
21+
or %g1, %m44(sym), %g3
22+
23+
! CHECK: or %g1, %l44(sym), %g3 ! encoding: [0x86,0x10,0b0110AAAA,A]
24+
! CHECK-NEXT ! fixup A - offset: 0, value: %l44(sym), kind: fixup_sparc_l44
25+
or %g1, %l44(sym), %g3
26+
27+
! CHECK: sethi %hh(sym), %l0 ! encoding: [0x21,0b00AAAAAA,A,A]
28+
! CHECK-NEXT: ! fixup A - offset: 0, value: %hh(sym), kind: fixup_sparc_hh
29+
sethi %hh(sym), %l0
30+
31+
! CHECK: or %g1, %hm(sym), %g3 ! encoding: [0x86,0x10,0b011000AA,A]
32+
! CHECK-NEXT ! fixup A - offset: 0, value: %hm(sym), kind: fixup_sparc_hm
33+
or %g1, %hm(sym), %g3

0 commit comments

Comments
 (0)