AArch64: port tls_value to ISLE. (#4821)
This commit is contained in:
@@ -825,7 +825,8 @@
|
|||||||
|
|
||||||
;; A call to the `ElfTlsGetAddr` libcall. Returns address of TLS symbol in x0.
|
;; A call to the `ElfTlsGetAddr` libcall. Returns address of TLS symbol in x0.
|
||||||
(ElfTlsGetAddr
|
(ElfTlsGetAddr
|
||||||
(symbol ExternalName))
|
(symbol ExternalName)
|
||||||
|
(rd WritableReg))
|
||||||
|
|
||||||
;; An unwind pseudo-instruction.
|
;; An unwind pseudo-instruction.
|
||||||
(Unwind
|
(Unwind
|
||||||
@@ -3068,3 +3069,12 @@
|
|||||||
(if (ty_vec64 ty))
|
(if (ty_vec64 ty))
|
||||||
(let ((src Reg (mov_from_vec src 0 (ScalarSize.Size64))))
|
(let ((src Reg (mov_from_vec src 0 (ScalarSize.Size64))))
|
||||||
(cmp_imm (OperandSize.Size64) src (u8_into_imm12 0))))
|
(cmp_imm (OperandSize.Size64) src (u8_into_imm12 0))))
|
||||||
|
|
||||||
|
;;;; TLS Values ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
;; Helper for emitting ElfTlsGetAddr.
|
||||||
|
(decl elf_tls_get_addr (ExternalName) Reg)
|
||||||
|
(rule (elf_tls_get_addr name)
|
||||||
|
(let ((dst WritableReg (temp_writable_reg $I64))
|
||||||
|
(_ Unit (emit (MInst.ElfTlsGetAddr name dst))))
|
||||||
|
dst))
|
||||||
|
|||||||
@@ -3191,7 +3191,10 @@ impl MachInstEmit for Inst {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&Inst::ElfTlsGetAddr { ref symbol } => {
|
&Inst::ElfTlsGetAddr { ref symbol, rd } => {
|
||||||
|
let rd = allocs.next_writable(rd);
|
||||||
|
assert_eq!(xreg(0), rd.to_reg());
|
||||||
|
|
||||||
// This is the instruction sequence that GCC emits for ELF GD TLS Relocations in aarch64
|
// This is the instruction sequence that GCC emits for ELF GD TLS Relocations in aarch64
|
||||||
// See: https://gcc.godbolt.org/z/KhMh5Gvra
|
// See: https://gcc.godbolt.org/z/KhMh5Gvra
|
||||||
|
|
||||||
|
|||||||
@@ -1044,8 +1044,8 @@ fn aarch64_get_operands<F: Fn(VReg) -> VReg>(inst: &Inst, collector: &mut Operan
|
|||||||
}
|
}
|
||||||
&Inst::VirtualSPOffsetAdj { .. } => {}
|
&Inst::VirtualSPOffsetAdj { .. } => {}
|
||||||
|
|
||||||
&Inst::ElfTlsGetAddr { .. } => {
|
&Inst::ElfTlsGetAddr { rd, .. } => {
|
||||||
collector.reg_def(Writable::from_reg(regs::xreg(0)));
|
collector.reg_fixed_def(rd, regs::xreg(0));
|
||||||
let mut clobbers = AArch64MachineDeps::get_regs_clobbered_by_call(CallConv::SystemV);
|
let mut clobbers = AArch64MachineDeps::get_regs_clobbered_by_call(CallConv::SystemV);
|
||||||
clobbers.remove(regs::xreg_preg(0));
|
clobbers.remove(regs::xreg_preg(0));
|
||||||
collector.reg_clobbers(clobbers);
|
collector.reg_clobbers(clobbers);
|
||||||
@@ -2710,8 +2710,9 @@ impl Inst {
|
|||||||
}
|
}
|
||||||
&Inst::EmitIsland { needed_space } => format!("emit_island {}", needed_space),
|
&Inst::EmitIsland { needed_space } => format!("emit_island {}", needed_space),
|
||||||
|
|
||||||
&Inst::ElfTlsGetAddr { ref symbol } => {
|
&Inst::ElfTlsGetAddr { ref symbol, rd } => {
|
||||||
format!("x0 = elf_tls_get_addr {}", symbol.display(None))
|
let rd = pretty_print_reg(rd.to_reg(), allocs);
|
||||||
|
format!("elf_tls_get_addr {}, {}", rd, symbol.display(None))
|
||||||
}
|
}
|
||||||
&Inst::Unwind { ref inst } => {
|
&Inst::Unwind { ref inst } => {
|
||||||
format!("unwind {:?}", inst)
|
format!("unwind {:?}", inst)
|
||||||
|
|||||||
@@ -2364,7 +2364,9 @@
|
|||||||
|
|
||||||
;;; Rules for `tls_value` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;; Rules for `tls_value` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
;; TODO.
|
(rule (lower (tls_value (symbol_value_data name _ _)))
|
||||||
|
(if (tls_model_is_elf_gd))
|
||||||
|
(elf_tls_get_addr name))
|
||||||
|
|
||||||
;;; Rules for `fcvt_low_from_sint` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;; Rules for `fcvt_low_from_sint` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use crate::isa::aarch64::inst::*;
|
|||||||
use crate::isa::aarch64::settings as aarch64_settings;
|
use crate::isa::aarch64::settings as aarch64_settings;
|
||||||
use crate::machinst::lower::*;
|
use crate::machinst::lower::*;
|
||||||
use crate::machinst::*;
|
use crate::machinst::*;
|
||||||
use crate::settings::{Flags, TlsModel};
|
use crate::settings::Flags;
|
||||||
use crate::{CodegenError, CodegenResult};
|
use crate::{CodegenError, CodegenResult};
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
@@ -459,23 +459,7 @@ pub(crate) fn lower_insn_to_regs(
|
|||||||
implemented_in_isle(ctx)
|
implemented_in_isle(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
Opcode::TlsValue => match flags.tls_model() {
|
Opcode::TlsValue => implemented_in_isle(ctx),
|
||||||
TlsModel::ElfGd => {
|
|
||||||
let dst = get_output_reg(ctx, outputs[0]).only_reg().unwrap();
|
|
||||||
let (name, _, _) = ctx.symbol_value(insn).unwrap();
|
|
||||||
let symbol = name.clone();
|
|
||||||
ctx.emit(Inst::ElfTlsGetAddr { symbol });
|
|
||||||
|
|
||||||
let x0 = xreg(0);
|
|
||||||
ctx.emit(Inst::gen_move(dst, x0, I64));
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
return Err(CodegenError::Unsupported(format!(
|
|
||||||
"Unimplemented TLS model in AArch64 backend: {:?}",
|
|
||||||
flags.tls_model()
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
Opcode::SqmulRoundSat => implemented_in_isle(ctx),
|
Opcode::SqmulRoundSat => implemented_in_isle(ctx),
|
||||||
|
|
||||||
|
|||||||
@@ -1026,20 +1026,6 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
|
|||||||
&self.f.dfg[ir_inst]
|
&self.f.dfg[ir_inst]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the symbol name, relocation distance estimate, and offset for a
|
|
||||||
/// symbol_value instruction.
|
|
||||||
pub fn symbol_value<'b>(
|
|
||||||
&'b self,
|
|
||||||
ir_inst: Inst,
|
|
||||||
) -> Option<(&'b ExternalName, RelocDistance, i64)> {
|
|
||||||
match &self.f.dfg[ir_inst] {
|
|
||||||
&InstructionData::UnaryGlobalValue { global_value, .. } => {
|
|
||||||
self.symbol_value_data(global_value)
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Likewise, but starting with a GlobalValue identifier.
|
/// Likewise, but starting with a GlobalValue identifier.
|
||||||
pub fn symbol_value_data<'b>(
|
pub fn symbol_value_data<'b>(
|
||||||
&'b self,
|
&'b self,
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ block0(v0: i32):
|
|||||||
; stp d8, d9, [sp, #-16]!
|
; stp d8, d9, [sp, #-16]!
|
||||||
; block0:
|
; block0:
|
||||||
; mov x25, x0
|
; mov x25, x0
|
||||||
; x0 = elf_tls_get_addr userextname0
|
; elf_tls_get_addr x0, userextname0
|
||||||
; mov x1, x0
|
; mov x1, x0
|
||||||
; mov x0, x25
|
; mov x0, x25
|
||||||
; ldp d8, d9, [sp], #16
|
; ldp d8, d9, [sp], #16
|
||||||
|
|||||||
Reference in New Issue
Block a user