compiler: Parse p- specs in datalayout string, allow definition of custom default data address space
This commit is contained in:
committed by
Edoardo Marangoni
parent
733b47ea4b
commit
93f1201c06
@@ -334,7 +334,7 @@ where
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout + HasTargetSpec,
|
||||
{
|
||||
let xlen = cx.data_layout().pointer_size.bits();
|
||||
let xlen = cx.data_layout().pointer_size().bits();
|
||||
let flen = match &cx.target_spec().llvm_abiname[..] {
|
||||
"ilp32f" | "lp64f" => 32,
|
||||
"ilp32d" | "lp64d" => 64,
|
||||
@@ -369,7 +369,7 @@ where
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout + HasTargetSpec,
|
||||
{
|
||||
let grlen = cx.data_layout().pointer_size.bits();
|
||||
let grlen = cx.data_layout().pointer_size().bits();
|
||||
|
||||
for arg in fn_abi.args.iter_mut() {
|
||||
if arg.is_ignore() {
|
||||
|
||||
@@ -10,7 +10,7 @@ where
|
||||
ret.extend_integer_width_to(32);
|
||||
} else {
|
||||
ret.make_indirect();
|
||||
*offset += cx.data_layout().pointer_size;
|
||||
*offset += cx.data_layout().pointer_size();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -733,7 +733,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
|
||||
}
|
||||
|
||||
if arg_idx.is_none()
|
||||
&& arg.layout.size > Primitive::Pointer(AddressSpace::DATA).size(cx) * 2
|
||||
&& arg.layout.size > Primitive::Pointer(AddressSpace::ZERO).size(cx) * 2
|
||||
&& !matches!(arg.layout.backend_repr, BackendRepr::SimdVector { .. })
|
||||
{
|
||||
// Return values larger than 2 registers using a return area
|
||||
@@ -792,7 +792,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
|
||||
|
||||
let size = arg.layout.size;
|
||||
if arg.layout.is_sized()
|
||||
&& size <= Primitive::Pointer(AddressSpace::DATA).size(cx)
|
||||
&& size <= Primitive::Pointer(AddressSpace::ZERO).size(cx)
|
||||
{
|
||||
// We want to pass small aggregates as immediates, but using
|
||||
// an LLVM aggregate type for this leads to bad optimizations,
|
||||
|
||||
@@ -418,7 +418,7 @@ where
|
||||
"ilp32d" | "lp64d" => 64,
|
||||
_ => 0,
|
||||
};
|
||||
let xlen = cx.data_layout().pointer_size.bits();
|
||||
let xlen = cx.data_layout().pointer_size().bits();
|
||||
|
||||
let mut avail_gprs = 8;
|
||||
let mut avail_fprs = 8;
|
||||
@@ -448,7 +448,7 @@ where
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout + HasTargetSpec,
|
||||
{
|
||||
let xlen = cx.data_layout().pointer_size.bits();
|
||||
let xlen = cx.data_layout().pointer_size().bits();
|
||||
|
||||
for arg in fn_abi.args.iter_mut() {
|
||||
if arg.is_ignore() {
|
||||
|
||||
@@ -10,7 +10,7 @@ where
|
||||
ret.extend_integer_width_to(32);
|
||||
} else {
|
||||
ret.make_indirect();
|
||||
*offset += cx.data_layout().pointer_size;
|
||||
*offset += cx.data_layout().pointer_size();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -219,7 +219,7 @@ where
|
||||
// SSE ABI. We prefer this over integer registers as float scalars need to be in SSE
|
||||
// registers for float operations, so that's the best place to pass them around.
|
||||
fn_abi.ret.cast_to(Reg { kind: RegKind::Vector, size: fn_abi.ret.layout.size });
|
||||
} else if fn_abi.ret.layout.size <= Primitive::Pointer(AddressSpace::DATA).size(cx) {
|
||||
} else if fn_abi.ret.layout.size <= Primitive::Pointer(AddressSpace::ZERO).size(cx) {
|
||||
// Same size or smaller than pointer, return in an integer register.
|
||||
fn_abi.ret.cast_to(Reg { kind: RegKind::Integer, size: fn_abi.ret.layout.size });
|
||||
} else {
|
||||
|
||||
@@ -2198,7 +2198,10 @@ pub struct TargetMetadata {
|
||||
|
||||
impl Target {
|
||||
pub fn parse_data_layout(&self) -> Result<TargetDataLayout, TargetDataLayoutErrors<'_>> {
|
||||
let mut dl = TargetDataLayout::parse_from_llvm_datalayout_string(&self.data_layout)?;
|
||||
let mut dl = TargetDataLayout::parse_from_llvm_datalayout_string(
|
||||
&self.data_layout,
|
||||
self.options.default_address_space,
|
||||
)?;
|
||||
|
||||
// Perform consistency checks against the Target information.
|
||||
if dl.endian != self.endian {
|
||||
@@ -2209,9 +2212,10 @@ impl Target {
|
||||
}
|
||||
|
||||
let target_pointer_width: u64 = self.pointer_width.into();
|
||||
if dl.pointer_size.bits() != target_pointer_width {
|
||||
let dl_pointer_size: u64 = dl.pointer_size().bits();
|
||||
if dl_pointer_size != target_pointer_width {
|
||||
return Err(TargetDataLayoutErrors::InconsistentTargetPointerWidth {
|
||||
pointer_size: dl.pointer_size.bits(),
|
||||
pointer_size: dl_pointer_size,
|
||||
target: self.pointer_width,
|
||||
});
|
||||
}
|
||||
@@ -2650,6 +2654,11 @@ pub struct TargetOptions {
|
||||
/// Whether the target supports XRay instrumentation.
|
||||
pub supports_xray: bool,
|
||||
|
||||
/// The default address space for this target. When using LLVM as a backend, most targets simply
|
||||
/// use LLVM's default address space (0). Some other targets, such as CHERI targets, use a
|
||||
/// custom default address space (in this specific case, `200`).
|
||||
pub default_address_space: rustc_abi::AddressSpace,
|
||||
|
||||
/// Whether the targets supports -Z small-data-threshold
|
||||
small_data_threshold_support: SmallDataThresholdSupport,
|
||||
}
|
||||
@@ -2878,6 +2887,7 @@ impl Default for TargetOptions {
|
||||
entry_name: "main".into(),
|
||||
entry_abi: CanonAbi::C,
|
||||
supports_xray: false,
|
||||
default_address_space: rustc_abi::AddressSpace::ZERO,
|
||||
small_data_threshold_support: SmallDataThresholdSupport::DefaultForArch,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user