// We save a total of 35 registers
.macro for_each_saved_reg op max
\op ra, 1
\op a1, 2
\op a2, 3
\op a3, 4
\op a4, 5
\op a5, 6
\op a6, 7
\op a7, 8
\op t0, 9
\op t1, 10
\op t2, 11
\op t3, 12
\op t4, 13
\op t5, 14
\op t6, 15
// save floating point regs
\op ft0, 16, f
\op ft1, 17, f
\op ft2, 18, f
\op ft3, 19, f
\op ft4, 20, f
\op ft5, 21, f
\op ft6, 22, f
\op ft7, 23, f
\op ft8, 24, f
\op ft9, 25, f
\op ft10, 26, f
\op ft11, 27, f
\op fa0, 28, f
\op fa1, 29, f
\op fa2, 30, f
\op fa3, 31, f
\op fa4, 32, f
\op fa5, 33, f
\op fa6, 34, f
\op fa7, 35, f
.endm
// These resolver functions must preserve every register except a0. They set a0
// to the offset of the TLS symbol relative to the thread pointer.
ENTRY_PRIVATE(tlsdesc_resolver_static) ld a0, 8(a0)
jr t0
END(tlsdesc_resolver_static)
ENTRY_PRIVATE(tlsdesc_resolver_dynamic)
// We only need 3 stack slots, but still require a 4th slot for alignment
addi sp, sp, -4*8
.cfi_def_cfa_offset 4*8
spill a1, 1
spill a2, 2
spill a3, 3
// Fallback if TlsDtv::generation < TlsDynamicResolverArg::generation
// since we need to call __tls_get_addr
blt a1, a3, L(fallback)
// We can't modify a0 yet, since tlsdesc_resolver_dynamic_slow_path requires
// a pointer to the TlsIndex, which is the second field of the
// TlsDynamicResolverArg. As a result, we can't modify a0 until we will no
// longer fallback. ld a1, 8(a0) // a1 = TlsIndex::module_id
slli a1, a1, 3 // a1 = module_id*8 -- scale the idx
add a1, a2, a1 // a1 = &TlsDtv::modules[module_id] ld a1, (a1) // a1 = TlsDtv::modules[module_id]
beqz a1, L(fallback) ld a3, 16(a0) // a3 = TlsIndex::offset
add a0, a1, a3 // a0 = TlsDtv::modules[module_id] + offset sub a0, a0, tp // a0 = TlsDtv::modules[module_id] + offset - tp
// On entry, a0 is the address of a TlsDynamicResolverArg object rather than
// the TlsDescriptor address passed to the original resolver function.
ENTRY_PRIVATE(tlsdesc_resolver_dynamic_slow_path)
// We save a total of 35 registers, but vector spills require an alignment
// of 16, so use an extra slot to align it correctly.
addi sp, sp, (-8*36)
.cfi_def_cfa_offset (8 * 36)
for_each_saved_reg spill, 36
spill_vector_regs
add a0, a0, 8
call __tls_get_addr
addi a0, a0, (-1 * TLS_DTV_OFFSET) // Correct the address by TLS_DTV_OFFSET sub a0, a0, tp
// The address of an unresolved weak TLS symbol evaluates to NULL with TLSDESC.
// The value returned by this function is added to the thread pointer, so return
// a negated thread pointer to cancel it out.
ENTRY_PRIVATE(tlsdesc_resolver_unresolved_weak) sub a0, zero, tp
jr t0
END(tlsdesc_resolver_unresolved_weak)
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.16 Sekunden
(vorverarbeitet am 2026-06-28)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.