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