Make it possible it use value_field for SIMD values stored ByVal
This commit is contained in:
parent
0ebc14cc40
commit
30a760dda2
@ -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),
|
||||
|
@ -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>) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user