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