Implement the tls_value for s390 in the ELF general-dynamic mode. Notable differences to the x86_64 implementation are: - We use a __tls_get_offset libcall instead of __tls_get_addr. - The current thread pointer (stored in a pair of access registers) needs to be added to the result of __tls_get_offset. - __tls_get_offset has a variant ABI that requires the address of the GOT (global offset table) is passed in %r12. This means we need a new libcall entries for __tls_get_offset. In addition, we also need a way to access _GLOBAL_OFFSET_TABLE_. The latter is a "magic" symbol with a well-known name defined by the ABI and recognized by the linker. This patch introduces a new ExternalName::KnownSymbol variant to support such names (originally due to @afonso360). We also need to emit a relocation on a symbol placed in a constant pool, as well as an extra relocation on the call to __tls_get_offset required for TLS linker optimization. Needed by the cg_clif frontend.
27 lines
539 B
Plaintext
27 lines
539 B
Plaintext
test compile precise-output
|
|
set tls_model=elf_gd
|
|
target s390x
|
|
|
|
function u0:0(i32) -> i64 {
|
|
gv0 = symbol colocated tls u1:0
|
|
|
|
block0(v0: i32):
|
|
v1 = global_value.i64 gv0
|
|
return v1
|
|
}
|
|
|
|
; stmg %r12, %r15, 96(%r15)
|
|
; aghi %r15, -160
|
|
; virtual_sp_offset_adjust 160
|
|
; block0:
|
|
; larl %r12, %ElfGlobalOffsetTable + 0
|
|
; bras %r1, 12 ; data u1:0@tlsgd ; lg %r2, 0(%r1)
|
|
; brasl %r14, %ElfTlsGetOffset:tls_gdcall:u1:0
|
|
; ear %r3, %a0
|
|
; sllg %r4, %r3, 32
|
|
; ear %r4, %a1
|
|
; agr %r2, %r4
|
|
; lmg %r12, %r15, 256(%r15)
|
|
; br %r14
|
|
|