From ef4e8cacf9490a92fbc94750d9e2bb6114cfd572 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Sun, 6 Dec 2020 01:35:23 -0500 Subject: [PATCH] [spv] refactor binary operators, add module and addition --- src/back/spv/instructions.rs | 117 +-------------------------- src/back/spv/writer.rs | 153 ++++++++++++++--------------------- 2 files changed, 60 insertions(+), 210 deletions(-) diff --git a/src/back/spv/instructions.rs b/src/back/spv/instructions.rs index ab8e56844a..fe03a4d61c 100644 --- a/src/back/spv/instructions.rs +++ b/src/back/spv/instructions.rs @@ -537,7 +537,7 @@ pub(super) fn instruction_composite_construct( // // Arithmetic Instructions // -fn instruction_binary( +pub(super) fn instruction_binary( op: Op, result_type_id: Word, id: Word, @@ -552,125 +552,10 @@ fn instruction_binary( instruction } -pub(super) fn instruction_i_sub( - result_type_id: Word, - id: Word, - operand_1: Word, - operand_2: Word, -) -> Instruction { - instruction_binary(Op::ISub, result_type_id, id, operand_1, operand_2) -} - -pub(super) fn instruction_f_sub( - result_type_id: Word, - id: Word, - operand_1: Word, - operand_2: Word, -) -> Instruction { - instruction_binary(Op::FSub, result_type_id, id, operand_1, operand_2) -} - -pub(super) fn instruction_i_mul( - result_type_id: Word, - id: Word, - operand_1: Word, - operand_2: Word, -) -> Instruction { - instruction_binary(Op::IMul, result_type_id, id, operand_1, operand_2) -} - -pub(super) fn instruction_f_mul( - result_type_id: Word, - id: Word, - operand_1: Word, - operand_2: Word, -) -> Instruction { - instruction_binary(Op::FMul, result_type_id, id, operand_1, operand_2) -} - -pub(super) fn instruction_vector_times_scalar( - result_type_id: Word, - id: Word, - vector_type_id: Word, - scalar_type_id: Word, -) -> Instruction { - let mut instruction = Instruction::new(Op::VectorTimesScalar); - instruction.set_type(result_type_id); - instruction.set_result(id); - instruction.add_operand(vector_type_id); - instruction.add_operand(scalar_type_id); - instruction -} - -pub(super) fn instruction_matrix_times_scalar( - result_type_id: Word, - id: Word, - matrix_id: Word, - scalar_id: Word, -) -> Instruction { - let mut instruction = Instruction::new(Op::MatrixTimesScalar); - instruction.set_type(result_type_id); - instruction.set_result(id); - instruction.add_operand(matrix_id); - instruction.add_operand(scalar_id); - instruction -} - -pub(super) fn instruction_vector_times_matrix( - result_type_id: Word, - id: Word, - vector_id: Word, - matrix_id: Word, -) -> Instruction { - let mut instruction = Instruction::new(Op::VectorTimesMatrix); - instruction.set_type(result_type_id); - instruction.set_result(id); - instruction.add_operand(vector_id); - instruction.add_operand(matrix_id); - instruction -} - -pub(super) fn instruction_matrix_times_vector( - result_type_id: Word, - id: Word, - matrix_id: Word, - vector_id: Word, -) -> Instruction { - let mut instruction = Instruction::new(Op::MatrixTimesVector); - instruction.set_type(result_type_id); - instruction.set_result(id); - instruction.add_operand(matrix_id); - instruction.add_operand(vector_id); - instruction -} - -pub(super) fn instruction_matrix_times_matrix( - result_type_id: Word, - id: Word, - left_matrix: Word, - right_matrix: Word, -) -> Instruction { - let mut instruction = Instruction::new(Op::MatrixTimesMatrix); - instruction.set_type(result_type_id); - instruction.set_result(id); - instruction.add_operand(left_matrix); - instruction.add_operand(right_matrix); - instruction -} - // // Bit Instructions // -pub(super) fn instruction_bitwise_and( - result_type_id: Word, - id: Word, - operand_1: Word, - operand_2: Word, -) -> Instruction { - instruction_binary(Op::BitwiseAnd, result_type_id, id, operand_1, operand_2) -} - // // Relational and Logical Instructions // diff --git a/src/back/spv/writer.rs b/src/back/spv/writer.rs index fc4cdea667..f4d71b82fb 100644 --- a/src/back/spv/writer.rs +++ b/src/back/spv/writer.rs @@ -1147,116 +1147,81 @@ impl Writer { let left_dimension = get_dimension(&left_ty_inner); let right_dimension = get_dimension(&right_ty_inner); - let (instruction, lookup_ty) = match op { + let (spirv_op, lookup_ty) = match op { + crate::BinaryOperator::Add => match *left_ty_inner { + crate::TypeInner::Scalar { kind, .. } + | crate::TypeInner::Vector { kind, .. } => match kind { + crate::ScalarKind::Float => (spirv::Op::FAdd, left_lookup_ty), + _ => (spirv::Op::IAdd, left_lookup_ty), + }, + _ => unreachable!(), + }, + crate::BinaryOperator::Subtract => match *left_ty_inner { + crate::TypeInner::Scalar { kind, .. } + | crate::TypeInner::Vector { kind, .. } => match kind { + crate::ScalarKind::Float => (spirv::Op::FSub, left_lookup_ty), + _ => (spirv::Op::ISub, left_lookup_ty), + }, + _ => unreachable!(), + }, crate::BinaryOperator::Multiply => match (left_dimension, right_dimension) { - (Dimension::Vector, Dimension::Scalar { .. }) => ( - super::instructions::instruction_vector_times_scalar( - left_result_type_id, - id, - left_id, - right_id, - ), - left_lookup_ty, - ), - (Dimension::Vector, Dimension::Matrix) => ( - super::instructions::instruction_vector_times_matrix( - left_result_type_id, - id, - left_id, - right_id, - ), - left_lookup_ty, - ), - (Dimension::Matrix, Dimension::Scalar { .. }) => ( - super::instructions::instruction_matrix_times_scalar( - left_result_type_id, - id, - left_id, - right_id, - ), - left_lookup_ty, - ), - (Dimension::Matrix, Dimension::Vector) => ( - super::instructions::instruction_matrix_times_vector( - right_result_type_id, - id, - left_id, - right_id, - ), - right_lookup_ty, - ), - (Dimension::Matrix, Dimension::Matrix) => ( - super::instructions::instruction_matrix_times_matrix( - left_result_type_id, - id, - left_id, - right_id, - ), - left_lookup_ty, - ), + (Dimension::Vector, Dimension::Scalar { .. }) => { + (spirv::Op::VectorTimesScalar, left_lookup_ty) + } + (Dimension::Vector, Dimension::Matrix) => { + (spirv::Op::VectorTimesMatrix, left_lookup_ty) + } + (Dimension::Matrix, Dimension::Scalar { .. }) => { + (spirv::Op::MatrixTimesScalar, left_lookup_ty) + } + (Dimension::Matrix, Dimension::Vector) => { + (spirv::Op::MatrixTimesVector, right_lookup_ty) + } + (Dimension::Matrix, Dimension::Matrix) => { + (spirv::Op::MatrixTimesMatrix, left_lookup_ty) + } (Dimension::Vector, Dimension::Vector) | (Dimension::Scalar, Dimension::Scalar) if left_ty_inner.scalar_kind() == Some(crate::ScalarKind::Float) => { - ( - super::instructions::instruction_f_mul( - left_result_type_id, - id, - left_id, - right_id, - ), - left_lookup_ty, - ) + (spirv::Op::FMul, left_lookup_ty) } (Dimension::Vector, Dimension::Vector) - | (Dimension::Scalar, Dimension::Scalar) => ( - super::instructions::instruction_i_mul( - left_result_type_id, - id, - left_id, - right_id, - ), - left_lookup_ty, - ), + | (Dimension::Scalar, Dimension::Scalar) => { + (spirv::Op::IMul, left_lookup_ty) + } _ => unreachable!(), }, - crate::BinaryOperator::Subtract => match *left_ty_inner { - crate::TypeInner::Scalar { kind, .. } => match kind { - crate::ScalarKind::Sint | crate::ScalarKind::Uint => ( - super::instructions::instruction_i_sub( - left_result_type_id, - id, - left_id, - right_id, - ), - left_lookup_ty, - ), - crate::ScalarKind::Float => ( - super::instructions::instruction_f_sub( - left_result_type_id, - id, - left_id, - right_id, - ), - left_lookup_ty, - ), + crate::BinaryOperator::Divide => match *left_ty_inner { + crate::TypeInner::Scalar { kind, .. } + | crate::TypeInner::Vector { kind, .. } => match kind { + crate::ScalarKind::Sint => (spirv::Op::SDiv, left_lookup_ty), + crate::ScalarKind::Uint => (spirv::Op::UDiv, left_lookup_ty), _ => unreachable!(), }, _ => unreachable!(), }, - crate::BinaryOperator::And => ( - super::instructions::instruction_bitwise_and( - left_result_type_id, - id, - left_id, - right_id, - ), - left_lookup_ty, - ), + crate::BinaryOperator::Modulo => match *left_ty_inner { + crate::TypeInner::Scalar { kind, .. } + | crate::TypeInner::Vector { kind, .. } => match kind { + crate::ScalarKind::Sint => (spirv::Op::SMod, left_lookup_ty), + crate::ScalarKind::Uint => (spirv::Op::UMod, left_lookup_ty), + crate::ScalarKind::Float => (spirv::Op::FMod, left_lookup_ty), + _ => unreachable!(), + }, + _ => unreachable!(), + }, + crate::BinaryOperator::And => (spirv::Op::BitwiseAnd, left_lookup_ty), _ => unimplemented!("{:?}", op), }; - block.body.push(instruction); + block.body.push(super::instructions::instruction_binary( + spirv_op, + left_result_type_id, + id, + left_id, + right_id, + )); Ok((id, lookup_ty)) } crate::Expression::LocalVariable(variable) => {