Index: include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def =================================================================== --- include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def +++ include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def @@ -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_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) Index: include/llvm/MC/MCExpr.h =================================================================== --- include/llvm/MC/MCExpr.h +++ include/llvm/MC/MCExpr.h @@ -236,6 +236,8 @@ 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 @@ 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 Index: lib/MC/MCELFStreamer.cpp =================================================================== --- lib/MC/MCELFStreamer.cpp +++ lib/MC/MCELFStreamer.cpp @@ -410,6 +410,8 @@ 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: @@ -417,6 +419,8 @@ 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: Index: lib/MC/MCExpr.cpp =================================================================== --- lib/MC/MCExpr.cpp +++ lib/MC/MCExpr.cpp @@ -257,6 +257,8 @@ 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 @@ 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"; @@ -364,6 +368,8 @@ .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) @@ -371,6 +377,8 @@ .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) Index: lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp =================================================================== --- lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp +++ lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp @@ -209,6 +209,12 @@ 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 @@ 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; Index: test/MC/PowerPC/ppc64-fixups.s =================================================================== --- test/MC/PowerPC/ppc64-fixups.s +++ test/MC/PowerPC/ppc64-fixups.s @@ -338,7 +338,6 @@ # 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 @@ # 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 @@ # 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 Index: test/MC/PowerPC/tls-ld-v2-abi.s =================================================================== --- /dev/null +++ test/MC/PowerPC/tls-ld-v2-abi.s @@ -0,0 +1,162 @@ +// 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, a 32 bit offset and both adjusted and non-adjusted +// 64 bit offsets. + .text + .abiversion 2 + + .globl short_offset + .p2align 4 + .type short_offset,@function +short_offset: +.Lfunc_begin0: +.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 3, i@dtprel(3) + addi 1, 1, 32 + ld 0, 16(1) + mtlr 0 + blr + .long 0 + .quad 0 +.Lfunc_end0: + .size short_offset, .Lfunc_end0-.Lfunc_begin0 + + + .globl medium_offset + .p2align 4 + .type medium_offset,@function +medium_offset: +.Lfunc_begin1: +.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 + .long 0 + .quad 0 +.Lfunc_end1: + .size medium_offset, .Lfunc_end1-.Lfunc_begin1 + + + .globl large_offset + .p2align 4 + .type large_offset,@function +large_offset: +.Lfunc_begin2: +.Lfunc_gep2: + addis 2, 12, .TOC.-.Lfunc_gep2@ha + addi 2, 2, .TOC.-.Lfunc_gep2@l +.Lfunc_lep2: + .localentry large_offset, .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@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 + .long 0 + .quad 0 +.Lfunc_end2: + .size large_offset, .Lfunc_end2-.Lfunc_begin2 + + + .globl not_adjusted + .p2align 4 + .type not_adjusted,@function +not_adjusted: +.Lfunc_begin3: +.Lfunc_gep3: + addis 2, 12, .TOC.-.Lfunc_gep3@ha + addi 2, 2, .TOC.-.Lfunc_gep3@l +.Lfunc_lep3: + .localentry not_adjusted, .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@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 + .long 0 + .quad 0 +.Lfunc_end3: + .size large_offset, .Lfunc_end3-.Lfunc_begin3 + + + + .type i,@object + .section .tdata,"awT",@progbits + .p2align 2 +i: + .long 55 + .size i, 4 + +# 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_HA i +# CHECK: 0x{{[0-9A-F]+}} R_PPC64_DTPREL16_LO_DS 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: ] Index: test/MC/PowerPC/tls-le-v2-abi.s =================================================================== --- /dev/null +++ test/MC/PowerPC/tls-le-v2-abi.s @@ -0,0 +1,98 @@ +// 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 a 16 bit offset, a 32 bit offset and both adjusted and non-adjusted +// 64 bit offsets. + .text + .abiversion 2 + + .globl short_offset + .p2align 4 + .type short_offset,@function +short_offset: +.Lfunc_begin0: + lwa 3, i@tprel(13) + blr + .long 0 + .quad 0 +.Lfunc_end0: + .size short_offset, .Lfunc_end0-.Lfunc_begin0 + + + .globl medium_offset + .p2align 4 + .type medium_offset,@function +medium_offset: +.Lfunc_begin1: + addis 3, 13, i@tprel@ha + addi 3, 3, i@tprel@l + lwa 3, 0(3) + blr + .long 0 + .quad 0 +.Lfunc_end1: + .size medium_offset, .Lfunc_end1-.Lfunc_begin1 + + + .globl large_offset + .p2align 4 + .type large_offset,@function +large_offset: +.Lfunc_begin2: + 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 + .long 0 + .quad 0 +.Lfunc_end2: + .size large_offset, .Lfunc_end2-.Lfunc_begin2 + + + .globl not_adjusted + .p2align 4 + .type not_adjusted,@function +not_adjusted: +.Lfunc_begin3: + 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 + .long 0 + .quad 0 +.Lfunc_end3: + .size not_adjusted, .Lfunc_end3-.Lfunc_begin3 + + + .type i,@object + .section .tdata,"awT",@progbits + .p2align 2 +i: + .long 55 + .size i, 4 + +# CHECK: Relocations [ +# CHECK: Section {{.*}} .rela.text { +# CHECK: 0x{{[0-9A-F]+}} R_PPC64_TPREL16_DS i +# CHECK: 0x{{[0-9A-F]+}} R_PPC64_TPREL16_HA 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: ]