From ecd6d4e4aacb8355cad5f7f3ab50864672aa8d67 Mon Sep 17 00:00:00 2001 From: teoxoy <28601907+teoxoy@users.noreply.github.com> Date: Thu, 28 Apr 2022 19:50:08 +0200 Subject: [PATCH] [spv-in] translate OpSMod correctly --- src/front/spv/convert.rs | 2 +- src/front/spv/mod.rs | 106 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 106 insertions(+), 2 deletions(-) diff --git a/src/front/spv/convert.rs b/src/front/spv/convert.rs index 365f55d51f..128f7ceaef 100644 --- a/src/front/spv/convert.rs +++ b/src/front/spv/convert.rs @@ -12,7 +12,7 @@ pub(super) const fn map_binary_operator(word: spirv::Op) -> Result Ok(BinaryOperator::Subtract), Op::IMul | Op::FMul => Ok(BinaryOperator::Multiply), Op::UDiv | Op::SDiv | Op::FDiv => Ok(BinaryOperator::Divide), - Op::UMod | Op::SMod | Op::SRem => Ok(BinaryOperator::Modulo), + Op::SRem => Ok(BinaryOperator::Modulo), // Relational and Logical Instructions Op::IEqual | Op::FOrdEqual | Op::FUnordEqual | Op::LogicalEqual => { Ok(BinaryOperator::Equal) diff --git a/src/front/spv/mod.rs b/src/front/spv/mod.rs index 342d3a8e32..cf4f50d1d7 100644 --- a/src/front/spv/mod.rs +++ b/src/front/spv/mod.rs @@ -1966,7 +1966,6 @@ impl> Parser { | Op::BitwiseXor | Op::BitwiseAnd | Op::SDiv - | Op::SMod | Op::SRem => { inst.expect(5)?; let operator = map_binary_operator(inst.op)?; @@ -2013,9 +2012,114 @@ impl> Parser { inst.expect(5)?; parse_expr_op!(crate::BinaryOperator::Modulo, BINARY)?; } + Op::SMod => { + inst.expect(5)?; + + // x - y * int(floor(float(x) / float(y))) + + let start = self.data_offset; + let result_type_id = self.next()?; + let result_id = self.next()?; + let p1_id = self.next()?; + let p2_id = self.next()?; + let span = self.span_from_with_op(start); + + let p1_lexp = self.lookup_expression.lookup(p1_id)?; + let left = self.get_expr_handle( + p1_id, + p1_lexp, + ctx, + &mut emitter, + &mut block, + body_idx, + ); + let p2_lexp = self.lookup_expression.lookup(p2_id)?; + let right = self.get_expr_handle( + p2_id, + p2_lexp, + ctx, + &mut emitter, + &mut block, + body_idx, + ); + + let left_cast = ctx.expressions.append( + crate::Expression::As { + expr: left, + kind: crate::ScalarKind::Float, + convert: None, + }, + span, + ); + let right_cast = ctx.expressions.append( + crate::Expression::As { + expr: right, + kind: crate::ScalarKind::Float, + convert: None, + }, + span, + ); + let div = ctx.expressions.append( + crate::Expression::Binary { + op: crate::BinaryOperator::Divide, + left: left_cast, + right: right_cast, + }, + span, + ); + let floor = ctx.expressions.append( + crate::Expression::Math { + fun: crate::MathFunction::Floor, + arg: div, + arg1: None, + arg2: None, + arg3: None, + }, + span, + ); + let result_ty = self.lookup_type.lookup(result_type_id)?; + let kind = ctx.type_arena[result_ty.handle] + .inner + .scalar_kind() + .unwrap(); + let cast = ctx.expressions.append( + crate::Expression::As { + expr: floor, + kind, + convert: None, + }, + span, + ); + let mult = ctx.expressions.append( + crate::Expression::Binary { + op: crate::BinaryOperator::Multiply, + left: cast, + right, + }, + span, + ); + let sub = ctx.expressions.append( + crate::Expression::Binary { + op: crate::BinaryOperator::Subtract, + left, + right: mult, + }, + span, + ); + self.lookup_expression.insert( + result_id, + LookupExpression { + handle: sub, + type_id: result_type_id, + block_id, + }, + ); + } Op::FMod => { inst.expect(5)?; + // x - y * floor(x / y) + let start = self.data_offset; let span = self.span_from_with_op(start);