From c64c620a382558590321e16b4e495ea1692387ee Mon Sep 17 00:00:00 2001 From: Volker Berlin Date: Sat, 13 Jul 2019 15:46:20 +0200 Subject: [PATCH] more math operation for the text format (Watparser) --- .../binary/BinaryModuleWriter.java | 67 ++++++++++++++++--- .../module/WasmNumericInstruction.java | 7 +- .../jwebassembly/wasm/NumericOperator.java | 8 ++- .../jwebassembly/watparser/WatParser.java | 24 +++++++ .../jwebassembly/module/WatParserTest.java | 58 ++++++++++++++++ 5 files changed, 150 insertions(+), 14 deletions(-) diff --git a/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java b/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java index 4a45e3f..82e5a7a 100644 --- a/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java +++ b/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java @@ -758,17 +758,6 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod default: } break; - case sqrt: - switch( valueType ) { - case f32: - op = F32_SQRT; - break; - case f64: - op = F64_SQRT; - break; - default: - } - break; case rem: switch( valueType ) { case i32: @@ -973,6 +962,62 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod codeStream.writeOpCode( REF_EQ ); op = I32_EQZ; break; + case sqrt: + switch( valueType ) { + case f32: + op = F32_SQRT; + break; + case f64: + op = F64_SQRT; + break; + default: + } + break; + case ceil: + switch( valueType ) { + case f32: + op = F32_CEIL; + break; + case f64: + op = F64_CEIL; + break; + default: + } + break; + case floor: + switch( valueType ) { + case f32: + op = F32_FLOOR; + break; + case f64: + op = F64_FLOOR; + break; + default: + } + break; + case trunc: + switch( valueType ) { + case f32: + op = F32_TRUNC; + break; + case f64: + op = F64_TRUNC; + break; + default: + } + break; + case nearest: + switch( valueType ) { + case f32: + op = F32_NEAREST; + break; + case f64: + op = F64_NEAREST; + break; + default: + } + break; + default: } if( op == 0 ) { diff --git a/src/de/inetsoftware/jwebassembly/module/WasmNumericInstruction.java b/src/de/inetsoftware/jwebassembly/module/WasmNumericInstruction.java index 4d6b326..491fa4b 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmNumericInstruction.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmNumericInstruction.java @@ -81,7 +81,7 @@ class WasmNumericInstruction extends WasmInstruction { case lt: case le: case ge: - return null; + return null; //TODO should this Valuetype.i32? But then tests failed. can be related to the getPopCount() of the block BlockInstaction IF default: return valueType; } @@ -94,6 +94,11 @@ class WasmNumericInstruction extends WasmInstruction { int getPopCount() { switch( numOp ) { case neg: + case sqrt: + case ceil: + case floor: + case trunc: + case nearest: return 1; default: return 2; diff --git a/src/de/inetsoftware/jwebassembly/wasm/NumericOperator.java b/src/de/inetsoftware/jwebassembly/wasm/NumericOperator.java index 3aa5a31..f2b5e7e 100644 --- a/src/de/inetsoftware/jwebassembly/wasm/NumericOperator.java +++ b/src/de/inetsoftware/jwebassembly/wasm/NumericOperator.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2018 Volker Berlin (i-net software) + * Copyright 2017 - 2019 Volker Berlin (i-net software) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +24,6 @@ public enum NumericOperator { neg, mul, div, - sqrt, rem, and, or, @@ -44,4 +43,9 @@ public enum NumericOperator { ifnonnull, ref_eq, ref_ne, + sqrt, + ceil, + floor, + trunc, + nearest, } diff --git a/src/de/inetsoftware/jwebassembly/watparser/WatParser.java b/src/de/inetsoftware/jwebassembly/watparser/WatParser.java index 034038a..e923a3e 100644 --- a/src/de/inetsoftware/jwebassembly/watparser/WatParser.java +++ b/src/de/inetsoftware/jwebassembly/watparser/WatParser.java @@ -78,42 +78,66 @@ public class WatParser extends WasmCodeBuilder { case "i64.trunc_sat_f64_s": addConvertInstruction( ValueTypeConvertion.d2l, javaCodePos, lineNumber ); break; + case "f32.ceil": + addNumericInstruction( NumericOperator.ceil, ValueType.f32, javaCodePos, lineNumber ); + break; case "f32.convert_i32_s": addConvertInstruction( ValueTypeConvertion.i2f, javaCodePos, lineNumber ); break; case "f32.div": addNumericInstruction( NumericOperator.div, ValueType.f32, javaCodePos, lineNumber ); break; + case "f32.floor": + addNumericInstruction( NumericOperator.floor, ValueType.f32, javaCodePos, lineNumber ); + break; case "f32.max": addNumericInstruction( NumericOperator.max, ValueType.f32, javaCodePos, lineNumber ); break; case "f32.mul": addNumericInstruction( NumericOperator.mul, ValueType.f32, javaCodePos, lineNumber ); break; + case "f32.nearest": + addNumericInstruction( NumericOperator.nearest, ValueType.f32, javaCodePos, lineNumber ); + break; case "f32.sqrt": addNumericInstruction( NumericOperator.sqrt, ValueType.f32, javaCodePos, lineNumber ); break; case "f32.sub": addNumericInstruction( NumericOperator.sub, ValueType.f32, javaCodePos, lineNumber ); break; + case "f32.trunc": + addNumericInstruction( NumericOperator.trunc, ValueType.f32, javaCodePos, lineNumber ); + break; + case "f64.ceil": + addNumericInstruction( NumericOperator.ceil, ValueType.f64, javaCodePos, lineNumber ); + break; case "f64.convert_i64_s": addConvertInstruction( ValueTypeConvertion.l2d, javaCodePos, lineNumber ); break; case "f64.div": addNumericInstruction( NumericOperator.div, ValueType.f64, javaCodePos, lineNumber ); break; + case "f64.floor": + addNumericInstruction( NumericOperator.floor, ValueType.f64, javaCodePos, lineNumber ); + break; case "f64.max": addNumericInstruction( NumericOperator.max, ValueType.f64, javaCodePos, lineNumber ); break; case "f64.mul": addNumericInstruction( NumericOperator.mul, ValueType.f64, javaCodePos, lineNumber ); break; + case "f64.nearest": + addNumericInstruction( NumericOperator.nearest, ValueType.f64, javaCodePos, lineNumber ); + break; case "f64.sqrt": addNumericInstruction( NumericOperator.sqrt, ValueType.f64, javaCodePos, lineNumber ); break; case "f64.sub": addNumericInstruction( NumericOperator.sub, ValueType.f64, javaCodePos, lineNumber ); break; + case "f64.trunc": + addNumericInstruction( NumericOperator.trunc, ValueType.f64, javaCodePos, lineNumber ); + break; // case "call": // addCallInstruction( method, javaCodePos ); // break; diff --git a/test/de/inetsoftware/jwebassembly/module/WatParserTest.java b/test/de/inetsoftware/jwebassembly/module/WatParserTest.java index a25affb..e5bb2c8 100644 --- a/test/de/inetsoftware/jwebassembly/module/WatParserTest.java +++ b/test/de/inetsoftware/jwebassembly/module/WatParserTest.java @@ -26,6 +26,7 @@ import javax.annotation.Nullable; import org.junit.Test; import de.inetsoftware.jwebassembly.WasmException; +import de.inetsoftware.jwebassembly.binary.BinaryModuleWriter; import de.inetsoftware.jwebassembly.text.TextModuleWriter; import de.inetsoftware.jwebassembly.watparser.WatParser; @@ -49,6 +50,13 @@ public class WatParserTest { String expected = normalize( "(module (func $A.a " + wat + " ) )" ); String actual = normalize( builder ); assertEquals( expected, actual ); + + // smoke test of the binary writer + writer = new BinaryModuleWriter( new WasmTarget( builder ), new HashMap<>() ); + writer.writeMethodStart( new FunctionName( "A.a()V" ), null ); + for( WasmInstruction instruction : codeBuilder.getInstructions() ) { + instruction.writeTo( writer ); + } } private String normalize( @Nullable CharSequence str ) { @@ -123,6 +131,11 @@ public class WatParserTest { test( "i64.trunc_sat_f64_s" ); } + @Test + public void f32_ceil() throws IOException { + test( "f32.ceil" ); + } + @Test public void f32_convert_i32_s() throws IOException { test( "f32.convert_i32_s" ); @@ -133,6 +146,11 @@ public class WatParserTest { test( "f32.div" ); } + @Test + public void f32_floor() throws IOException { + test( "f32.floor" ); + } + @Test public void f32_max() throws IOException { test( "f32.max" ); @@ -143,11 +161,31 @@ public class WatParserTest { test( "f32.mul" ); } + @Test + public void f32_nearest() throws IOException { + test( "f32.nearest" ); + } + + @Test + public void f32_sqrt() throws IOException { + test( "f32.sqrt" ); + } + @Test public void f32_sub() throws IOException { test( "f32.sub" ); } + @Test + public void f32_trunc() throws IOException { + test( "f32.trunc" ); + } + + @Test + public void f64_ceil() throws IOException { + test( "f64.ceil" ); + } + @Test public void f64_convert_i64_s() throws IOException { test( "f64.convert_i64_s" ); @@ -158,6 +196,16 @@ public class WatParserTest { test( "f64.div" ); } + @Test + public void f64_floor() throws IOException { + test( "f64.floor" ); + } + + @Test + public void f64_nearest() throws IOException { + test( "f64.nearest" ); + } + @Test public void f64_max() throws IOException { test( "f64.max" ); @@ -168,11 +216,21 @@ public class WatParserTest { test( "f64.mul" ); } + @Test + public void f64_sqrt() throws IOException { + test( "f64.sqrt" ); + } + @Test public void f64_sub() throws IOException { test( "f64.sub" ); } + @Test + public void f64_trunc() throws IOException { + test( "f64.trunc" ); + } + @Test public void return_() throws IOException { test( "return\n" );