[PowerPC] Add support for high and higha symbol modifiers on tls modifers.

Enables using the high and high-adjusted symbol modifiers on thread local
storage modifers in powerpc assembly. Needed to be able to support 64 bit
thread-pointer and dynamic-thread-pointer access sequences.

Differential Revision: https://reviews.llvm.org/D47754

llvm-svn: 334856
This commit is contained in:
Sean Fertile 2018-06-15 19:47:16 +00:00
parent 80b8f82f17
commit cac28aeb3f
8 changed files with 349 additions and 1 deletions

View File

@ -91,6 +91,10 @@
#undef R_PPC64_TLSLD
#undef R_PPC64_ADDR16_HIGH
#undef R_PPC64_ADDR16_HIGHA
#undef R_PPC64_TPREL16_HIGH
#undef R_PPC64_TPREL16_HIGHA
#undef R_PPC64_DTPREL16_HIGH
#undef R_PPC64_DTPREL16_HIGHA
#undef R_PPC64_IRELATIVE
#undef R_PPC64_REL16
#undef R_PPC64_REL16_LO
@ -180,6 +184,10 @@ ELF_RELOC(R_PPC64_TLSGD, 107)
ELF_RELOC(R_PPC64_TLSLD, 108)
ELF_RELOC(R_PPC64_ADDR16_HIGH, 110)
ELF_RELOC(R_PPC64_ADDR16_HIGHA, 111)
ELF_RELOC(R_PPC64_TPREL16_HIGH, 112)
ELF_RELOC(R_PPC64_TPREL16_HIGHA, 113)
ELF_RELOC(R_PPC64_DTPREL16_HIGH, 114)
ELF_RELOC(R_PPC64_DTPREL16_HIGHA, 115)
ELF_RELOC(R_PPC64_IRELATIVE, 248)
ELF_RELOC(R_PPC64_REL16, 249)
ELF_RELOC(R_PPC64_REL16_LO, 250)

View File

@ -236,6 +236,8 @@ public:
VK_PPC_TPREL_LO, // symbol@tprel@l
VK_PPC_TPREL_HI, // symbol@tprel@h
VK_PPC_TPREL_HA, // symbol@tprel@ha
VK_PPC_TPREL_HIGH, // symbol@tprel@high
VK_PPC_TPREL_HIGHA, // symbol@tprel@higha
VK_PPC_TPREL_HIGHER, // symbol@tprel@higher
VK_PPC_TPREL_HIGHERA, // symbol@tprel@highera
VK_PPC_TPREL_HIGHEST, // symbol@tprel@highest
@ -243,6 +245,8 @@ public:
VK_PPC_DTPREL_LO, // symbol@dtprel@l
VK_PPC_DTPREL_HI, // symbol@dtprel@h
VK_PPC_DTPREL_HA, // symbol@dtprel@ha
VK_PPC_DTPREL_HIGH, // symbol@dtprel@high
VK_PPC_DTPREL_HIGHA, // symbol@dtprel@higha
VK_PPC_DTPREL_HIGHER, // symbol@dtprel@higher
VK_PPC_DTPREL_HIGHERA, // symbol@dtprel@highera
VK_PPC_DTPREL_HIGHEST, // symbol@dtprel@highest

View File

@ -411,6 +411,8 @@ void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) {
case MCSymbolRefExpr::VK_PPC_TPREL_LO:
case MCSymbolRefExpr::VK_PPC_TPREL_HI:
case MCSymbolRefExpr::VK_PPC_TPREL_HA:
case MCSymbolRefExpr::VK_PPC_TPREL_HIGH:
case MCSymbolRefExpr::VK_PPC_TPREL_HIGHA:
case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER:
case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA:
case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST:
@ -418,6 +420,8 @@ void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) {
case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
case MCSymbolRefExpr::VK_PPC_DTPREL_HI:
case MCSymbolRefExpr::VK_PPC_DTPREL_HA:
case MCSymbolRefExpr::VK_PPC_DTPREL_HIGH:
case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHA:
case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER:
case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA:
case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST:

View File

@ -257,6 +257,8 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
case VK_PPC_TPREL_LO: return "tprel@l";
case VK_PPC_TPREL_HI: return "tprel@h";
case VK_PPC_TPREL_HA: return "tprel@ha";
case VK_PPC_TPREL_HIGH: return "tprel@high";
case VK_PPC_TPREL_HIGHA: return "tprel@higha";
case VK_PPC_TPREL_HIGHER: return "tprel@higher";
case VK_PPC_TPREL_HIGHERA: return "tprel@highera";
case VK_PPC_TPREL_HIGHEST: return "tprel@highest";
@ -264,6 +266,8 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
case VK_PPC_DTPREL_LO: return "dtprel@l";
case VK_PPC_DTPREL_HI: return "dtprel@h";
case VK_PPC_DTPREL_HA: return "dtprel@ha";
case VK_PPC_DTPREL_HIGH: return "dtprel@high";
case VK_PPC_DTPREL_HIGHA: return "dtprel@higha";
case VK_PPC_DTPREL_HIGHER: return "dtprel@higher";
case VK_PPC_DTPREL_HIGHERA: return "dtprel@highera";
case VK_PPC_DTPREL_HIGHEST: return "dtprel@highest";
@ -365,6 +369,8 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) {
.Case("tprel@l", VK_PPC_TPREL_LO)
.Case("tprel@h", VK_PPC_TPREL_HI)
.Case("tprel@ha", VK_PPC_TPREL_HA)
.Case("tprel@high", VK_PPC_TPREL_HIGH)
.Case("tprel@higha", VK_PPC_TPREL_HIGHA)
.Case("tprel@higher", VK_PPC_TPREL_HIGHER)
.Case("tprel@highera", VK_PPC_TPREL_HIGHERA)
.Case("tprel@highest", VK_PPC_TPREL_HIGHEST)
@ -372,6 +378,8 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) {
.Case("dtprel@l", VK_PPC_DTPREL_LO)
.Case("dtprel@h", VK_PPC_DTPREL_HI)
.Case("dtprel@ha", VK_PPC_DTPREL_HA)
.Case("dtprel@high", VK_PPC_DTPREL_HIGH)
.Case("dtprel@higha", VK_PPC_DTPREL_HIGHA)
.Case("dtprel@higher", VK_PPC_DTPREL_HIGHER)
.Case("dtprel@highera", VK_PPC_DTPREL_HIGHERA)
.Case("dtprel@highest", VK_PPC_DTPREL_HIGHEST)

View File

@ -209,6 +209,12 @@ unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
case MCSymbolRefExpr::VK_PPC_TPREL_HA:
Type = ELF::R_PPC_TPREL16_HA;
break;
case MCSymbolRefExpr::VK_PPC_TPREL_HIGH:
Type = ELF::R_PPC64_TPREL16_HIGH;
break;
case MCSymbolRefExpr::VK_PPC_TPREL_HIGHA:
Type = ELF::R_PPC64_TPREL16_HIGHA;
break;
case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER:
Type = ELF::R_PPC64_TPREL16_HIGHER;
break;
@ -233,6 +239,12 @@ unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
case MCSymbolRefExpr::VK_PPC_DTPREL_HA:
Type = ELF::R_PPC64_DTPREL16_HA;
break;
case MCSymbolRefExpr::VK_PPC_DTPREL_HIGH:
Type = ELF::R_PPC64_DTPREL16_HIGH;
break;
case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHA:
Type = ELF::R_PPC64_DTPREL16_HIGHA;
break;
case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER:
Type = ELF::R_PPC64_DTPREL16_HIGHER;
break;

View File

@ -338,7 +338,6 @@ base:
# CHECK-LE-REL: 0x{{[0-9A-F]*[048C]}} R_PPC64_GOT16_LO_DS target 0x0
ld 1, target@got@l(3)
# CHECK-BE: addis 3, 2, target@tprel@ha # encoding: [0x3c,0x62,A,A]
# CHECK-LE: addis 3, 2, target@tprel@ha # encoding: [A,A,0x62,0x3c]
# CHECK-BE-NEXT: # fixup A - offset: 2, value: target@tprel@ha, kind: fixup_ppc_half16
@ -347,6 +346,22 @@ base:
# CHECK-LE-REL: 0x{{[0-9A-F]*[048C]}} R_PPC64_TPREL16_HA target 0x0
addis 3, 2, target@tprel@ha
# CHECK-BE: addis 3, 2, target@tprel@higha # encoding: [0x3c,0x62,A,A]
# CHECK-LE: addis 3, 2, target@tprel@higha # encoding: [A,A,0x62,0x3c]
# CHECK-BE-NEXT: # fixup A - offset: 2, value: target@tprel@higha, kind: fixup_ppc_half16
# CHECK-LE-NEXT: # fixup A - offset: 0, value: target@tprel@higha, kind: fixup_ppc_half16
# CHECK-BE-REL: 0x{{[0-9A-F]*[26AE]}} R_PPC64_TPREL16_HIGHA target 0x0
# CHECK-LE-REL: 0x{{[0-9A-F]*[048C]}} R_PPC64_TPREL16_HIGHA target 0x0
addis 3, 2, target@tprel@higha
# CHECK-BE: addis 3, 2, target@tprel@high # encoding: [0x3c,0x62,A,A]
# CHECK-LE: addis 3, 2, target@tprel@high # encoding: [A,A,0x62,0x3c]
# CHECK-BE-NEXT: # fixup A - offset: 2, value: target@tprel@high, kind: fixup_ppc_half16
# CHECK-LE-NEXT: # fixup A - offset: 0, value: target@tprel@high, kind: fixup_ppc_half16
# CHECK-BE-REL: 0x{{[0-9A-F]*[26AE]}} R_PPC64_TPREL16_HIGH target 0x0
# CHECK-LE-REL: 0x{{[0-9A-F]*[048C]}} R_PPC64_TPREL16_HIGH target 0x0
addis 3, 2, target@tprel@high
# CHECK-BE: addi 3, 3, target@tprel@l # encoding: [0x38,0x63,A,A]
# CHECK-LE: addi 3, 3, target@tprel@l # encoding: [A,A,0x63,0x38]
# CHECK-BE-NEXT: # fixup A - offset: 2, value: target@tprel@l, kind: fixup_ppc_half16
@ -427,6 +442,22 @@ base:
# CHECK-LE-REL: 0x{{[0-9A-F]*[048C]}} R_PPC64_DTPREL16_HA target 0x0
addis 3, 2, target@dtprel@ha
# CHECK-BE: addis 3, 2, target@dtprel@higha # encoding: [0x3c,0x62,A,A]
# CHECK-LE: addis 3, 2, target@dtprel@higha # encoding: [A,A,0x62,0x3c]
# CHECK-BE-NEXT: # fixup A - offset: 2, value: target@dtprel@higha, kind: fixup_ppc_half16
# CHECK-LE-NEXT: # fixup A - offset: 0, value: target@dtprel@higha, kind: fixup_ppc_half16
# CHECK-BE-REL: 0x{{[0-9A-F]*[26AE]}} R_PPC64_DTPREL16_HIGHA target 0x0
# CHECK-LE-REL: 0x{{[0-9A-F]*[048C]}} R_PPC64_DTPREL16_HIGHA target 0x0
addis 3, 2, target@dtprel@higha
# CHECK-BE: addis 3, 2, target@dtprel@high # encoding: [0x3c,0x62,A,A]
# CHECK-LE: addis 3, 2, target@dtprel@high # encoding: [A,A,0x62,0x3c]
# CHECK-BE-NEXT: # fixup A - offset: 2, value: target@dtprel@high, kind: fixup_ppc_half16
# CHECK-LE-NEXT: # fixup A - offset: 0, value: target@dtprel@high, kind: fixup_ppc_half16
# CHECK-BE-REL: 0x{{[0-9A-F]*[26AE]}} R_PPC64_DTPREL16_HIGH target 0x0
# CHECK-LE-REL: 0x{{[0-9A-F]*[048C]}} R_PPC64_DTPREL16_HIGH target 0x0
addis 3, 2, target@dtprel@high
# CHECK-BE: addi 3, 3, target@dtprel@l # encoding: [0x38,0x63,A,A]
# CHECK-LE: addi 3, 3, target@dtprel@l # encoding: [A,A,0x63,0x38]
# CHECK-BE-NEXT: # fixup A - offset: 2, value: target@dtprel@l, kind: fixup_ppc_half16

View File

@ -0,0 +1,177 @@
// RUN: llvm-mc -triple=powerpc64le-pc-linux -filetype=obj %s -o - | \
// RUN: llvm-readobj -r | FileCheck %s
// RUN: llvm-mc -triple=powerpc64-pc-linux -filetype=obj %s -o - | \
// RUN: llvm-readobj -r | FileCheck %s
// Verify we can handle all the dtprel symbol modifiers for local-dynamic tls.
// Tests a 16 bit offset on both DS-form and D-form instructions, 32 bit
// adjusted and non-adjusted offsets, and 64 bit adjusted and non-adjusted
// offsets.
.text
.abiversion 2
.globl short_offset
.p2align 4
.type short_offset,@function
short_offset:
.Lfunc_gep0:
addis 2, 12, .TOC.-.Lfunc_gep0@ha
addi 2, 2, .TOC.-.Lfunc_gep0@l
.Lfunc_lep0:
.localentry short_offset, .Lfunc_lep0-.Lfunc_gep0
mflr 0
std 0, 16(1)
stdu 1, -32(1)
addis 3, 2, i@got@tlsld@ha
addi 3, 3, i@got@tlsld@l
bl __tls_get_addr(i@tlsld)
nop
lwa 4, i@dtprel(3)
addi 5, 3, i@dtprel
lwa 3, 0(5)
add 3, 4, 3
addi 1, 1, 32
ld 0, 16(1)
mtlr 0
blr
.globl medium_offset
.p2align 4
.type medium_offset,@function
medium_offset:
.Lfunc_gep1:
addis 2, 12, .TOC.-.Lfunc_gep1@ha
addi 2, 2, .TOC.-.Lfunc_gep1@l
.Lfunc_lep1:
.localentry medium_offset, .Lfunc_lep1-.Lfunc_gep1
mflr 0
std 0, 16(1)
stdu 1, -32(1)
addis 3, 2, i@got@tlsld@ha
addi 3, 3, i@got@tlsld@l
bl __tls_get_addr(i@tlsld)
nop
addis 3, 3, i@dtprel@ha
lwa 3, i@dtprel@l(3)
addi 1, 1, 32
ld 0, 16(1)
mtlr 0
blr
.globl medium_not_adjusted
.p2align 4
.type medium_not_adjusted,@function
medium_not_adjusted:
.Lfunc_gep2:
addis 2, 12, .TOC.-.Lfunc_gep2@ha
addi 2, 2, .TOC.-.Lfunc_gep2@l
.Lfunc_lep2:
.localentry medium_not_adjusted, .Lfunc_lep2-.Lfunc_gep2
mflr 0
std 0, 16(1)
stdu 1, -32(1)
addis 3, 2, i@got@tlsld@ha
addi 3, 3, i@got@tlsld@l
bl __tls_get_addr(i@tlsld)
nop
lis 4, i@dtprel@h
ori 4, 4, i@dtprel@l
add 3, 3, 4
addi 1, 1, 32
ld 0, 16(1)
mtlr 0
blr
.globl large_offset
.p2align 4
.type large_offset,@function
large_offset:
.Lfunc_gep3:
addis 2, 12, .TOC.-.Lfunc_gep3@ha
addi 2, 2, .TOC.-.Lfunc_gep3@l
.Lfunc_lep3:
.localentry large_offset, .Lfunc_lep3-.Lfunc_gep3
mflr 0
std 0, 16(1)
stdu 1, -32(1)
addis 3, 2, i@got@tlsld@ha
addi 3, 3, i@got@tlsld@l
bl __tls_get_addr(i@tlsld)
nop
lis 4, i@dtprel@highesta
ori 4, 4, i@dtprel@highera
sldi 4, 4, 32
addis 4, 4, i@dtprel@higha
addi 4, 4, i@dtprel@l
lwax 3, 4, 3
addi 1, 1, 32
ld 0, 16(1)
mtlr 0
blr
.globl not_adjusted
.p2align 4
.type not_adjusted,@function
not_adjusted:
.Lfunc_gep4:
addis 2, 12, .TOC.-.Lfunc_gep4@ha
addi 2, 2, .TOC.-.Lfunc_gep4@l
.Lfunc_lep4:
.localentry not_adjusted, .Lfunc_lep4-.Lfunc_gep4
mflr 0
std 0, 16(1)
stdu 1, -32(1)
addis 3, 2, i@got@tlsld@ha
addi 3, 3, i@got@tlsld@l
bl __tls_get_addr(i@tlsld)
nop
lis 4, i@dtprel@highest
ori 4, 4, i@dtprel@higher
sldi 4, 4, 32
oris 4, 4, i@dtprel@high
ori 4, 4, i@dtprel@l
lwax 3, 4, 3
addi 1, 1, 32
ld 0, 16(1)
mtlr 0
blr
.type i,@object
.section .tdata,"awT",@progbits
.p2align 2
i:
.long 55
.size i, 4
.type j,@object
.data
.p2align 3
j:
.quad i@dtprel
.size j, 8
# CHECK: Relocations [
# CHECK: Section {{.*}} .rela.text {
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_GOT_TLSLD16_HA i
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_GOT_TLSLD16_LO i
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_TLSLD i
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_REL24 __tls_get_addr
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_DTPREL16_DS i
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_DTPREL16 i
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_DTPREL16_HA i
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_DTPREL16_LO_DS i
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_DTPREL16_HI i
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_DTPREL16_HIGHESTA i
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_DTPREL16_HIGHERA i
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_DTPREL16_HIGHA i
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_DTPREL16_LO i
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_DTPREL16_HIGHEST i
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_DTPREL16_HIGHER i
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_DTPREL16_HIGH i
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_DTPREL16_LO i
# CHECK: }
# CHECK: Section {{.*}} .rela.data {
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_DTPREL64 i
# CHECK: }
# CHECK: ]

View File

@ -0,0 +1,104 @@
// RUN: llvm-mc -triple=powerpc64le-pc-linux -filetype=obj %s -o - | \
// RUN: llvm-readobj -r | FileCheck %s
// RUN: llvm-mc -triple=powerpc64-pc-linux -filetype=obj %s -o - | \
// RUN: llvm-readobj -r | FileCheck %s
// Verify we can handle all the tprel symbol modifiers for local exec tls.
// Tests 16 bit offsets on both DS-form and D-form instructions, 32 bit
// adjusted and non-adjusted offsets and 64 bit adjusted and non-adjusted
// offsets.
.text
.abiversion 2
.globl short_offset_ds
.p2align 4
.type short_offset_ds,@function
short_offset_ds:
lwa 3, i@tprel(13)
blr
.globl short_offset
.p2align 4
.type short_offset,@function
short_offset:
addi 3, 13, i@tprel
blr
.globl medium_offset
.p2align 4
.type medium_offset,@function
medium_offset:
addis 3, 13, i@tprel@ha
lwa 3, i@tprel@l(3)
blr
.globl medium_not_adjusted
.p2align 4
.type medium_not_adjusted,@function
medium_not_adjusted:
lis 3, i@tprel@h
ori 3, 3, i@tprel@l
lwax 3, 3, 13
blr
.globl large_offset
.p2align 4
.type large_offset,@function
large_offset:
lis 3, i@tprel@highesta
ori 3, 3, i@tprel@highera
sldi 3, 3, 32
oris 3, 3, i@tprel@higha
addi 3, 3, i@tprel@l
lwax 3, 3, 13
blr
.globl not_adjusted
.p2align 4
.type not_adjusted,@function
not_adjusted:
lis 3, i@tprel@highest
ori 3, 3, i@tprel@higher
sldi 3, 3, 32
oris 3, 3, i@tprel@high
ori 3, 3, i@tprel@l
lwax 3, 3, 13
blr
.type i,@object
.section .tdata,"awT",@progbits
.p2align 2
i:
.long 55
.size i, 4
.type j,@object
.data
.p2align 3
j:
.quad i@tprel
.size j, 8
# CHECK: Relocations [
# CHECK: Section {{.*}} .rela.text {
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_TPREL16_DS i
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_TPREL16 i
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_TPREL16_HA i
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_TPREL16_LO_DS i
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_TPREL16_HI i
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_TPREL16_LO i
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_TPREL16_HIGHESTA i
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_TPREL16_HIGHERA i
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_TPREL16_HIGHA i
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_TPREL16_LO i
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_TPREL16_HIGHEST i
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_TPREL16_HIGHER i
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_TPREL16_HIGH i
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_TPREL16_LO i
# CHECK: }
# CHECK: Section (6) .rela.data {
# CHECK: 0x{{[0-9A-F]+}} R_PPC64_TPREL64 i
# CHECK: }
# CHECK: ]