Index: lib/Target/Sparc/AsmParser/SparcAsmParser.cpp =================================================================== --- lib/Target/Sparc/AsmParser/SparcAsmParser.cpp +++ lib/Target/Sparc/AsmParser/SparcAsmParser.cpp @@ -873,18 +873,12 @@ case AsmToken::Integer: case AsmToken::LParen: case AsmToken::Dot: - if (!getParser().parseExpression(EVal, E)) - Op = SparcOperand::CreateImm(EVal, S, E); - break; - - case AsmToken::Identifier: { - StringRef Identifier; - if (!getParser().parseIdentifier(Identifier)) { - E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); - MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); + case AsmToken::Identifier: + if (getParser().parseExpression(EVal, E)) + break; - const MCExpr *Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, - getContext()); + int64_t Res; + if (!EVal->evaluateAsAbsolute(Res)) { SparcMCExpr::VariantKind Kind = SparcMCExpr::VK_Sparc_13; if (getContext().getObjectFileInfo()->isPositionIndependent()) { @@ -893,14 +887,11 @@ else Kind = SparcMCExpr::VK_Sparc_GOT13; } - - Res = SparcMCExpr::create(Kind, Res, getContext()); - - Op = SparcOperand::CreateImm(Res, S, E); + EVal = SparcMCExpr::create(Kind, EVal, getContext()); } + Op = SparcOperand::CreateImm(EVal, S, E); break; } - } return (Op) ? MatchOperand_Success : MatchOperand_ParseFail; } Index: test/MC/Sparc/sparc-assembly-exprs.s =================================================================== --- test/MC/Sparc/sparc-assembly-exprs.s +++ test/MC/Sparc/sparc-assembly-exprs.s @@ -1,4 +1,5 @@ ! RUN: llvm-mc %s -arch=sparc -show-encoding | FileCheck %s +! RUN: llvm-mc %s -arch=sparc -filetype=obj | llvm-objdump -r -d - | FileCheck %s --check-prefix=OBJDUMP ! CHECK: mov 1033, %o1 ! encoding: [0x92,0x10,0x24,0x09] mov (0x400|9), %o1 @@ -11,3 +12,35 @@ ! DOTEXPR: .Ltmp0 ! DOTEXPR-NEXT: ba .Ltmp0+8 b . + 8 + + ! CHECK: ba symStart+4 ! encoding: [0x10,0b10AAAAAA,A,A] + ! CHECK: fixup A - offset: 0, value: symStart+4, kind: fixup_sparc_br22 + ! OBJDUMP: ba 1 +symStart: + b symStart + 4 + + ! CHECK: mov symEnd-symStart, %g1 ! encoding: [0x82,0x10,0b001AAAAA,A] + ! CHECK: fixup A - offset: 0, value: symEnd-symStart, kind: fixup_sparc_13 + ! OBJDUMP: mov 24, %g1 + mov symEnd - symStart, %g1 + + ! CHECK: sethi %hi(sym+10), %g2 ! encoding: [0x05,0b00AAAAAA,A,A] + ! CHECK: fixup A - offset: 0, value: %hi(sym+10), kind: fixup_sparc_hi22 + ! OBJDUMP: R_SPARC_HI22 sym+10 + sethi %hi(sym + 10), %g2 + + ! CHECK: call foo+40 ! encoding: [0b01AAAAAA,A,A,A] + ! CHECK: fixup A - offset: 0, value: foo+40, kind: fixup_sparc_call30 + ! OBJDUMP: R_SPARC_WDISP30 foo+40 + call foo + 40 + + ! CHECK: add %g1, val+100, %g1 ! encoding: [0x82,0x00,0b011AAAAA,A] + ! CHECK: fixup A - offset: 0, value: val+100, kind: fixup_sparc_13 + ! OBJDUMP: R_SPARC_13 val+100 + add %g1, val + 100, %g1 + + ! CHECK: add %g1, 100+val, %g2 ! encoding: [0x84,0x00,0b011AAAAA,A] + ! CHECK: fixup A - offset: 0, value: 100+val, kind: fixup_sparc_13 + ! OBJDUMP: R_SPARC_13 val+100 + add %g1, 100 + val, %g2 +symEnd: