From 588ac6db4785a3f6143d35f9790aaa6c51c5999a Mon Sep 17 00:00:00 2001 From: Volker Berlin Date: Sun, 14 Jul 2019 12:41:40 +0200 Subject: [PATCH] implement reinterpret opcodes and use it in the WatParser. --- .../binary/BinaryModuleWriter.java | 14 +++++- .../module/ValueTypeConvertion.java | 6 ++- .../jwebassembly/text/TextModuleWriter.java | 14 +++++- .../jwebassembly/watparser/WatParser.java | 12 +++++ .../jwebassembly/module/WatParserTest.java | 20 ++++++++ .../jwebassembly/runtime/MathAPI.java | 48 +++++++++++++++++++ 6 files changed, 111 insertions(+), 3 deletions(-) diff --git a/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java b/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java index 82e5a7a..1e35a01 100644 --- a/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java +++ b/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java @@ -1075,8 +1075,20 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod case i2s: op = I32_EXTEND16_S; break; + case f2i_re: + op = I32_REINTERPRET_F32; + break; + case i2f_re: + op = F32_REINTERPRET_I32; + break; + case d2l_re: + op = I64_REINTERPRET_F64; + break; + case l2d_re: + op = F64_REINTERPRET_I64; + break; default: - throw new Error( "Unknown cast: " + cast ); + throw new Error( "Unknown cast/type conversion: " + cast ); } codeStream.writeOpCode( op ); } diff --git a/src/de/inetsoftware/jwebassembly/module/ValueTypeConvertion.java b/src/de/inetsoftware/jwebassembly/module/ValueTypeConvertion.java index 680f68f..a2efc9f 100644 --- a/src/de/inetsoftware/jwebassembly/module/ValueTypeConvertion.java +++ b/src/de/inetsoftware/jwebassembly/module/ValueTypeConvertion.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. @@ -37,4 +37,8 @@ public enum ValueTypeConvertion { i2b, i2c, i2s, + f2i_re, + i2f_re, + d2l_re, + l2d_re, } \ No newline at end of file diff --git a/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java b/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java index 6d8c53f..a76155b 100644 --- a/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java +++ b/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java @@ -566,8 +566,20 @@ public class TextModuleWriter extends ModuleWriter { case i2s: op = "i32.extend16_s"; break; + case f2i_re: + op = "i32.reinterpret_f32"; + break; + case i2f_re: + op = "f32.reinterpret_i32"; + break; + case d2l_re: + op = "i64.reinterpret_f64"; + break; + case l2d_re: + op = "f64.reinterpret_i64"; + break; default: - throw new Error( "Unknown cast: " + cast ); + throw new Error( "Unknown cast/type conversion: " + cast ); } newline( methodOutput ); methodOutput.append( op ); diff --git a/src/de/inetsoftware/jwebassembly/watparser/WatParser.java b/src/de/inetsoftware/jwebassembly/watparser/WatParser.java index e923a3e..a3bc683 100644 --- a/src/de/inetsoftware/jwebassembly/watparser/WatParser.java +++ b/src/de/inetsoftware/jwebassembly/watparser/WatParser.java @@ -69,12 +69,18 @@ public class WatParser extends WasmCodeBuilder { case "i32.add": addNumericInstruction( NumericOperator.add, ValueType.i32, javaCodePos, lineNumber ); break; + case "i32.reinterpret_f32": + addConvertInstruction( ValueTypeConvertion.f2i_re, javaCodePos, lineNumber ); + break; case "i32.trunc_sat_f32_s": addConvertInstruction( ValueTypeConvertion.f2i, javaCodePos, lineNumber ); break; case "i64.extend_i32_s": addConvertInstruction( ValueTypeConvertion.i2l, javaCodePos, lineNumber ); break; + case "i64.reinterpret_f64": + addConvertInstruction( ValueTypeConvertion.d2l_re, javaCodePos, lineNumber ); + break; case "i64.trunc_sat_f64_s": addConvertInstruction( ValueTypeConvertion.d2l, javaCodePos, lineNumber ); break; @@ -99,6 +105,9 @@ public class WatParser extends WasmCodeBuilder { case "f32.nearest": addNumericInstruction( NumericOperator.nearest, ValueType.f32, javaCodePos, lineNumber ); break; + case "f32.reinterpret_i32": + addConvertInstruction( ValueTypeConvertion.i2f_re, javaCodePos, lineNumber ); + break; case "f32.sqrt": addNumericInstruction( NumericOperator.sqrt, ValueType.f32, javaCodePos, lineNumber ); break; @@ -129,6 +138,9 @@ public class WatParser extends WasmCodeBuilder { case "f64.nearest": addNumericInstruction( NumericOperator.nearest, ValueType.f64, javaCodePos, lineNumber ); break; + case "f64.reinterpret_i64": + addConvertInstruction( ValueTypeConvertion.l2d_re, javaCodePos, lineNumber ); + break; case "f64.sqrt": addNumericInstruction( NumericOperator.sqrt, ValueType.f64, javaCodePos, lineNumber ); break; diff --git a/test/de/inetsoftware/jwebassembly/module/WatParserTest.java b/test/de/inetsoftware/jwebassembly/module/WatParserTest.java index e5bb2c8..6f80cfa 100644 --- a/test/de/inetsoftware/jwebassembly/module/WatParserTest.java +++ b/test/de/inetsoftware/jwebassembly/module/WatParserTest.java @@ -116,6 +116,11 @@ public class WatParserTest { test( " i32.const -7 " ); } + @Test + public void i32_reinterpret_f32() throws IOException { + test( "i32.reinterpret_f32" ); + } + @Test public void i32_trunc_sat_f32_s() throws IOException { test( "i32.trunc_sat_f32_s" ); @@ -126,6 +131,11 @@ public class WatParserTest { test( "i64.extend_i32_s" ); } + @Test + public void i64_reinterpret_f64() throws IOException { + test( "i64.reinterpret_f64" ); + } + @Test public void i64_trunc_sat_f64_s() throws IOException { test( "i64.trunc_sat_f64_s" ); @@ -166,6 +176,11 @@ public class WatParserTest { test( "f32.nearest" ); } + @Test + public void f32_reinterpret_i32() throws IOException { + test( "f32.reinterpret_i32" ); + } + @Test public void f32_sqrt() throws IOException { test( "f32.sqrt" ); @@ -216,6 +231,11 @@ public class WatParserTest { test( "f64.mul" ); } + @Test + public void f64_reinterpret_i64() throws IOException { + test( "f64.reinterpret_i64" ); + } + @Test public void f64_sqrt() throws IOException { test( "f64.sqrt" ); diff --git a/test/de/inetsoftware/jwebassembly/runtime/MathAPI.java b/test/de/inetsoftware/jwebassembly/runtime/MathAPI.java index 7208144..15ac05f 100644 --- a/test/de/inetsoftware/jwebassembly/runtime/MathAPI.java +++ b/test/de/inetsoftware/jwebassembly/runtime/MathAPI.java @@ -42,6 +42,10 @@ public class MathAPI extends AbstractBaseTest { ArrayList list = new ArrayList<>(); for( ScriptEngine[] val : ScriptEngine.testParams() ) { ScriptEngine script = val[0]; + addParam( list, script, "floatToIntBits" ); + addParam( list, script, "intBitsToFloat" ); + addParam( list, script, "doubleToLongBits" ); + addParam( list, script, "longBitsToDouble" ); addParam( list, script, "sin0" ); addParam( list, script, "sinPI" ); addParam( list, script, "cos0" ); @@ -59,6 +63,10 @@ public class MathAPI extends AbstractBaseTest { addParam( list, script, "ceil8_5" ); addParam( list, script, "floor8_5" ); addParam( list, script, "rint8_5" ); + addParam( list, script, "atan2_5_5" ); + addParam( list, script, "pow3_4" ); + addParam( list, script, "round3_5" ); + addParam( list, script, "round_3_5" ); } rule.setTestParameters( list ); return list; @@ -66,6 +74,26 @@ public class MathAPI extends AbstractBaseTest { static class TestClass { + @Export + static int floatToIntBits() { + return Float.floatToIntBits( 7 ); + } + + @Export + static float intBitsToFloat() { + return Float.intBitsToFloat( 0x41f8_0000 ); // 31.0 + } + + @Export + static int doubleToLongBits() { + return (int)Double.doubleToLongBits( 7 ); + } + + @Export + static double longBitsToDouble() { + return Double.longBitsToDouble( 0x41f8_0000 ); // 31.0 + } + @Export static double sin0() { return Math.sin( 0 ); @@ -155,5 +183,25 @@ public class MathAPI extends AbstractBaseTest { static double rint8_5() { return Math.rint( 8.5 ); } + + @Export + static double atan2_5_5() { + return Math.atan2( 5, 5 ); + } + + @Export + static double pow3_4() { + return Math.pow( 3, 4 ); + } + + @Export + static int round3_5() { + return Math.round( 3.5F ); + } + + @Export + static double round_3_5() { + return Math.round( -3.5F ); + } } }