1263320SdimPull in r198681 from upstream llvm trunk (by Venkatraman Govindaraju):
2263320Sdim
3263320Sdim  [Sparc] Add support for parsing sparc asm modifiers such as %hi, %lo etc., 
4263320Sdim  Also, correct the offsets for FixupsKindInfo.
5263320Sdim
6269012SemasteIntroduced here: http://svnweb.freebsd.org/changeset/base/262261
7263320Sdim
8263320SdimIndex: lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
9263320Sdim===================================================================
10263320Sdim--- lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
11263320Sdim+++ lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
12263320Sdim@@ -27,11 +27,11 @@ static unsigned adjustFixupValue(unsigned Kind, ui
13263320Sdim   case FK_Data_8:
14263320Sdim     return Value;
15263320Sdim   case Sparc::fixup_sparc_call30:
16263320Sdim-    return Value & 0x3fffffff;
17263320Sdim+    return (Value >> 2) & 0x3fffffff;
18263320Sdim   case Sparc::fixup_sparc_br22:
19263320Sdim-    return Value & 0x3fffff;
20263320Sdim+    return (Value >> 2) & 0x3fffff;
21263320Sdim   case Sparc::fixup_sparc_br19:
22263320Sdim-    return Value & 0x1ffff;
23263320Sdim+    return (Value >> 2) & 0x1ffff;
24263320Sdim   case Sparc::fixup_sparc_hi22:
25263320Sdim     return (Value >> 10) & 0x3fffff;
26263320Sdim   case Sparc::fixup_sparc_lo10:
27263320Sdim@@ -45,7 +45,7 @@ static unsigned adjustFixupValue(unsigned Kind, ui
28263320Sdim   case Sparc::fixup_sparc_hh:
29263320Sdim     return (Value >> 42) & 0x3fffff;
30263320Sdim   case Sparc::fixup_sparc_hm:
31263320Sdim-    return (Value >>32) & 0x3ff;
32263320Sdim+    return (Value >> 32) & 0x3ff;
33263320Sdim   }
34263320Sdim }
35263320Sdim 
36263320Sdim@@ -62,16 +62,16 @@ namespace {
37263320Sdim     const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const {
38263320Sdim       const static MCFixupKindInfo Infos[Sparc::NumTargetFixupKinds] = {
39263320Sdim         // name                    offset bits  flags
40263320Sdim-        { "fixup_sparc_call30",     0,     30,  MCFixupKindInfo::FKF_IsPCRel },
41263320Sdim-        { "fixup_sparc_br22",       0,     22,  MCFixupKindInfo::FKF_IsPCRel },
42263320Sdim-        { "fixup_sparc_br19",       0,     19,  MCFixupKindInfo::FKF_IsPCRel },
43263320Sdim-        { "fixup_sparc_hi22",       0,     22,  0 },
44263320Sdim-        { "fixup_sparc_lo10",       0,     10,  0 },
45263320Sdim-        { "fixup_sparc_h44",        0,     22,  0 },
46263320Sdim-        { "fixup_sparc_m44",        0,     10,  0 },
47263320Sdim-        { "fixup_sparc_l44",        0,     12,  0 },
48263320Sdim-        { "fixup_sparc_hh",         0,     21,  0 },
49263320Sdim-        { "fixup_sparc_hm",         0,     10,  0 },
50263320Sdim+        { "fixup_sparc_call30",     2,     30,  MCFixupKindInfo::FKF_IsPCRel },
51263320Sdim+        { "fixup_sparc_br22",      10,     22,  MCFixupKindInfo::FKF_IsPCRel },
52263320Sdim+        { "fixup_sparc_br19",      13,     19,  MCFixupKindInfo::FKF_IsPCRel },
53263320Sdim+        { "fixup_sparc_hi22",      10,     22,  0 },
54263320Sdim+        { "fixup_sparc_lo10",      22,     10,  0 },
55263320Sdim+        { "fixup_sparc_h44",       10,     22,  0 },
56263320Sdim+        { "fixup_sparc_m44",       22,     10,  0 },
57263320Sdim+        { "fixup_sparc_l44",       20,     12,  0 },
58263320Sdim+        { "fixup_sparc_hh",        10,     22,  0 },
59263320Sdim+        { "fixup_sparc_hm",        22,     10,  0 },
60263320Sdim       };
61263320Sdim 
62263320Sdim       if (Kind < FirstTargetFixupKind)
63263320SdimIndex: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
64263320Sdim===================================================================
65263320Sdim--- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
66263320Sdim+++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
67263320Sdim@@ -67,6 +67,37 @@ void SparcMCExpr::PrintImpl(raw_ostream &OS) const
68263320Sdim     OS << ')';
69263320Sdim }
70263320Sdim 
71263320Sdim+SparcMCExpr::VariantKind SparcMCExpr::parseVariantKind(StringRef name)
72263320Sdim+{
73263320Sdim+  return StringSwitch<SparcMCExpr::VariantKind>(name)
74263320Sdim+    .Case("lo",  VK_Sparc_LO)
75263320Sdim+    .Case("hi",  VK_Sparc_HI)
76263320Sdim+    .Case("h44", VK_Sparc_H44)
77263320Sdim+    .Case("m44", VK_Sparc_M44)
78263320Sdim+    .Case("l44", VK_Sparc_L44)
79263320Sdim+    .Case("hh",  VK_Sparc_HH)
80263320Sdim+    .Case("hm",  VK_Sparc_HM)
81263320Sdim+    .Case("tgd_hi22",   VK_Sparc_TLS_GD_HI22)
82263320Sdim+    .Case("tgd_lo10",   VK_Sparc_TLS_GD_LO10)
83263320Sdim+    .Case("tgd_add",    VK_Sparc_TLS_GD_ADD)
84263320Sdim+    .Case("tgd_call",   VK_Sparc_TLS_GD_CALL)
85263320Sdim+    .Case("tldm_hi22",  VK_Sparc_TLS_LDM_HI22)
86263320Sdim+    .Case("tldm_lo10",  VK_Sparc_TLS_LDM_LO10)
87263320Sdim+    .Case("tldm_add",   VK_Sparc_TLS_LDM_ADD)
88263320Sdim+    .Case("tldm_call",  VK_Sparc_TLS_LDM_CALL)
89263320Sdim+    .Case("tldo_hix22", VK_Sparc_TLS_LDO_HIX22)
90263320Sdim+    .Case("tldo_lox10", VK_Sparc_TLS_LDO_LOX10)
91263320Sdim+    .Case("tldo_add",   VK_Sparc_TLS_LDO_ADD)
92263320Sdim+    .Case("tie_hi22",   VK_Sparc_TLS_IE_HI22)
93263320Sdim+    .Case("tie_lo10",   VK_Sparc_TLS_IE_LO10)
94263320Sdim+    .Case("tie_ld",     VK_Sparc_TLS_IE_LD)
95263320Sdim+    .Case("tie_ldx",    VK_Sparc_TLS_IE_LDX)
96263320Sdim+    .Case("tie_add",    VK_Sparc_TLS_IE_ADD)
97263320Sdim+    .Case("tle_hix22",  VK_Sparc_TLS_LE_HIX22)
98263320Sdim+    .Case("tle_lox10",  VK_Sparc_TLS_LE_LOX10)
99263320Sdim+    .Default(VK_Sparc_None);
100263320Sdim+}
101263320Sdim+
102263320Sdim bool
103263320Sdim SparcMCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
104263320Sdim                                          const MCAsmLayout *Layout) const {
105263320SdimIndex: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
106263320Sdim===================================================================
107263320Sdim--- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
108263320Sdim+++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
109263320Sdim@@ -19,6 +19,7 @@
110263320Sdim 
111263320Sdim namespace llvm {
112263320Sdim 
113263320Sdim+class StringRef;
114263320Sdim class SparcMCExpr : public MCTargetExpr {
115263320Sdim public:
116263320Sdim   enum VariantKind {
117263320Sdim@@ -90,6 +91,7 @@ class SparcMCExpr : public MCTargetExpr {
118263320Sdim 
119263320Sdim   static bool classof(const SparcMCExpr *) { return true; }
120263320Sdim 
121263320Sdim+  static VariantKind parseVariantKind(StringRef name);
122263320Sdim 
123263320Sdim };
124263320Sdim 
125263320SdimIndex: lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
126263320Sdim===================================================================
127263320Sdim--- lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
128263320Sdim+++ lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
129263320Sdim@@ -8,6 +8,7 @@
130263320Sdim //===----------------------------------------------------------------------===//
131263320Sdim 
132263320Sdim #include "MCTargetDesc/SparcMCTargetDesc.h"
133263320Sdim+#include "MCTargetDesc/SparcMCExpr.h"
134263320Sdim #include "llvm/ADT/STLExtras.h"
135263320Sdim #include "llvm/MC/MCContext.h"
136263320Sdim #include "llvm/MC/MCInst.h"
137263320Sdim@@ -68,6 +69,7 @@ class SparcAsmParser : public MCTargetAsmParser {
138263320Sdim   // returns true if Tok is matched to a register and returns register in RegNo.
139263320Sdim   bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo, bool isDFP,
140263320Sdim                          bool isQFP);
141263320Sdim+  bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc);
142263320Sdim 
143263320Sdim public:
144263320Sdim   SparcAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
145263320Sdim@@ -536,15 +538,19 @@ SparcAsmParser::parseSparcAsmOperand(SparcOperand
146263320Sdim     unsigned RegNo;
147263320Sdim     if (matchRegisterName(Parser.getTok(), RegNo, false, false)) {
148263320Sdim       Parser.Lex(); // Eat the identifier token.
149263320Sdim+      E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
150263320Sdim       Op = SparcOperand::CreateReg(RegNo, SparcOperand::rk_None, S, E);
151263320Sdim       break;
152263320Sdim     }
153263320Sdim-    // FIXME: Handle modifiers like %hi, %lo etc.,
154263320Sdim+    if (matchSparcAsmModifiers(EVal, E)) {
155263320Sdim+      E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
156263320Sdim+      Op = SparcOperand::CreateImm(EVal, S, E);
157263320Sdim+    }
158263320Sdim     break;
159263320Sdim 
160263320Sdim   case AsmToken::Minus:
161263320Sdim   case AsmToken::Integer:
162263320Sdim-    if (!getParser().parseExpression(EVal))
163263320Sdim+    if (!getParser().parseExpression(EVal, E))
164263320Sdim       Op = SparcOperand::CreateImm(EVal, S, E);
165263320Sdim     break;
166263320Sdim 
167263320Sdim@@ -551,13 +557,11 @@ SparcAsmParser::parseSparcAsmOperand(SparcOperand
168263320Sdim   case AsmToken::Identifier: {
169263320Sdim     StringRef Identifier;
170263320Sdim     if (!getParser().parseIdentifier(Identifier)) {
171263320Sdim-      SMLoc E = SMLoc::getFromPointer(Parser.getTok().
172263320Sdim-                                      getLoc().getPointer() - 1);
173263320Sdim+      E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
174263320Sdim       MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier);
175263320Sdim 
176263320Sdim       const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
177263320Sdim                                                   getContext());
178263320Sdim-
179263320Sdim       Op = SparcOperand::CreateImm(Res, S, E);
180263320Sdim     }
181263320Sdim     break;
182263320Sdim@@ -675,7 +679,33 @@ bool SparcAsmParser::matchRegisterName(const AsmTo
183263320Sdim }
184263320Sdim 
185263320Sdim 
186263320Sdim+bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
187263320Sdim+                                            SMLoc &EndLoc)
188263320Sdim+{
189263320Sdim+  AsmToken Tok = Parser.getTok();
190263320Sdim+  if (!Tok.is(AsmToken::Identifier))
191263320Sdim+    return false;
192263320Sdim 
193263320Sdim+  StringRef name = Tok.getString();
194263320Sdim+
195263320Sdim+  SparcMCExpr::VariantKind VK = SparcMCExpr::parseVariantKind(name);
196263320Sdim+
197263320Sdim+  if (VK == SparcMCExpr::VK_Sparc_None)
198263320Sdim+    return false;
199263320Sdim+
200263320Sdim+  Parser.Lex(); // Eat the identifier.
201263320Sdim+  if (Parser.getTok().getKind() != AsmToken::LParen)
202263320Sdim+    return false;
203263320Sdim+
204263320Sdim+  Parser.Lex(); // Eat the LParen token.
205263320Sdim+  const MCExpr *subExpr;
206263320Sdim+  if (Parser.parseParenExpression(subExpr, EndLoc))
207263320Sdim+    return false;
208263320Sdim+  EVal = SparcMCExpr::Create(VK, subExpr, getContext());
209263320Sdim+  return true;
210263320Sdim+}
211263320Sdim+
212263320Sdim+
213263320Sdim extern "C" void LLVMInitializeSparcAsmParser() {
214263320Sdim   RegisterMCAsmParser<SparcAsmParser> A(TheSparcTarget);
215263320Sdim   RegisterMCAsmParser<SparcAsmParser> B(TheSparcV9Target);
216263320SdimIndex: test/MC/Sparc/sparc-relocations.s
217263320Sdim===================================================================
218263320Sdim--- test/MC/Sparc/sparc-relocations.s
219263320Sdim+++ test/MC/Sparc/sparc-relocations.s
220263320Sdim@@ -0,0 +1,33 @@
221263320Sdim+! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s
222263320Sdim+
223263320Sdim+        ! CHECK: call foo     ! encoding: [0b01AAAAAA,A,A,A]
224263320Sdim+        ! CHECK:              !   fixup A - offset: 0, value: foo, kind: fixup_sparc_call30
225263320Sdim+        call foo
226263320Sdim+
227263320Sdim+        ! CHECK: or %g1, %lo(sym), %g3 ! encoding: [0x86,0x10,0b011000AA,A]
228263320Sdim+        ! CHECK-NEXT                   !   fixup A - offset: 0, value: %lo(sym), kind: fixup_sparc_lo10
229263320Sdim+        or %g1, %lo(sym), %g3
230263320Sdim+
231263320Sdim+        ! CHECK: sethi %hi(sym), %l0  ! encoding: [0x21,0b00AAAAAA,A,A]
232263320Sdim+        ! CHECK-NEXT:                 !   fixup A - offset: 0, value: %hi(sym), kind: fixup_sparc_hi22
233263320Sdim+        sethi %hi(sym), %l0
234263320Sdim+
235263320Sdim+        ! CHECK: sethi %h44(sym), %l0  ! encoding: [0x21,0b00AAAAAA,A,A]
236263320Sdim+        ! CHECK-NEXT:                 !   fixup A - offset: 0, value: %h44(sym), kind: fixup_sparc_h44
237263320Sdim+        sethi %h44(sym), %l0
238263320Sdim+
239263320Sdim+        ! CHECK: or %g1, %m44(sym), %g3 ! encoding: [0x86,0x10,0b011000AA,A]
240263320Sdim+        ! CHECK-NEXT                   !   fixup A - offset: 0, value: %m44(sym), kind: fixup_sparc_m44
241263320Sdim+        or %g1, %m44(sym), %g3
242263320Sdim+
243263320Sdim+        ! CHECK: or %g1, %l44(sym), %g3 ! encoding: [0x86,0x10,0b0110AAAA,A]
244263320Sdim+        ! CHECK-NEXT                   !   fixup A - offset: 0, value: %l44(sym), kind: fixup_sparc_l44
245263320Sdim+        or %g1, %l44(sym), %g3
246263320Sdim+
247263320Sdim+        ! CHECK: sethi %hh(sym), %l0  ! encoding: [0x21,0b00AAAAAA,A,A]
248263320Sdim+        ! CHECK-NEXT:                 !   fixup A - offset: 0, value: %hh(sym), kind: fixup_sparc_hh
249263320Sdim+        sethi %hh(sym), %l0
250263320Sdim+
251263320Sdim+        ! CHECK: or %g1, %hm(sym), %g3 ! encoding: [0x86,0x10,0b011000AA,A]
252263320Sdim+        ! CHECK-NEXT                   !   fixup A - offset: 0, value: %hm(sym), kind: fixup_sparc_hm
253263320Sdim+        or %g1, %hm(sym), %g3
254263320SdimIndex: test/MC/Sparc/sparc-ctrl-instructions.s
255263320Sdim===================================================================
256263320Sdim--- test/MC/Sparc/sparc-ctrl-instructions.s
257263320Sdim+++ test/MC/Sparc/sparc-ctrl-instructions.s
258263320Sdim@@ -1,23 +1,33 @@
259263320Sdim ! RUN: llvm-mc %s -arch=sparc   -show-encoding | FileCheck %s
260263320Sdim ! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s
261263320Sdim 
262263320Sdim-        ! CHECK: call foo
263263320Sdim+        ! CHECK: call foo     ! encoding: [0b01AAAAAA,A,A,A]
264263320Sdim+        ! CHECK:              !   fixup A - offset: 0, value: foo, kind: fixup_sparc_call30
265263320Sdim         call foo
266263320Sdim 
267263320Sdim-        ! CHECK: call %g1+%i2
268263320Sdim+        ! CHECK: call %g1+%i2 ! encoding: [0x9f,0xc0,0x40,0x1a]
269263320Sdim         call %g1 + %i2
270263320Sdim 
271263320Sdim-        ! CHECK: call %o1+8
272263320Sdim+        ! CHECK: call %o1+8   ! encoding: [0x9f,0xc2,0x60,0x08]
273263320Sdim         call %o1 + 8
274263320Sdim 
275263320Sdim-        ! CHECK: call %g1
276263320Sdim+        ! CHECK: call %g1     ! encoding: [0x9f,0xc0,0x60,0x00]
277263320Sdim         call %g1
278263320Sdim 
279263320Sdim-        ! CHECK: jmp %g1+%i2
280263320Sdim+        ! CHECK: call %g1+%lo(sym)   ! encoding: [0x9f,0xc0,0b011000AA,A]
281263320Sdim+        ! CHECK-NEXT:                ! fixup A - offset: 0, value: %lo(sym), kind: fixup_sparc_lo10
282263320Sdim+        call %g1+%lo(sym)
283263320Sdim+
284263320Sdim+        ! CHECK: jmp %g1+%i2  ! encoding: [0x81,0xc0,0x40,0x1a]
285263320Sdim         jmp %g1 + %i2
286263320Sdim 
287263320Sdim-        ! CHECK: jmp %o1+8
288263320Sdim+        ! CHECK: jmp %o1+8    ! encoding: [0x81,0xc2,0x60,0x08]
289263320Sdim         jmp %o1 + 8
290263320Sdim 
291263320Sdim-        ! CHECK: jmp %g1
292263320Sdim+        ! CHECK: jmp %g1      ! encoding: [0x81,0xc0,0x60,0x00]
293263320Sdim         jmp %g1
294263320Sdim+
295263320Sdim+        ! CHECK: jmp %g1+%lo(sym)   ! encoding: [0x81,0xc0,0b011000AA,A]
296263320Sdim+        ! CHECK-NEXT:                ! fixup A - offset: 0, value: %lo(sym), kind: fixup_sparc_lo10
297263320Sdim+        jmp %g1+%lo(sym)
298263320Sdim+
299