Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions compiler/rustc_codegen_gcc/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,7 @@ fn reg_class_to_gcc(reg_class: InlineAsmRegClass) -> &'static str {
InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::reg) => "r",
InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::freg) => "f",
InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => "d", // more specific than "r"
InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => "f",
InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg | MipsInlineAsmRegClass::wreg) => "f",
InlineAsmRegClass::Msp430(Msp430InlineAsmRegClass::reg) => "r",
// https://github.com/gcc-mirror/gcc/blob/master/gcc/config/nvptx/nvptx.md -> look for
// "define_constraint".
Expand Down Expand Up @@ -846,6 +846,7 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
}
InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => cx.type_i32(),
InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => cx.type_f32(),
InlineAsmRegClass::Mips(MipsInlineAsmRegClass::wreg) => cx.type_vector(cx.type_i32(), 4),
InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg16) => cx.type_i16(),
InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg32) => cx.type_i32(),
InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg64) => cx.type_i64(),
Expand Down Expand Up @@ -1090,7 +1091,9 @@ fn modifier_to_gcc(
modifier
}
}
InlineAsmRegClass::Mips(_) => None,
InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => None,
InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => modifier,
InlineAsmRegClass::Mips(MipsInlineAsmRegClass::wreg) => Some('w'),
InlineAsmRegClass::Nvptx(_) => None,
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vsreg) => {
if modifier.is_none() {
Expand Down
52 changes: 42 additions & 10 deletions compiler/rustc_codegen_llvm/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,7 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) ->
| LoongArch(LoongArchInlineAsmRegClass::vreg)
| LoongArch(LoongArchInlineAsmRegClass::xreg) => "f",
Mips(MipsInlineAsmRegClass::reg) => "r",
Mips(MipsInlineAsmRegClass::freg) => "f",
Mips(MipsInlineAsmRegClass::freg | MipsInlineAsmRegClass::wreg) => "f",
Nvptx(NvptxInlineAsmRegClass::reg16) => "h",
Nvptx(NvptxInlineAsmRegClass::reg32) => "r",
Nvptx(NvptxInlineAsmRegClass::reg64) => "l",
Expand Down Expand Up @@ -905,7 +905,9 @@ fn modifier_to_llvm(
modifier
}
}
Mips(_) => None,
Mips(MipsInlineAsmRegClass::reg) => None,
Mips(MipsInlineAsmRegClass::freg) => modifier,
Mips(MipsInlineAsmRegClass::wreg) => Some('w'),
Nvptx(_) => None,
PowerPC(PowerPCInlineAsmRegClass::vsreg) => {
// The documentation for the 'x' modifier is missing for llvm, and the gcc
Expand Down Expand Up @@ -1011,6 +1013,7 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
LoongArch(LoongArchInlineAsmRegClass::xreg) => cx.type_vector(cx.type_i32(), 8),
Mips(MipsInlineAsmRegClass::reg) => cx.type_i32(),
Mips(MipsInlineAsmRegClass::freg) => cx.type_f32(),
Mips(MipsInlineAsmRegClass::wreg) => cx.type_vector(cx.type_i32(), 4),
Nvptx(NvptxInlineAsmRegClass::reg16) => cx.type_i16(),
Nvptx(NvptxInlineAsmRegClass::reg32) => cx.type_i32(),
Nvptx(NvptxInlineAsmRegClass::reg64) => cx.type_i64(),
Expand Down Expand Up @@ -1249,12 +1252,24 @@ fn llvm_fixup_input<'ll, 'tcx>(
(Mips(MipsInlineAsmRegClass::reg), BackendRepr::Scalar(s)) => {
match s.primitive() {
// MIPS only supports register-length arithmetics.
Primitive::Int(Integer::I8 | Integer::I16, _) => bx.zext(value, bx.cx.type_i32()),
Primitive::Float(Float::F32) => bx.bitcast(value, bx.cx.type_i32()),
Primitive::Float(Float::F64) => bx.bitcast(value, bx.cx.type_i64()),
Primitive::Int(Integer::I8 | Integer::I16, _) => bx.zext(value, bx.type_i32()),
Primitive::Float(Float::F16) => {
let value = bx.bitcast(value, bx.type_i16());
bx.zext(value, bx.type_i32())
}
Primitive::Float(Float::F32) => bx.bitcast(value, bx.type_i32()),
Primitive::Float(Float::F64) => bx.bitcast(value, bx.type_i64()),
_ => value,
}
}
(
Mips(MipsInlineAsmRegClass::freg | MipsInlineAsmRegClass::wreg),
BackendRepr::Scalar(s),
) if s.primitive() == Primitive::Float(Float::F16) => {
let value = bx.bitcast(value, bx.type_i16());
let value = bx.zext(value, bx.type_i32());
bx.bitcast(value, bx.type_f32())
}
(RiscV(RiscVInlineAsmRegClass::freg), BackendRepr::Scalar(s))
if s.primitive() == Primitive::Float(Float::F16)
&& !any_target_feature_enabled(bx, instance, &[sym::zfhmin, sym::zfh]) =>
Expand Down Expand Up @@ -1414,13 +1429,25 @@ fn llvm_fixup_output<'ll, 'tcx>(
(Mips(MipsInlineAsmRegClass::reg), BackendRepr::Scalar(s)) => {
match s.primitive() {
// MIPS only supports register-length arithmetics.
Primitive::Int(Integer::I8, _) => bx.trunc(value, bx.cx.type_i8()),
Primitive::Int(Integer::I16, _) => bx.trunc(value, bx.cx.type_i16()),
Primitive::Float(Float::F32) => bx.bitcast(value, bx.cx.type_f32()),
Primitive::Float(Float::F64) => bx.bitcast(value, bx.cx.type_f64()),
Primitive::Int(Integer::I8, _) => bx.trunc(value, bx.type_i8()),
Primitive::Int(Integer::I16, _) => bx.trunc(value, bx.type_i16()),
Primitive::Float(Float::F16) => {
let value = bx.trunc(value, bx.type_i16());
bx.bitcast(value, bx.type_f16())
}
Primitive::Float(Float::F32) => bx.bitcast(value, bx.type_f32()),
Primitive::Float(Float::F64) => bx.bitcast(value, bx.type_f64()),
_ => value,
}
}
(
Mips(MipsInlineAsmRegClass::freg | MipsInlineAsmRegClass::wreg),
BackendRepr::Scalar(s),
) if s.primitive() == Primitive::Float(Float::F16) => {
let value = bx.bitcast(value, bx.type_i32());
let value = bx.trunc(value, bx.type_i16());
bx.bitcast(value, bx.type_f16())
}
(RiscV(RiscVInlineAsmRegClass::freg), BackendRepr::Scalar(s))
if s.primitive() == Primitive::Float(Float::F16)
&& !any_target_feature_enabled(bx, instance, &[sym::zfhmin, sym::zfh]) =>
Expand Down Expand Up @@ -1567,11 +1594,16 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
match s.primitive() {
// MIPS only supports register-length arithmetics.
Primitive::Int(Integer::I8 | Integer::I16, _) => cx.type_i32(),
Primitive::Float(Float::F32) => cx.type_i32(),
Primitive::Float(Float::F16 | Float::F32) => cx.type_i32(),
Primitive::Float(Float::F64) => cx.type_i64(),
_ => layout.llvm_type(cx),
}
}

(
Mips(MipsInlineAsmRegClass::freg | MipsInlineAsmRegClass::wreg),
BackendRepr::Scalar(s),
) if s.primitive() == Primitive::Float(Float::F16) => cx.type_f32(),
(RiscV(RiscVInlineAsmRegClass::freg), BackendRepr::Scalar(s))
if s.primitive() == Primitive::Float(Float::F16)
&& !any_target_feature_enabled(cx, instance, &[sym::zfhmin, sym::zfh]) =>
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1377,6 +1377,7 @@ symbols! {
move_ref_pattern,
move_size_limit,
movrs_target_feature,
msa,
msp430,
mul,
mul_assign,
Expand Down
108 changes: 104 additions & 4 deletions compiler/rustc_target/src/asm/mips.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,19 @@ def_reg_class! {
Mips MipsInlineAsmRegClass {
reg,
freg,
wreg,
}
}

impl MipsInlineAsmRegClass {
pub fn valid_modifiers(self, _arch: super::InlineAsmArch) -> &'static [char] {
&[]
match self {
Self::reg => &[],
Self::freg => &['w'],
// LLVM doesn't currently support displaying vector registers holding vector types as
// float registers.
Self::wreg => &[],
}
}

pub fn suggest_class(self, _arch: InlineAsmArch, _ty: InlineAsmType) -> Option<Self> {
Expand All @@ -37,9 +44,12 @@ impl MipsInlineAsmRegClass {
arch: InlineAsmArch,
) -> &'static [(InlineAsmType, Option<Symbol>)] {
match (self, arch) {
(Self::reg, InlineAsmArch::Mips64) => types! { _: I8, I16, I32, I64, F32, F64; },
(Self::reg, _) => types! { _: I8, I16, I32, F32; },
(Self::freg, _) => types! { _: F32, F64; },
(Self::reg, InlineAsmArch::Mips64) => types! { _: I8, I16, I32, I64, F16, F32, F64; },
(Self::reg, _) => types! { _: I8, I16, I32, F16, F32; },
(Self::freg, _) => types! { _: F16, F32, F64; },
(Self::wreg, _) => {
types! { msa: F16, F32, F64, VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF16(8), VecF32(4), VecF64(2); }
}
}
}
}
Expand Down Expand Up @@ -105,6 +115,38 @@ def_regs! {
f29: freg = ["$f29"],
f30: freg = ["$f30"],
f31: freg = ["$f31"],
w0: wreg = ["$w0"],
w1: wreg = ["$w1"],
w2: wreg = ["$w2"],
w3: wreg = ["$w3"],
w4: wreg = ["$w4"],
w5: wreg = ["$w5"],
w6: wreg = ["$w6"],
w7: wreg = ["$w7"],
w8: wreg = ["$w8"],
w9: wreg = ["$w9"],
w10: wreg = ["$w10"],
w11: wreg = ["$w11"],
w12: wreg = ["$w12"],
w13: wreg = ["$w13"],
w14: wreg = ["$w14"],
w15: wreg = ["$w15"],
w16: wreg = ["$w16"],
w17: wreg = ["$w17"],
w18: wreg = ["$w18"],
w19: wreg = ["$w19"],
w20: wreg = ["$w20"],
w21: wreg = ["$w21"],
w22: wreg = ["$w22"],
w23: wreg = ["$w23"],
w24: wreg = ["$w24"],
w25: wreg = ["$w25"],
w26: wreg = ["$w26"],
w27: wreg = ["$w27"],
w28: wreg = ["$w28"],
w29: wreg = ["$w29"],
w30: wreg = ["$w30"],
w31: wreg = ["$w31"],
#error = ["$0"] =>
"constant zero cannot be used as an operand for inline asm",
#error = ["$1"] =>
Expand Down Expand Up @@ -133,4 +175,62 @@ impl MipsInlineAsmReg {
) -> fmt::Result {
out.write_str(self.name())
}

pub fn overlapping_regs(self, mut cb: impl FnMut(MipsInlineAsmReg)) {
cb(self);

macro_rules! reg_conflicts {
(
$(
$full:ident : $($field:ident)*
),*;
) => {
match self {
$(
Self::$full => {
$(cb(Self::$field);)*
}
$(Self::$field)|* => cb(Self::$full),
)*
_ => {}
}
};
}

// Float registers overlap the first half of vector registers.
reg_conflicts! {
w0: f0,
w1: f1,
w2: f2,
w3: f3,
w4: f4,
w5: f5,
w6: f6,
w7: f7,
w8: f8,
w9: f9,
w10: f10,
w11: f11,
w12: f12,
w13: f13,
w14: f14,
w15: f15,
w16: f16,
w17: f17,
w18: f18,
w19: f19,
w20: f20,
w21: f21,
w22: f22,
w23: f23,
w24: f24,
w25: f25,
w26: f26,
w27: f27,
w28: f28,
w29: f29,
w30: f30,
w31: f31;
}
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_target/src/asm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ impl InlineAsmReg {
Self::PowerPC(r) => r.overlapping_regs(|r| cb(Self::PowerPC(r))),
Self::Hexagon(r) => r.overlapping_regs(|r| cb(Self::Hexagon(r))),
Self::LoongArch(r) => r.overlapping_regs(|r| cb(Self::LoongArch(r))),
Self::Mips(_) => cb(self),
Self::Mips(r) => r.overlapping_regs(|r| cb(Self::Mips(r))),
Self::S390x(r) => r.overlapping_regs(|r| cb(Self::S390x(r))),
Self::Sparc(r) => r.overlapping_regs(|r| cb(Self::Sparc(r))),
Self::Xtensa(_) => cb(self),
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_target/src/target_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,8 @@ static POWERPC_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
const MIPS_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
// tidy-alphabetical-start
("fp64", Unstable(sym::mips_target_feature), &[]),
// FIXME(#150253): msa requires either fp64 or no hard float support at all: LLVM requires fp64
// FIXME(#150253): msa requires revision 5 or greater (mips32r5/mips64r5 in LLVM)
("msa", Unstable(sym::mips_target_feature), &[]),
("virt", Unstable(sym::mips_target_feature), &[]),
// tidy-alphabetical-end
Expand Down
17 changes: 12 additions & 5 deletions library/std/src/sys/pal/sgx/abi/tls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ mod sync_bitset;
use self::sync_bitset::*;
use crate::cell::Cell;
use crate::num::NonZero;
use crate::sync::atomic::{Atomic, AtomicUsize, Ordering};
use crate::sync::atomic::{AtomicPtr, Ordering};
use crate::{mem, ptr};

#[cfg(target_pointer_width = "64")]
Expand All @@ -29,7 +29,8 @@ static TLS_KEY_IN_USE: SyncBitset = SYNC_BITSET_INIT;
// Specifying linkage/symbol name is solely to ensure a single instance between this crate and its unit tests
#[cfg_attr(test, linkage = "available_externally")]
#[unsafe(export_name = "_ZN16__rust_internals3std3sys3pal3sgx3abi3tls14TLS_DESTRUCTORE")]
static TLS_DESTRUCTOR: [Atomic<usize>; TLS_KEYS] = [const { AtomicUsize::new(0) }; TLS_KEYS];
static TLS_DESTRUCTOR: [AtomicPtr<()>; TLS_KEYS] =
[const { AtomicPtr::new(ptr::null_mut()) }; TLS_KEYS];

unsafe extern "C" {
fn get_tls_ptr() -> *const u8;
Expand Down Expand Up @@ -71,7 +72,10 @@ impl<'a> Drop for ActiveTls<'a> {
fn drop(&mut self) {
let value_with_destructor = |key: usize| {
let ptr = TLS_DESTRUCTOR[key].load(Ordering::Relaxed);
unsafe { mem::transmute::<_, Option<unsafe extern "C" fn(*mut u8)>>(ptr) }
// SAFETY:
// - Matches the transmute+store below in `Tls::create`.
// - SGX/x86-64: `Option<fn(..)>` is layout compatible with `*mut ()`.
unsafe { mem::transmute::<*mut (), Option<unsafe extern "C" fn(*mut u8)>>(ptr) }
.map(|dtor| (self.tls.data_index(key), dtor))
};

Expand Down Expand Up @@ -115,8 +119,11 @@ impl Tls {
} else {
rtabort!("TLS limit exceeded")
};
rtunwrap!(Some, TLS_DESTRUCTOR.get(index))
.store(dtor.map_or(0, |f| f as usize), Ordering::Relaxed);
// SAFETY:
// - Matches the load+transmute above in `ActiveTls::drop`.
// - SGX/x86-64: `Option<fn(..)>` is layout compatible with `*mut ()`.
let ptr = unsafe { mem::transmute::<Option<unsafe extern "C" fn(*mut u8)>, *mut ()>(dtor) };
rtunwrap!(Some, TLS_DESTRUCTOR.get(index)).store(ptr, Ordering::Relaxed);
unsafe { Self::current() }.data_index(index).set(ptr::null_mut());
Key::from_index(index)
}
Expand Down
16 changes: 7 additions & 9 deletions src/librustdoc/html/macro_expansion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,9 @@ impl<'ast> ExpandedCodeVisitor<'ast> {
return;
}
let callsite_span = new_span.source_callsite();
if let Some(index) =
self.expanded_codes.iter().position(|info| info.span.overlaps(callsite_span))
if let Some(info) =
self.expanded_codes.iter_mut().find(|info| info.span.overlaps(callsite_span))
{
let info = &mut self.expanded_codes[index];
// If the new span we got has the exact same span information as a span already in the
// list, it means it's generated from the same macro but is a different item, so we need
// to add it as well.
Expand All @@ -86,12 +85,11 @@ impl<'ast> ExpandedCodeVisitor<'ast> {
info.code = f();
} else {
// We push the new item after the existing one.
let expanded_code = &mut self.expanded_codes[index];
expanded_code.code.push('\n');
expanded_code.code.push_str(&f());
let lo = BytePos(expanded_code.expanded_span.lo().0.min(new_span.lo().0));
let hi = BytePos(expanded_code.expanded_span.hi().0.max(new_span.hi().0));
expanded_code.expanded_span = expanded_code.expanded_span.with_lo(lo).with_hi(hi);
info.code.push('\n');
info.code.push_str(&f());
let lo = BytePos(info.expanded_span.lo().0.min(new_span.lo().0));
let hi = BytePos(info.expanded_span.hi().0.max(new_span.hi().0));
info.expanded_span = info.expanded_span.with_lo(lo).with_hi(hi);
}
} else {
// We add a new item.
Expand Down
Loading
Loading