use rustc_middle::mir;
use rustc_middle::mir::interpret::{ConstValue, Pointer, Scalar};
-use rustc_middle::ty::layout::TyAndLayout;
+use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
use rustc_middle::ty::Ty;
-use rustc_target::abi::{Abi, Align, LayoutOf, Size};
+use rustc_target::abi::{Abi, Align, Size};
use std::fmt;
pub layout: TyAndLayout<'tcx>,
}
-impl<V: CodegenObject> fmt::Debug for OperandRef<'tcx, V> {
+impl<V: CodegenObject> fmt::Debug for OperandRef<'_, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "OperandRef({:?} @ {:?})", self.val, self.layout)
}
let val = match val {
ConstValue::Scalar(x) => {
- let scalar = match layout.abi {
- Abi::Scalar(ref x) => x,
- _ => bug!("from_const: invalid ByVal layout: {:#?}", layout),
+ let Abi::Scalar(scalar) = layout.abi else {
+ bug!("from_const: invalid ByVal layout: {:#?}", layout);
};
let llval = bx.scalar_to_backend(x, scalar, bx.immediate_backend_type(layout));
OperandValue::Immediate(llval)
}
ConstValue::Slice { data, start, end } => {
- let a_scalar = match layout.abi {
- Abi::ScalarPair(ref a, _) => a,
- _ => bug!("from_const: invalid ScalarPair layout: {:#?}", layout),
+ let Abi::ScalarPair(a_scalar, _) = layout.abi else {
+ bug!("from_const: invalid ScalarPair layout: {:#?}", layout);
};
- let a = Scalar::from(Pointer::new(
- bx.tcx().create_memory_alloc(data),
- Size::from_bytes(start),
- ));
+ let a = Scalar::from_pointer(
+ Pointer::new(bx.tcx().create_memory_alloc(data), Size::from_bytes(start)),
+ &bx.tcx(),
+ );
let a_llval = bx.scalar_to_backend(
a,
a_scalar,
}
pub fn deref<Cx: LayoutTypeMethods<'tcx>>(self, cx: &Cx) -> PlaceRef<'tcx, V> {
+ if self.layout.ty.is_box() {
+ bug!("dereferencing {:?} in codegen", self.layout.ty);
+ }
+
let projected_ty = self
.layout
.ty
.builtin_deref(true)
.unwrap_or_else(|| bug!("deref of non-pointer {:?}", self))
.ty;
+
let (llptr, llextra) = match self.val {
OperandValue::Immediate(llptr) => (llptr, None),
OperandValue::Pair(llptr, llextra) => (llptr, Some(llextra)),
llval: V,
layout: TyAndLayout<'tcx>,
) -> Self {
- let val = if let Abi::ScalarPair(ref a, ref b) = layout.abi {
+ let val = if let Abi::ScalarPair(a, b) = layout.abi {
debug!("Operand::from_immediate_or_packed_pair: unpacking {:?} @ {:?}", llval, layout);
// Deconstruct the immediate aggregate.
let field = self.layout.field(bx.cx(), i);
let offset = self.layout.fields.offset(i);
- let mut val = match (self.val, &self.layout.abi) {
+ let mut val = match (self.val, self.layout.abi) {
// If the field is ZST, it has no data.
_ if field.is_zst() => {
return OperandRef::new_zst(bx, field);
}
// Extract a scalar component from a pair.
- (OperandValue::Pair(a_llval, b_llval), &Abi::ScalarPair(ref a, ref b)) => {
+ (OperandValue::Pair(a_llval, b_llval), Abi::ScalarPair(a, b)) => {
if offset.bytes() == 0 {
- assert_eq!(field.size, a.value.size(bx.cx()));
+ assert_eq!(field.size, a.size(bx.cx()));
OperandValue::Immediate(a_llval)
} else {
- assert_eq!(offset, a.value.size(bx.cx()).align_to(b.value.align(bx.cx()).abi));
- assert_eq!(field.size, b.value.size(bx.cx()));
+ assert_eq!(offset, a.size(bx.cx()).align_to(b.align(bx.cx()).abi));
+ assert_eq!(field.size, b.size(bx.cx()));
OperandValue::Immediate(b_llval)
}
}
// `#[repr(simd)]` types are also immediate.
- (OperandValue::Immediate(llval), &Abi::Vector { .. }) => {
+ (OperandValue::Immediate(llval), Abi::Vector { .. }) => {
OperandValue::Immediate(bx.extract_element(llval, bx.cx().const_usize(i as u64)))
}
_ => bug!("OperandRef::extract_field({:?}): not applicable", self),
};
- match (&mut val, &field.abi) {
+ match (&mut val, field.abi) {
(OperandValue::Immediate(llval), _) => {
// Bools in union fields needs to be truncated.
*llval = bx.to_immediate(*llval, field);
}
match self {
OperandValue::Ref(r, None, source_align) => {
+ if flags.contains(MemFlags::NONTEMPORAL) {
+ // HACK(nox): This is inefficient but there is no nontemporal memcpy.
+ let ty = bx.backend_type(dest.layout);
+ let ptr = bx.pointercast(r, bx.type_ptr_to(ty));
+ let val = bx.load(ty, ptr, source_align);
+ bx.store_with_flags(val, dest.llval, dest.align, flags);
+ return;
+ }
base::memcpy_ty(bx, dest.llval, dest.align, r, source_align, dest.layout, flags)
}
OperandValue::Ref(_, Some(_), _) => {
bx.store_with_flags(val, dest.llval, dest.align, flags);
}
OperandValue::Pair(a, b) => {
- let (a_scalar, b_scalar) = match dest.layout.abi {
- Abi::ScalarPair(ref a, ref b) => (a, b),
- _ => bug!("store_with_flags: invalid ScalarPair layout: {:#?}", dest.layout),
+ let Abi::ScalarPair(a_scalar, b_scalar) = dest.layout.abi else {
+ bug!("store_with_flags: invalid ScalarPair layout: {:#?}", dest.layout);
};
- let b_offset = a_scalar.value.size(bx).align_to(b_scalar.value.align(bx).abi);
+ let ty = bx.backend_type(dest.layout);
+ let b_offset = a_scalar.size(bx).align_to(b_scalar.align(bx).abi);
- let llptr = bx.struct_gep(dest.llval, 0);
+ let llptr = bx.struct_gep(ty, dest.llval, 0);
let val = bx.from_immediate(a);
let align = dest.align;
bx.store_with_flags(val, llptr, align, flags);
- let llptr = bx.struct_gep(dest.llval, 1);
+ let llptr = bx.struct_gep(ty, dest.llval, 1);
let val = bx.from_immediate(b);
let align = dest.align.restrict_for_offset(b_offset);
bx.store_with_flags(val, llptr, align, flags);
.unwrap_or_else(|| bug!("indirect_dest has non-pointer type: {:?}", indirect_dest))
.ty;
- let (llptr, llextra) = if let OperandValue::Ref(llptr, Some(llextra), _) = self {
- (llptr, llextra)
- } else {
+ let OperandValue::Ref(llptr, Some(llextra), _) = self else {
bug!("store_unsized called with a sized value")
};