Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -2664,9 +2664,11 @@ const MipsMCExpr *GotExpr = MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext()); const MCExpr *LoExpr = nullptr; - if (Res.getSymA()->getSymbol().isInSection() || - Res.getSymA()->getSymbol().isTemporary()) + const MCSymbol * Sym = getSingleMCSymbol(SymExpr); + + if ((Sym->isELF() && cast(Sym)->getBinding() == ELF::STB_LOCAL)) { LoExpr = MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext()); + } else if (Res.getConstant() != 0) { // External symbols fully resolve the symbol with just the %got(symbol) // but we must still account for any offset to the symbol for expressions @@ -2688,6 +2690,7 @@ TOut.emitRRX(Mips::LW, TmpReg, ABI.GetGlobalPtr(), MCOperand::createExpr(GotExpr), IDLoc, STI); + Sym->setUsedInReloc(); if (LoExpr) TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), Index: lib/Target/Mips/Mips16HardFloat.cpp =================================================================== --- lib/Target/Mips/Mips16HardFloat.cpp +++ lib/Target/Mips/Mips16HardFloat.cpp @@ -470,17 +470,18 @@ BasicBlock *BB = BasicBlock::Create(Context, "entry", FStub); std::string AsmText; + AsmText += LocalName + " = " + Name + "\n"; if (PicMode) { AsmText += ".set noreorder\n"; AsmText += ".cpload $$25\n"; AsmText += ".set reorder\n"; AsmText += ".reloc 0, R_MIPS_NONE, " + Name + "\n"; - AsmText += "la $$25, " + LocalName + "\n"; + AsmText += "lw $$25, %got(" + LocalName + ")($$gp)\n"; + AsmText += "addiu $$25, $$25, %lo(" + LocalName +")\n"; } else AsmText += "la $$25, " + Name + "\n"; AsmText += swapFPIntParams(PV, M, LE, false); AsmText += "jr $$25\n"; - AsmText += LocalName + " = " + Name + "\n"; EmitInlineAsm(Context, BB, AsmText); new UnreachableInst(FStub->getContext(), BB); Index: test/CodeGen/Mips/hf16call32_body.ll =================================================================== --- test/CodeGen/Mips/hf16call32_body.ll +++ test/CodeGen/Mips/hf16call32_body.ll @@ -20,11 +20,11 @@ } ; stel: .section .mips16.fn.v_sf,"ax",@progbits ; stel: .ent __fn_stub_v_sf +; stel: __fn_local_v_sf = v_sf ; stel: lui $25, %hi(v_sf) ; stel: addiu $25, $25, %lo(v_sf) ; stel: mfc1 $4, $f12 ; stel: jr $25 -; stel: __fn_local_v_sf = v_sf ; stel: .end __fn_stub_v_sf declare i32 @printf(i8*, ...) #1 @@ -41,12 +41,12 @@ ; stel: .section .mips16.fn.v_df,"ax",@progbits ; stel: .ent __fn_stub_v_df +; stel: __fn_local_v_df = v_df ; stel: lui $25, %hi(v_df) ; stel: addiu $25, $25, %lo(v_df) ; stel: mfc1 $4, $f12 ; stel: mfc1 $5, $f13 ; stel: jr $25 -; stel: __fn_local_v_df = v_df ; stel: .end __fn_stub_v_df ; Function Attrs: nounwind @@ -65,12 +65,12 @@ ; stel: .section .mips16.fn.v_sf_sf,"ax",@progbits ; stel: .ent __fn_stub_v_sf_sf +; stel: __fn_local_v_sf_sf = v_sf_sf ; stel: lui $25, %hi(v_sf_sf) ; stel: addiu $25, $25, %lo(v_sf_sf) ; stel: mfc1 $4, $f12 ; stel: mfc1 $5, $f14 ; stel: jr $25 -; stel: __fn_local_v_sf_sf = v_sf_sf ; stel: .end __fn_stub_v_sf_sf ; Function Attrs: nounwind @@ -89,13 +89,13 @@ ; stel: .section .mips16.fn.v_sf_df,"ax",@progbits ; stel: .ent __fn_stub_v_sf_df +; stel: __fn_local_v_sf_df = v_sf_df ; stel: lui $25, %hi(v_sf_df) ; stel: addiu $25, $25, %lo(v_sf_df) ; stel: mfc1 $4, $f12 ; stel: mfc1 $6, $f14 ; stel: mfc1 $7, $f15 ; stel: jr $25 -; stel: __fn_local_v_sf_df = v_sf_df ; stel: .end __fn_stub_v_sf_df ; Function Attrs: nounwind @@ -114,13 +114,13 @@ ; stel: .section .mips16.fn.v_df_sf,"ax",@progbits ; stel: .ent __fn_stub_v_df_sf +; stel: __fn_local_v_df_sf = v_df_sf ; stel: lui $25, %hi(v_df_sf) ; stel: addiu $25, $25, %lo(v_df_sf) ; stel: mfc1 $4, $f12 ; stel: mfc1 $5, $f13 ; stel: mfc1 $6, $f14 ; stel: jr $25 -; stel: __fn_local_v_df_sf = v_df_sf ; stel: .end __fn_stub_v_df_sf ; Function Attrs: nounwind @@ -139,6 +139,7 @@ ; stel: .section .mips16.fn.v_df_df,"ax",@progbits ; stel: .ent __fn_stub_v_df_df +; stel: __fn_local_v_df_df = v_df_df ; stel: lui $25, %hi(v_df_df) ; stel: addiu $25, $25, %lo(v_df_df) ; stel: mfc1 $4, $f12 @@ -146,7 +147,6 @@ ; stel: mfc1 $6, $f14 ; stel: mfc1 $7, $f15 ; stel: jr $25 -; stel: __fn_local_v_df_df = v_df_df ; stel: .end __fn_stub_v_df_df ; Function Attrs: nounwind @@ -170,11 +170,11 @@ ; stel: .section .mips16.fn.sf_sf,"ax",@progbits ; stel: .ent __fn_stub_sf_sf +; stel: __fn_local_sf_sf = sf_sf ; stel: lui $25, %hi(sf_sf) ; stel: addiu $25, $25, %lo(sf_sf) ; stel: mfc1 $4, $f12 ; stel: jr $25 -; stel: __fn_local_sf_sf = sf_sf ; stel: .end __fn_stub_sf_sf @@ -191,12 +191,12 @@ ; stel: .section .mips16.fn.sf_df,"ax",@progbits ; stel: .ent __fn_stub_sf_df +; stel: __fn_local_sf_df = sf_df ; stel: lui $25, %hi(sf_df) ; stel: addiu $25, $25, %lo(sf_df) ; stel: mfc1 $4, $f12 ; stel: mfc1 $5, $f13 ; stel: jr $25 -; stel: __fn_local_sf_df = sf_df ; stel: .end __fn_stub_sf_df ; Function Attrs: nounwind @@ -216,12 +216,12 @@ ; stel: .section .mips16.fn.sf_sf_sf,"ax",@progbits ; stel: .ent __fn_stub_sf_sf_sf +; stel: __fn_local_sf_sf_sf = sf_sf_sf ; stel: lui $25, %hi(sf_sf_sf) ; stel: addiu $25, $25, %lo(sf_sf_sf) ; stel: mfc1 $4, $f12 ; stel: mfc1 $5, $f14 ; stel: jr $25 -; stel: __fn_local_sf_sf_sf = sf_sf_sf ; stel: .end __fn_stub_sf_sf_sf ; Function Attrs: nounwind @@ -241,13 +241,13 @@ ; stel: .section .mips16.fn.sf_sf_df,"ax",@progbits ; stel: .ent __fn_stub_sf_sf_df +; stel: __fn_local_sf_sf_df = sf_sf_df ; stel: lui $25, %hi(sf_sf_df) ; stel: addiu $25, $25, %lo(sf_sf_df) ; stel: mfc1 $4, $f12 ; stel: mfc1 $6, $f14 ; stel: mfc1 $7, $f15 ; stel: jr $25 -; stel: __fn_local_sf_sf_df = sf_sf_df ; stel: .end __fn_stub_sf_sf_df ; Function Attrs: nounwind @@ -267,13 +267,13 @@ ; stel: .section .mips16.fn.sf_df_sf,"ax",@progbits ; stel: .ent __fn_stub_sf_df_sf +; stel: __fn_local_sf_df_sf = sf_df_sf ; stel: lui $25, %hi(sf_df_sf) ; stel: addiu $25, $25, %lo(sf_df_sf) ; stel: mfc1 $4, $f12 ; stel: mfc1 $5, $f13 ; stel: mfc1 $6, $f14 ; stel: jr $25 -; stel: __fn_local_sf_df_sf = sf_df_sf ; stel: .end __fn_stub_sf_df_sf ; Function Attrs: nounwind @@ -293,6 +293,7 @@ ; stel: .section .mips16.fn.sf_df_df,"ax",@progbits ; stel: .ent __fn_stub_sf_df_df +; stel: __fn_local_sf_df_df = sf_df_df ; stel: lui $25, %hi(sf_df_df) ; stel: addiu $25, $25, %lo(sf_df_df) ; stel: mfc1 $4, $f12 @@ -300,7 +301,6 @@ ; stel: mfc1 $6, $f14 ; stel: mfc1 $7, $f15 ; stel: jr $25 -; stel: __fn_local_sf_df_df = sf_df_df ; stel: .end __fn_stub_sf_df_df attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } Index: test/CodeGen/Mips/hf1_body.ll =================================================================== --- test/CodeGen/Mips/hf1_body.ll +++ test/CodeGen/Mips/hf1_body.ll @@ -1,11 +1,5 @@ ; RUN: llc -mtriple=mipsel-linux-gnu -march=mipsel -mattr=mips16 \ -; RUN: -relocation-model=pic -no-integrated-as < %s | \ -; RUN: FileCheck %s -check-prefixes=ALL,GAS - -; The integrated assembler expands assembly macros before printing. -; RUN: llc -mtriple=mipsel-linux-gnu -march=mipsel -mattr=mips16 \ -; RUN: -relocation-model=pic < %s | \ -; RUN: FileCheck %s -check-prefixes=ALL,IAS +; RUN: -relocation-model=pic < %s | FileCheck %s @x = external global float @@ -18,13 +12,12 @@ store float %0, float* @x, align 4 ret void } -; ALL-LABEL: .ent __fn_stub_v_sf -; ALL: .cpload $25 -; ALL: .set reorder -; ALL: .reloc 0, R_MIPS_NONE, v_sf -; GAS: la $25, $__fn_local_v_sf -; IAS: lw $25, %got($$__fn_local_v_sf)($gp) -; IAS: addiu $25, $25, %lo($$__fn_local_v_sf) -; ALL: mfc1 $4, $f12 -; ALL: jr $25 -; ALL: .end __fn_stub_v_sf +; CHECK-LABEL: .ent __fn_stub_v_sf +; CHECK: .cpload $25 +; CHECK: .set reorder +; CHECK: .reloc 0, R_MIPS_NONE, v_sf +; CHECK: lw $25, %got($__fn_local_v_sf)($gp) +; CHECK: addiu $25, $25, %lo($__fn_local_v_sf) +; CHECK: mfc1 $4, $f12 +; CHECK: jr $25 +; CHECK: .end __fn_stub_v_sf Index: test/MC/Mips/macro-la-pic.s =================================================================== --- test/MC/Mips/macro-la-pic.s +++ test/MC/Mips/macro-la-pic.s @@ -1,54 +1,95 @@ # RUN: llvm-mc %s -triple=mips-unknown-linux -show-encoding -mcpu=mips32r2 | \ -# RUN: FileCheck %s +# RUN: FileCheck -check-prefix=CHECK-AS %s # RUN: llvm-mc %s -triple=mips-unknown-linux -show-encoding -mcpu=mips32r6 | \ -# RUN: FileCheck %s +# RUN: FileCheck -check-prefix=CHECK-AS %s + +# Check the result of producing object files for the correct expansion. The +# difference in expansion is due to the ASMStreamer emitting .glob(a)l as a +# directive and not updating the symbol table. The ELFStreamer does update the +# symbol table, and therefore we can perform the symbol visibilty sensitive +# expansion correctly. + +# RUN: llvm-mc < %s -triple=mips-unknown-linux -show-encoding -mcpu=mips32r2 \ +# RUN: -filetype=obj -o - | llvm-objdump -d -r - | \ +# RUN: FileCheck -check-prefix=CHECK-OBJ %s # N32 should be acceptable too but it currently errors out. # N64 should be acceptable too but we cannot convert la to dla yet. .option pic2 -la $5, symbol # CHECK: lw $5, %got(symbol)($gp) # encoding: [0x8f,0x85,A,A] - # CHECK: # fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT -la $5, symbol($6) # CHECK: lw $5, %got(symbol)($gp) # encoding: [0x8f,0x85,A,A] - # CHECK: # fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT - # CHECK: addu $5, $5, $6 # encoding: [0x00,0xa6,0x28,0x21] -la $6, symbol($6) # CHECK: lw $1, %got(symbol)($gp) # encoding: [0x8f,0x81,A,A] - # CHECK: # fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT - # CHECK: addu $6, $1, $6 # encoding: [0x00,0x26,0x30,0x21] -la $5, symbol+8 # CHECK: lw $5, %got(symbol+8)($gp) # encoding: [0x8f,0x85,A,A] - # CHECK: # fixup A - offset: 0, value: %got(symbol+8), kind: fixup_Mips_GOT -la $5, symbol+8($6) # CHECK: lw $5, %got(symbol+8)($gp) # encoding: [0x8f,0x85,A,A] - # CHECK: # fixup A - offset: 0, value: %got(symbol+8), kind: fixup_Mips_GOT - # CHECK: addu $5, $5, $6 # encoding: [0x00,0xa6,0x28,0x21] -la $6, symbol+8($6) # CHECK: lw $1, %got(symbol+8)($gp) # encoding: [0x8f,0x81,A,A] - # CHECK: # fixup A - offset: 0, value: %got(symbol+8), kind: fixup_Mips_GOT - # CHECK: addiu $1, $1, 8 # encoding: [0x24,0x21,0x00,0x08] - # CHECK: addu $6, $1, $6 # encoding: [0x00,0x26,0x30,0x21] -la $5, 1f # CHECK: lw $5, %got($tmp0)($gp) # encoding: [0x8f,0x85,A,A] - # CHECK: # fixup A - offset: 0, value: %got($tmp0), kind: fixup_Mips_GOT - # CHECK: addiu $5, $5, %lo($tmp0) # encoding: [0x24,0xa5,A,A] - # CHECK: # fixup A - offset: 0, value: %lo($tmp0), kind: fixup_Mips_LO16 +la $5, symbol # CHECK-AS: lw $5, %got(symbol)($gp) # encoding: [0x8f,0x85,A,A] + # CHECK-AS: # fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT +la $5, symbol($6) # CHECK-AS: lw $5, %got(symbol)($gp) # encoding: [0x8f,0x85,A,A] + # CHECK-AS: # fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT + # CHECK-AS: addu $5, $5, $6 # encoding: [0x00,0xa6,0x28,0x21] +la $6, symbol($6) # CHECK-AS: lw $1, %got(symbol)($gp) # encoding: [0x8f,0x81,A,A] + # CHECK-AS: # fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT + # CHECK-AS: addu $6, $1, $6 # encoding: [0x00,0x26,0x30,0x21] +la $5, symbol+8 # CHECK-AS: lw $5, %got(symbol+8)($gp) # encoding: [0x8f,0x85,A,A] + # CHECK-AS: # fixup A - offset: 0, value: %got(symbol+8), kind: fixup_Mips_GOT +la $5, symbol+8($6) # CHECK-AS: lw $5, %got(symbol+8)($gp) # encoding: [0x8f,0x85,A,A] + # CHECK-AS: # fixup A - offset: 0, value: %got(symbol+8), kind: fixup_Mips_GOT + # CHECK-AS: addu $5, $5, $6 # encoding: [0x00,0xa6,0x28,0x21] +la $6, symbol+8($6) # CHECK-AS: lw $1, %got(symbol+8)($gp) # encoding: [0x8f,0x81,A,A] + # CHECK-AS: # fixup A - offset: 0, value: %got(symbol+8), kind: fixup_Mips_GOT + # CHECK-AS: addiu $1, $1, 8 # encoding: [0x24,0x21,0x00,0x08] + # CHECK-AS: addu $6, $1, $6 # encoding: [0x00,0x26,0x30,0x21] 1: +la $5, 1b # CHECK-AS: lw $5, %got($tmp0)($gp) # encoding: [0x8f,0x85,A,A] + # CHECK-AS: # fixup A - offset: 0, value: %got($tmp0), kind: fixup_Mips_GOT + # CHECK-AS: addiu $5, $5, %lo($tmp0) # encoding: [0x24,0xa5,A,A] + # CHECK-AS: # fixup A - offset: 0, value: %lo($tmp0), kind: fixup_Mips_LO16 # PIC expansions involving $25 are special. -la $25, symbol # CHECK: lw $25, %call16(symbol)($gp) # encoding: [0x8f,0x99,A,A] - # CHECK: # fixup A - offset: 0, value: %call16(symbol), kind: fixup_Mips_CALL16 -la $25, symbol($6) # CHECK: lw $25, %got(symbol)($gp) # encoding: [0x8f,0x99,A,A] - # CHECK: # fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT - # CHECK: addu $25, $25, $6 # encoding: [0x03,0x26,0xc8,0x21] -la $25, symbol($25) # CHECK: lw $1, %got(symbol)($gp) # encoding: [0x8f,0x81,A,A] - # CHECK: # fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT - # CHECK: addu $25, $1, $25 # encoding: [0x00,0x39,0xc8,0x21] -la $25, symbol+8 # CHECK: lw $25, %got(symbol+8)($gp) # encoding: [0x8f,0x99,A,A] - # CHECK: # fixup A - offset: 0, value: %got(symbol+8), kind: fixup_Mips_GOT -la $25, symbol+8($6) # CHECK: lw $25, %got(symbol+8)($gp) # encoding: [0x8f,0x99,A,A] - # CHECK: # fixup A - offset: 0, value: %got(symbol+8), kind: fixup_Mips_GOT - # CHECK: addu $25, $25, $6 # encoding: [0x03,0x26,0xc8,0x21] -la $25, symbol+8($25) # CHECK: lw $1, %got(symbol+8)($gp) # encoding: [0x8f,0x81,A,A] - # CHECK: # fixup A - offset: 0, value: %got(symbol+8), kind: fixup_Mips_GOT - # CHECK: addiu $1, $1, 8 # encoding: [0x24,0x21,0x00,0x08] - # CHECK: addu $25, $1, $25 # encoding: [0x00,0x39,0xc8,0x21] -la $25, 1f # CHECK: lw $25, %got($tmp1)($gp) # encoding: [0x8f,0x99,A,A] - # CHECK: # fixup A - offset: 0, value: %got($tmp1), kind: fixup_Mips_GOT - # CHECK: addiu $25, $25, %lo($tmp1) # encoding: [0x27,0x39,A,A] - # CHECK: # fixup A - offset: 0, value: %lo($tmp1), kind: fixup_Mips_LO16 +la $25, symbol # CHECK-AS: lw $25, %call16(symbol)($gp) # encoding: [0x8f,0x99,A,A] + # CHECK-AS: # fixup A - offset: 0, value: %call16(symbol), kind: fixup_Mips_CALL16 +la $25, symbol($6) # CHECK-AS: lw $25, %got(symbol)($gp) # encoding: [0x8f,0x99,A,A] + # CHECK-AS: # fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT + # CHECK-AS: addu $25, $25, $6 # encoding: [0x03,0x26,0xc8,0x21] +la $25, symbol($25) # CHECK-AS: lw $1, %got(symbol)($gp) # encoding: [0x8f,0x81,A,A] + # CHECK-AS: # fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT + # CHECK-AS: addu $25, $1, $25 # encoding: [0x00,0x39,0xc8,0x21] +la $25, symbol+8 # CHECK-AS: lw $25, %got(symbol+8)($gp) # encoding: [0x8f,0x99,A,A] + # CHECK-AS: # fixup A - offset: 0, value: %got(symbol+8), kind: fixup_Mips_GOT +la $25, symbol+8($6) # CHECK-AS: lw $25, %got(symbol+8)($gp) # encoding: [0x8f,0x99,A,A] + # CHECK-AS: # fixup A - offset: 0, value: %got(symbol+8), kind: fixup_Mips_GOT + # CHECK-AS: addu $25, $25, $6 # encoding: [0x03,0x26,0xc8,0x21] +la $25, symbol+8($25) # CHECK-AS: lw $1, %got(symbol+8)($gp) # encoding: [0x8f,0x81,A,A] + # CHECK-AS: # fixup A - offset: 0, value: %got(symbol+8), kind: fixup_Mips_GOT + # CHECK-AS: addiu $1, $1, 8 # encoding: [0x24,0x21,0x00,0x08] + # CHECK-AS: addu $25, $1, $25 # encoding: [0x00,0x39,0xc8,0x21] 1: +la $25, 1b # CHECK-AS: lw $25, %got($tmp1)($gp) # encoding: [0x8f,0x99,A,A] + # CHECK-AS: # fixup A - offset: 0, value: %got($tmp1), kind: fixup_Mips_GOT + # CHECK-AS: addiu $25, $25, %lo($tmp1) # encoding: [0x27,0x39,A,A] + # CHECK-AS: # fixup A - offset: 0, value: %lo($tmp1), kind: fixup_Mips_LO16 + +# Implict global reference +la $4, bar # CHECK-AS: lw $4, %got(bar)($gp) # encoding: [0x8f,0x84,A,A] + # CHECK-AS: # fixup A - offset: 0, value: %got(bar), kind: fixup_Mips_GOT + + +# Explicit forward local reference +.data +bar1: +.word 1 +.text +foo1: +la $4, bar1 # CHECK-AS: lw $4, %got(bar1)($gp) # encoding: [0x8f,0x84,A,A] + # CHECK-AS: # fixup A - offset: 0, value: %got(bar1), kind: fixup_Mips_GOT + # CHECK-AS: addiu $4, $4, %lo(bar1) # encoding: [0x24,0x84,A,A] + # CHECK-AS: # fixup A - offset: 0, value: %lo(bar1), kind: fixup_Mips_LO16 + +# Explict forwad global reference +.data +.global bar2 +bar2: +.word 1 +.text +foo2: +la $4, bar2 # CHECK-AS: lw $4, %got(bar2)($gp) # encoding: [0x8f,0x84,A,A] + # CHECK-AS; # fixup A - offset: 0, value: %got(bar2), kind: fixup_Mips_GOT + # CHECK-AS: addiu $4, $4, %lo(bar2) # encoding: [0x24,0x84,A,A] + # CHECK-AS: # fixup A - offset: 0, value: %lo(bar2), kind: fixup_Mips_LO16 + + # CHECK-OBJ: 8f 84 00 00 lw $4, 0($gp) + # CHECK-OBJ: 00000084: R_MIPS_GOT16 bar2