diff options
Diffstat (limited to 'compiler/rustc_target/src')
| -rw-r--r-- | compiler/rustc_target/src/abi/call/mod.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_target/src/abi/call/nvptx64.rs | 47 | ||||
| -rw-r--r-- | compiler/rustc_target/src/abi/mod.rs | 32 | ||||
| -rw-r--r-- | compiler/rustc_target/src/asm/mips.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_target/src/asm/mod.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_target/src/asm/x86.rs | 11 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/mod.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/wasm64_unknown_unknown.rs | 2 |
8 files changed, 90 insertions, 23 deletions
diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index ce564d1455b..afce10ff1cb 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -696,7 +696,13 @@ impl<'a, Ty> FnAbi<'a, Ty> { "sparc" => sparc::compute_abi_info(cx, self), "sparc64" => sparc64::compute_abi_info(cx, self), "nvptx" => nvptx::compute_abi_info(self), - "nvptx64" => nvptx64::compute_abi_info(self), + "nvptx64" => { + if cx.target_spec().adjust_abi(abi) == spec::abi::Abi::PtxKernel { + nvptx64::compute_ptx_kernel_abi_info(cx, self) + } else { + nvptx64::compute_abi_info(self) + } + } "hexagon" => hexagon::compute_abi_info(self), "riscv32" | "riscv64" => riscv::compute_abi_info(cx, self), "wasm32" | "wasm64" => { diff --git a/compiler/rustc_target/src/abi/call/nvptx64.rs b/compiler/rustc_target/src/abi/call/nvptx64.rs index 16f331b16d5..fc16f1c97a4 100644 --- a/compiler/rustc_target/src/abi/call/nvptx64.rs +++ b/compiler/rustc_target/src/abi/call/nvptx64.rs @@ -1,21 +1,35 @@ -// Reference: PTX Writer's Guide to Interoperability -// https://docs.nvidia.com/cuda/ptx-writers-guide-to-interoperability - -use crate::abi::call::{ArgAbi, FnAbi}; +use crate::abi::call::{ArgAbi, FnAbi, PassMode, Reg, Size, Uniform}; +use crate::abi::{HasDataLayout, TyAbiInterface}; fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) { if ret.layout.is_aggregate() && ret.layout.size.bits() > 64 { ret.make_indirect(); - } else { - ret.extend_integer_width_to(64); } } fn classify_arg<Ty>(arg: &mut ArgAbi<'_, Ty>) { if arg.layout.is_aggregate() && arg.layout.size.bits() > 64 { arg.make_indirect(); - } else { - arg.extend_integer_width_to(64); + } +} + +fn classify_arg_kernel<'a, Ty, C>(_cx: &C, arg: &mut ArgAbi<'a, Ty>) +where + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, +{ + if matches!(arg.mode, PassMode::Pair(..)) && (arg.layout.is_adt() || arg.layout.is_tuple()) { + let align_bytes = arg.layout.align.abi.bytes(); + + let unit = match align_bytes { + 1 => Reg::i8(), + 2 => Reg::i16(), + 4 => Reg::i32(), + 8 => Reg::i64(), + 16 => Reg::i128(), + _ => unreachable!("Align is given as power of 2 no larger than 16 bytes"), + }; + arg.cast_to(Uniform { unit, total: Size::from_bytes(2 * align_bytes) }); } } @@ -31,3 +45,20 @@ pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) { classify_arg(arg); } } + +pub fn compute_ptx_kernel_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) +where + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, +{ + if !fn_abi.ret.layout.is_unit() && !fn_abi.ret.layout.is_never() { + panic!("Kernels should not return anything other than () or !"); + } + + for arg in &mut fn_abi.args { + if arg.is_ignore() { + continue; + } + classify_arg_kernel(cx, arg); + } +} diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index 169167f69bf..0e8fd9cc93f 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -1355,6 +1355,10 @@ pub trait TyAbiInterface<'a, C>: Sized { cx: &C, offset: Size, ) -> Option<PointeeInfo>; + fn is_adt(this: TyAndLayout<'a, Self>) -> bool; + fn is_never(this: TyAndLayout<'a, Self>) -> bool; + fn is_tuple(this: TyAndLayout<'a, Self>) -> bool; + fn is_unit(this: TyAndLayout<'a, Self>) -> bool; } impl<'a, Ty> TyAndLayout<'a, Ty> { @@ -1396,6 +1400,34 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { _ => false, } } + + pub fn is_adt<C>(self) -> bool + where + Ty: TyAbiInterface<'a, C>, + { + Ty::is_adt(self) + } + + pub fn is_never<C>(self) -> bool + where + Ty: TyAbiInterface<'a, C>, + { + Ty::is_never(self) + } + + pub fn is_tuple<C>(self) -> bool + where + Ty: TyAbiInterface<'a, C>, + { + Ty::is_tuple(self) + } + + pub fn is_unit<C>(self) -> bool + where + Ty: TyAbiInterface<'a, C>, + { + Ty::is_unit(self) + } } impl<'a, Ty> TyAndLayout<'a, Ty> { diff --git a/compiler/rustc_target/src/asm/mips.rs b/compiler/rustc_target/src/asm/mips.rs index b1e8737b52b..4e7c2eb1bf8 100644 --- a/compiler/rustc_target/src/asm/mips.rs +++ b/compiler/rustc_target/src/asm/mips.rs @@ -43,7 +43,8 @@ impl MipsInlineAsmRegClass { } } -// The reserved registers are somewhat taken from <https://git.io/JUR1k#L150>. +// The reserved registers are somewhat taken from +// <https://github.com/llvm/llvm-project/blob/deb8f8bcf31540c657716ea5242183b0792702a1/llvm/lib/Target/Mips/MipsRegisterInfo.cpp#L150>. def_regs! { Mips MipsInlineAsmReg MipsInlineAsmRegClass { r2: reg = ["$2"], diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index 5bc4b566daf..6bc807c7c44 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -893,7 +893,7 @@ impl InlineAsmClobberAbi { xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, - k1, k2, k3, k4, k5, k6, k7, + k0, k1, k2, k3, k4, k5, k6, k7, mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7, st0, st1, st2, st3, st4, st5, st6, st7, @@ -908,7 +908,7 @@ impl InlineAsmClobberAbi { zmm16, zmm17, zmm18, zmm19, zmm20, zmm21, zmm22, zmm23, zmm24, zmm25, zmm26, zmm27, zmm28, zmm29, zmm30, zmm31, - k1, k2, k3, k4, k5, k6, k7, + k0, k1, k2, k3, k4, k5, k6, k7, mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7, st0, st1, st2, st3, st4, st5, st6, st7, @@ -927,7 +927,7 @@ impl InlineAsmClobberAbi { zmm16, zmm17, zmm18, zmm19, zmm20, zmm21, zmm22, zmm23, zmm24, zmm25, zmm26, zmm27, zmm28, zmm29, zmm30, zmm31, - k1, k2, k3, k4, k5, k6, k7, + k0, k1, k2, k3, k4, k5, k6, k7, mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7, st0, st1, st2, st3, st4, st5, st6, st7, diff --git a/compiler/rustc_target/src/asm/x86.rs b/compiler/rustc_target/src/asm/x86.rs index 7c136a47548..854674c7f2f 100644 --- a/compiler/rustc_target/src/asm/x86.rs +++ b/compiler/rustc_target/src/asm/x86.rs @@ -14,6 +14,7 @@ def_reg_class! { ymm_reg, zmm_reg, kreg, + kreg0, mmx_reg, x87_reg, } @@ -38,7 +39,7 @@ impl X86InlineAsmRegClass { } Self::reg_byte => &[], Self::xmm_reg | Self::ymm_reg | Self::zmm_reg => &['x', 'y', 'z'], - Self::kreg => &[], + Self::kreg | Self::kreg0 => &[], Self::mmx_reg | Self::x87_reg => &[], } } @@ -77,7 +78,7 @@ impl X86InlineAsmRegClass { 256 => Some(('y', "ymm0")), _ => Some(('x', "xmm0")), }, - Self::kreg => None, + Self::kreg | Self::kreg0 => None, Self::mmx_reg | Self::x87_reg => None, } } @@ -95,7 +96,7 @@ impl X86InlineAsmRegClass { Self::xmm_reg => Some(('x', "xmm0")), Self::ymm_reg => Some(('y', "ymm0")), Self::zmm_reg => Some(('z', "zmm0")), - Self::kreg => None, + Self::kreg | Self::kreg0 => None, Self::mmx_reg | Self::x87_reg => None, } } @@ -132,6 +133,7 @@ impl X86InlineAsmRegClass { avx512f: I8, I16; avx512bw: I32, I64; }, + Self::kreg0 => &[], Self::mmx_reg | Self::x87_reg => &[], } } @@ -294,6 +296,7 @@ def_regs! { zmm29: zmm_reg = ["zmm29", "xmm29", "ymm29"] % x86_64_only, zmm30: zmm_reg = ["zmm30", "xmm30", "ymm30"] % x86_64_only, zmm31: zmm_reg = ["zmm31", "xmm31", "ymm31"] % x86_64_only, + k0: kreg0 = ["k0"], k1: kreg = ["k1"], k2: kreg = ["k2"], k3: kreg = ["k3"], @@ -323,8 +326,6 @@ def_regs! { "the stack pointer cannot be used as an operand for inline asm", #error = ["ip", "eip", "rip"] => "the instruction pointer cannot be used as an operand for inline asm", - #error = ["k0"] => - "the k0 AVX mask register cannot be used as an operand for inline asm", } } diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index bd5b712c143..965a3c10983 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -2249,10 +2249,6 @@ impl ToJson for Target { let name = (stringify!($attr)).replace("_", "-"); d.insert(name, self.$attr.to_json()); }}; - ($attr:ident, $key_name:expr) => {{ - let name = $key_name; - d.insert(name.into(), self.$attr.to_json()); - }}; } macro_rules! target_option_val { diff --git a/compiler/rustc_target/src/spec/wasm64_unknown_unknown.rs b/compiler/rustc_target/src/spec/wasm64_unknown_unknown.rs index 609b7d42e43..6826c0ac62b 100644 --- a/compiler/rustc_target/src/spec/wasm64_unknown_unknown.rs +++ b/compiler/rustc_target/src/spec/wasm64_unknown_unknown.rs @@ -36,7 +36,7 @@ pub fn target() -> Target { Target { llvm_target: "wasm64-unknown-unknown".into(), pointer_width: 64, - data_layout: "e-m:e-p:64:64-i64:64-n32:64-S128-ni:1:10:20".into(), + data_layout: "e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20".into(), arch: "wasm64".into(), options, } |
