Add TLS support for ELF and MachO (#1174)
* Add TLS support * Add binemit and legalize tests * Spill all caller-saved registers when necessary
This commit is contained in:
@@ -3259,10 +3259,73 @@ pub(crate) fn define<'shared>(
|
||||
recipes.add_recipe(
|
||||
EncodingRecipeBuilder::new("safepoint", &formats.multiary, 0).emit(
|
||||
r#"
|
||||
sink.add_stackmap(args, func, isa);
|
||||
"#,
|
||||
sink.add_stackmap(args, func, isa);
|
||||
"#,
|
||||
),
|
||||
);
|
||||
|
||||
// Both `elf_tls_get_addr` and `macho_tls_get_addr` require all caller-saved registers to be spilled.
|
||||
// This is currently special cased in `regalloc/spilling.rs` in the `visit_inst` function.
|
||||
|
||||
recipes.add_recipe(
|
||||
EncodingRecipeBuilder::new("elf_tls_get_addr", &formats.unary_global_value, 16)
|
||||
// FIXME Correct encoding for non rax registers
|
||||
.operands_out(vec![reg_rax])
|
||||
.emit(
|
||||
r#"
|
||||
// output %rax
|
||||
// clobbers %rdi
|
||||
|
||||
// Those data16 prefixes are necessary to pad to 16 bytes.
|
||||
|
||||
// data16 lea gv@tlsgd(%rip),%rdi
|
||||
sink.put1(0x66); // data16
|
||||
sink.put1(0b01001000); // rex.w
|
||||
const LEA: u8 = 0x8d;
|
||||
sink.put1(LEA); // lea
|
||||
modrm_riprel(0b111/*out_reg0*/, sink); // 0x3d
|
||||
sink.reloc_external(Reloc::ElfX86_64TlsGd,
|
||||
&func.global_values[global_value].symbol_name(),
|
||||
-4);
|
||||
sink.put4(0);
|
||||
|
||||
// data16 data16 callq __tls_get_addr-4
|
||||
sink.put1(0x66); // data16
|
||||
sink.put1(0x66); // data16
|
||||
sink.put1(0b01001000); // rex.w
|
||||
sink.put1(0xe8); // call
|
||||
sink.reloc_external(Reloc::X86CallPLTRel4,
|
||||
&ExternalName::LibCall(LibCall::ElfTlsGetAddr),
|
||||
-4);
|
||||
sink.put4(0);
|
||||
"#,
|
||||
),
|
||||
);
|
||||
|
||||
recipes.add_recipe(
|
||||
EncodingRecipeBuilder::new("macho_tls_get_addr", &formats.unary_global_value, 9)
|
||||
// FIXME Correct encoding for non rax registers
|
||||
.operands_out(vec![reg_rax])
|
||||
.emit(
|
||||
r#"
|
||||
// output %rax
|
||||
// clobbers %rdi
|
||||
|
||||
// movq gv@tlv(%rip), %rdi
|
||||
sink.put1(0x48); // rex
|
||||
sink.put1(0x8b); // mov
|
||||
modrm_riprel(0b111/*out_reg0*/, sink); // 0x3d
|
||||
sink.reloc_external(Reloc::MachOX86_64Tlv,
|
||||
&func.global_values[global_value].symbol_name(),
|
||||
-4);
|
||||
sink.put4(0);
|
||||
|
||||
// callq *(%rdi)
|
||||
sink.put1(0xff);
|
||||
sink.put1(0x17);
|
||||
"#,
|
||||
),
|
||||
);
|
||||
|
||||
recipes
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user