From 421178e72be768daac9e7d7741b8338cf6739a51 Mon Sep 17 00:00:00 2001 From: Zoltan Herczeg Date: Tue, 17 Dec 2024 09:17:48 +0000 Subject: [PATCH] Fix argument passing of float binary callback operations Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com --- src/jit/FloatMathInl.h | 26 ++++++++++++++++++++++---- test/jit/f32-operations.wast | 7 +++++++ test/jit/f64-operations.wast | 11 +++++++++++ 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/jit/FloatMathInl.h b/src/jit/FloatMathInl.h index 766214d2d..a5c14dc72 100644 --- a/src/jit/FloatMathInl.h +++ b/src/jit/FloatMathInl.h @@ -83,6 +83,26 @@ static void emitMoveFloat(sljit_compiler* compiler, Instruction* instr) } } +static void emitInitFR0FR1(sljit_compiler* compiler, sljit_s32 movOp, JITArg* params) +{ + if (params[1].arg != SLJIT_FR0) { + MOVE_TO_FREG(compiler, movOp, SLJIT_FR0, params[0].arg, params[0].argw); + MOVE_TO_FREG(compiler, movOp, SLJIT_FR1, params[1].arg, params[1].argw); + return; + } + + if (params[0].arg != SLJIT_FR1) { + sljit_emit_fop1(compiler, movOp, SLJIT_FR1, 0, SLJIT_FR0, 0); + MOVE_TO_FREG(compiler, movOp, SLJIT_FR0, params[0].arg, params[0].argw); + return; + } + + // Swap arguments. + sljit_emit_fop1(compiler, movOp, SLJIT_TMP_DEST_FREG, 0, SLJIT_FR0, 0); + sljit_emit_fop1(compiler, movOp, SLJIT_FR0, 0, SLJIT_FR1, 0); + sljit_emit_fop1(compiler, movOp, SLJIT_FR1, 0, SLJIT_TMP_DEST_FREG, 0); +} + // Float operations. // TODO Canonical NaN static sljit_f32 floatFloor(sljit_f32 operand) @@ -267,15 +287,13 @@ static void emitFloatBinary(sljit_compiler* compiler, Instruction* instr) ASSERT(instr->info() & Instruction::kIsCallback); if (f32Func) { - MOVE_TO_FREG(compiler, SLJIT_MOV_F32, SLJIT_FR0, args[0].arg, args[0].argw); - MOVE_TO_FREG(compiler, SLJIT_MOV_F32, SLJIT_FR1, args[1].arg, args[1].argw); + emitInitFR0FR1(compiler, SLJIT_MOV_F32, args); sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(F32, F32, F32), SLJIT_IMM, GET_FUNC_ADDR(sljit_sw, f32Func)); MOVE_FROM_FREG(compiler, SLJIT_MOV_F32, args[2].arg, args[2].argw, SLJIT_FR0); return; } - MOVE_TO_FREG(compiler, SLJIT_MOV_F64, SLJIT_FR0, args[0].arg, args[0].argw); - MOVE_TO_FREG(compiler, SLJIT_MOV_F64, SLJIT_FR1, args[1].arg, args[1].argw); + emitInitFR0FR1(compiler, SLJIT_MOV_F64, args); sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(F64, F64, F64), SLJIT_IMM, GET_FUNC_ADDR(sljit_sw, f64Func)); MOVE_FROM_FREG(compiler, SLJIT_MOV_F64, args[2].arg, args[2].argw, SLJIT_FR0); } diff --git a/test/jit/f32-operations.wast b/test/jit/f32-operations.wast index bccfe356a..a8c27dbc3 100644 --- a/test/jit/f32-operations.wast +++ b/test/jit/f32-operations.wast @@ -150,6 +150,12 @@ f32.const -nan f32.floor ) + +(func (export "test17") (param f32) (result f32) + f32.const 1.0 + local.get 0 + f32.max +) ) (assert_return (invoke "test1") (f32.const 4.4)) @@ -168,3 +174,4 @@ (assert_return (invoke "test14") (i32.const 0) (i32.const 1) (i32.const 0)) (assert_return (invoke "test15") (i32.const 1) (i32.const 1) (i32.const 0) (i32.const 1)) (assert_return (invoke "test16") (f32.const nan:canonical)) +(assert_return (invoke "test17" (f32.const 10.0)) (f32.const 10.0)) diff --git a/test/jit/f64-operations.wast b/test/jit/f64-operations.wast index dbc71a08f..1bb44f1e3 100644 --- a/test/jit/f64-operations.wast +++ b/test/jit/f64-operations.wast @@ -155,6 +155,16 @@ f64.const -nan f64.floor ) + +(func (export "test28") (param f64 f64) (result f64) + local.get 1 + f64.const 10.0 + f64.add + local.get 0 + f64.min + local.get 1 + f64.add +) ) (assert_return (invoke "test11") (f64.const 4.4)) @@ -174,3 +184,4 @@ (assert_return (invoke "test25") (i32.const 0) (i32.const 1) (i32.const 0)) (assert_return (invoke "test26") (i32.const 1) (i32.const 1) (i32.const 0) (i32.const 1)) (assert_return (invoke "test27") (f64.const nan:canonical)) +(assert_return (invoke "test28" (f64.const 100.0) (f64.const 20.0)) (f64.const 50.0))