1 Pull in r198681 from upstream llvm trunk (by Venkatraman Govindaraju):
3 [Sparc] Add support for parsing sparc asm modifiers such as %hi, %lo etc.,
4 Also, correct the offsets for FixupsKindInfo.
6 Introduced here: http://svnweb.freebsd.org/changeset/base/262261
8 Index: lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
9 ===================================================================
10 --- lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
11 +++ lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
12 @@ -27,11 +27,11 @@ static unsigned adjustFixupValue(unsigned Kind, ui
15 case Sparc::fixup_sparc_call30:
16 - return Value & 0x3fffffff;
17 + return (Value >> 2) & 0x3fffffff;
18 case Sparc::fixup_sparc_br22:
19 - return Value & 0x3fffff;
20 + return (Value >> 2) & 0x3fffff;
21 case Sparc::fixup_sparc_br19:
22 - return Value & 0x1ffff;
23 + return (Value >> 2) & 0x1ffff;
24 case Sparc::fixup_sparc_hi22:
25 return (Value >> 10) & 0x3fffff;
26 case Sparc::fixup_sparc_lo10:
27 @@ -45,7 +45,7 @@ static unsigned adjustFixupValue(unsigned Kind, ui
28 case Sparc::fixup_sparc_hh:
29 return (Value >> 42) & 0x3fffff;
30 case Sparc::fixup_sparc_hm:
31 - return (Value >>32) & 0x3ff;
32 + return (Value >> 32) & 0x3ff;
36 @@ -62,16 +62,16 @@ namespace {
37 const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const {
38 const static MCFixupKindInfo Infos[Sparc::NumTargetFixupKinds] = {
39 // name offset bits flags
40 - { "fixup_sparc_call30", 0, 30, MCFixupKindInfo::FKF_IsPCRel },
41 - { "fixup_sparc_br22", 0, 22, MCFixupKindInfo::FKF_IsPCRel },
42 - { "fixup_sparc_br19", 0, 19, MCFixupKindInfo::FKF_IsPCRel },
43 - { "fixup_sparc_hi22", 0, 22, 0 },
44 - { "fixup_sparc_lo10", 0, 10, 0 },
45 - { "fixup_sparc_h44", 0, 22, 0 },
46 - { "fixup_sparc_m44", 0, 10, 0 },
47 - { "fixup_sparc_l44", 0, 12, 0 },
48 - { "fixup_sparc_hh", 0, 21, 0 },
49 - { "fixup_sparc_hm", 0, 10, 0 },
50 + { "fixup_sparc_call30", 2, 30, MCFixupKindInfo::FKF_IsPCRel },
51 + { "fixup_sparc_br22", 10, 22, MCFixupKindInfo::FKF_IsPCRel },
52 + { "fixup_sparc_br19", 13, 19, MCFixupKindInfo::FKF_IsPCRel },
53 + { "fixup_sparc_hi22", 10, 22, 0 },
54 + { "fixup_sparc_lo10", 22, 10, 0 },
55 + { "fixup_sparc_h44", 10, 22, 0 },
56 + { "fixup_sparc_m44", 22, 10, 0 },
57 + { "fixup_sparc_l44", 20, 12, 0 },
58 + { "fixup_sparc_hh", 10, 22, 0 },
59 + { "fixup_sparc_hm", 22, 10, 0 },
62 if (Kind < FirstTargetFixupKind)
63 Index: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
64 ===================================================================
65 --- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
66 +++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
67 @@ -67,6 +67,37 @@ void SparcMCExpr::PrintImpl(raw_ostream &OS) const
71 +SparcMCExpr::VariantKind SparcMCExpr::parseVariantKind(StringRef name)
73 + return StringSwitch<SparcMCExpr::VariantKind>(name)
74 + .Case("lo", VK_Sparc_LO)
75 + .Case("hi", VK_Sparc_HI)
76 + .Case("h44", VK_Sparc_H44)
77 + .Case("m44", VK_Sparc_M44)
78 + .Case("l44", VK_Sparc_L44)
79 + .Case("hh", VK_Sparc_HH)
80 + .Case("hm", VK_Sparc_HM)
81 + .Case("tgd_hi22", VK_Sparc_TLS_GD_HI22)
82 + .Case("tgd_lo10", VK_Sparc_TLS_GD_LO10)
83 + .Case("tgd_add", VK_Sparc_TLS_GD_ADD)
84 + .Case("tgd_call", VK_Sparc_TLS_GD_CALL)
85 + .Case("tldm_hi22", VK_Sparc_TLS_LDM_HI22)
86 + .Case("tldm_lo10", VK_Sparc_TLS_LDM_LO10)
87 + .Case("tldm_add", VK_Sparc_TLS_LDM_ADD)
88 + .Case("tldm_call", VK_Sparc_TLS_LDM_CALL)
89 + .Case("tldo_hix22", VK_Sparc_TLS_LDO_HIX22)
90 + .Case("tldo_lox10", VK_Sparc_TLS_LDO_LOX10)
91 + .Case("tldo_add", VK_Sparc_TLS_LDO_ADD)
92 + .Case("tie_hi22", VK_Sparc_TLS_IE_HI22)
93 + .Case("tie_lo10", VK_Sparc_TLS_IE_LO10)
94 + .Case("tie_ld", VK_Sparc_TLS_IE_LD)
95 + .Case("tie_ldx", VK_Sparc_TLS_IE_LDX)
96 + .Case("tie_add", VK_Sparc_TLS_IE_ADD)
97 + .Case("tle_hix22", VK_Sparc_TLS_LE_HIX22)
98 + .Case("tle_lox10", VK_Sparc_TLS_LE_LOX10)
99 + .Default(VK_Sparc_None);
103 SparcMCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
104 const MCAsmLayout *Layout) const {
105 Index: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
106 ===================================================================
107 --- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
108 +++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
114 class SparcMCExpr : public MCTargetExpr {
117 @@ -90,6 +91,7 @@ class SparcMCExpr : public MCTargetExpr {
119 static bool classof(const SparcMCExpr *) { return true; }
121 + static VariantKind parseVariantKind(StringRef name);
125 Index: lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
126 ===================================================================
127 --- lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
128 +++ lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
130 //===----------------------------------------------------------------------===//
132 #include "MCTargetDesc/SparcMCTargetDesc.h"
133 +#include "MCTargetDesc/SparcMCExpr.h"
134 #include "llvm/ADT/STLExtras.h"
135 #include "llvm/MC/MCContext.h"
136 #include "llvm/MC/MCInst.h"
137 @@ -68,6 +69,7 @@ class SparcAsmParser : public MCTargetAsmParser {
138 // returns true if Tok is matched to a register and returns register in RegNo.
139 bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo, bool isDFP,
141 + bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc);
144 SparcAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
145 @@ -536,15 +538,19 @@ SparcAsmParser::parseSparcAsmOperand(SparcOperand
147 if (matchRegisterName(Parser.getTok(), RegNo, false, false)) {
148 Parser.Lex(); // Eat the identifier token.
149 + E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
150 Op = SparcOperand::CreateReg(RegNo, SparcOperand::rk_None, S, E);
153 - // FIXME: Handle modifiers like %hi, %lo etc.,
154 + if (matchSparcAsmModifiers(EVal, E)) {
155 + E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
156 + Op = SparcOperand::CreateImm(EVal, S, E);
160 case AsmToken::Minus:
161 case AsmToken::Integer:
162 - if (!getParser().parseExpression(EVal))
163 + if (!getParser().parseExpression(EVal, E))
164 Op = SparcOperand::CreateImm(EVal, S, E);
167 @@ -551,13 +557,11 @@ SparcAsmParser::parseSparcAsmOperand(SparcOperand
168 case AsmToken::Identifier: {
169 StringRef Identifier;
170 if (!getParser().parseIdentifier(Identifier)) {
171 - SMLoc E = SMLoc::getFromPointer(Parser.getTok().
172 - getLoc().getPointer() - 1);
173 + E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
174 MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier);
176 const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
179 Op = SparcOperand::CreateImm(Res, S, E);
182 @@ -675,7 +679,33 @@ bool SparcAsmParser::matchRegisterName(const AsmTo
186 +bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
189 + AsmToken Tok = Parser.getTok();
190 + if (!Tok.is(AsmToken::Identifier))
193 + StringRef name = Tok.getString();
195 + SparcMCExpr::VariantKind VK = SparcMCExpr::parseVariantKind(name);
197 + if (VK == SparcMCExpr::VK_Sparc_None)
200 + Parser.Lex(); // Eat the identifier.
201 + if (Parser.getTok().getKind() != AsmToken::LParen)
204 + Parser.Lex(); // Eat the LParen token.
205 + const MCExpr *subExpr;
206 + if (Parser.parseParenExpression(subExpr, EndLoc))
208 + EVal = SparcMCExpr::Create(VK, subExpr, getContext());
213 extern "C" void LLVMInitializeSparcAsmParser() {
214 RegisterMCAsmParser<SparcAsmParser> A(TheSparcTarget);
215 RegisterMCAsmParser<SparcAsmParser> B(TheSparcV9Target);
216 Index: test/MC/Sparc/sparc-relocations.s
217 ===================================================================
218 --- test/MC/Sparc/sparc-relocations.s
219 +++ test/MC/Sparc/sparc-relocations.s
221 +! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s
223 + ! CHECK: call foo ! encoding: [0b01AAAAAA,A,A,A]
224 + ! CHECK: ! fixup A - offset: 0, value: foo, kind: fixup_sparc_call30
227 + ! CHECK: or %g1, %lo(sym), %g3 ! encoding: [0x86,0x10,0b011000AA,A]
228 + ! CHECK-NEXT ! fixup A - offset: 0, value: %lo(sym), kind: fixup_sparc_lo10
229 + or %g1, %lo(sym), %g3
231 + ! CHECK: sethi %hi(sym), %l0 ! encoding: [0x21,0b00AAAAAA,A,A]
232 + ! CHECK-NEXT: ! fixup A - offset: 0, value: %hi(sym), kind: fixup_sparc_hi22
233 + sethi %hi(sym), %l0
235 + ! CHECK: sethi %h44(sym), %l0 ! encoding: [0x21,0b00AAAAAA,A,A]
236 + ! CHECK-NEXT: ! fixup A - offset: 0, value: %h44(sym), kind: fixup_sparc_h44
237 + sethi %h44(sym), %l0
239 + ! CHECK: or %g1, %m44(sym), %g3 ! encoding: [0x86,0x10,0b011000AA,A]
240 + ! CHECK-NEXT ! fixup A - offset: 0, value: %m44(sym), kind: fixup_sparc_m44
241 + or %g1, %m44(sym), %g3
243 + ! CHECK: or %g1, %l44(sym), %g3 ! encoding: [0x86,0x10,0b0110AAAA,A]
244 + ! CHECK-NEXT ! fixup A - offset: 0, value: %l44(sym), kind: fixup_sparc_l44
245 + or %g1, %l44(sym), %g3
247 + ! CHECK: sethi %hh(sym), %l0 ! encoding: [0x21,0b00AAAAAA,A,A]
248 + ! CHECK-NEXT: ! fixup A - offset: 0, value: %hh(sym), kind: fixup_sparc_hh
249 + sethi %hh(sym), %l0
251 + ! CHECK: or %g1, %hm(sym), %g3 ! encoding: [0x86,0x10,0b011000AA,A]
252 + ! CHECK-NEXT ! fixup A - offset: 0, value: %hm(sym), kind: fixup_sparc_hm
253 + or %g1, %hm(sym), %g3
254 Index: test/MC/Sparc/sparc-ctrl-instructions.s
255 ===================================================================
256 --- test/MC/Sparc/sparc-ctrl-instructions.s
257 +++ test/MC/Sparc/sparc-ctrl-instructions.s
259 ! RUN: llvm-mc %s -arch=sparc -show-encoding | FileCheck %s
260 ! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s
263 + ! CHECK: call foo ! encoding: [0b01AAAAAA,A,A,A]
264 + ! CHECK: ! fixup A - offset: 0, value: foo, kind: fixup_sparc_call30
267 - ! CHECK: call %g1+%i2
268 + ! CHECK: call %g1+%i2 ! encoding: [0x9f,0xc0,0x40,0x1a]
271 - ! CHECK: call %o1+8
272 + ! CHECK: call %o1+8 ! encoding: [0x9f,0xc2,0x60,0x08]
276 + ! CHECK: call %g1 ! encoding: [0x9f,0xc0,0x60,0x00]
279 - ! CHECK: jmp %g1+%i2
280 + ! CHECK: call %g1+%lo(sym) ! encoding: [0x9f,0xc0,0b011000AA,A]
281 + ! CHECK-NEXT: ! fixup A - offset: 0, value: %lo(sym), kind: fixup_sparc_lo10
284 + ! CHECK: jmp %g1+%i2 ! encoding: [0x81,0xc0,0x40,0x1a]
288 + ! CHECK: jmp %o1+8 ! encoding: [0x81,0xc2,0x60,0x08]
292 + ! CHECK: jmp %g1 ! encoding: [0x81,0xc0,0x60,0x00]
295 + ! CHECK: jmp %g1+%lo(sym) ! encoding: [0x81,0xc0,0b011000AA,A]
296 + ! CHECK-NEXT: ! fixup A - offset: 0, value: %lo(sym), kind: fixup_sparc_lo10