diff --git a/core/src/main/java/org/teavm/backend/wasm/render/WasmCRenderingVisitor.java b/core/src/main/java/org/teavm/backend/wasm/render/WasmCRenderingVisitor.java index 219e51db1..9259a9da7 100644 --- a/core/src/main/java/org/teavm/backend/wasm/render/WasmCRenderingVisitor.java +++ b/core/src/main/java/org/teavm/backend/wasm/render/WasmCRenderingVisitor.java @@ -642,21 +642,27 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor { if (type != null && expression.getSourceType() != expression.getTargetType()) { switch (expression.getTargetType()) { case INT32: - if (expression.isSigned()) { + if (expression.getSourceType() == WasmType.FLOAT32 && expression.isReinterpret()) { + result.setText("reinterpret_float32(" + operand.getText() + ")"); + } else if (expression.isSigned()) { result.setText("(int32_t) " + operand.getText()); } else { result.setText("(uint32_t) " + operand.getText()); } break; case INT64: - if (expression.isSigned()) { + if (expression.getSourceType() == WasmType.FLOAT64 && expression.isReinterpret()) { + result.setText("reinterpret_float64(" + operand.getText() + ")"); + } else if (expression.isSigned()) { result.setText("(int64_t) " + operand.getText()); } else { result.setText("(uint64_t) " + operand.getText()); } break; case FLOAT32: - if (expression.getSourceType() == WasmType.FLOAT64) { + if (expression.getSourceType() == WasmType.INT32 && expression.isReinterpret()) { + result.setText("reinterpret_int32(" + operand.getText() + ")"); + } else if (expression.getSourceType() == WasmType.FLOAT64) { result.setText("(float) " + operand.getText()); } else if (expression.isSigned()) { result.setText("(float) (int64_t) " + operand.getText()); @@ -665,7 +671,9 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor { } break; case FLOAT64: - if (expression.getSourceType() == WasmType.FLOAT32) { + if (expression.getSourceType() == WasmType.INT64 && expression.isReinterpret()) { + result.setText("reinterpret_int64(" + operand.getText() + ")"); + } else if (expression.getSourceType() == WasmType.FLOAT32) { result.setText("(double) " + operand.getText()); } else if (expression.isSigned()) { result.setText("(double) (int64_t) " + operand.getText()); diff --git a/core/src/main/resources/org/teavm/backend/wasm/wasm-runtime.c b/core/src/main/resources/org/teavm/backend/wasm/wasm-runtime.c index 76dd1737a..87b3f2d26 100644 --- a/core/src/main/resources/org/teavm/backend/wasm/wasm-runtime.c +++ b/core/src/main/resources/org/teavm/backend/wasm/wasm-runtime.c @@ -17,4 +17,27 @@ static int64_t currentTimeMillis() { clock_gettime(CLOCK_REALTIME, &time); return time.tv_sec * 1000 + (int64_t) round(time.tv_nsec / 1000000); +} + +static union { float f; int32_t i; } reinterpret_union_32; +static union { double f; int64_t i; } reinterpret_union_64; + +inline static int64_t reinterpret_float64(double v) { + reinterpret_union_64.f = v; + return reinterpret_union_64.i; +} + +inline static double reinterpret_int64(int64_t v) { + reinterpret_union_64.i = v; + return reinterpret_union_64.f; +} + +inline static int32_t reinterpret_float32(double v) { + reinterpret_union_32.f = v; + return reinterpret_union_32.i; +} + +inline static float reinterpret_int32(int32_t v) { + reinterpret_union_32.i = v; + return reinterpret_union_32.f; } \ No newline at end of file