mirror of
https://github.com/vosen/ZLUDA.git
synced 2025-07-18 09:46:21 +03:00
Better propagate information about address-mov and emit conversion for it
This commit is contained in:
@ -316,7 +316,7 @@ pub struct PredAt<ID> {
|
|||||||
|
|
||||||
pub enum Instruction<P: ArgParams> {
|
pub enum Instruction<P: ArgParams> {
|
||||||
Ld(LdData, Arg2<P>),
|
Ld(LdData, Arg2<P>),
|
||||||
Mov(MovType, Arg2Mov<P>),
|
Mov(MovDetails, Arg2<P>),
|
||||||
MovVector(MovVectorDetails, Arg2Vec<P>),
|
MovVector(MovVectorDetails, Arg2Vec<P>),
|
||||||
Mul(MulDetails, Arg3<P>),
|
Mul(MulDetails, Arg3<P>),
|
||||||
Add(AddDetails, Arg3<P>),
|
Add(AddDetails, Arg3<P>),
|
||||||
@ -354,7 +354,6 @@ pub struct CallInst<P: ArgParams> {
|
|||||||
pub trait ArgParams {
|
pub trait ArgParams {
|
||||||
type ID;
|
type ID;
|
||||||
type Operand;
|
type Operand;
|
||||||
type MovOperand;
|
|
||||||
type CallOperand;
|
type CallOperand;
|
||||||
type VecOperand;
|
type VecOperand;
|
||||||
}
|
}
|
||||||
@ -366,7 +365,6 @@ pub struct ParsedArgParams<'a> {
|
|||||||
impl<'a> ArgParams for ParsedArgParams<'a> {
|
impl<'a> ArgParams for ParsedArgParams<'a> {
|
||||||
type ID = &'a str;
|
type ID = &'a str;
|
||||||
type Operand = Operand<&'a str>;
|
type Operand = Operand<&'a str>;
|
||||||
type MovOperand = MovOperand<&'a str>;
|
|
||||||
type CallOperand = CallOperand<&'a str>;
|
type CallOperand = CallOperand<&'a str>;
|
||||||
type VecOperand = (&'a str, u8);
|
type VecOperand = (&'a str, u8);
|
||||||
}
|
}
|
||||||
@ -380,25 +378,6 @@ pub struct Arg2<P: ArgParams> {
|
|||||||
pub src: P::Operand,
|
pub src: P::Operand,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Arg2Mov<P: ArgParams> {
|
|
||||||
pub dst: P::ID,
|
|
||||||
pub src: P::MovOperand,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'input> From<Arg2<ParsedArgParams<'input>>> for Arg2Mov<ParsedArgParams<'input>> {
|
|
||||||
fn from(a: Arg2<ParsedArgParams<'input>>) -> Arg2Mov<ParsedArgParams<'input>> {
|
|
||||||
let new_src = match a.src {
|
|
||||||
Operand::Reg(r) => MovOperand::Reg(r),
|
|
||||||
Operand::RegOffset(r, imm) => MovOperand::RegOffset(r, imm),
|
|
||||||
Operand::Imm(x) => MovOperand::Imm(x),
|
|
||||||
};
|
|
||||||
Arg2Mov {
|
|
||||||
dst: a.dst,
|
|
||||||
src: new_src,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Arg2St<P: ArgParams> {
|
pub struct Arg2St<P: ArgParams> {
|
||||||
pub src1: P::Operand,
|
pub src1: P::Operand,
|
||||||
pub src2: P::Operand,
|
pub src2: P::Operand,
|
||||||
@ -433,14 +412,6 @@ pub struct Arg5<P: ArgParams> {
|
|||||||
pub src3: P::Operand,
|
pub src3: P::Operand,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub enum MovOperand<ID> {
|
|
||||||
Reg(ID),
|
|
||||||
Address(ID),
|
|
||||||
RegOffset(ID, i32),
|
|
||||||
AddressOffset(ID, i32),
|
|
||||||
Imm(u32),
|
|
||||||
}
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub enum Operand<ID> {
|
pub enum Operand<ID> {
|
||||||
Reg(ID),
|
Reg(ID),
|
||||||
@ -530,6 +501,11 @@ sub_scalar_type!(MovVectorType {
|
|||||||
F64,
|
F64,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
pub struct MovDetails {
|
||||||
|
pub typ: MovType,
|
||||||
|
pub src_is_address: bool
|
||||||
|
}
|
||||||
|
|
||||||
sub_type! {
|
sub_type! {
|
||||||
MovType {
|
MovType {
|
||||||
Scalar(MovScalarType),
|
Scalar(MovScalarType),
|
||||||
|
@ -496,7 +496,7 @@ LdCacheOperator: ast::LdCacheOperator = {
|
|||||||
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-mov
|
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-mov
|
||||||
InstMov: ast::Instruction<ast::ParsedArgParams<'input>> = {
|
InstMov: ast::Instruction<ast::ParsedArgParams<'input>> = {
|
||||||
"mov" <t:MovType> <a:Arg2> => {
|
"mov" <t:MovType> <a:Arg2> => {
|
||||||
ast::Instruction::Mov(t, a.into())
|
ast::Instruction::Mov(ast::MovDetails{ src_is_address: false, typ: t }, a)
|
||||||
},
|
},
|
||||||
"mov" <t:MovVectorType> <a:Arg2Vec> => {
|
"mov" <t:MovVectorType> <a:Arg2Vec> => {
|
||||||
ast::Instruction::MovVector(ast::MovVectorDetails{typ: t, length: 0}, a)
|
ast::Instruction::MovVector(ast::MovVectorDetails{typ: t, length: 0}, a)
|
||||||
|
@ -4,43 +4,30 @@
|
|||||||
OpCapability Kernel
|
OpCapability Kernel
|
||||||
OpCapability Int64
|
OpCapability Int64
|
||||||
OpCapability Int8
|
OpCapability Int8
|
||||||
%25 = OpExtInstImport "OpenCL.std"
|
%12 = OpExtInstImport "OpenCL.std"
|
||||||
OpMemoryModel Physical64 OpenCL
|
OpMemoryModel Physical64 OpenCL
|
||||||
OpEntryPoint Kernel %1 "add"
|
OpEntryPoint Kernel %1 "mov_address"
|
||||||
%void = OpTypeVoid
|
%void = OpTypeVoid
|
||||||
%ulong = OpTypeInt 64 0
|
%ulong = OpTypeInt 64 0
|
||||||
%28 = OpTypeFunction %void %ulong %ulong
|
%15 = OpTypeFunction %void %ulong %ulong
|
||||||
%_ptr_Function_ulong = OpTypePointer Function %ulong
|
%_ptr_Function_ulong = OpTypePointer Function %ulong
|
||||||
%_ptr_Generic_ulong = OpTypePointer Generic %ulong
|
%uchar = OpTypeInt 8 0
|
||||||
%ulong_1 = OpConstant %ulong 1
|
%uint = OpTypeInt 32 0
|
||||||
%1 = OpFunction %void None %28
|
%uint_8 = OpConstant %uint 8
|
||||||
%8 = OpFunctionParameter %ulong
|
%_arr_uchar_uint_8 = OpTypeArray %uchar %uint_8
|
||||||
%9 = OpFunctionParameter %ulong
|
%_ptr_Function__arr_uchar_uint_8 = OpTypePointer Function %_arr_uchar_uint_8
|
||||||
%23 = OpLabel
|
%1 = OpFunction %void None %15
|
||||||
|
%6 = OpFunctionParameter %ulong
|
||||||
|
%7 = OpFunctionParameter %ulong
|
||||||
|
%10 = OpLabel
|
||||||
%2 = OpVariable %_ptr_Function_ulong Function
|
%2 = OpVariable %_ptr_Function_ulong Function
|
||||||
%3 = OpVariable %_ptr_Function_ulong Function
|
%3 = OpVariable %_ptr_Function_ulong Function
|
||||||
%4 = OpVariable %_ptr_Function_ulong Function
|
%4 = OpVariable %_ptr_Function__arr_uchar_uint_8 Function
|
||||||
%5 = OpVariable %_ptr_Function_ulong Function
|
%5 = OpVariable %_ptr_Function_ulong Function
|
||||||
%6 = OpVariable %_ptr_Function_ulong Function
|
OpStore %2 %6
|
||||||
%7 = OpVariable %_ptr_Function_ulong Function
|
OpStore %3 %7
|
||||||
OpStore %2 %8
|
%9 = OpConvertPtrToU %ulong %4
|
||||||
OpStore %3 %9
|
%8 = OpCopyObject %ulong %9
|
||||||
%11 = OpLoad %ulong %2
|
OpStore %5 %8
|
||||||
%10 = OpCopyObject %ulong %11
|
|
||||||
OpStore %4 %10
|
|
||||||
%13 = OpLoad %ulong %3
|
|
||||||
%12 = OpCopyObject %ulong %13
|
|
||||||
OpStore %5 %12
|
|
||||||
%15 = OpLoad %ulong %4
|
|
||||||
%21 = OpConvertUToPtr %_ptr_Generic_ulong %15
|
|
||||||
%14 = OpLoad %ulong %21
|
|
||||||
OpStore %6 %14
|
|
||||||
%17 = OpLoad %ulong %6
|
|
||||||
%16 = OpIAdd %ulong %17 %ulong_1
|
|
||||||
OpStore %7 %16
|
|
||||||
%18 = OpLoad %ulong %5
|
|
||||||
%19 = OpLoad %ulong %7
|
|
||||||
%22 = OpConvertUToPtr %_ptr_Generic_ulong %18
|
|
||||||
OpStore %22 %19
|
|
||||||
OpReturn
|
OpReturn
|
||||||
OpFunctionEnd
|
OpFunctionEnd
|
||||||
|
@ -480,37 +480,19 @@ fn add_types_to_statements(
|
|||||||
};
|
};
|
||||||
Ok(Statement::Instruction(ast::Instruction::St(d, arg)))
|
Ok(Statement::Instruction(ast::Instruction::St(d, arg)))
|
||||||
}
|
}
|
||||||
Statement::Instruction(ast::Instruction::Mov(d, mut arg)) => {
|
Statement::Instruction(ast::Instruction::Mov(mut d, arg)) => {
|
||||||
arg.src = match arg.src {
|
if let Some(src_id) = arg.src.underlying() {
|
||||||
ast::MovOperand::Reg(id) => {
|
let (scope, _) = id_defs.get_typed(*src_id)?;
|
||||||
let (ss, _) = id_defs.get_typed(id)?;
|
d.src_is_address = match scope {
|
||||||
match ss {
|
StateSpace::Reg => false,
|
||||||
StateSpace::Reg => ast::MovOperand::Reg(id),
|
|
||||||
StateSpace::Const
|
StateSpace::Const
|
||||||
| StateSpace::Global
|
| StateSpace::Global
|
||||||
| StateSpace::Local
|
| StateSpace::Local
|
||||||
| StateSpace::Shared
|
| StateSpace::Shared
|
||||||
| StateSpace::Param
|
| StateSpace::Param
|
||||||
| StateSpace::ParamReg => ast::MovOperand::Address(id),
|
| StateSpace::ParamReg => true,
|
||||||
}
|
|
||||||
}
|
|
||||||
ast::MovOperand::RegOffset(id, imm) => {
|
|
||||||
let (ss, _) = id_defs.get_typed(id)?;
|
|
||||||
match ss {
|
|
||||||
StateSpace::Reg => ast::MovOperand::RegOffset(id, imm),
|
|
||||||
StateSpace::Const
|
|
||||||
| StateSpace::Global
|
|
||||||
| StateSpace::Local
|
|
||||||
| StateSpace::Shared
|
|
||||||
| StateSpace::Param
|
|
||||||
| StateSpace::ParamReg => ast::MovOperand::AddressOffset(id, imm),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
a @ ast::MovOperand::Imm(_) => a,
|
|
||||||
ast::MovOperand::Address(_) | ast::MovOperand::AddressOffset(_, _) => {
|
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
}
|
||||||
Ok(Statement::Instruction(ast::Instruction::Mov(d, arg)))
|
Ok(Statement::Instruction(ast::Instruction::Mov(d, arg)))
|
||||||
}
|
}
|
||||||
Statement::Instruction(ast::Instruction::MovVector(dets, args)) => {
|
Statement::Instruction(ast::Instruction::MovVector(dets, args)) => {
|
||||||
@ -982,24 +964,6 @@ impl<'a, 'b> ArgumentMapVisitor<NormalizedArgParams, ExpandedArgParams>
|
|||||||
}));
|
}));
|
||||||
Ok(new_id)
|
Ok(new_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mov_operand(
|
|
||||||
&mut self,
|
|
||||||
desc: ArgumentDescriptor<ast::MovOperand<spirv::Word>>,
|
|
||||||
typ: ast::Type,
|
|
||||||
) -> Result<spirv::Word, TranslateError> {
|
|
||||||
match desc.op {
|
|
||||||
ast::MovOperand::Reg(r) => self.operand(desc.new_op(ast::Operand::Reg(r)), typ),
|
|
||||||
ast::MovOperand::RegOffset(r, imm) => {
|
|
||||||
self.operand(desc.new_op(ast::Operand::RegOffset(r, imm)), typ)
|
|
||||||
}
|
|
||||||
ast::MovOperand::Imm(x) => self.operand(desc.new_op(ast::Operand::Imm(x)), typ),
|
|
||||||
ast::MovOperand::Address(r) => self.operand(desc.new_op(ast::Operand::Reg(r)), typ),
|
|
||||||
ast::MovOperand::AddressOffset(r, imm) => {
|
|
||||||
self.operand(desc.new_op(ast::Operand::RegOffset(r, imm)), typ)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1081,7 +1045,7 @@ fn insert_implicit_conversions(
|
|||||||
ast::Instruction::Mov(d, mut arg) => {
|
ast::Instruction::Mov(d, mut arg) => {
|
||||||
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-mov-2
|
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-mov-2
|
||||||
// TODO: handle the case of mixed vector/scalar implicit conversions
|
// TODO: handle the case of mixed vector/scalar implicit conversions
|
||||||
let inst_typ_is_bit = match d {
|
let inst_typ_is_bit = match d.typ {
|
||||||
ast::MovType::Scalar(t) => {
|
ast::MovType::Scalar(t) => {
|
||||||
ast::ScalarType::from(t).kind() == ScalarKind::Bit
|
ast::ScalarType::from(t).kind() == ScalarKind::Bit
|
||||||
}
|
}
|
||||||
@ -1097,7 +1061,7 @@ fn insert_implicit_conversions(
|
|||||||
id_def,
|
id_def,
|
||||||
arg.src,
|
arg.src,
|
||||||
src_type,
|
src_type,
|
||||||
d.into(),
|
d.typ.into(),
|
||||||
ConversionKind::Default,
|
ConversionKind::Default,
|
||||||
);
|
);
|
||||||
did_vector_implicit = true;
|
did_vector_implicit = true;
|
||||||
@ -1107,7 +1071,7 @@ fn insert_implicit_conversions(
|
|||||||
post_conv = Some(get_conversion_dst(
|
post_conv = Some(get_conversion_dst(
|
||||||
id_def,
|
id_def,
|
||||||
&mut arg.dst,
|
&mut arg.dst,
|
||||||
d.into(),
|
d.typ.into(),
|
||||||
dst_type,
|
dst_type,
|
||||||
ConversionKind::Default,
|
ConversionKind::Default,
|
||||||
));
|
));
|
||||||
@ -1305,9 +1269,9 @@ fn emit_function_body_ops(
|
|||||||
}
|
}
|
||||||
// SPIR-V does not support ret as guaranteed-converged
|
// SPIR-V does not support ret as guaranteed-converged
|
||||||
ast::Instruction::Ret(_) => builder.ret()?,
|
ast::Instruction::Ret(_) => builder.ret()?,
|
||||||
ast::Instruction::Mov(mov_type, arg) => {
|
ast::Instruction::Mov(d, arg) => {
|
||||||
let result_type =
|
let result_type =
|
||||||
map.get_or_add(builder, SpirvType::from(ast::Type::from(*mov_type)));
|
map.get_or_add(builder, SpirvType::from(ast::Type::from(d.typ)));
|
||||||
builder.copy_object(result_type, Some(arg.dst), arg.src)?;
|
builder.copy_object(result_type, Some(arg.dst), arg.src)?;
|
||||||
}
|
}
|
||||||
ast::Instruction::Mul(mul, arg) => match mul {
|
ast::Instruction::Mul(mul, arg) => match mul {
|
||||||
@ -1690,6 +1654,10 @@ fn emit_implicit_conversion(
|
|||||||
let from_parts = cv.from.to_parts();
|
let from_parts = cv.from.to_parts();
|
||||||
let to_parts = cv.to.to_parts();
|
let to_parts = cv.to.to_parts();
|
||||||
match (from_parts.kind, to_parts.kind, cv.kind) {
|
match (from_parts.kind, to_parts.kind, cv.kind) {
|
||||||
|
(_, _, ConversionKind::PtrToBit) => {
|
||||||
|
let dst_type = map.get_or_add_scalar(builder, ast::ScalarType::B64);
|
||||||
|
builder.convert_ptr_to_u(dst_type, Some(cv.dst), cv.src)?;
|
||||||
|
}
|
||||||
(_, _, ConversionKind::BitToPtr(space)) => {
|
(_, _, ConversionKind::BitToPtr(space)) => {
|
||||||
let dst_type = map.get_or_add(
|
let dst_type = map.get_or_add(
|
||||||
builder,
|
builder,
|
||||||
@ -2214,7 +2182,6 @@ pub trait ArgParamsEx: ast::ArgParams {
|
|||||||
id: &Self::ID,
|
id: &Self::ID,
|
||||||
decl: &'b GlobalFnDeclResolver<'x, 'b>,
|
decl: &'b GlobalFnDeclResolver<'x, 'b>,
|
||||||
) -> Result<&'b FnDecl, TranslateError>;
|
) -> Result<&'b FnDecl, TranslateError>;
|
||||||
fn get_src_semantics(m: &Self::MovOperand) -> ArgumentSemantics;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'input> ArgParamsEx for ast::ParsedArgParams<'input> {
|
impl<'input> ArgParamsEx for ast::ParsedArgParams<'input> {
|
||||||
@ -2224,10 +2191,6 @@ impl<'input> ArgParamsEx for ast::ParsedArgParams<'input> {
|
|||||||
) -> Result<&'b FnDecl, TranslateError> {
|
) -> Result<&'b FnDecl, TranslateError> {
|
||||||
decl.get_fn_decl_str(id)
|
decl.get_fn_decl_str(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_src_semantics(_: &Self::MovOperand) -> ArgumentSemantics {
|
|
||||||
ArgumentSemantics::Default
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum NormalizedArgParams {}
|
enum NormalizedArgParams {}
|
||||||
@ -2243,7 +2206,6 @@ type UnadornedStatement = Statement<ast::Instruction<NormalizedArgParams>, Norma
|
|||||||
impl ast::ArgParams for NormalizedArgParams {
|
impl ast::ArgParams for NormalizedArgParams {
|
||||||
type ID = spirv::Word;
|
type ID = spirv::Word;
|
||||||
type Operand = ast::Operand<spirv::Word>;
|
type Operand = ast::Operand<spirv::Word>;
|
||||||
type MovOperand = ast::MovOperand<spirv::Word>;
|
|
||||||
type CallOperand = ast::CallOperand<spirv::Word>;
|
type CallOperand = ast::CallOperand<spirv::Word>;
|
||||||
type VecOperand = (spirv::Word, u8);
|
type VecOperand = (spirv::Word, u8);
|
||||||
}
|
}
|
||||||
@ -2255,10 +2217,6 @@ impl ArgParamsEx for NormalizedArgParams {
|
|||||||
) -> Result<&'b FnDecl, TranslateError> {
|
) -> Result<&'b FnDecl, TranslateError> {
|
||||||
decl.get_fn_decl(*id)
|
decl.get_fn_decl(*id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_src_semantics(m: &ast::MovOperand<spirv::Word>) -> ArgumentSemantics {
|
|
||||||
m.src_semantics()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
@ -2284,7 +2242,6 @@ struct Function<'input> {
|
|||||||
impl ast::ArgParams for ExpandedArgParams {
|
impl ast::ArgParams for ExpandedArgParams {
|
||||||
type ID = spirv::Word;
|
type ID = spirv::Word;
|
||||||
type Operand = spirv::Word;
|
type Operand = spirv::Word;
|
||||||
type MovOperand = spirv::Word;
|
|
||||||
type CallOperand = spirv::Word;
|
type CallOperand = spirv::Word;
|
||||||
type VecOperand = spirv::Word;
|
type VecOperand = spirv::Word;
|
||||||
}
|
}
|
||||||
@ -2296,10 +2253,6 @@ impl ArgParamsEx for ExpandedArgParams {
|
|||||||
) -> Result<&'b FnDecl, TranslateError> {
|
) -> Result<&'b FnDecl, TranslateError> {
|
||||||
decl.get_fn_decl(*id)
|
decl.get_fn_decl(*id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_src_semantics(_: &spirv::Word) -> ArgumentSemantics {
|
|
||||||
ArgumentSemantics::Default
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trait ArgumentMapVisitor<T: ArgParamsEx, U: ArgParamsEx> {
|
trait ArgumentMapVisitor<T: ArgParamsEx, U: ArgParamsEx> {
|
||||||
@ -2313,11 +2266,6 @@ trait ArgumentMapVisitor<T: ArgParamsEx, U: ArgParamsEx> {
|
|||||||
desc: ArgumentDescriptor<T::Operand>,
|
desc: ArgumentDescriptor<T::Operand>,
|
||||||
typ: ast::Type,
|
typ: ast::Type,
|
||||||
) -> Result<U::Operand, TranslateError>;
|
) -> Result<U::Operand, TranslateError>;
|
||||||
fn mov_operand(
|
|
||||||
&mut self,
|
|
||||||
desc: ArgumentDescriptor<T::MovOperand>,
|
|
||||||
typ: ast::Type,
|
|
||||||
) -> Result<U::MovOperand, TranslateError>;
|
|
||||||
fn src_call_operand(
|
fn src_call_operand(
|
||||||
&mut self,
|
&mut self,
|
||||||
desc: ArgumentDescriptor<T::CallOperand>,
|
desc: ArgumentDescriptor<T::CallOperand>,
|
||||||
@ -2353,14 +2301,6 @@ where
|
|||||||
self(desc, Some(t))
|
self(desc, Some(t))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mov_operand(
|
|
||||||
&mut self,
|
|
||||||
desc: ArgumentDescriptor<spirv::Word>,
|
|
||||||
t: ast::Type,
|
|
||||||
) -> Result<spirv::Word, TranslateError> {
|
|
||||||
self(desc, Some(t))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn src_call_operand(
|
fn src_call_operand(
|
||||||
&mut self,
|
&mut self,
|
||||||
desc: ArgumentDescriptor<spirv::Word>,
|
desc: ArgumentDescriptor<spirv::Word>,
|
||||||
@ -2423,22 +2363,6 @@ where
|
|||||||
) -> Result<(spirv::Word, u8), TranslateError> {
|
) -> Result<(spirv::Word, u8), TranslateError> {
|
||||||
Ok((self(desc.op.0)?, desc.op.1))
|
Ok((self(desc.op.0)?, desc.op.1))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mov_operand(
|
|
||||||
&mut self,
|
|
||||||
desc: ArgumentDescriptor<ast::MovOperand<&str>>,
|
|
||||||
_: ast::Type,
|
|
||||||
) -> Result<ast::MovOperand<spirv::Word>, TranslateError> {
|
|
||||||
match desc.op {
|
|
||||||
ast::MovOperand::Reg(r) => Ok(ast::MovOperand::Reg(self(r)?)),
|
|
||||||
ast::MovOperand::Address(a) => Ok(ast::MovOperand::Address(self(a)?)),
|
|
||||||
ast::MovOperand::RegOffset(r, imm) => Ok(ast::MovOperand::RegOffset(self(r)?, imm)),
|
|
||||||
ast::MovOperand::AddressOffset(a, imm) => {
|
|
||||||
Ok(ast::MovOperand::AddressOffset(self(a)?, imm))
|
|
||||||
}
|
|
||||||
ast::MovOperand::Imm(x) => Ok(ast::MovOperand::Imm(x)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ArgumentDescriptor<Op> {
|
struct ArgumentDescriptor<Op> {
|
||||||
@ -2479,7 +2403,7 @@ impl<T: ArgParamsEx> ast::Instruction<T> {
|
|||||||
ast::Instruction::MovVector(t, a.map(visitor, (t.typ, t.length))?)
|
ast::Instruction::MovVector(t, a.map(visitor, (t.typ, t.length))?)
|
||||||
}
|
}
|
||||||
ast::Instruction::Abs(d, arg) => {
|
ast::Instruction::Abs(d, arg) => {
|
||||||
ast::Instruction::Abs(d, arg.map(visitor, ast::Type::Scalar(d.typ))?)
|
ast::Instruction::Abs(d, arg.map(visitor, false, ast::Type::Scalar(d.typ))?)
|
||||||
}
|
}
|
||||||
// Call instruction is converted to a call statement early on
|
// Call instruction is converted to a call statement early on
|
||||||
ast::Instruction::Call(_) => unreachable!(),
|
ast::Instruction::Call(_) => unreachable!(),
|
||||||
@ -2488,8 +2412,9 @@ impl<T: ArgParamsEx> ast::Instruction<T> {
|
|||||||
let is_param = d.state_space == ast::LdStateSpace::Param;
|
let is_param = d.state_space == ast::LdStateSpace::Param;
|
||||||
ast::Instruction::Ld(d, a.map_ld(visitor, inst_type, is_param)?)
|
ast::Instruction::Ld(d, a.map_ld(visitor, inst_type, is_param)?)
|
||||||
}
|
}
|
||||||
ast::Instruction::Mov(mov_type, a) => {
|
ast::Instruction::Mov(d, a) => {
|
||||||
ast::Instruction::Mov(mov_type, a.map(visitor, mov_type.into())?)
|
let mapped = a.map(visitor, d.src_is_address, d.typ.into())?;
|
||||||
|
ast::Instruction::Mov(d, mapped)
|
||||||
}
|
}
|
||||||
ast::Instruction::Mul(d, a) => {
|
ast::Instruction::Mul(d, a) => {
|
||||||
let inst_type = d.get_type();
|
let inst_type = d.get_type();
|
||||||
@ -2507,7 +2432,7 @@ impl<T: ArgParamsEx> ast::Instruction<T> {
|
|||||||
let inst_type = d.typ;
|
let inst_type = d.typ;
|
||||||
ast::Instruction::SetpBool(d, a.map(visitor, ast::Type::Scalar(inst_type))?)
|
ast::Instruction::SetpBool(d, a.map(visitor, ast::Type::Scalar(inst_type))?)
|
||||||
}
|
}
|
||||||
ast::Instruction::Not(t, a) => ast::Instruction::Not(t, a.map(visitor, t.to_type())?),
|
ast::Instruction::Not(t, a) => ast::Instruction::Not(t, a.map(visitor, false, t.to_type())?),
|
||||||
ast::Instruction::Cvt(d, a) => {
|
ast::Instruction::Cvt(d, a) => {
|
||||||
let (dst_t, src_t) = match &d {
|
let (dst_t, src_t) = match &d {
|
||||||
ast::CvtDetails::FloatFromFloat(desc) => (
|
ast::CvtDetails::FloatFromFloat(desc) => (
|
||||||
@ -2541,7 +2466,7 @@ impl<T: ArgParamsEx> ast::Instruction<T> {
|
|||||||
ast::Instruction::Ret(d) => ast::Instruction::Ret(d),
|
ast::Instruction::Ret(d) => ast::Instruction::Ret(d),
|
||||||
ast::Instruction::Cvta(d, a) => {
|
ast::Instruction::Cvta(d, a) => {
|
||||||
let inst_type = ast::Type::Scalar(ast::ScalarType::B64);
|
let inst_type = ast::Type::Scalar(ast::ScalarType::B64);
|
||||||
ast::Instruction::Cvta(d, a.map(visitor, inst_type)?)
|
ast::Instruction::Cvta(d, a.map(visitor, false, inst_type)?)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -2616,28 +2541,6 @@ where
|
|||||||
desc.op.1,
|
desc.op.1,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mov_operand(
|
|
||||||
&mut self,
|
|
||||||
desc: ArgumentDescriptor<ast::MovOperand<spirv::Word>>,
|
|
||||||
t: ast::Type,
|
|
||||||
) -> Result<ast::MovOperand<spirv::Word>, TranslateError> {
|
|
||||||
match desc.op {
|
|
||||||
ast::MovOperand::Reg(r) => Ok(ast::MovOperand::Reg(self(desc.new_op(r), Some(t))?)),
|
|
||||||
ast::MovOperand::Address(a) => {
|
|
||||||
Ok(ast::MovOperand::Address(self(desc.new_op(a), Some(t))?))
|
|
||||||
}
|
|
||||||
ast::MovOperand::RegOffset(r, imm) => Ok(ast::MovOperand::RegOffset(
|
|
||||||
self(desc.new_op(r), Some(t))?,
|
|
||||||
imm,
|
|
||||||
)),
|
|
||||||
ast::MovOperand::AddressOffset(a, imm) => Ok(ast::MovOperand::AddressOffset(
|
|
||||||
self(desc.new_op(a), Some(t))?,
|
|
||||||
imm,
|
|
||||||
)),
|
|
||||||
ast::MovOperand::Imm(x) => Ok(ast::MovOperand::Imm(x)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ast::Type {
|
impl ast::Type {
|
||||||
@ -2836,6 +2739,7 @@ impl<T: ArgParamsEx> ast::Arg2<T> {
|
|||||||
fn map<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
|
fn map<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
|
||||||
self,
|
self,
|
||||||
visitor: &mut V,
|
visitor: &mut V,
|
||||||
|
src_is_addr: bool,
|
||||||
t: ast::Type,
|
t: ast::Type,
|
||||||
) -> Result<ast::Arg2<U>, TranslateError> {
|
) -> Result<ast::Arg2<U>, TranslateError> {
|
||||||
let new_dst = visitor.variable(
|
let new_dst = visitor.variable(
|
||||||
@ -2850,7 +2754,11 @@ impl<T: ArgParamsEx> ast::Arg2<T> {
|
|||||||
ArgumentDescriptor {
|
ArgumentDescriptor {
|
||||||
op: self.src,
|
op: self.src,
|
||||||
is_dst: false,
|
is_dst: false,
|
||||||
sema: ArgumentSemantics::Default,
|
sema: if src_is_addr {
|
||||||
|
ArgumentSemantics::Address
|
||||||
|
} else {
|
||||||
|
ArgumentSemantics::Default
|
||||||
|
},
|
||||||
},
|
},
|
||||||
t,
|
t,
|
||||||
)?;
|
)?;
|
||||||
@ -2915,46 +2823,6 @@ impl<T: ArgParamsEx> ast::Arg2<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ArgParamsEx> ast::Arg2Mov<T> {
|
|
||||||
fn map<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
|
|
||||||
self,
|
|
||||||
visitor: &mut V,
|
|
||||||
t: ast::Type,
|
|
||||||
) -> Result<ast::Arg2Mov<U>, TranslateError> {
|
|
||||||
let dst = visitor.variable(
|
|
||||||
ArgumentDescriptor {
|
|
||||||
op: self.dst,
|
|
||||||
is_dst: true,
|
|
||||||
sema: ArgumentSemantics::Default,
|
|
||||||
},
|
|
||||||
Some(t),
|
|
||||||
)?;
|
|
||||||
let src_sema = T::get_src_semantics(&self.src);
|
|
||||||
let src = visitor.mov_operand(
|
|
||||||
ArgumentDescriptor {
|
|
||||||
op: self.src,
|
|
||||||
is_dst: false,
|
|
||||||
sema: src_sema,
|
|
||||||
},
|
|
||||||
t,
|
|
||||||
)?;
|
|
||||||
Ok(ast::Arg2Mov { dst, src })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ast::MovOperand<T> {
|
|
||||||
fn src_semantics(&self) -> ArgumentSemantics {
|
|
||||||
match self {
|
|
||||||
ast::MovOperand::Reg(_)
|
|
||||||
| ast::MovOperand::RegOffset(_, _)
|
|
||||||
| ast::MovOperand::Imm(_) => ArgumentSemantics::Default,
|
|
||||||
ast::MovOperand::Address(_) | ast::MovOperand::AddressOffset(_, _) => {
|
|
||||||
ArgumentSemantics::Address
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ArgParamsEx> ast::Arg2St<T> {
|
impl<T: ArgParamsEx> ast::Arg2St<T> {
|
||||||
fn map<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
|
fn map<U: ArgParamsEx, V: ArgumentMapVisitor<T, U>>(
|
||||||
self,
|
self,
|
||||||
|
Reference in New Issue
Block a user