Importing rustc-1.56.0
Change-Id: I98941481270706fa55f8fb2cb91686ae3bd30f38
diff --git a/compiler/rustc_target/src/abi/call/aarch64.rs b/compiler/rustc_target/src/abi/call/aarch64.rs
index a5e985d..4613a45 100644
--- a/compiler/rustc_target/src/abi/call/aarch64.rs
+++ b/compiler/rustc_target/src/abi/call/aarch64.rs
@@ -1,10 +1,10 @@
use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind, Uniform};
-use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
+use crate::abi::{HasDataLayout, TyAbiInterface};
fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) -> Option<Uniform>
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
{
arg.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()).and_then(|unit| {
let size = arg.layout.size;
@@ -26,8 +26,8 @@
fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>)
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
{
if !ret.layout.is_aggregate() {
ret.extend_integer_width_to(32);
@@ -48,8 +48,8 @@
fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
{
if !arg.layout.is_aggregate() {
arg.extend_integer_width_to(32);
@@ -70,8 +70,8 @@
pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
{
if !fn_abi.ret.is_ignore() {
classify_ret(cx, &mut fn_abi.ret);
diff --git a/compiler/rustc_target/src/abi/call/amdgpu.rs b/compiler/rustc_target/src/abi/call/amdgpu.rs
index 0b4f279..9be9747 100644
--- a/compiler/rustc_target/src/abi/call/amdgpu.rs
+++ b/compiler/rustc_target/src/abi/call/amdgpu.rs
@@ -1,26 +1,26 @@
use crate::abi::call::{ArgAbi, FnAbi};
-use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
+use crate::abi::{HasDataLayout, TyAbiInterface};
fn classify_ret<'a, Ty, C>(_cx: &C, ret: &mut ArgAbi<'a, Ty>)
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
{
ret.extend_integer_width_to(32);
}
fn classify_arg<'a, Ty, C>(_cx: &C, arg: &mut ArgAbi<'a, Ty>)
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
{
arg.extend_integer_width_to(32);
}
pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
{
if !fn_abi.ret.is_ignore() {
classify_ret(cx, &mut fn_abi.ret);
diff --git a/compiler/rustc_target/src/abi/call/arm.rs b/compiler/rustc_target/src/abi/call/arm.rs
index b560e11..e66c213 100644
--- a/compiler/rustc_target/src/abi/call/arm.rs
+++ b/compiler/rustc_target/src/abi/call/arm.rs
@@ -1,11 +1,11 @@
use crate::abi::call::{ArgAbi, Conv, FnAbi, Reg, RegKind, Uniform};
-use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
+use crate::abi::{HasDataLayout, TyAbiInterface};
use crate::spec::HasTargetSpec;
fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) -> Option<Uniform>
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
{
arg.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()).and_then(|unit| {
let size = arg.layout.size;
@@ -27,8 +27,8 @@
fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>, vfp: bool)
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
{
if !ret.layout.is_aggregate() {
ret.extend_integer_width_to(32);
@@ -53,8 +53,8 @@
fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>, vfp: bool)
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
{
if !arg.layout.is_aggregate() {
arg.extend_integer_width_to(32);
@@ -75,8 +75,8 @@
pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout + HasTargetSpec,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout + HasTargetSpec,
{
// If this is a target with a hard-float ABI, and the function is not explicitly
// `extern "aapcs"`, then we must use the VFP registers for homogeneous aggregates.
diff --git a/compiler/rustc_target/src/abi/call/mips.rs b/compiler/rustc_target/src/abi/call/mips.rs
index 733a732..cc44319 100644
--- a/compiler/rustc_target/src/abi/call/mips.rs
+++ b/compiler/rustc_target/src/abi/call/mips.rs
@@ -1,10 +1,9 @@
use crate::abi::call::{ArgAbi, FnAbi, Reg, Uniform};
-use crate::abi::{HasDataLayout, LayoutOf, Size, TyAndLayoutMethods};
+use crate::abi::{HasDataLayout, Size};
-fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'_, Ty>, offset: &mut Size)
+fn classify_ret<Ty, C>(cx: &C, ret: &mut ArgAbi<'_, Ty>, offset: &mut Size)
where
- Ty: TyAndLayoutMethods<'a, C>,
- C: LayoutOf<Ty = Ty> + HasDataLayout,
+ C: HasDataLayout,
{
if !ret.layout.is_aggregate() {
ret.extend_integer_width_to(32);
@@ -14,10 +13,9 @@
}
}
-fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'_, Ty>, offset: &mut Size)
+fn classify_arg<Ty, C>(cx: &C, arg: &mut ArgAbi<'_, Ty>, offset: &mut Size)
where
- Ty: TyAndLayoutMethods<'a, C>,
- C: LayoutOf<Ty = Ty> + HasDataLayout,
+ C: HasDataLayout,
{
let dl = cx.data_layout();
let size = arg.layout.size;
@@ -35,10 +33,9 @@
*offset = offset.align_to(align) + size.align_to(align);
}
-pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'_, Ty>)
+pub fn compute_abi_info<Ty, C>(cx: &C, fn_abi: &mut FnAbi<'_, Ty>)
where
- Ty: TyAndLayoutMethods<'a, C>,
- C: LayoutOf<Ty = Ty> + HasDataLayout,
+ C: HasDataLayout,
{
let mut offset = Size::ZERO;
if !fn_abi.ret.is_ignore() {
diff --git a/compiler/rustc_target/src/abi/call/mips64.rs b/compiler/rustc_target/src/abi/call/mips64.rs
index a630c84..28ca93c 100644
--- a/compiler/rustc_target/src/abi/call/mips64.rs
+++ b/compiler/rustc_target/src/abi/call/mips64.rs
@@ -1,5 +1,5 @@
use crate::abi::call::{ArgAbi, ArgExtension, CastTarget, FnAbi, PassMode, Reg, RegKind, Uniform};
-use crate::abi::{self, HasDataLayout, LayoutOf, Size, TyAndLayout, TyAndLayoutMethods};
+use crate::abi::{self, HasDataLayout, Size, TyAbiInterface};
fn extend_integer_width_mips<Ty>(arg: &mut ArgAbi<'_, Ty>, bits: u64) {
// Always sign extend u32 values on 64-bit mips
@@ -19,8 +19,8 @@
fn float_reg<'a, Ty, C>(cx: &C, ret: &ArgAbi<'a, Ty>, i: usize) -> Option<Reg>
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
{
match ret.layout.field(cx, i).abi {
abi::Abi::Scalar(ref scalar) => match scalar.value {
@@ -34,8 +34,8 @@
fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>)
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
{
if !ret.layout.is_aggregate() {
extend_integer_width_mips(ret, 64);
@@ -74,8 +74,8 @@
fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
{
if !arg.layout.is_aggregate() {
extend_integer_width_mips(arg, 64);
@@ -144,8 +144,8 @@
pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
{
if !fn_abi.ret.is_ignore() {
classify_ret(cx, &mut fn_abi.ret);
diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs
index 6e0e140..6d3c731 100644
--- a/compiler/rustc_target/src/abi/call/mod.rs
+++ b/compiler/rustc_target/src/abi/call/mod.rs
@@ -1,5 +1,5 @@
use crate::abi::{self, Abi, Align, FieldsShape, Size};
-use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
+use crate::abi::{HasDataLayout, TyAbiInterface, TyAndLayout};
use crate::spec::{self, HasTargetSpec};
mod aarch64;
@@ -316,8 +316,7 @@
/// specific targets.
pub fn homogeneous_aggregate<C>(&self, cx: &C) -> Result<HomogeneousAggregate, Heterogeneous>
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = Self>,
+ Ty: TyAbiInterface<'a, C> + Copy,
{
match self.abi {
Abi::Uninhabited => Err(Heterogeneous),
@@ -603,8 +602,8 @@
impl<'a, Ty> FnAbi<'a, Ty> {
pub fn adjust_for_cabi<C>(&mut self, cx: &C, abi: spec::abi::Abi) -> Result<(), String>
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout + HasTargetSpec,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout + HasTargetSpec,
{
if abi == spec::abi::Abi::X86Interrupt {
if let Some(arg) = self.args.first_mut() {
diff --git a/compiler/rustc_target/src/abi/call/powerpc64.rs b/compiler/rustc_target/src/abi/call/powerpc64.rs
index 8c2a9d0..c22ef9c 100644
--- a/compiler/rustc_target/src/abi/call/powerpc64.rs
+++ b/compiler/rustc_target/src/abi/call/powerpc64.rs
@@ -3,7 +3,7 @@
// need to be fixed when PowerPC vector support is added.
use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind, Uniform};
-use crate::abi::{Endian, HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
+use crate::abi::{Endian, HasDataLayout, TyAbiInterface};
use crate::spec::HasTargetSpec;
#[derive(Debug, Clone, Copy, PartialEq)]
@@ -19,8 +19,8 @@
abi: ABI,
) -> Option<Uniform>
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
{
arg.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()).and_then(|unit| {
// ELFv1 only passes one-member aggregates transparently.
@@ -43,8 +43,8 @@
fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>, abi: ABI)
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
{
if !ret.layout.is_aggregate() {
ret.extend_integer_width_to(64);
@@ -86,8 +86,8 @@
fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>, abi: ABI)
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
{
if !arg.layout.is_aggregate() {
arg.extend_integer_width_to(64);
@@ -116,8 +116,8 @@
pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout + HasTargetSpec,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout + HasTargetSpec,
{
let abi = if cx.target_spec().env == "musl" {
ELFv2
diff --git a/compiler/rustc_target/src/abi/call/riscv.rs b/compiler/rustc_target/src/abi/call/riscv.rs
index 1ab881d..8c2ef8c 100644
--- a/compiler/rustc_target/src/abi/call/riscv.rs
+++ b/compiler/rustc_target/src/abi/call/riscv.rs
@@ -5,9 +5,7 @@
// https://github.com/llvm/llvm-project/blob/8e780252a7284be45cf1ba224cabd884847e8e92/clang/lib/CodeGen/TargetInfo.cpp#L9311-L9773
use crate::abi::call::{ArgAbi, ArgExtension, CastTarget, FnAbi, PassMode, Reg, RegKind, Uniform};
-use crate::abi::{
- self, Abi, FieldsShape, HasDataLayout, LayoutOf, Size, TyAndLayout, TyAndLayoutMethods,
-};
+use crate::abi::{self, Abi, FieldsShape, HasDataLayout, Size, TyAbiInterface, TyAndLayout};
use crate::spec::HasTargetSpec;
#[derive(Copy, Clone)]
@@ -43,8 +41,7 @@
field2_kind: &mut RegPassKind,
) -> Result<(), CannotUseFpConv>
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>>,
+ Ty: TyAbiInterface<'a, C> + Copy,
{
match arg_layout.abi {
Abi::Scalar(ref scalar) => match scalar.value {
@@ -130,8 +127,7 @@
flen: u64,
) -> Option<FloatConv>
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>>,
+ Ty: TyAbiInterface<'a, C> + Copy,
{
let mut field1_kind = RegPassKind::Unknown;
let mut field2_kind = RegPassKind::Unknown;
@@ -149,8 +145,7 @@
fn classify_ret<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>, xlen: u64, flen: u64) -> bool
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>>,
+ Ty: TyAbiInterface<'a, C> + Copy,
{
if let Some(conv) = should_use_fp_conv(cx, &arg.layout, xlen, flen) {
match conv {
@@ -212,8 +207,7 @@
avail_gprs: &mut u64,
avail_fprs: &mut u64,
) where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>>,
+ Ty: TyAbiInterface<'a, C> + Copy,
{
if !is_vararg {
match should_use_fp_conv(cx, &arg.layout, xlen, flen) {
@@ -320,8 +314,8 @@
pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout + HasTargetSpec,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout + HasTargetSpec,
{
let flen = match &cx.target_spec().llvm_abiname[..] {
"ilp32f" | "lp64f" => 32,
diff --git a/compiler/rustc_target/src/abi/call/s390x.rs b/compiler/rustc_target/src/abi/call/s390x.rs
index 005dcc6..5941089 100644
--- a/compiler/rustc_target/src/abi/call/s390x.rs
+++ b/compiler/rustc_target/src/abi/call/s390x.rs
@@ -2,13 +2,9 @@
// for a pre-z13 machine or using -mno-vx.
use crate::abi::call::{ArgAbi, FnAbi, Reg};
-use crate::abi::{self, HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
+use crate::abi::{self, HasDataLayout, TyAbiInterface, TyAndLayout};
-fn classify_ret<'a, Ty, C>(ret: &mut ArgAbi<'_, Ty>)
-where
- Ty: TyAndLayoutMethods<'a, C>,
- C: LayoutOf<Ty = Ty> + HasDataLayout,
-{
+fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
if !ret.layout.is_aggregate() && ret.layout.size.bits() <= 64 {
ret.extend_integer_width_to(64);
} else {
@@ -18,8 +14,8 @@
fn is_single_fp_element<'a, Ty, C>(cx: &C, layout: TyAndLayout<'a, Ty>) -> bool
where
- Ty: TyAndLayoutMethods<'a, C>,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C>,
+ C: HasDataLayout,
{
match layout.abi {
abi::Abi::Scalar(ref scalar) => scalar.value.is_float(),
@@ -36,8 +32,8 @@
fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
{
if !arg.layout.is_aggregate() && arg.layout.size.bits() <= 64 {
arg.extend_integer_width_to(64);
@@ -63,8 +59,8 @@
pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
{
if !fn_abi.ret.is_ignore() {
classify_ret(&mut fn_abi.ret);
diff --git a/compiler/rustc_target/src/abi/call/sparc.rs b/compiler/rustc_target/src/abi/call/sparc.rs
index 733a732..cc44319 100644
--- a/compiler/rustc_target/src/abi/call/sparc.rs
+++ b/compiler/rustc_target/src/abi/call/sparc.rs
@@ -1,10 +1,9 @@
use crate::abi::call::{ArgAbi, FnAbi, Reg, Uniform};
-use crate::abi::{HasDataLayout, LayoutOf, Size, TyAndLayoutMethods};
+use crate::abi::{HasDataLayout, Size};
-fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'_, Ty>, offset: &mut Size)
+fn classify_ret<Ty, C>(cx: &C, ret: &mut ArgAbi<'_, Ty>, offset: &mut Size)
where
- Ty: TyAndLayoutMethods<'a, C>,
- C: LayoutOf<Ty = Ty> + HasDataLayout,
+ C: HasDataLayout,
{
if !ret.layout.is_aggregate() {
ret.extend_integer_width_to(32);
@@ -14,10 +13,9 @@
}
}
-fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'_, Ty>, offset: &mut Size)
+fn classify_arg<Ty, C>(cx: &C, arg: &mut ArgAbi<'_, Ty>, offset: &mut Size)
where
- Ty: TyAndLayoutMethods<'a, C>,
- C: LayoutOf<Ty = Ty> + HasDataLayout,
+ C: HasDataLayout,
{
let dl = cx.data_layout();
let size = arg.layout.size;
@@ -35,10 +33,9 @@
*offset = offset.align_to(align) + size.align_to(align);
}
-pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'_, Ty>)
+pub fn compute_abi_info<Ty, C>(cx: &C, fn_abi: &mut FnAbi<'_, Ty>)
where
- Ty: TyAndLayoutMethods<'a, C>,
- C: LayoutOf<Ty = Ty> + HasDataLayout,
+ C: HasDataLayout,
{
let mut offset = Size::ZERO;
if !fn_abi.ret.is_ignore() {
diff --git a/compiler/rustc_target/src/abi/call/sparc64.rs b/compiler/rustc_target/src/abi/call/sparc64.rs
index a647675..5d74c94 100644
--- a/compiler/rustc_target/src/abi/call/sparc64.rs
+++ b/compiler/rustc_target/src/abi/call/sparc64.rs
@@ -1,12 +1,12 @@
// FIXME: This needs an audit for correctness and completeness.
use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind, Uniform};
-use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
+use crate::abi::{HasDataLayout, TyAbiInterface};
fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) -> Option<Uniform>
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
{
arg.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()).and_then(|unit| {
// Ensure we have at most eight uniquely addressable members.
@@ -26,8 +26,8 @@
fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>)
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
{
if !ret.layout.is_aggregate() {
ret.extend_integer_width_to(64);
@@ -52,8 +52,8 @@
fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
{
if !arg.layout.is_aggregate() {
arg.extend_integer_width_to(64);
@@ -76,8 +76,8 @@
pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
{
if !fn_abi.ret.is_ignore() {
classify_ret(cx, &mut fn_abi.ret);
diff --git a/compiler/rustc_target/src/abi/call/wasm.rs b/compiler/rustc_target/src/abi/call/wasm.rs
index bf2c08b..3237cde 100644
--- a/compiler/rustc_target/src/abi/call/wasm.rs
+++ b/compiler/rustc_target/src/abi/call/wasm.rs
@@ -1,10 +1,10 @@
use crate::abi::call::{ArgAbi, FnAbi, Uniform};
-use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
+use crate::abi::{HasDataLayout, TyAbiInterface};
fn unwrap_trivial_aggregate<'a, Ty, C>(cx: &C, val: &mut ArgAbi<'a, Ty>) -> bool
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
{
if val.layout.is_aggregate() {
if let Some(unit) = val.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()) {
@@ -20,8 +20,8 @@
fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>)
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
{
ret.extend_integer_width_to(32);
if ret.layout.is_aggregate() && !unwrap_trivial_aggregate(cx, ret) {
@@ -31,8 +31,8 @@
fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
{
arg.extend_integer_width_to(32);
if arg.layout.is_aggregate() && !unwrap_trivial_aggregate(cx, arg) {
@@ -43,8 +43,8 @@
/// The purpose of this ABI is to match the C ABI (aka clang) exactly.
pub fn compute_c_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
{
if !fn_abi.ret.is_ignore() {
classify_ret(cx, &mut fn_abi.ret);
diff --git a/compiler/rustc_target/src/abi/call/x86.rs b/compiler/rustc_target/src/abi/call/x86.rs
index ff8849e..3fc197b 100644
--- a/compiler/rustc_target/src/abi/call/x86.rs
+++ b/compiler/rustc_target/src/abi/call/x86.rs
@@ -1,5 +1,5 @@
use crate::abi::call::{ArgAttribute, FnAbi, PassMode, Reg, RegKind};
-use crate::abi::{self, HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
+use crate::abi::{self, HasDataLayout, TyAbiInterface, TyAndLayout};
use crate::spec::HasTargetSpec;
#[derive(PartialEq)]
@@ -10,8 +10,8 @@
fn is_single_fp_element<'a, Ty, C>(cx: &C, layout: TyAndLayout<'a, Ty>) -> bool
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
{
match layout.abi {
abi::Abi::Scalar(ref scalar) => scalar.value.is_float(),
@@ -28,8 +28,8 @@
pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>, flavor: Flavor)
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout + HasTargetSpec,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout + HasTargetSpec,
{
if !fn_abi.ret.is_ignore() {
if fn_abi.ret.layout.is_aggregate() {
diff --git a/compiler/rustc_target/src/abi/call/x86_64.rs b/compiler/rustc_target/src/abi/call/x86_64.rs
index a55658b..08f0aab 100644
--- a/compiler/rustc_target/src/abi/call/x86_64.rs
+++ b/compiler/rustc_target/src/abi/call/x86_64.rs
@@ -2,7 +2,7 @@
// https://github.com/jckarter/clay/blob/master/compiler/src/externals.cpp
use crate::abi::call::{ArgAbi, CastTarget, FnAbi, Reg, RegKind};
-use crate::abi::{self, Abi, HasDataLayout, LayoutOf, Size, TyAndLayout, TyAndLayoutMethods};
+use crate::abi::{self, Abi, HasDataLayout, Size, TyAbiInterface, TyAndLayout};
/// Classification of "eightbyte" components.
// N.B., the order of the variants is from general to specific,
@@ -26,8 +26,8 @@
arg: &ArgAbi<'a, Ty>,
) -> Result<[Option<Class>; MAX_EIGHTBYTES], Memory>
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
{
fn classify<'a, Ty, C>(
cx: &C,
@@ -36,8 +36,8 @@
off: Size,
) -> Result<(), Memory>
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
{
if !off.is_aligned(layout.align.abi) {
if !layout.is_zst() {
@@ -172,8 +172,8 @@
pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
where
- Ty: TyAndLayoutMethods<'a, C> + Copy,
- C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C> + Copy,
+ C: HasDataLayout,
{
let mut int_regs = MAX_INT_REGS;
let mut sse_regs = MAX_SSE_REGS;
diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs
index 9a24edf..8203999 100644
--- a/compiler/rustc_target/src/abi/mod.rs
+++ b/compiler/rustc_target/src/abi/mod.rs
@@ -5,6 +5,7 @@
use std::convert::{TryFrom, TryInto};
use std::fmt;
+use std::iter::Step;
use std::num::NonZeroUsize;
use std::ops::{Add, AddAssign, Deref, Mul, Range, RangeInclusive, Sub};
use std::str::FromStr;
@@ -36,6 +37,9 @@
pub vector_align: Vec<(Size, AbiAndPrefAlign)>,
pub instruction_address_space: AddressSpace,
+
+ /// Minimum size of #[repr(C)] enums (default I32 bits)
+ pub c_enum_min_size: Integer,
}
impl Default for TargetDataLayout {
@@ -60,6 +64,7 @@
(Size::from_bits(128), AbiAndPrefAlign::new(align(128))),
],
instruction_address_space: AddressSpace::DATA,
+ c_enum_min_size: Integer::I32,
}
}
}
@@ -173,6 +178,8 @@
));
}
+ dl.c_enum_min_size = Integer::from_size(Size::from_bits(target.c_enum_min_bits))?;
+
Ok(dl)
}
@@ -187,6 +194,7 @@
/// to represent object size in bits. It would need to be 1 << 61 to account for this, but is
/// currently conservatively bounded to 1 << 47 as that is enough to cover the current usable
/// address space on 64-bit ARMv8 and x86_64.
+ #[inline]
pub fn obj_size_bound(&self) -> u64 {
match self.pointer_size.bits() {
16 => 1 << 15,
@@ -196,6 +204,7 @@
}
}
+ #[inline]
pub fn ptr_sized_integer(&self) -> Integer {
match self.pointer_size.bits() {
16 => I16,
@@ -205,6 +214,7 @@
}
}
+ #[inline]
pub fn vector_align(&self, vec_size: Size) -> AbiAndPrefAlign {
for &(size, align) in &self.vector_align {
if size == vec_size {
@@ -434,6 +444,43 @@
}
}
+impl Step for Size {
+ #[inline]
+ fn steps_between(start: &Self, end: &Self) -> Option<usize> {
+ u64::steps_between(&start.bytes(), &end.bytes())
+ }
+
+ #[inline]
+ fn forward_checked(start: Self, count: usize) -> Option<Self> {
+ u64::forward_checked(start.bytes(), count).map(Self::from_bytes)
+ }
+
+ #[inline]
+ fn forward(start: Self, count: usize) -> Self {
+ Self::from_bytes(u64::forward(start.bytes(), count))
+ }
+
+ #[inline]
+ unsafe fn forward_unchecked(start: Self, count: usize) -> Self {
+ Self::from_bytes(u64::forward_unchecked(start.bytes(), count))
+ }
+
+ #[inline]
+ fn backward_checked(start: Self, count: usize) -> Option<Self> {
+ u64::backward_checked(start.bytes(), count).map(Self::from_bytes)
+ }
+
+ #[inline]
+ fn backward(start: Self, count: usize) -> Self {
+ Self::from_bytes(u64::backward(start.bytes(), count))
+ }
+
+ #[inline]
+ unsafe fn backward_unchecked(start: Self, count: usize) -> Self {
+ Self::from_bytes(u64::backward_unchecked(start.bytes(), count))
+ }
+}
+
/// Alignment of a type in bytes (always a power of two).
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Encodable, Decodable)]
#[derive(HashStable_Generic)]
@@ -518,14 +565,17 @@
}
impl AbiAndPrefAlign {
+ #[inline]
pub fn new(align: Align) -> AbiAndPrefAlign {
AbiAndPrefAlign { abi: align, pref: align }
}
+ #[inline]
pub fn min(self, other: AbiAndPrefAlign) -> AbiAndPrefAlign {
AbiAndPrefAlign { abi: self.abi.min(other.abi), pref: self.pref.min(other.pref) }
}
+ #[inline]
pub fn max(self, other: AbiAndPrefAlign) -> AbiAndPrefAlign {
AbiAndPrefAlign { abi: self.abi.max(other.abi), pref: self.pref.max(other.pref) }
}
@@ -542,6 +592,7 @@
}
impl Integer {
+ #[inline]
pub fn size(self) -> Size {
match self {
I8 => Size::from_bytes(1),
@@ -565,6 +616,7 @@
}
/// Finds the smallest Integer type which can represent the signed value.
+ #[inline]
pub fn fit_signed(x: i128) -> Integer {
match x {
-0x0000_0000_0000_0080..=0x0000_0000_0000_007f => I8,
@@ -576,6 +628,7 @@
}
/// Finds the smallest Integer type which can represent the unsigned value.
+ #[inline]
pub fn fit_unsigned(x: u128) -> Integer {
match x {
0..=0x0000_0000_0000_00ff => I8,
@@ -610,6 +663,20 @@
}
I8
}
+
+ // FIXME(eddyb) consolidate this and other methods that find the appropriate
+ // `Integer` given some requirements.
+ #[inline]
+ fn from_size(size: Size) -> Result<Self, String> {
+ match size.bits() {
+ 8 => Ok(Integer::I8),
+ 16 => Ok(Integer::I16),
+ 32 => Ok(Integer::I32),
+ 64 => Ok(Integer::I64),
+ 128 => Ok(Integer::I128),
+ _ => Err(format!("rust does not support integers with {} bits", size.bits())),
+ }
+ }
}
/// Fundamental unit of memory access and layout.
@@ -651,41 +718,94 @@
}
}
+ // FIXME(eddyb) remove, it's trivial thanks to `matches!`.
+ #[inline]
pub fn is_float(self) -> bool {
matches!(self, F32 | F64)
}
+ // FIXME(eddyb) remove, it's completely unused.
+ #[inline]
pub fn is_int(self) -> bool {
matches!(self, Int(..))
}
}
+/// Inclusive wrap-around range of valid values, that is, if
+/// start > end, it represents `start..=MAX`,
+/// followed by `0..=end`.
+///
+/// That is, for an i8 primitive, a range of `254..=2` means following
+/// sequence:
+///
+/// 254 (-2), 255 (-1), 0, 1, 2
+///
+/// This is intended specifically to mirror LLVM’s `!range` metadata,
+/// semantics.
+#[derive(Clone, PartialEq, Eq, Hash)]
+#[derive(HashStable_Generic)]
+pub struct WrappingRange {
+ pub start: u128,
+ pub end: u128,
+}
+
+impl WrappingRange {
+ /// Returns `true` if `v` is contained in the range.
+ #[inline(always)]
+ pub fn contains(&self, v: u128) -> bool {
+ if self.start <= self.end {
+ self.start <= v && v <= self.end
+ } else {
+ self.start <= v || v <= self.end
+ }
+ }
+
+ /// Returns `true` if zero is contained in the range.
+ /// Equal to `range.contains(0)` but should be faster.
+ #[inline(always)]
+ pub fn contains_zero(&self) -> bool {
+ self.start > self.end || self.start == 0
+ }
+
+ /// Returns `self` with replaced `start`
+ #[inline(always)]
+ pub fn with_start(mut self, start: u128) -> Self {
+ self.start = start;
+ self
+ }
+
+ /// Returns `self` with replaced `end`
+ #[inline(always)]
+ pub fn with_end(mut self, end: u128) -> Self {
+ self.end = end;
+ self
+ }
+}
+
+impl fmt::Debug for WrappingRange {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(fmt, "{}..={}", self.start, self.end)?;
+ Ok(())
+ }
+}
+
/// Information about one scalar component of a Rust type.
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
#[derive(HashStable_Generic)]
pub struct Scalar {
pub value: Primitive,
- /// Inclusive wrap-around range of valid values, that is, if
- /// start > end, it represents `start..=MAX`,
- /// followed by `0..=end`.
- ///
- /// That is, for an i8 primitive, a range of `254..=2` means following
- /// sequence:
- ///
- /// 254 (-2), 255 (-1), 0, 1, 2
- ///
- /// This is intended specifically to mirror LLVM’s `!range` metadata,
- /// semantics.
// FIXME(eddyb) always use the shortest range, e.g., by finding
// the largest space between two consecutive valid values and
// taking everything else as the (shortest) valid range.
- pub valid_range: RangeInclusive<u128>,
+ pub valid_range: WrappingRange,
}
impl Scalar {
+ #[inline]
pub fn is_bool(&self) -> bool {
- matches!(self.value, Int(I8, false)) && self.valid_range == (0..=1)
+ matches!(self.value, Int(I8, false))
+ && matches!(self.valid_range, WrappingRange { start: 0, end: 1 })
}
/// Returns the valid range as a `x..y` range.
@@ -698,8 +818,8 @@
let bits = self.value.size(cx).bits();
assert!(bits <= 128);
let mask = !0u128 >> (128 - bits);
- let start = *self.valid_range.start();
- let end = *self.valid_range.end();
+ let start = self.valid_range.start;
+ let end = self.valid_range.end;
assert_eq!(start, start & mask);
assert_eq!(end, end & mask);
start..(end.wrapping_add(1) & mask)
@@ -749,6 +869,7 @@
}
impl FieldsShape {
+ #[inline]
pub fn count(&self) -> usize {
match *self {
FieldsShape::Primitive => 0,
@@ -758,6 +879,7 @@
}
}
+ #[inline]
pub fn offset(&self, i: usize) -> Size {
match *self {
FieldsShape::Primitive => {
@@ -781,6 +903,7 @@
}
}
+ #[inline]
pub fn memory_index(&self, i: usize) -> usize {
match *self {
FieldsShape::Primitive => {
@@ -864,6 +987,7 @@
}
/// Returns `true` if this is a single signed integer scalar
+ #[inline]
pub fn is_signed(&self) -> bool {
match *self {
Abi::Scalar(ref scal) => match scal.value {
@@ -954,14 +1078,14 @@
let max_value = !0u128 >> (128 - bits);
// Find out how many values are outside the valid range.
- let niche = v.end().wrapping_add(1)..*v.start();
+ let niche = v.end.wrapping_add(1)..v.start;
niche.end.wrapping_sub(niche.start) & max_value
}
pub fn reserve<C: HasDataLayout>(&self, cx: &C, count: u128) -> Option<(u128, Scalar)> {
assert!(count > 0);
- let Scalar { value, valid_range: ref v } = self.scalar;
+ let Scalar { value, valid_range: v } = self.scalar.clone();
let bits = value.size(cx).bits();
assert!(bits <= 128);
let max_value = !0u128 >> (128 - bits);
@@ -971,24 +1095,14 @@
}
// Compute the range of invalid values being reserved.
- let start = v.end().wrapping_add(1) & max_value;
- let end = v.end().wrapping_add(count) & max_value;
+ let start = v.end.wrapping_add(1) & max_value;
+ let end = v.end.wrapping_add(count) & max_value;
- // If the `end` of our range is inside the valid range,
- // then we ran out of invalid values.
- // FIXME(eddyb) abstract this with a wraparound range type.
- let valid_range_contains = |x| {
- if v.start() <= v.end() {
- *v.start() <= x && x <= *v.end()
- } else {
- *v.start() <= x || x <= *v.end()
- }
- };
- if valid_range_contains(end) {
+ if v.contains(end) {
return None;
}
- Some((start, Scalar { value, valid_range: *v.start()..=end }))
+ Some((start, Scalar { value, valid_range: v.with_end(end) }))
}
}
@@ -1046,7 +1160,7 @@
/// to that obtained from `layout_of(ty)`, as we need to produce
/// layouts for which Rust types do not exist, such as enum variants
/// or synthetic fields of enums (i.e., discriminants) and fat pointers.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable_Generic)]
pub struct TyAndLayout<'a, Ty> {
pub ty: Ty,
pub layout: &'a Layout,
@@ -1060,9 +1174,9 @@
}
/// Trait for context types that can compute layouts of things.
-pub trait LayoutOf {
- type Ty;
- type TyAndLayout;
+pub trait LayoutOf<'a>: Sized {
+ type Ty: TyAbiInterface<'a, Self>;
+ type TyAndLayout: MaybeResult<TyAndLayout<'a, Self::Ty>>;
fn layout_of(&self, ty: Self::Ty) -> Self::TyAndLayout;
fn spanned_layout_of(&self, ty: Self::Ty, _span: Span) -> Self::TyAndLayout {
@@ -1070,9 +1184,6 @@
}
}
-/// The `TyAndLayout` above will always be a `MaybeResult<TyAndLayout<'_, Self>>`.
-/// We can't add the bound due to the lifetime, but this trait is still useful when
-/// writing code that's generic over the `LayoutOf` impl.
pub trait MaybeResult<T> {
type Error;
@@ -1125,41 +1236,42 @@
pub address_space: AddressSpace,
}
-pub trait TyAndLayoutMethods<'a, C: LayoutOf<Ty = Self>>: Sized {
- fn for_variant(
+/// Trait that needs to be implemented by the higher-level type representation
+/// (e.g. `rustc_middle::ty::Ty`), to provide `rustc_target::abi` functionality.
+pub trait TyAbiInterface<'a, C>: Sized {
+ fn ty_and_layout_for_variant(
this: TyAndLayout<'a, Self>,
cx: &C,
variant_index: VariantIdx,
) -> TyAndLayout<'a, Self>;
- fn field(this: TyAndLayout<'a, Self>, cx: &C, i: usize) -> C::TyAndLayout;
- fn pointee_info_at(this: TyAndLayout<'a, Self>, cx: &C, offset: Size) -> Option<PointeeInfo>;
+ fn ty_and_layout_field(this: TyAndLayout<'a, Self>, cx: &C, i: usize) -> TyAndLayout<'a, Self>;
+ fn ty_and_layout_pointee_info_at(
+ this: TyAndLayout<'a, Self>,
+ cx: &C,
+ offset: Size,
+ ) -> Option<PointeeInfo>;
}
impl<'a, Ty> TyAndLayout<'a, Ty> {
pub fn for_variant<C>(self, cx: &C, variant_index: VariantIdx) -> Self
where
- Ty: TyAndLayoutMethods<'a, C>,
- C: LayoutOf<Ty = Ty>,
+ Ty: TyAbiInterface<'a, C>,
{
- Ty::for_variant(self, cx, variant_index)
+ Ty::ty_and_layout_for_variant(self, cx, variant_index)
}
- /// Callers might want to use `C: LayoutOf<Ty=Ty, TyAndLayout: MaybeResult<Self>>`
- /// to allow recursion (see `might_permit_zero_init` below for an example).
- pub fn field<C>(self, cx: &C, i: usize) -> C::TyAndLayout
+ pub fn field<C>(self, cx: &C, i: usize) -> Self
where
- Ty: TyAndLayoutMethods<'a, C>,
- C: LayoutOf<Ty = Ty>,
+ Ty: TyAbiInterface<'a, C>,
{
- Ty::field(self, cx, i)
+ Ty::ty_and_layout_field(self, cx, i)
}
pub fn pointee_info_at<C>(self, cx: &C, offset: Size) -> Option<PointeeInfo>
where
- Ty: TyAndLayoutMethods<'a, C>,
- C: LayoutOf<Ty = Ty>,
+ Ty: TyAbiInterface<'a, C>,
{
- Ty::pointee_info_at(self, cx, offset)
+ Ty::ty_and_layout_pointee_info_at(self, cx, offset)
}
}
@@ -1187,17 +1299,16 @@
/// FIXME: Once we removed all the conservatism, we could alternatively
/// create an all-0/all-undef constant and run the const value validator to see if
/// this is a valid value for the given type.
- pub fn might_permit_raw_init<C, E>(self, cx: &C, zero: bool) -> Result<bool, E>
+ pub fn might_permit_raw_init<C>(self, cx: &C, zero: bool) -> bool
where
Self: Copy,
- Ty: TyAndLayoutMethods<'a, C>,
- C: LayoutOf<Ty = Ty, TyAndLayout: MaybeResult<Self, Error = E>> + HasDataLayout,
+ Ty: TyAbiInterface<'a, C>,
+ C: HasDataLayout,
{
let scalar_allows_raw_init = move |s: &Scalar| -> bool {
if zero {
- let range = &s.valid_range;
// The range must contain 0.
- range.contains(&0) || (*range.start() > *range.end()) // wrap-around allows 0
+ s.valid_range.contains_zero()
} else {
// The range must include all values. `valid_range_exclusive` handles
// the wrap-around using target arithmetic; with wrap-around then the full
@@ -1217,7 +1328,7 @@
};
if !valid {
// This is definitely not okay.
- return Ok(false);
+ return false;
}
// If we have not found an error yet, we need to recursively descend into fields.
@@ -1228,16 +1339,15 @@
}
FieldsShape::Arbitrary { offsets, .. } => {
for idx in 0..offsets.len() {
- let field = self.field(cx, idx).to_result()?;
- if !field.might_permit_raw_init(cx, zero)? {
+ if !self.field(cx, idx).might_permit_raw_init(cx, zero) {
// We found a field that is unhappy with this kind of initialization.
- return Ok(false);
+ return false;
}
}
}
}
// FIXME(#66151): For now, we are conservative and do not check `self.variants`.
- Ok(true)
+ true
}
}
diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs
index b52fa5b..99699c5 100644
--- a/compiler/rustc_target/src/asm/mod.rs
+++ b/compiler/rustc_target/src/asm/mod.rs
@@ -154,6 +154,7 @@
mod nvptx;
mod powerpc;
mod riscv;
+mod s390x;
mod spirv;
mod wasm;
mod x86;
@@ -166,6 +167,7 @@
pub use nvptx::{NvptxInlineAsmReg, NvptxInlineAsmRegClass};
pub use powerpc::{PowerPCInlineAsmReg, PowerPCInlineAsmRegClass};
pub use riscv::{RiscVInlineAsmReg, RiscVInlineAsmRegClass};
+pub use s390x::{S390xInlineAsmReg, S390xInlineAsmRegClass};
pub use spirv::{SpirVInlineAsmReg, SpirVInlineAsmRegClass};
pub use wasm::{WasmInlineAsmReg, WasmInlineAsmRegClass};
pub use x86::{X86InlineAsmReg, X86InlineAsmRegClass};
@@ -184,6 +186,7 @@
Mips64,
PowerPC,
PowerPC64,
+ S390x,
SpirV,
Wasm32,
Bpf,
@@ -206,6 +209,7 @@
"hexagon" => Ok(Self::Hexagon),
"mips" => Ok(Self::Mips),
"mips64" => Ok(Self::Mips64),
+ "s390x" => Ok(Self::S390x),
"spirv" => Ok(Self::SpirV),
"wasm32" => Ok(Self::Wasm32),
"bpf" => Ok(Self::Bpf),
@@ -235,6 +239,7 @@
PowerPC(PowerPCInlineAsmReg),
Hexagon(HexagonInlineAsmReg),
Mips(MipsInlineAsmReg),
+ S390x(S390xInlineAsmReg),
SpirV(SpirVInlineAsmReg),
Wasm(WasmInlineAsmReg),
Bpf(BpfInlineAsmReg),
@@ -252,6 +257,7 @@
Self::PowerPC(r) => r.name(),
Self::Hexagon(r) => r.name(),
Self::Mips(r) => r.name(),
+ Self::S390x(r) => r.name(),
Self::Bpf(r) => r.name(),
Self::Err => "<reg>",
}
@@ -266,6 +272,7 @@
Self::PowerPC(r) => InlineAsmRegClass::PowerPC(r.reg_class()),
Self::Hexagon(r) => InlineAsmRegClass::Hexagon(r.reg_class()),
Self::Mips(r) => InlineAsmRegClass::Mips(r.reg_class()),
+ Self::S390x(r) => InlineAsmRegClass::S390x(r.reg_class()),
Self::Bpf(r) => InlineAsmRegClass::Bpf(r.reg_class()),
Self::Err => InlineAsmRegClass::Err,
}
@@ -305,6 +312,9 @@
InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
Self::Mips(MipsInlineAsmReg::parse(arch, has_feature, target, &name)?)
}
+ InlineAsmArch::S390x => {
+ Self::S390x(S390xInlineAsmReg::parse(arch, has_feature, target, &name)?)
+ }
InlineAsmArch::SpirV => {
Self::SpirV(SpirVInlineAsmReg::parse(arch, has_feature, target, &name)?)
}
@@ -333,6 +343,7 @@
Self::PowerPC(r) => r.emit(out, arch, modifier),
Self::Hexagon(r) => r.emit(out, arch, modifier),
Self::Mips(r) => r.emit(out, arch, modifier),
+ Self::S390x(r) => r.emit(out, arch, modifier),
Self::Bpf(r) => r.emit(out, arch, modifier),
Self::Err => unreachable!("Use of InlineAsmReg::Err"),
}
@@ -344,9 +355,10 @@
Self::Arm(r) => r.overlapping_regs(|r| cb(Self::Arm(r))),
Self::AArch64(_) => cb(self),
Self::RiscV(_) => cb(self),
- Self::PowerPC(_) => cb(self),
+ Self::PowerPC(r) => r.overlapping_regs(|r| cb(Self::PowerPC(r))),
Self::Hexagon(r) => r.overlapping_regs(|r| cb(Self::Hexagon(r))),
Self::Mips(_) => cb(self),
+ Self::S390x(_) => cb(self),
Self::Bpf(r) => r.overlapping_regs(|r| cb(Self::Bpf(r))),
Self::Err => unreachable!("Use of InlineAsmReg::Err"),
}
@@ -374,6 +386,7 @@
PowerPC(PowerPCInlineAsmRegClass),
Hexagon(HexagonInlineAsmRegClass),
Mips(MipsInlineAsmRegClass),
+ S390x(S390xInlineAsmRegClass),
SpirV(SpirVInlineAsmRegClass),
Wasm(WasmInlineAsmRegClass),
Bpf(BpfInlineAsmRegClass),
@@ -392,6 +405,7 @@
Self::PowerPC(r) => r.name(),
Self::Hexagon(r) => r.name(),
Self::Mips(r) => r.name(),
+ Self::S390x(r) => r.name(),
Self::SpirV(r) => r.name(),
Self::Wasm(r) => r.name(),
Self::Bpf(r) => r.name(),
@@ -412,6 +426,7 @@
Self::PowerPC(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::PowerPC),
Self::Hexagon(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Hexagon),
Self::Mips(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Mips),
+ Self::S390x(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::S390x),
Self::SpirV(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::SpirV),
Self::Wasm(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Wasm),
Self::Bpf(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Bpf),
@@ -439,6 +454,7 @@
Self::PowerPC(r) => r.suggest_modifier(arch, ty),
Self::Hexagon(r) => r.suggest_modifier(arch, ty),
Self::Mips(r) => r.suggest_modifier(arch, ty),
+ Self::S390x(r) => r.suggest_modifier(arch, ty),
Self::SpirV(r) => r.suggest_modifier(arch, ty),
Self::Wasm(r) => r.suggest_modifier(arch, ty),
Self::Bpf(r) => r.suggest_modifier(arch, ty),
@@ -462,6 +478,7 @@
Self::PowerPC(r) => r.default_modifier(arch),
Self::Hexagon(r) => r.default_modifier(arch),
Self::Mips(r) => r.default_modifier(arch),
+ Self::S390x(r) => r.default_modifier(arch),
Self::SpirV(r) => r.default_modifier(arch),
Self::Wasm(r) => r.default_modifier(arch),
Self::Bpf(r) => r.default_modifier(arch),
@@ -469,7 +486,7 @@
}
}
- /// Returns a list of supported types for this register class, each with a
+ /// Returns a list of supported types for this register class, each with an
/// options target feature required to use this type.
pub fn supported_types(
self,
@@ -484,6 +501,7 @@
Self::PowerPC(r) => r.supported_types(arch),
Self::Hexagon(r) => r.supported_types(arch),
Self::Mips(r) => r.supported_types(arch),
+ Self::S390x(r) => r.supported_types(arch),
Self::SpirV(r) => r.supported_types(arch),
Self::Wasm(r) => r.supported_types(arch),
Self::Bpf(r) => r.supported_types(arch),
@@ -509,6 +527,7 @@
InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
Self::Mips(MipsInlineAsmRegClass::parse(arch, name)?)
}
+ InlineAsmArch::S390x => Self::S390x(S390xInlineAsmRegClass::parse(arch, name)?),
InlineAsmArch::SpirV => Self::SpirV(SpirVInlineAsmRegClass::parse(arch, name)?),
InlineAsmArch::Wasm32 => Self::Wasm(WasmInlineAsmRegClass::parse(arch, name)?),
InlineAsmArch::Bpf => Self::Bpf(BpfInlineAsmRegClass::parse(arch, name)?),
@@ -527,6 +546,7 @@
Self::PowerPC(r) => r.valid_modifiers(arch),
Self::Hexagon(r) => r.valid_modifiers(arch),
Self::Mips(r) => r.valid_modifiers(arch),
+ Self::S390x(r) => r.valid_modifiers(arch),
Self::SpirV(r) => r.valid_modifiers(arch),
Self::Wasm(r) => r.valid_modifiers(arch),
Self::Bpf(r) => r.valid_modifiers(arch),
@@ -695,6 +715,11 @@
mips::fill_reg_map(arch, has_feature, target, &mut map);
map
}
+ InlineAsmArch::S390x => {
+ let mut map = s390x::regclass_map();
+ s390x::fill_reg_map(arch, has_feature, target, &mut map);
+ map
+ }
InlineAsmArch::SpirV => {
let mut map = spirv::regclass_map();
spirv::fill_reg_map(arch, has_feature, target, &mut map);
@@ -712,3 +737,185 @@
}
}
}
+
+#[derive(
+ Copy,
+ Clone,
+ Encodable,
+ Decodable,
+ Debug,
+ Eq,
+ PartialEq,
+ PartialOrd,
+ Hash,
+ HashStable_Generic
+)]
+pub enum InlineAsmClobberAbi {
+ X86,
+ X86_64Win,
+ X86_64SysV,
+ Arm,
+ AArch64,
+ RiscV,
+}
+
+impl InlineAsmClobberAbi {
+ /// Parses a clobber ABI for the given target, or returns a list of supported
+ /// clobber ABIs for the target.
+ pub fn parse(
+ arch: InlineAsmArch,
+ target: &Target,
+ name: Symbol,
+ ) -> Result<Self, &'static [&'static str]> {
+ let name = &*name.as_str();
+ match arch {
+ InlineAsmArch::X86 => match name {
+ "C" | "system" | "efiapi" | "cdecl" | "stdcall" | "fastcall" => {
+ Ok(InlineAsmClobberAbi::X86)
+ }
+ _ => Err(&["C", "system", "efiapi", "cdecl", "stdcall", "fastcall"]),
+ },
+ InlineAsmArch::X86_64 => match name {
+ "C" | "system" if !target.is_like_windows => Ok(InlineAsmClobberAbi::X86_64SysV),
+ "C" | "system" if target.is_like_windows => Ok(InlineAsmClobberAbi::X86_64Win),
+ "win64" | "efiapi" => Ok(InlineAsmClobberAbi::X86_64Win),
+ "sysv64" => Ok(InlineAsmClobberAbi::X86_64SysV),
+ _ => Err(&["C", "system", "efiapi", "win64", "sysv64"]),
+ },
+ InlineAsmArch::Arm => match name {
+ "C" | "system" | "efiapi" | "aapcs" => Ok(InlineAsmClobberAbi::Arm),
+ _ => Err(&["C", "system", "efiapi", "aapcs"]),
+ },
+ InlineAsmArch::AArch64 => match name {
+ "C" | "system" | "efiapi" => Ok(InlineAsmClobberAbi::AArch64),
+ _ => Err(&["C", "system", "efiapi"]),
+ },
+ InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => match name {
+ "C" | "system" | "efiapi" => Ok(InlineAsmClobberAbi::RiscV),
+ _ => Err(&["C", "system", "efiapi"]),
+ },
+ _ => Err(&[]),
+ }
+ }
+
+ /// Returns the set of registers which are clobbered by this ABI.
+ pub fn clobbered_regs(self) -> &'static [InlineAsmReg] {
+ macro_rules! clobbered_regs {
+ ($arch:ident $arch_reg:ident {
+ $(
+ $reg:ident,
+ )*
+ }) => {
+ &[
+ $(InlineAsmReg::$arch($arch_reg::$reg),)*
+ ]
+ };
+ }
+ match self {
+ InlineAsmClobberAbi::X86 => clobbered_regs! {
+ X86 X86InlineAsmReg {
+ ax, cx, dx,
+
+ xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
+
+ k1, k2, k3, k4, k5, k6, k7,
+
+ mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7,
+ st0, st1, st2, st3, st4, st5, st6, st7,
+ }
+ },
+ InlineAsmClobberAbi::X86_64SysV => clobbered_regs! {
+ X86 X86InlineAsmReg {
+ ax, cx, dx, si, di, r8, r9, r10, r11,
+
+ xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
+ xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
+ zmm16, zmm17, zmm18, zmm19, zmm20, zmm21, zmm22, zmm23,
+ zmm24, zmm25, zmm26, zmm27, zmm28, zmm29, zmm30, zmm31,
+
+ k1, k2, k3, k4, k5, k6, k7,
+
+ mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7,
+ st0, st1, st2, st3, st4, st5, st6, st7,
+ }
+ },
+ InlineAsmClobberAbi::X86_64Win => clobbered_regs! {
+ X86 X86InlineAsmReg {
+ // rdi and rsi are callee-saved on windows
+ ax, cx, dx, r8, r9, r10, r11,
+
+ // xmm6-xmm15 are callee-saved on windows, but we need to
+ // mark them as clobbered anyways because the upper portions
+ // of ymm6-ymm15 are volatile.
+ xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
+ xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
+ zmm16, zmm17, zmm18, zmm19, zmm20, zmm21, zmm22, zmm23,
+ zmm24, zmm25, zmm26, zmm27, zmm28, zmm29, zmm30, zmm31,
+
+ k1, k2, k3, k4, k5, k6, k7,
+
+ mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7,
+ st0, st1, st2, st3, st4, st5, st6, st7,
+ }
+ },
+ InlineAsmClobberAbi::AArch64 => clobbered_regs! {
+ AArch64 AArch64InlineAsmReg {
+ x0, x1, x2, x3, x4, x5, x6, x7,
+ x8, x9, x10, x11, x12, x13, x14, x15,
+ // x18 is platform-reserved or temporary, but we exclude it
+ // here since it is a reserved register.
+ x16, x17, x30,
+
+ // Technically the low 64 bits of v8-v15 are preserved, but
+ // we have no way of expressing this using clobbers.
+ v0, v1, v2, v3, v4, v5, v6, v7,
+ v8, v9, v10, v11, v12, v13, v14, v15,
+ v16, v17, v18, v19, v20, v21, v22, v23,
+ v24, v25, v26, v27, v28, v29, v30, v31,
+
+ p0, p1, p2, p3, p4, p5, p6, p7,
+ p8, p9, p10, p11, p12, p13, p14, p15,
+ ffr,
+
+ }
+ },
+ InlineAsmClobberAbi::Arm => clobbered_regs! {
+ Arm ArmInlineAsmReg {
+ // r9 is platform-reserved and is treated as callee-saved.
+ r0, r1, r2, r3, r12, r14,
+
+ // The finest-grained register variant is used here so that
+ // partial uses of larger registers are properly handled.
+ s0, s1, s2, s3, s4, s5, s6, s7,
+ s8, s9, s10, s11, s12, s13, s14, s15,
+ // s16-s31 are callee-saved
+ d16, d17, d18, d19, d20, d21, d22, d23,
+ d24, d25, d26, d27, d28, d29, d30, d31,
+ }
+ },
+ InlineAsmClobberAbi::RiscV => clobbered_regs! {
+ RiscV RiscVInlineAsmReg {
+ // ra
+ x1,
+ // t0-t2
+ x5, x6, x7,
+ // a0-a7
+ x10, x11, x12, x13, x14, x15, x16, x17,
+ // t3-t6
+ x28, x29, x30, x31,
+ // ft0-ft7
+ f0, f1, f2, f3, f4, f5, f6, f7,
+ // fa0-fa7
+ f10, f11, f12, f13, f14, f15, f16, f17,
+ // ft8-ft11
+ f28, f29, f30, f31,
+
+ v0, v1, v2, v3, v4, v5, v6, v7,
+ v8, v9, v10, v11, v12, v13, v14, v15,
+ v16, v17, v18, v19, v20, v21, v22, v23,
+ v24, v25, v26, v27, v28, v29, v30, v31,
+ }
+ },
+ }
+ }
+}
diff --git a/compiler/rustc_target/src/asm/powerpc.rs b/compiler/rustc_target/src/asm/powerpc.rs
index 42fc25c..51a4303 100644
--- a/compiler/rustc_target/src/asm/powerpc.rs
+++ b/compiler/rustc_target/src/asm/powerpc.rs
@@ -7,6 +7,8 @@
reg,
reg_nonzero,
freg,
+ cr,
+ xer,
}
}
@@ -44,6 +46,7 @@
}
}
Self::freg => types! { _: F32, F64; },
+ Self::cr | Self::xer => &[],
}
}
}
@@ -108,6 +111,16 @@
f29: freg = ["f29", "fr29"],
f30: freg = ["f30", "fr30"],
f31: freg = ["f31", "fr31"],
+ cr: cr = ["cr"],
+ cr0: cr = ["cr0"],
+ cr1: cr = ["cr1"],
+ cr2: cr = ["cr2"],
+ cr3: cr = ["cr3"],
+ cr4: cr = ["cr4"],
+ cr5: cr = ["cr5"],
+ cr6: cr = ["cr6"],
+ cr7: cr = ["cr7"],
+ xer: xer = ["xer"],
#error = ["r1", "1", "sp"] =>
"the stack pointer cannot be used as an operand for inline asm",
#error = ["r2", "2"] =>
@@ -136,17 +149,55 @@
_arch: InlineAsmArch,
_modifier: Option<char>,
) -> fmt::Result {
+ macro_rules! do_emit {
+ (
+ $($(($reg:ident, $value:literal)),*;)*
+ ) => {
+ out.write_str(match self {
+ $($(Self::$reg => $value,)*)*
+ })
+ };
+ }
// Strip off the leading prefix.
- if self as u32 <= Self::r28 as u32 {
- let index = self as u32 - Self::r28 as u32;
- write!(out, "{}", index)
- } else if self as u32 >= Self::f0 as u32 && self as u32 <= Self::f31 as u32 {
- let index = self as u32 - Self::f31 as u32;
- write!(out, "{}", index)
- } else {
- unreachable!()
+ do_emit! {
+ (r0, "0"), (r3, "3"), (r4, "4"), (r5, "5"), (r6, "6"), (r7, "7");
+ (r8, "8"), (r9, "9"), (r10, "10"), (r11, "11"), (r12, "12"), (r14, "14"), (r15, "15");
+ (r16, "16"), (r17, "17"), (r18, "18"), (r19, "19"), (r20, "20"), (r21, "21"), (r22, "22"), (r23, "23");
+ (r24, "24"), (r25, "25"), (r26, "26"), (r27, "27"), (r28, "28");
+ (f0, "0"), (f1, "1"), (f2, "2"), (f3, "3"), (f4, "4"), (f5, "5"), (f6, "6"), (f7, "7");
+ (f8, "8"), (f9, "9"), (f10, "10"), (f11, "11"), (f12, "12"), (f13, "13"), (f14, "14"), (f15, "15");
+ (f16, "16"), (f17, "17"), (f18, "18"), (f19, "19"), (f20, "20"), (f21, "21"), (f22, "22"), (f23, "23");
+ (f24, "24"), (f25, "25"), (f26, "26"), (f27, "27"), (f28, "28"), (f29, "29"), (f30, "30"), (f31, "31");
+ (cr, "cr");
+ (cr0, "0"), (cr1, "1"), (cr2, "2"), (cr3, "3"), (cr4, "4"), (cr5, "5"), (cr6, "6"), (cr7, "7");
+ (xer, "xer");
}
}
- pub fn overlapping_regs(self, mut _cb: impl FnMut(PowerPCInlineAsmReg)) {}
+ pub fn overlapping_regs(self, mut cb: impl FnMut(PowerPCInlineAsmReg)) {
+ macro_rules! reg_conflicts {
+ (
+ $(
+ $full:ident : $($field:ident)*
+ ),*;
+ ) => {
+ match self {
+ $(
+ Self::$full => {
+ cb(Self::$full);
+ $(cb(Self::$field);)*
+ }
+ $(Self::$field)|* => {
+ cb(Self::$full);
+ cb(self);
+ }
+ )*
+ r => cb(r),
+ }
+ };
+ }
+ reg_conflicts! {
+ cr : cr0 cr1 cr2 cr3 cr4 cr5 cr6 cr7;
+ }
+ }
}
diff --git a/compiler/rustc_target/src/asm/s390x.rs b/compiler/rustc_target/src/asm/s390x.rs
new file mode 100644
index 0000000..a74873f
--- /dev/null
+++ b/compiler/rustc_target/src/asm/s390x.rs
@@ -0,0 +1,106 @@
+use super::{InlineAsmArch, InlineAsmType};
+use rustc_macros::HashStable_Generic;
+use std::fmt;
+
+def_reg_class! {
+ S390x S390xInlineAsmRegClass {
+ reg,
+ freg,
+ }
+}
+
+impl S390xInlineAsmRegClass {
+ pub fn valid_modifiers(self, _arch: super::InlineAsmArch) -> &'static [char] {
+ &[]
+ }
+
+ pub fn suggest_class(self, _arch: InlineAsmArch, _ty: InlineAsmType) -> Option<Self> {
+ None
+ }
+
+ pub fn suggest_modifier(
+ self,
+ _arch: InlineAsmArch,
+ _ty: InlineAsmType,
+ ) -> Option<(char, &'static str)> {
+ None
+ }
+
+ pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
+ None
+ }
+
+ pub fn supported_types(
+ self,
+ arch: InlineAsmArch,
+ ) -> &'static [(InlineAsmType, Option<&'static str>)] {
+ match (self, arch) {
+ (Self::reg, _) => types! { _: I8, I16, I32, I64; },
+ (Self::freg, _) => types! { _: F32, F64; },
+ }
+ }
+}
+
+def_regs! {
+ S390x S390xInlineAsmReg S390xInlineAsmRegClass {
+ r0: reg = ["r0"],
+ r1: reg = ["r1"],
+ r2: reg = ["r2"],
+ r3: reg = ["r3"],
+ r4: reg = ["r4"],
+ r5: reg = ["r5"],
+ r6: reg = ["r6"],
+ r7: reg = ["r7"],
+ r8: reg = ["r8"],
+ r9: reg = ["r9"],
+ r10: reg = ["r10"],
+ r12: reg = ["r12"],
+ r13: reg = ["r13"],
+ r14: reg = ["r14"],
+ f0: freg = ["f0"],
+ f1: freg = ["f1"],
+ f2: freg = ["f2"],
+ f3: freg = ["f3"],
+ f4: freg = ["f4"],
+ f5: freg = ["f5"],
+ f6: freg = ["f6"],
+ f7: freg = ["f7"],
+ f8: freg = ["f8"],
+ f9: freg = ["f9"],
+ f10: freg = ["f10"],
+ f11: freg = ["f11"],
+ f12: freg = ["f12"],
+ f13: freg = ["f13"],
+ f14: freg = ["f14"],
+ f15: freg = ["f15"],
+ #error = ["r11"] =>
+ "The frame pointer cannot be used as an operand for inline asm",
+ #error = ["r15"] =>
+ "The stack pointer cannot be used as an operand for inline asm",
+ #error = [
+ "c0", "c1", "c2", "c3",
+ "c4", "c5", "c6", "c7",
+ "c8", "c9", "c10", "c11",
+ "c12", "c13", "c14", "c15"
+ ] =>
+ "control registers are reserved by the kernel and cannot be used as operands for inline asm",
+ #error = [
+ "a0", "a1", "a2", "a3",
+ "a4", "a5", "a6", "a7",
+ "a8", "a9", "a10", "a11",
+ "a12", "a13", "a14", "a15"
+ ] =>
+ "access registers are not supported and cannot be used as operands for inline asm",
+ }
+}
+
+impl S390xInlineAsmReg {
+ pub fn emit(
+ self,
+ out: &mut dyn fmt::Write,
+ _arch: InlineAsmArch,
+ _modifier: Option<char>,
+ ) -> fmt::Result {
+ write!(out, "%{}", self.name())
+ }
+}
diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs
index d39e5a5..e75c525 100644
--- a/compiler/rustc_target/src/lib.rs
+++ b/compiler/rustc_target/src/lib.rs
@@ -14,6 +14,8 @@
#![feature(associated_type_bounds)]
#![feature(exhaustive_patterns)]
#![feature(min_specialization)]
+#![feature(step_trait)]
+#![feature(unchecked_math)]
use std::path::{Path, PathBuf};
diff --git a/compiler/rustc_target/src/spec/aarch64_apple_ios.rs b/compiler/rustc_target/src/spec/aarch64_apple_ios.rs
index e5805d9..6468419 100644
--- a/compiler/rustc_target/src/spec/aarch64_apple_ios.rs
+++ b/compiler/rustc_target/src/spec/aarch64_apple_ios.rs
@@ -2,8 +2,15 @@
use crate::spec::{FramePointer, Target, TargetOptions};
pub fn target() -> Target {
+ // Clang automatically chooses a more specific target based on
+ // IPHONEOS_DEPLOYMENT_TARGET.
+ // This is required for the target to pick the right
+ // MACH-O commands, so we do too.
+ let arch = "arm64";
+ let llvm_target = super::apple_base::ios_llvm_target(arch);
+
Target {
- llvm_target: "arm64-apple-ios".to_string(),
+ llvm_target,
pointer_width: 64,
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".to_string(),
arch: "aarch64".to_string(),
diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/aarch64_unknown_freebsd.rs
index 09ea7d3..0caecd2 100644
--- a/compiler/rustc_target/src/spec/aarch64_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/aarch64_unknown_freebsd.rs
@@ -1,4 +1,4 @@
-use crate::spec::{Target, TargetOptions};
+use crate::spec::{SanitizerSet, Target, TargetOptions};
pub fn target() -> Target {
Target {
@@ -6,6 +6,12 @@
pointer_width: 64,
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
arch: "aarch64".to_string(),
- options: TargetOptions { max_atomic_width: Some(128), ..super::freebsd_base::opts() },
+ options: TargetOptions {
+ max_atomic_width: Some(128),
+ supported_sanitizers: SanitizerSet::ADDRESS
+ | SanitizerSet::MEMORY
+ | SanitizerSet::THREAD,
+ ..super::freebsd_base::opts()
+ },
}
}
diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_uefi.rs b/compiler/rustc_target/src/spec/aarch64_unknown_uefi.rs
new file mode 100644
index 0000000..20c528d
--- /dev/null
+++ b/compiler/rustc_target/src/spec/aarch64_unknown_uefi.rs
@@ -0,0 +1,27 @@
+// This defines the aarch64 target for UEFI systems as described in the UEFI specification. See the
+// uefi-base module for generic UEFI options.
+
+use super::uefi_msvc_base;
+use crate::spec::{LinkerFlavor, LldFlavor, Target};
+
+pub fn target() -> Target {
+ let mut base = uefi_msvc_base::opts();
+
+ base.max_atomic_width = Some(64);
+
+ let pre_link_args_msvc = vec!["/machine:arm64".to_string()];
+
+ base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().extend(pre_link_args_msvc.clone());
+ base.pre_link_args
+ .get_mut(&LinkerFlavor::Lld(LldFlavor::Link))
+ .unwrap()
+ .extend(pre_link_args_msvc);
+
+ Target {
+ llvm_target: "aarch64-unknown-windows".to_string(),
+ pointer_width: 64,
+ data_layout: "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128".to_string(),
+ arch: "aarch64".to_string(),
+ options: base,
+ }
+}
diff --git a/compiler/rustc_target/src/spec/abi.rs b/compiler/rustc_target/src/spec/abi.rs
index ee36090..e3a2226 100644
--- a/compiler/rustc_target/src/spec/abi.rs
+++ b/compiler/rustc_target/src/spec/abi.rs
@@ -87,6 +87,9 @@
}
impl Abi {
+ /// Default ABI chosen for `extern fn` declarations without an explicit ABI.
+ pub const FALLBACK: Abi = Abi::C { unwind: false };
+
#[inline]
pub fn index(self) -> usize {
// N.B., this ordering MUST match the AbiDatas array above.
diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs
index 0c8a892..a21b784 100644
--- a/compiler/rustc_target/src/spec/apple_base.rs
+++ b/compiler/rustc_target/src/spec/apple_base.rs
@@ -1,6 +1,6 @@
use std::env;
-use crate::spec::{FramePointer, SplitDebuginfo, TargetOptions};
+use crate::spec::{FramePointer, LldFlavor, SplitDebuginfo, TargetOptions};
pub fn opts(os: &str) -> TargetOptions {
// ELF TLS is only available in macOS 10.7+. If you try to compile for 10.6
@@ -35,6 +35,7 @@
abi_return_struct_as_int: true,
emit_debug_gdb_scripts: false,
eh_frame_header: false,
+ lld_flavor: LldFlavor::Ld64,
// The historical default for macOS targets is to run `dsymutil` which
// generates a packed version of debuginfo split from the main file.
@@ -91,6 +92,17 @@
deployment_target("IPHONEOS_DEPLOYMENT_TARGET").unwrap_or((7, 0))
}
+pub fn ios_llvm_target(arch: &str) -> String {
+ // Modern iOS tooling extracts information about deployment target
+ // from LC_BUILD_VERSION. This load command will only be emitted when
+ // we build with a version specific `llvm_target`, with the version
+ // set high enough. Luckily one LC_BUILD_VERSION is enough, for Xcode
+ // to pick it up (since std and core are still built with the fallback
+ // of version 7.0 and hence emit the old LC_IPHONE_MIN_VERSION).
+ let (major, minor) = ios_deployment_target();
+ format!("{}-apple-ios{}.{}.0", arch, major, minor)
+}
+
pub fn ios_sim_llvm_target(arch: &str) -> String {
let (major, minor) = ios_deployment_target();
format!("{}-apple-ios{}.{}.0-simulator", arch, major, minor)
diff --git a/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs b/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs
index c98a12c..ed4779c 100644
--- a/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs
@@ -20,6 +20,8 @@
panic_strategy: PanicStrategy::Abort,
max_atomic_width: Some(32),
emit_debug_gdb_scripts: false,
+ // GCC and Clang default to 8 for arm-none here
+ c_enum_min_bits: 8,
..Default::default()
},
}
diff --git a/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs
index 2926354..b60e289 100644
--- a/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs
+++ b/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs
@@ -21,6 +21,8 @@
features: "+vfp3,-d32,-fp16".to_string(),
max_atomic_width: Some(32),
emit_debug_gdb_scripts: false,
+ // GCC and Clang default to 8 for arm-none here
+ c_enum_min_bits: 8,
..Default::default()
},
}
diff --git a/compiler/rustc_target/src/spec/armv7_apple_ios.rs b/compiler/rustc_target/src/spec/armv7_apple_ios.rs
index 2f22868..1f90c78 100644
--- a/compiler/rustc_target/src/spec/armv7_apple_ios.rs
+++ b/compiler/rustc_target/src/spec/armv7_apple_ios.rs
@@ -3,7 +3,7 @@
pub fn target() -> Target {
Target {
- llvm_target: "armv7-apple-ios".to_string(),
+ llvm_target: super::apple_base::ios_llvm_target("armv7"),
pointer_width: 32,
data_layout: "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32".to_string(),
arch: "arm".to_string(),
diff --git a/compiler/rustc_target/src/spec/armv7a_none_eabi.rs b/compiler/rustc_target/src/spec/armv7a_none_eabi.rs
index 8bff60e..88040f4 100644
--- a/compiler/rustc_target/src/spec/armv7a_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/armv7a_none_eabi.rs
@@ -28,6 +28,7 @@
max_atomic_width: Some(64),
panic_strategy: PanicStrategy::Abort,
emit_debug_gdb_scripts: false,
+ c_enum_min_bits: 8,
..Default::default()
};
Target {
diff --git a/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs b/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs
index ea2751e..af32484 100644
--- a/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs
+++ b/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs
@@ -19,6 +19,8 @@
max_atomic_width: Some(64),
panic_strategy: PanicStrategy::Abort,
emit_debug_gdb_scripts: false,
+ // GCC and Clang default to 8 for arm-none here
+ c_enum_min_bits: 8,
..Default::default()
};
Target {
diff --git a/compiler/rustc_target/src/spec/armv7r_none_eabi.rs b/compiler/rustc_target/src/spec/armv7r_none_eabi.rs
index c695542..c0e9709 100644
--- a/compiler/rustc_target/src/spec/armv7r_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/armv7r_none_eabi.rs
@@ -19,6 +19,8 @@
panic_strategy: PanicStrategy::Abort,
max_atomic_width: Some(32),
emit_debug_gdb_scripts: false,
+ // GCC and Clang default to 8 for arm-none here
+ c_enum_min_bits: 8,
..Default::default()
},
}
diff --git a/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs
index 50c3702..b126887 100644
--- a/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs
+++ b/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs
@@ -20,6 +20,8 @@
features: "+vfp3,-d32,-fp16".to_string(),
max_atomic_width: Some(32),
emit_debug_gdb_scripts: false,
+ // GCC and Clang default to 8 for arm-none here
+ c_enum_min_bits: 8,
..Default::default()
},
}
diff --git a/compiler/rustc_target/src/spec/freebsd_base.rs b/compiler/rustc_target/src/spec/freebsd_base.rs
index 998d6ff..f2ec6aa 100644
--- a/compiler/rustc_target/src/spec/freebsd_base.rs
+++ b/compiler/rustc_target/src/spec/freebsd_base.rs
@@ -1,4 +1,4 @@
-use crate::spec::{FramePointer, RelroLevel, TargetOptions};
+use crate::spec::{RelroLevel, TargetOptions};
pub fn opts() -> TargetOptions {
TargetOptions {
@@ -8,7 +8,6 @@
families: vec!["unix".to_string()],
has_rpath: true,
position_independent_executables: true,
- frame_pointer: FramePointer::Always, // FIXME 43575: should be MayOmit...
relro_level: RelroLevel::Full,
abi_return_struct_as_int: true,
dwarf_version: Some(2),
diff --git a/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs
index e0097ee..27d306c 100644
--- a/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs
@@ -13,6 +13,8 @@
base.dynamic_linking = true;
base.executables = true;
+ base.c_enum_min_bits = 8;
+
Target {
llvm_target: "hexagon-unknown-linux-musl".to_string(),
pointer_width: 32,
diff --git a/compiler/rustc_target/src/spec/i386_apple_ios.rs b/compiler/rustc_target/src/spec/i386_apple_ios.rs
index f5d7be4..4419dfe 100644
--- a/compiler/rustc_target/src/spec/i386_apple_ios.rs
+++ b/compiler/rustc_target/src/spec/i386_apple_ios.rs
@@ -4,7 +4,7 @@
pub fn target() -> Target {
let base = opts("ios", Arch::I386);
Target {
- llvm_target: "i386-apple-ios".to_string(),
+ llvm_target: super::apple_base::ios_sim_llvm_target("i386"),
pointer_width: 32,
data_layout: "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-\
f64:32:64-f80:128-n8:16:32-S128"
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 0185132..27322136 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -664,7 +664,7 @@
self.into_iter()
.map(|v| Some(v.as_str()?.to_json()))
.collect::<Option<Vec<_>>>()
- .unwrap_or(Vec::new())
+ .unwrap_or_default()
.to_json()
}
}
@@ -802,6 +802,7 @@
("armv6-unknown-freebsd", armv6_unknown_freebsd),
("armv7-unknown-freebsd", armv7_unknown_freebsd),
("i686-unknown-freebsd", i686_unknown_freebsd),
+ ("powerpc-unknown-freebsd", powerpc_unknown_freebsd),
("powerpc64-unknown-freebsd", powerpc64_unknown_freebsd),
("powerpc64le-unknown-freebsd", powerpc64le_unknown_freebsd),
("x86_64-unknown-freebsd", x86_64_unknown_freebsd),
@@ -902,6 +903,7 @@
("riscv32i-unknown-none-elf", riscv32i_unknown_none_elf),
("riscv32imc-unknown-none-elf", riscv32imc_unknown_none_elf),
+ ("riscv32imc-esp-espidf", riscv32imc_esp_espidf),
("riscv32imac-unknown-none-elf", riscv32imac_unknown_none_elf),
("riscv32gc-unknown-linux-gnu", riscv32gc_unknown_linux_gnu),
("riscv32gc-unknown-linux-musl", riscv32gc_unknown_linux_musl),
@@ -917,6 +919,7 @@
("x86_64-unknown-uefi", x86_64_unknown_uefi),
("i686-unknown-uefi", i686_unknown_uefi),
+ ("aarch64-unknown-uefi", aarch64_unknown_uefi),
("nvptx64-nvidia-cuda", nvptx64_nvidia_cuda),
@@ -1333,6 +1336,9 @@
/// If present it's a default value to use for adjusting the C ABI.
pub default_adjusted_cabi: Option<Abi>,
+
+ /// Minimum number of bits in #[repr(C)] enum. Defaults to 32.
+ pub c_enum_min_bits: u64,
}
impl Default for TargetOptions {
@@ -1437,6 +1443,7 @@
split_debuginfo: SplitDebuginfo::Off,
supported_sanitizers: SanitizerSet::empty(),
default_adjusted_cabi: None,
+ c_enum_min_bits: 32,
}
}
}
@@ -1494,7 +1501,8 @@
| Cdecl
| EfiApi => true,
X86Interrupt => ["x86", "x86_64"].contains(&&self.arch[..]),
- Aapcs | CCmseNonSecureCall => ["arm", "aarch64"].contains(&&self.arch[..]),
+ Aapcs => "arm" == self.arch,
+ CCmseNonSecureCall => ["arm", "aarch64"].contains(&&self.arch[..]),
Win64 | SysV64 => self.arch == "x86_64",
PtxKernel => self.arch == "nvptx64",
Msp430Interrupt => self.arch == "msp430",
@@ -1601,6 +1609,12 @@
base.$key_name = s;
}
} );
+ ($key_name:ident, u64) => ( {
+ let name = (stringify!($key_name)).replace("_", "-");
+ if let Some(s) = obj.remove_key(&name).and_then(|j| Json::as_u64(&j)) {
+ base.$key_name = s;
+ }
+ } );
($key_name:ident, Option<u32>) => ( {
let name = (stringify!($key_name)).replace("_", "-");
if let Some(s) = obj.remove_key(&name).and_then(|j| Json::as_u64(&j)) {
@@ -2014,10 +2028,11 @@
key!(split_debuginfo, SplitDebuginfo)?;
key!(supported_sanitizers, SanitizerSet)?;
key!(default_adjusted_cabi, Option<Abi>)?;
+ key!(c_enum_min_bits, u64);
if base.is_builtin {
// This can cause unfortunate ICEs later down the line.
- return Err(format!("may not set is_builtin for targets not built-in"));
+ return Err("may not set is_builtin for targets not built-in".to_string());
}
// Each field should have been read using `Json::remove_key` so any keys remaining are unused.
let remaining_keys = obj.as_object().ok_or("Expected JSON object for target")?.keys();
@@ -2252,6 +2267,7 @@
target_option_val!(has_thumb_interworking);
target_option_val!(split_debuginfo);
target_option_val!(supported_sanitizers);
+ target_option_val!(c_enum_min_bits);
if let Some(abi) = self.default_adjusted_cabi {
d.insert("default-adjusted-cabi".to_string(), Abi::name(abi).to_json());
diff --git a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs
index 559a1a4..f10d4d4 100644
--- a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs
@@ -14,7 +14,7 @@
Target {
llvm_target: "powerpc64-unknown-linux-gnu".to_string(),
pointer_width: 64,
- data_layout: "E-m:e-i64:64-n32:64-v256:256:256-v512:512:512".to_string(),
+ data_layout: "E-m:e-i64:64-n32:64-S128-v256:256:256-v512:512:512".to_string(),
arch: "powerpc64".to_string(),
options: TargetOptions { endian: Endian::Big, mcount: "_mcount".to_string(), ..base },
}
diff --git a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs
index f1190b1..6116217 100644
--- a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs
@@ -10,7 +10,7 @@
Target {
llvm_target: "powerpc64-unknown-linux-musl".to_string(),
pointer_width: 64,
- data_layout: "E-m:e-i64:64-n32:64-v256:256:256-v512:512:512".to_string(),
+ data_layout: "E-m:e-i64:64-n32:64-S128-v256:256:256-v512:512:512".to_string(),
arch: "powerpc64".to_string(),
options: TargetOptions { endian: Endian::Big, mcount: "_mcount".to_string(), ..base },
}
diff --git a/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs
index 3ebc546..9c63997 100644
--- a/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs
@@ -10,7 +10,7 @@
Target {
llvm_target: "powerpc64-unknown-linux-gnu".to_string(),
pointer_width: 64,
- data_layout: "E-m:e-i64:64-n32:64-v256:256:256-v512:512:512".to_string(),
+ data_layout: "E-m:e-i64:64-n32:64-S128-v256:256:256-v512:512:512".to_string(),
arch: "powerpc64".to_string(),
options: TargetOptions { endian: Endian::Big, ..base },
}
diff --git a/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs
index 76f70e4..f645ece 100644
--- a/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs
@@ -9,7 +9,7 @@
Target {
llvm_target: "powerpc64le-unknown-linux-gnu".to_string(),
pointer_width: 64,
- data_layout: "e-m:e-i64:64-n32:64-v256:256:256-v512:512:512".to_string(),
+ data_layout: "e-m:e-i64:64-n32:64-S128-v256:256:256-v512:512:512".to_string(),
arch: "powerpc64".to_string(),
options: TargetOptions { mcount: "_mcount".to_string(), ..base },
}
diff --git a/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs
index 42c4910..934371f 100644
--- a/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs
@@ -9,7 +9,7 @@
Target {
llvm_target: "powerpc64le-unknown-linux-musl".to_string(),
pointer_width: 64,
- data_layout: "e-m:e-i64:64-n32:64-v256:256:256-v512:512:512".to_string(),
+ data_layout: "e-m:e-i64:64-n32:64-S128-v256:256:256-v512:512:512".to_string(),
arch: "powerpc64".to_string(),
options: TargetOptions { mcount: "_mcount".to_string(), ..base },
}
diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs b/compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs
new file mode 100644
index 0000000..e113180
--- /dev/null
+++ b/compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs
@@ -0,0 +1,27 @@
+use crate::abi::Endian;
+use crate::spec::{LinkerFlavor, RelocModel, Target, TargetOptions};
+
+pub fn target() -> Target {
+ let mut base = super::freebsd_base::opts();
+ base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".to_string());
+ // Extra hint to linker that we are generating secure-PLT code.
+ base.pre_link_args
+ .entry(LinkerFlavor::Gcc)
+ .or_default()
+ .push("--target=powerpc-unknown-freebsd13.0".to_string());
+ base.max_atomic_width = Some(32);
+
+ Target {
+ llvm_target: "powerpc-unknown-freebsd13.0".to_string(),
+ pointer_width: 32,
+ data_layout: "E-m:e-p:32:32-i64:64-n32".to_string(),
+ arch: "powerpc".to_string(),
+ options: TargetOptions {
+ endian: Endian::Big,
+ features: "+secure-plt".to_string(),
+ relocation_model: RelocModel::Pic,
+ mcount: "_mcount".to_string(),
+ ..base
+ },
+ }
+}
diff --git a/compiler/rustc_target/src/spec/riscv32imc_esp_espidf.rs b/compiler/rustc_target/src/spec/riscv32imc_esp_espidf.rs
new file mode 100644
index 0000000..fb084af
--- /dev/null
+++ b/compiler/rustc_target/src/spec/riscv32imc_esp_espidf.rs
@@ -0,0 +1,37 @@
+use crate::spec::{LinkerFlavor, PanicStrategy, RelocModel};
+use crate::spec::{Target, TargetOptions};
+
+pub fn target() -> Target {
+ Target {
+ data_layout: "e-m:e-p:32:32-i64:64-n32-S128".to_string(),
+ llvm_target: "riscv32".to_string(),
+ pointer_width: 32,
+ arch: "riscv32".to_string(),
+
+ options: TargetOptions {
+ families: vec!["unix".to_string()],
+ os: "espidf".to_string(),
+ env: "newlib".to_string(),
+ vendor: "espressif".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
+ linker: Some("riscv32-esp-elf-gcc".to_string()),
+ cpu: "generic-rv32".to_string(),
+
+ // While the RiscV32IMC architecture does not natively support atomics, ESP-IDF does support
+ // the __atomic* and __sync* GCC builtins, so setting `max_atomic_width` to `Some(32)`
+ // and `atomic_cas` to `true` will cause the compiler to emit libcalls to these builtins.
+ //
+ // Support for atomics is necessary for the Rust STD library, which is supported by the ESP-IDF framework.
+ max_atomic_width: Some(32),
+ atomic_cas: true,
+
+ features: "+m,+c".to_string(),
+ executables: true,
+ panic_strategy: PanicStrategy::Abort,
+ relocation_model: RelocModel::Static,
+ emit_debug_gdb_scripts: false,
+ eh_frame_header: false,
+ ..Default::default()
+ },
+ }
+}
diff --git a/compiler/rustc_target/src/spec/thumb_base.rs b/compiler/rustc_target/src/spec/thumb_base.rs
index bac1203..e2e5285 100644
--- a/compiler/rustc_target/src/spec/thumb_base.rs
+++ b/compiler/rustc_target/src/spec/thumb_base.rs
@@ -53,6 +53,9 @@
// LLVM is eager to trash the link register when calling `noreturn` functions, which
// breaks debugging. Preserve LR by default to prevent that from happening.
frame_pointer: FramePointer::Always,
+ // ARM supports multiple ABIs for enums, the linux one matches the default of 32 here
+ // but any arm-none or thumb-none target will be defaulted to 8 on GCC and clang
+ c_enum_min_bits: 8,
..Default::default()
}
}
diff --git a/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs b/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs
index 3021393..86b1a75 100644
--- a/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs
+++ b/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs
@@ -43,7 +43,7 @@
Target {
llvm_target: "wasm32-unknown-emscripten".to_string(),
pointer_width: 32,
- data_layout: "e-m:e-p:32:32-i64:64-n32:64-S128".to_string(),
+ data_layout: "e-m:e-p:32:32-i64:64-f128:64-n32:64-S128-ni:1:10:20".to_string(),
arch: "wasm32".to_string(),
options: opts,
}
diff --git a/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs b/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs
index 834c4db..134c680 100644
--- a/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs
+++ b/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs
@@ -54,7 +54,7 @@
Target {
llvm_target: "wasm32-unknown-unknown".to_string(),
pointer_width: 32,
- data_layout: "e-m:e-p:32:32-i64:64-n32:64-S128".to_string(),
+ data_layout: "e-m:e-p:32:32-i64:64-n32:64-S128-ni:1:10:20".to_string(),
arch: "wasm32".to_string(),
options,
}
diff --git a/compiler/rustc_target/src/spec/wasm32_wasi.rs b/compiler/rustc_target/src/spec/wasm32_wasi.rs
index a6b12d2..2dab206 100644
--- a/compiler/rustc_target/src/spec/wasm32_wasi.rs
+++ b/compiler/rustc_target/src/spec/wasm32_wasi.rs
@@ -109,7 +109,7 @@
Target {
llvm_target: "wasm32-wasi".to_string(),
pointer_width: 32,
- data_layout: "e-m:e-p:32:32-i64:64-n32:64-S128".to_string(),
+ data_layout: "e-m:e-p:32:32-i64:64-n32:64-S128-ni:1:10:20".to_string(),
arch: "wasm32".to_string(),
options,
}
diff --git a/compiler/rustc_target/src/spec/wasm64_unknown_unknown.rs b/compiler/rustc_target/src/spec/wasm64_unknown_unknown.rs
index 8bfb229..fb6526c 100644
--- a/compiler/rustc_target/src/spec/wasm64_unknown_unknown.rs
+++ b/compiler/rustc_target/src/spec/wasm64_unknown_unknown.rs
@@ -32,7 +32,7 @@
Target {
llvm_target: "wasm64-unknown-unknown".to_string(),
pointer_width: 64,
- data_layout: "e-m:e-p:64:64-i64:64-n32:64-S128".to_string(),
+ data_layout: "e-m:e-p:64:64-i64:64-n32:64-S128-ni:1:10:20".to_string(),
arch: "wasm64".to_string(),
options,
}
diff --git a/compiler/rustc_target/src/spec/x86_64_apple_ios.rs b/compiler/rustc_target/src/spec/x86_64_apple_ios.rs
index adb8771..6e20bd2 100644
--- a/compiler/rustc_target/src/spec/x86_64_apple_ios.rs
+++ b/compiler/rustc_target/src/spec/x86_64_apple_ios.rs
@@ -4,7 +4,7 @@
pub fn target() -> Target {
let base = opts("ios", Arch::X86_64);
Target {
- llvm_target: "x86_64-apple-ios".to_string(),
+ llvm_target: super::apple_base::ios_sim_llvm_target("x86_64"),
pointer_width: 64,
data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
.to_string(),
diff --git a/compiler/rustc_target/src/spec/x86_64_pc_solaris.rs b/compiler/rustc_target/src/spec/x86_64_pc_solaris.rs
index b78e43d..34b6d29 100644
--- a/compiler/rustc_target/src/spec/x86_64_pc_solaris.rs
+++ b/compiler/rustc_target/src/spec/x86_64_pc_solaris.rs
@@ -1,4 +1,4 @@
-use crate::spec::{LinkerFlavor, StackProbeType, Target};
+use crate::spec::{LinkerFlavor, SanitizerSet, StackProbeType, Target};
pub fn target() -> Target {
let mut base = super::solaris_base::opts();
@@ -8,6 +8,7 @@
base.max_atomic_width = Some(64);
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call;
+ base.supported_sanitizers = SanitizerSet::ADDRESS;
Target {
llvm_target: "x86_64-pc-solaris".to_string(),
diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_illumos.rs b/compiler/rustc_target/src/spec/x86_64_unknown_illumos.rs
index d3f9349..ec196a7 100644
--- a/compiler/rustc_target/src/spec/x86_64_unknown_illumos.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_illumos.rs
@@ -1,10 +1,11 @@
-use crate::spec::{LinkerFlavor, Target};
+use crate::spec::{LinkerFlavor, SanitizerSet, Target};
pub fn target() -> Target {
let mut base = super::illumos_base::opts();
base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string(), "-std=c99".to_string()]);
base.cpu = "x86-64".to_string();
base.max_atomic_width = Some(64);
+ base.supported_sanitizers = SanitizerSet::ADDRESS;
Target {
// LLVM does not currently have a separate illumos target,
diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs
index 0269c7a..9ba8628 100644
--- a/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs
@@ -1,4 +1,4 @@
-use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
+use crate::spec::{LinkerFlavor, SanitizerSet, StackProbeType, Target, TargetOptions};
pub fn target() -> Target {
let mut base = super::netbsd_base::opts();
@@ -7,6 +7,8 @@
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string());
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call;
+ base.supported_sanitizers =
+ SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::MEMORY | SanitizerSet::THREAD;
Target {
llvm_target: "x86_64-unknown-netbsd".to_string(),