Make it possible it use value_field for SIMD values stored ByVal

This commit is contained in:
bjorn3 2019-12-25 12:38:18 +01:00
parent 0ebc14cc40
commit 30a760dda2
2 changed files with 31 additions and 33 deletions

View File

@ -272,8 +272,8 @@ macro simd_int_binop {
},
($fx:expr, $op_u:ident|$op_s:ident($x:ident, $y:ident) -> $ret:ident) => {
let (lane_layout, lane_count) = lane_type_and_count($fx.tcx, $x.layout());
let x_val = $x.load_vector($fx);
let y_val = $y.load_vector($fx);
let x_val = $x.load_scalar($fx);
let y_val = $y.load_scalar($fx);
let res = match lane_layout.ty.kind {
ty::Uint(_) => $fx.bcx.ins().$op_u(x_val, y_val),
@ -290,8 +290,8 @@ macro simd_int_flt_binop {
},
($fx:expr, $op_u:ident|$op_s:ident|$op_f:ident($x:ident, $y:ident) -> $ret:ident) => {
let (lane_layout, lane_count) = lane_type_and_count($fx.tcx, $x.layout());
let x_val = $x.load_vector($fx);
let y_val = $y.load_vector($fx);
let x_val = $x.load_scalar($fx);
let y_val = $y.load_scalar($fx);
let res = match lane_layout.ty.kind {
ty::Uint(_) => $fx.bcx.ins().$op_u(x_val, y_val),
@ -305,8 +305,8 @@ macro simd_int_flt_binop {
macro simd_flt_binop($fx:expr, $op:ident($x:ident, $y:ident) -> $ret:ident) {
let (lane_layout, lane_count) = lane_type_and_count($fx.tcx, $x.layout());
let x_val = $x.load_vector($fx);
let y_val = $y.load_vector($fx);
let x_val = $x.load_scalar($fx);
let y_val = $y.load_scalar($fx);
let res = match lane_layout.ty.kind {
ty::Float(_) => $fx.bcx.ins().$op(x_val, y_val),

View File

@ -122,11 +122,14 @@ impl<'tcx> CValue<'tcx> {
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,
@ -158,37 +161,32 @@ impl<'tcx> CValue<'tcx> {
}
}
/// Load a value with layout.abi of vector
pub fn load_vector<'a>(self, fx: &mut FunctionCx<'_, 'tcx, impl Backend>) -> Value {
let layout = self.1;
match self.0 {
CValueInner::ByRef(ptr) => {
let clif_ty = match layout.abi {
layout::Abi::Vector { ref element, count } => {
scalar_to_clif_type(fx.tcx, element.clone()).by(u16::try_from(count).unwrap()).unwrap()
}
_ => unreachable!(),
};
ptr.load(fx, clif_ty, MemFlags::new())
}
CValueInner::ByVal(value) => value,
CValueInner::ByValPair(_, _) => bug!("Please use load_scalar_pair for ByValPair"),
}
}
pub fn value_field<'a>(
self,
fx: &mut FunctionCx<'_, 'tcx, impl Backend>,
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>) {