Fix PtrAccess

This commit is contained in:
Andrzej Janik 2021-05-30 20:21:43 +02:00
commit 4091f658b2

View file

@ -2349,98 +2349,29 @@ impl<'a, 'b> FlattenArguments<'a, 'b> {
state_space: ast::StateSpace, state_space: ast::StateSpace,
) -> Result<spirv::Word, TranslateError> { ) -> Result<spirv::Word, TranslateError> {
let (reg, offset) = desc.op; let (reg, offset) = desc.op;
let add_type;
match typ { match typ {
ast::Type::Scalar(underlying_type) => { ast::Type::Scalar(underlying_type) => {
let (reg_typ, space) = self.id_def.get_typed(reg)?; let id_constant_stmt = self.id_def.register_intermediate(
if let ast::Type::Pointer(..) = reg_typ { ast::Type::Scalar(ast::ScalarType::S64),
let id_constant_stmt = self.id_def.register_intermediate(typ.clone(), space); ast::StateSpace::Reg,
self.func.push(Statement::Constant(ConstantDefinition { );
dst: id_constant_stmt, self.func.push(Statement::Constant(ConstantDefinition {
typ: ast::ScalarType::S64, dst: id_constant_stmt,
value: ast::ImmediateValue::S64(offset as i64), typ: ast::ScalarType::S64,
})); value: ast::ImmediateValue::S64(offset as i64),
let dst = self.id_def.register_intermediate(typ.clone(), space); }));
self.func.push(Statement::PtrAccess(PtrAccess { let dst = self.id_def.register_intermediate(typ.clone(), state_space);
underlying_type: *underlying_type, self.func.push(Statement::PtrAccess(PtrAccess {
state_space: state_space, underlying_type: *underlying_type,
dst, state_space: state_space,
ptr_src: reg, dst,
offset_src: id_constant_stmt, ptr_src: reg,
})); offset_src: id_constant_stmt,
return Ok(dst); }));
} else { Ok(dst)
add_type = reg_typ;
}
} }
_ => return Err(error_unreachable()), _ => Err(error_unreachable()),
};
let (width, kind) = match add_type {
ast::Type::Scalar(scalar_t) => {
let kind = match scalar_t.kind() {
kind @ ast::ScalarKind::Bit
| kind @ ast::ScalarKind::Unsigned
| kind @ ast::ScalarKind::Signed => kind,
ast::ScalarKind::Float => return Err(TranslateError::MismatchedType),
ast::ScalarKind::Float2 => return Err(TranslateError::MismatchedType),
ast::ScalarKind::Pred => return Err(TranslateError::MismatchedType),
};
(scalar_t.size_of(), kind)
}
_ => return Err(TranslateError::MismatchedType),
};
let arith_detail = if kind == ast::ScalarKind::Signed {
ast::ArithDetails::Signed(ast::ArithSInt {
typ: ast::ScalarType::from_parts(width, ast::ScalarKind::Signed),
saturate: false,
})
} else {
ast::ArithDetails::Unsigned(ast::ScalarType::from_parts(
width,
ast::ScalarKind::Unsigned,
))
};
let id_constant_stmt = self
.id_def
.register_intermediate(add_type.clone(), ast::StateSpace::Reg);
let result_id = self
.id_def
.register_intermediate(add_type, ast::StateSpace::Reg);
// TODO: check for edge cases around min value/max value/wrapping
if offset < 0 && kind != ast::ScalarKind::Signed {
self.func.push(Statement::Constant(ConstantDefinition {
dst: id_constant_stmt,
typ: ast::ScalarType::from_parts(width, kind),
value: ast::ImmediateValue::U64(-(offset as i64) as u64),
}));
self.func.push(Statement::Instruction(
ast::Instruction::<ExpandedArgParams>::Sub(
arith_detail,
ast::Arg3 {
dst: result_id,
src1: reg,
src2: id_constant_stmt,
},
),
));
} else {
self.func.push(Statement::Constant(ConstantDefinition {
dst: id_constant_stmt,
typ: ast::ScalarType::from_parts(width, kind),
value: ast::ImmediateValue::S64(offset as i64),
}));
self.func.push(Statement::Instruction(
ast::Instruction::<ExpandedArgParams>::Add(
arith_detail,
ast::Arg3 {
dst: result_id,
src1: reg,
src2: id_constant_stmt,
},
),
));
} }
Ok(result_id)
} }
fn immediate( fn immediate(
@ -2519,32 +2450,8 @@ fn insert_implicit_conversions(
Statement::Instruction(inst) => { Statement::Instruction(inst) => {
insert_implicit_conversions_impl(&mut result, id_def, inst)?; insert_implicit_conversions_impl(&mut result, id_def, inst)?;
} }
Statement::PtrAccess(PtrAccess { Statement::PtrAccess(access) => {
underlying_type, insert_implicit_conversions_impl(&mut result, id_def, access)?;
state_space,
dst,
ptr_src,
offset_src: constant_src,
}) => {
let visit_desc = VisitArgumentDescriptor {
desc: ArgumentDescriptor {
op: ptr_src,
is_dst: false,
non_default_implicit_conversion: None,
},
typ: &ast::Type::Pointer(underlying_type, state_space),
state_space: new_todo!(),
stmt_ctor: |new_ptr_src| {
Statement::PtrAccess(PtrAccess {
underlying_type,
state_space,
dst,
ptr_src: new_ptr_src,
offset_src: constant_src,
})
},
};
insert_implicit_conversions_impl(&mut result, id_def, visit_desc)?;
} }
Statement::RepackVector(repack) => { Statement::RepackVector(repack) => {
insert_implicit_conversions_impl(&mut result, id_def, repack)?; insert_implicit_conversions_impl(&mut result, id_def, repack)?;
@ -5458,16 +5365,7 @@ impl<P: ArgParamsEx<Id = spirv::Word>> PtrAccess<P> {
self, self,
visitor: &mut V, visitor: &mut V,
) -> Result<PtrAccess<To>, TranslateError> { ) -> Result<PtrAccess<To>, TranslateError> {
let sema = match self.state_space { let ptr_type = ast::Type::Scalar(self.underlying_type.clone());
ast::StateSpace::Const
| ast::StateSpace::Global
| ast::StateSpace::Shared
| ast::StateSpace::Generic => ArgumentSemantics::PhysicalPointer,
ast::StateSpace::Local | ast::StateSpace::Param => ArgumentSemantics::RegisterPointer,
ast::StateSpace::Reg => new_todo!(),
ast::StateSpace::Sreg => new_todo!(),
};
let ptr_type = ast::Type::Pointer(self.underlying_type.clone(), new_todo!());
let new_dst = visitor.id( let new_dst = visitor.id(
ArgumentDescriptor { ArgumentDescriptor {
op: self.dst, op: self.dst,
@ -5492,7 +5390,7 @@ impl<P: ArgParamsEx<Id = spirv::Word>> PtrAccess<P> {
non_default_implicit_conversion: None, non_default_implicit_conversion: None,
}, },
&ast::Type::Scalar(ast::ScalarType::S64), &ast::Type::Scalar(ast::ScalarType::S64),
self.state_space, ast::StateSpace::Reg,
)?; )?;
Ok(PtrAccess { Ok(PtrAccess {
underlying_type: self.underlying_type, underlying_type: self.underlying_type,