From cbcdcf470fbd6f97e2f8672dadc2b06c236ba6e1 Mon Sep 17 00:00:00 2001 From: Timo de Kort Date: Sat, 14 Nov 2020 11:36:57 +0100 Subject: [PATCH] [spv-out] Add and implement i_sub and f_sub --- src/back/spv/instructions.rs | 46 ++++-- src/back/spv/writer.rs | 302 ++++++++++++++++++----------------- 2 files changed, 190 insertions(+), 158 deletions(-) diff --git a/src/back/spv/instructions.rs b/src/back/spv/instructions.rs index 6741dbbf6e..b763f7c549 100644 --- a/src/back/spv/instructions.rs +++ b/src/back/spv/instructions.rs @@ -571,6 +571,38 @@ pub(super) fn instruction_composite_construct( // // Arithmetic Instructions // +fn instruction_binary( + op: Op, + result_type_id: Word, + id: Word, + operand_1: Word, + operand_2: Word, +) -> Instruction { + let mut instruction = Instruction::new(op); + instruction.set_type(result_type_id); + instruction.set_result(id); + instruction.add_operand(operand_1); + instruction.add_operand(operand_2); + 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, @@ -578,12 +610,7 @@ pub(super) fn instruction_i_mul( operand_1: Word, operand_2: Word, ) -> Instruction { - let mut instruction = Instruction::new(Op::IMul); - instruction.set_type(result_type_id); - instruction.set_result(id); - instruction.add_operand(operand_1); - instruction.add_operand(operand_2); - instruction + instruction_binary(Op::IMul, result_type_id, id, operand_1, operand_2) } pub(super) fn instruction_f_mul( @@ -592,12 +619,7 @@ pub(super) fn instruction_f_mul( operand_1: Word, operand_2: Word, ) -> Instruction { - let mut instruction = Instruction::new(Op::FMul); - instruction.set_type(result_type_id); - instruction.set_result(id); - instruction.add_operand(operand_1); - instruction.add_operand(operand_2); - instruction + instruction_binary(Op::FMul, result_type_id, id, operand_1, operand_2) } pub(super) fn instruction_vector_times_scalar( diff --git a/src/back/spv/writer.rs b/src/back/spv/writer.rs index 264091572b..96062ac01f 100644 --- a/src/back/spv/writer.rs +++ b/src/back/spv/writer.rs @@ -190,13 +190,8 @@ impl Writer { } else { match lookup_ty { LookupType::Handle(handle) => match arena[handle].inner { - crate::TypeInner::Scalar { kind, width } => self.get_type_id( - arena, - LookupType::Local(LocalType::Scalar { - kind, - width, - }), - ), + crate::TypeInner::Scalar { kind, width } => self + .get_type_id(arena, LookupType::Local(LocalType::Scalar { kind, width })), _ => self.write_type_declaration_arena(arena, handle), }, LookupType::Local(local_ty) => self.write_type_declaration_local(arena, local_ty), @@ -1062,153 +1057,168 @@ impl Writer { Ok((id, Some(LookupType::Handle(ty)))) } crate::Expression::Binary { op, left, right } => { - match op { - crate::BinaryOperator::Multiply => { - let id = self.generate_id(); - let left_expression = &ir_function.expressions[left]; - let right_expression = &ir_function.expressions[right]; - let (left_id, left_lookup_ty) = self.write_expression( - ir_module, - ir_function, - left_expression, - block, - function, - )?; - let (right_id, right_lookup_ty) = self.write_expression( - ir_module, - ir_function, - right_expression, - block, - function, - )?; + let id = self.generate_id(); + let left_expression = &ir_function.expressions[left]; + let right_expression = &ir_function.expressions[right]; + let (left_id, left_lookup_ty) = self.write_expression( + ir_module, + ir_function, + left_expression, + block, + function, + )?; + let (right_id, right_lookup_ty) = self.write_expression( + ir_module, + ir_function, + right_expression, + block, + function, + )?; - let left_lookup_ty = left_lookup_ty.unwrap(); - let right_lookup_ty = right_lookup_ty.unwrap(); + let left_lookup_ty = left_lookup_ty.unwrap(); + let right_lookup_ty = right_lookup_ty.unwrap(); - let left_ty_inner = self.get_type_inner(&ir_module.types, left_lookup_ty); - let right_ty_inner = self.get_type_inner(&ir_module.types, right_lookup_ty); + let left_ty_inner = self.get_type_inner(&ir_module.types, left_lookup_ty); + let right_ty_inner = self.get_type_inner(&ir_module.types, right_lookup_ty); - let left_result_type_id = - self.get_type_id(&ir_module.types, left_lookup_ty); + let left_result_type_id = self.get_type_id(&ir_module.types, left_lookup_ty); - let right_result_type_id = - self.get_type_id(&ir_module.types, right_lookup_ty); + let right_result_type_id = self.get_type_id(&ir_module.types, right_lookup_ty); - let left_id = match *left_expression { - crate::Expression::LocalVariable(_) - | crate::Expression::GlobalVariable(_) => { - let load_id = self.generate_id(); - block.body.push(super::instructions::instruction_load( - left_result_type_id, - load_id, - left_id, - None, - )); - load_id - } - _ => left_id, - }; - - let right_id = match *right_expression { - crate::Expression::LocalVariable(..) - | crate::Expression::GlobalVariable(..) => { - let load_id = self.generate_id(); - block.body.push(super::instructions::instruction_load( - right_result_type_id, - load_id, - right_id, - None, - )); - load_id - } - _ => right_id, - }; - - let (instruction, lookup_ty) = match *left_ty_inner { - crate::TypeInner::Vector { .. } => match *right_ty_inner { - crate::TypeInner::Scalar { .. } => ( - super::instructions::instruction_vector_times_scalar( - left_result_type_id, - id, - left_id, - right_id, - ), - left_lookup_ty, - ), - crate::TypeInner::Matrix { .. } => ( - super::instructions::instruction_vector_times_matrix( - left_result_type_id, - id, - left_id, - right_id, - ), - left_lookup_ty, - ), - _ => unreachable!(), - }, - crate::TypeInner::Matrix { .. } => match *right_ty_inner { - crate::TypeInner::Scalar { .. } => ( - super::instructions::instruction_matrix_times_scalar( - left_result_type_id, - id, - left_id, - right_id, - ), - left_lookup_ty, - ), - crate::TypeInner::Vector { .. } => ( - super::instructions::instruction_matrix_times_vector( - right_result_type_id, - id, - left_id, - right_id, - ), - right_lookup_ty, - ), - crate::TypeInner::Matrix { .. } => ( - super::instructions::instruction_matrix_times_matrix( - left_result_type_id, - id, - left_id, - right_id, - ), - left_lookup_ty, - ), - _ => unreachable!(), - }, - crate::TypeInner::Scalar { kind, .. } => { - // Always assuming left and hand side are equal scalar types. - match kind { - crate::ScalarKind::Float => ( - super::instructions::instruction_f_mul( - left_result_type_id, - id, - left_id, - right_id, - ), - left_lookup_ty, - ), - crate::ScalarKind::Sint | crate::ScalarKind::Uint => ( - super::instructions::instruction_i_mul( - left_result_type_id, - id, - left_id, - right_id, - ), - left_lookup_ty, - ), - _ => unreachable!(), - } - } - _ => unreachable!(), - }; - - block.body.push(instruction); - Ok((id, Some(lookup_ty))) + let left_id = match *left_expression { + crate::Expression::LocalVariable(_) | crate::Expression::GlobalVariable(_) => { + let load_id = self.generate_id(); + block.body.push(super::instructions::instruction_load( + left_result_type_id, + load_id, + left_id, + None, + )); + load_id } + _ => left_id, + }; + let right_id = match *right_expression { + crate::Expression::LocalVariable(..) + | crate::Expression::GlobalVariable(..) => { + let load_id = self.generate_id(); + block.body.push(super::instructions::instruction_load( + right_result_type_id, + load_id, + right_id, + None, + )); + load_id + } + _ => right_id, + }; + + let (instruction, lookup_ty) = match op { + crate::BinaryOperator::Multiply => match *left_ty_inner { + crate::TypeInner::Vector { .. } => match *right_ty_inner { + crate::TypeInner::Scalar { .. } => ( + super::instructions::instruction_vector_times_scalar( + left_result_type_id, + id, + left_id, + right_id, + ), + left_lookup_ty, + ), + crate::TypeInner::Matrix { .. } => ( + super::instructions::instruction_vector_times_matrix( + left_result_type_id, + id, + left_id, + right_id, + ), + left_lookup_ty, + ), + _ => unreachable!(), + }, + crate::TypeInner::Matrix { .. } => match *right_ty_inner { + crate::TypeInner::Scalar { .. } => ( + super::instructions::instruction_matrix_times_scalar( + left_result_type_id, + id, + left_id, + right_id, + ), + left_lookup_ty, + ), + crate::TypeInner::Vector { .. } => ( + super::instructions::instruction_matrix_times_vector( + right_result_type_id, + id, + left_id, + right_id, + ), + right_lookup_ty, + ), + crate::TypeInner::Matrix { .. } => ( + super::instructions::instruction_matrix_times_matrix( + left_result_type_id, + id, + left_id, + right_id, + ), + left_lookup_ty, + ), + _ => unreachable!(), + }, + crate::TypeInner::Scalar { kind, .. } => match kind { + crate::ScalarKind::Sint | crate::ScalarKind::Uint => ( + super::instructions::instruction_i_mul( + left_result_type_id, + id, + left_id, + right_id, + ), + left_lookup_ty, + ), + crate::ScalarKind::Float => ( + super::instructions::instruction_f_mul( + left_result_type_id, + id, + left_id, + right_id, + ), + left_lookup_ty, + ), + _ => unreachable!(), + }, + _ => 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, + ), + _ => unreachable!(), + }, + _ => unreachable!(), + }, _ => unimplemented!("{:?}", op), - } + }; + + block.body.push(instruction); + Ok((id, Some(lookup_ty))) } crate::Expression::LocalVariable(variable) => { let var = &ir_function.local_variables[variable];