patch-r262261-llvm-r198681-sparc.diff revision 269012
1Pull in r198681 from upstream llvm trunk (by Venkatraman Govindaraju):
2
3  [Sparc] Add support for parsing sparc asm modifiers such as %hi, %lo etc., 
4  Also, correct the offsets for FixupsKindInfo.
5
6Introduced here: http://svnweb.freebsd.org/changeset/base/262261
7
8Index: 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
13   case FK_Data_8:
14     return Value;
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;
33   }
34 }
35 
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 },
60       };
61 
62       if (Kind < FirstTargetFixupKind)
63Index: 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
68     OS << ')';
69 }
70 
71+SparcMCExpr::VariantKind SparcMCExpr::parseVariantKind(StringRef name)
72+{
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);
100+}
101+
102 bool
103 SparcMCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
104                                          const MCAsmLayout *Layout) const {
105Index: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
106===================================================================
107--- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
108+++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
109@@ -19,6 +19,7 @@
110 
111 namespace llvm {
112 
113+class StringRef;
114 class SparcMCExpr : public MCTargetExpr {
115 public:
116   enum VariantKind {
117@@ -90,6 +91,7 @@ class SparcMCExpr : public MCTargetExpr {
118 
119   static bool classof(const SparcMCExpr *) { return true; }
120 
121+  static VariantKind parseVariantKind(StringRef name);
122 
123 };
124 
125Index: lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
126===================================================================
127--- lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
128+++ lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
129@@ -8,6 +8,7 @@
130 //===----------------------------------------------------------------------===//
131 
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,
140                          bool isQFP);
141+  bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc);
142 
143 public:
144   SparcAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
145@@ -536,15 +538,19 @@ SparcAsmParser::parseSparcAsmOperand(SparcOperand
146     unsigned RegNo;
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);
151       break;
152     }
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);
157+    }
158     break;
159 
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);
165     break;
166 
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);
175 
176       const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
177                                                   getContext());
178-
179       Op = SparcOperand::CreateImm(Res, S, E);
180     }
181     break;
182@@ -675,7 +679,33 @@ bool SparcAsmParser::matchRegisterName(const AsmTo
183 }
184 
185 
186+bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
187+                                            SMLoc &EndLoc)
188+{
189+  AsmToken Tok = Parser.getTok();
190+  if (!Tok.is(AsmToken::Identifier))
191+    return false;
192 
193+  StringRef name = Tok.getString();
194+
195+  SparcMCExpr::VariantKind VK = SparcMCExpr::parseVariantKind(name);
196+
197+  if (VK == SparcMCExpr::VK_Sparc_None)
198+    return false;
199+
200+  Parser.Lex(); // Eat the identifier.
201+  if (Parser.getTok().getKind() != AsmToken::LParen)
202+    return false;
203+
204+  Parser.Lex(); // Eat the LParen token.
205+  const MCExpr *subExpr;
206+  if (Parser.parseParenExpression(subExpr, EndLoc))
207+    return false;
208+  EVal = SparcMCExpr::Create(VK, subExpr, getContext());
209+  return true;
210+}
211+
212+
213 extern "C" void LLVMInitializeSparcAsmParser() {
214   RegisterMCAsmParser<SparcAsmParser> A(TheSparcTarget);
215   RegisterMCAsmParser<SparcAsmParser> B(TheSparcV9Target);
216Index: test/MC/Sparc/sparc-relocations.s
217===================================================================
218--- test/MC/Sparc/sparc-relocations.s
219+++ test/MC/Sparc/sparc-relocations.s
220@@ -0,0 +1,33 @@
221+! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s
222+
223+        ! CHECK: call foo     ! encoding: [0b01AAAAAA,A,A,A]
224+        ! CHECK:              !   fixup A - offset: 0, value: foo, kind: fixup_sparc_call30
225+        call foo
226+
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
230+
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
234+
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
238+
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
242+
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
246+
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
250+
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
254Index: test/MC/Sparc/sparc-ctrl-instructions.s
255===================================================================
256--- test/MC/Sparc/sparc-ctrl-instructions.s
257+++ test/MC/Sparc/sparc-ctrl-instructions.s
258@@ -1,23 +1,33 @@
259 ! RUN: llvm-mc %s -arch=sparc   -show-encoding | FileCheck %s
260 ! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s
261 
262-        ! CHECK: call foo
263+        ! CHECK: call foo     ! encoding: [0b01AAAAAA,A,A,A]
264+        ! CHECK:              !   fixup A - offset: 0, value: foo, kind: fixup_sparc_call30
265         call foo
266 
267-        ! CHECK: call %g1+%i2
268+        ! CHECK: call %g1+%i2 ! encoding: [0x9f,0xc0,0x40,0x1a]
269         call %g1 + %i2
270 
271-        ! CHECK: call %o1+8
272+        ! CHECK: call %o1+8   ! encoding: [0x9f,0xc2,0x60,0x08]
273         call %o1 + 8
274 
275-        ! CHECK: call %g1
276+        ! CHECK: call %g1     ! encoding: [0x9f,0xc0,0x60,0x00]
277         call %g1
278 
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
282+        call %g1+%lo(sym)
283+
284+        ! CHECK: jmp %g1+%i2  ! encoding: [0x81,0xc0,0x40,0x1a]
285         jmp %g1 + %i2
286 
287-        ! CHECK: jmp %o1+8
288+        ! CHECK: jmp %o1+8    ! encoding: [0x81,0xc2,0x60,0x08]
289         jmp %o1 + 8
290 
291-        ! CHECK: jmp %g1
292+        ! CHECK: jmp %g1      ! encoding: [0x81,0xc0,0x60,0x00]
293         jmp %g1
294+
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
297+        jmp %g1+%lo(sym)
298+
299