use crate::prelude::*;
-use cranelift::codegen::ir::immediates::Offset32;
+use cranelift_codegen::ir::immediates::Offset32;
fn codegen_field<'tcx>(
fx: &mut FunctionCx<'_, 'tcx, impl Backend>,
self.1
}
- pub fn force_stack<'a>(self, fx: &mut FunctionCx<'_, 'tcx, impl Backend>) -> Value {
+ pub fn force_stack<'a>(self, fx: &mut FunctionCx<'_, 'tcx, impl Backend>) -> Pointer {
let layout = self.1;
match self.0 {
- CValueInner::ByRef(ptr) => ptr.get_addr(fx),
+ CValueInner::ByRef(ptr) => ptr,
CValueInner::ByVal(_) | CValueInner::ByValPair(_, _) => {
let cplace = CPlace::new_stack_slot(fx, layout.ty);
cplace.write_cvalue(fx, self);
- cplace.to_addr(fx)
+ cplace.to_ptr(fx)
}
}
}
pub fn try_to_addr(self) -> Option<Value> {
match self.0 {
CValueInner::ByRef(ptr) => {
- let (base_addr, offset) = ptr.get_addr_and_offset();
- if offset == Offset32::new(0) {
- Some(base_addr)
+ if let Some((base_addr, offset)) = ptr.try_get_addr_and_offset() {
+ if offset == Offset32::new(0) {
+ Some(base_addr)
+ } else {
+ None
+ }
} else {
None
}
let layout = self.1;
match self.0 {
CValueInner::ByRef(ptr) => {
- let scalar = match layout.abi {
- layout::Abi::Scalar(ref scalar) => scalar.clone(),
+ let clif_ty = match layout.abi {
+ layout::Abi::Scalar(ref scalar) => scalar_to_clif_type(fx.tcx, scalar.clone()),
+ layout::Abi::Vector { ref element, count } => {
+ scalar_to_clif_type(fx.tcx, element.clone())
+ .by(u16::try_from(count).unwrap()).unwrap()
+ }
_ => unreachable!(),
};
- let clif_ty = scalar_to_clif_type(fx.tcx, scalar);
ptr.load(fx, clif_ty, MemFlags::new())
}
CValueInner::ByVal(value) => value,
field: mir::Field,
) -> CValue<'tcx> {
let layout = self.1;
- let ptr = match self.0 {
- CValueInner::ByRef(ptr) => ptr,
+ match self.0 {
+ CValueInner::ByVal(val) => {
+ match layout.abi {
+ layout::Abi::Vector { element: _, count } => {
+ let count = u8::try_from(count).expect("SIMD type with more than 255 lanes???");
+ let field = u8::try_from(field.index()).unwrap();
+ assert!(field < count);
+ let lane = fx.bcx.ins().extractlane(val, field);
+ let field_layout = layout.field(&*fx, usize::from(field));
+ CValue::by_val(lane, field_layout)
+ }
+ _ => unreachable!("value_field for ByVal with abi {:?}", layout.abi),
+ }
+ }
+ CValueInner::ByRef(ptr) => {
+ let (field_ptr, field_layout) = codegen_field(fx, ptr, None, layout, field);
+ CValue::by_ref(field_ptr, field_layout)
+ }
_ => bug!("place_field for {:?}", self),
- };
-
- let (field_ptr, field_layout) = codegen_field(fx, ptr, None, layout, field);
- CValue::by_ref(field_ptr, field_layout)
+ }
}
pub fn unsize_value<'a>(self, fx: &mut FunctionCx<'_, 'tcx, impl Backend>, dest: CPlace<'tcx>) {
pub enum CPlaceInner {
Var(Local),
Addr(Pointer, Option<Value>),
- Stack(StackSlot),
NoPlace,
}
offset: None,
});
CPlace {
- inner: CPlaceInner::Stack(stack_slot),
+ inner: CPlaceInner::Addr(Pointer::stack_slot(stack_slot), None),
layout,
}
}
match self.inner {
CPlaceInner::Var(var) => {
let val = fx.bcx.use_var(mir_var(var));
- fx.bcx.set_val_label(val, cranelift::codegen::ir::ValueLabel::from_u32(var.as_u32()));
+ fx.bcx.set_val_label(val, cranelift_codegen::ir::ValueLabel::from_u32(var.as_u32()));
CValue::by_val(val, layout)
}
CPlaceInner::Addr(ptr, extra) => {
assert!(extra.is_none(), "unsized values are not yet supported");
CValue::by_ref(ptr, layout)
}
- CPlaceInner::Stack(stack_slot) => CValue::by_ref(
- Pointer::new(fx.bcx.ins().stack_addr(fx.pointer_type, stack_slot, 0)),
- layout,
- ),
CPlaceInner::NoPlace => CValue::by_ref(
Pointer::const_addr(fx, i64::try_from(self.layout.align.pref.bytes()).unwrap()),
layout,
}
}
- pub fn to_addr(self, fx: &mut FunctionCx<'_, 'tcx, impl Backend>) -> Value {
- self.to_ptr(fx).get_addr(fx)
- }
-
pub fn to_ptr_maybe_unsized(
self,
fx: &mut FunctionCx<'_, 'tcx, impl Backend>,
) -> (Pointer, Option<Value>) {
match self.inner {
CPlaceInner::Addr(ptr, extra) => (ptr, extra),
- CPlaceInner::Stack(stack_slot) => (
- Pointer::new(fx.bcx.ins().stack_addr(fx.pointer_type, stack_slot, 0)),
- None,
- ),
CPlaceInner::NoPlace => {
(
Pointer::const_addr(fx, i64::try_from(self.layout.align.pref.bytes()).unwrap()),
}
}
- pub fn to_addr_maybe_unsized(
- self,
- fx: &mut FunctionCx<'_, 'tcx, impl Backend>,
- ) -> (Value, Option<Value>) {
- let (ptr, extra) = self.to_ptr_maybe_unsized(fx);
- (ptr.get_addr(fx), extra)
- }
-
pub fn write_cvalue(self, fx: &mut FunctionCx<'_, 'tcx, impl Backend>, from: CValue<'tcx>) {
- use rustc::hir::Mutability::*;
+ #[cfg(debug_assertions)]
+ {
+ use cranelift_codegen::cursor::{Cursor, CursorPosition};
+ let cur_ebb = match fx.bcx.cursor().position() {
+ CursorPosition::After(ebb) => ebb,
+ _ => unreachable!(),
+ };
+ fx.add_comment(
+ fx.bcx.func.layout.last_inst(cur_ebb).unwrap(),
+ format!("write_cvalue: {:?} <- {:?}",self, from),
+ );
+ }
let from_ty = from.layout().ty;
let to_ty = self.layout().ty;
to_ty: Ty<'tcx>,
) {
match (&from_ty.kind, &to_ty.kind) {
- (ty::Ref(_, t, Immutable), ty::Ref(_, u, Immutable))
- | (ty::Ref(_, t, Mutable), ty::Ref(_, u, Immutable))
- | (ty::Ref(_, t, Mutable), ty::Ref(_, u, Mutable)) => {
+ (ty::Ref(_, t, Mutability::Not), ty::Ref(_, u, Mutability::Not))
+ | (ty::Ref(_, t, Mutability::Mut), ty::Ref(_, u, Mutability::Not))
+ | (ty::Ref(_, t, Mutability::Mut), ty::Ref(_, u, Mutability::Mut)) => {
assert_assignable(fx, t, u);
// &mut T -> &T is allowed
// &'a T -> &'b T is allowed
}
- (ty::Ref(_, _, Immutable), ty::Ref(_, _, Mutable)) => panic!(
+ (ty::Ref(_, _, Mutability::Not), ty::Ref(_, _, Mutability::Mut)) => panic!(
"Cant assign value of type {} to place of type {}",
from_ty, to_ty
),
let to_ptr = match self.inner {
CPlaceInner::Var(var) => {
let data = from.load_scalar(fx);
- fx.bcx.set_val_label(data, cranelift::codegen::ir::ValueLabel::from_u32(var.as_u32()));
+ fx.bcx.set_val_label(data, cranelift_codegen::ir::ValueLabel::from_u32(var.as_u32()));
fx.bcx.def_var(mir_var(var), data);
return;
}
CPlaceInner::Addr(ptr, None) => ptr,
- CPlaceInner::Stack(stack_slot) => {
- Pointer::new(fx.bcx.ins().stack_addr(fx.pointer_type, stack_slot, 0))
- }
CPlaceInner::NoPlace => {
if dst_layout.abi != Abi::Uninhabited {
assert_eq!(dst_layout.size.bytes(), 0, "{:?}", dst_layout);
pub fn write_place_ref(self, fx: &mut FunctionCx<'_, 'tcx, impl Backend>, dest: CPlace<'tcx>) {
if has_ptr_meta(fx.tcx, self.layout().ty) {
- let (value, extra) = self.to_addr_maybe_unsized(fx);
+ let (ptr, extra) = self.to_ptr_maybe_unsized(fx);
let ptr = CValue::by_val_pair(
- value,
+ ptr.get_addr(fx),
extra.expect("unsized type without metadata"),
dest.layout(),
);
dest.write_cvalue(fx, ptr);
} else {
- let ptr = CValue::by_val(self.to_addr(fx), dest.layout());
+ let ptr = CValue::by_val(self.to_ptr(fx).get_addr(fx), dest.layout());
dest.write_cvalue(fx, ptr);
}
}