Signed-off-by: Arthur Huillet <arthur.huil...@free.fr> --- The patch that makes things work. :)
arch/x86/emit-code.c | 8 ++++++++ arch/x86/include/arch/instruction.h | 1 + arch/x86/insn-selector_32.brg | 22 +++++++++++++++++++--- arch/x86/lir-printer.c | 7 +++++++ arch/x86/use-def.c | 1 + include/jit/expression.h | 1 + jit/arithmetic-bc.c | 4 ++-- jit/tree-printer.c | 1 + regression/jvm/FloatArithmeticTest.java | 14 +++++++------- regression/run-suite.sh | 1 + test/jit/arithmetic-bc-test.c | 4 ++-- 11 files changed, 50 insertions(+), 14 deletions(-) diff --git a/arch/x86/emit-code.c b/arch/x86/emit-code.c index bed1900..577df05 100644 --- a/arch/x86/emit-code.c +++ b/arch/x86/emit-code.c @@ -1056,6 +1056,13 @@ static void emit_xor_reg_reg(struct buffer *buf, struct operand *src, emit_reg_reg(buf, 0x33, dest, src); } +static void emit_xor_xmm_reg_reg(struct buffer *buf, struct operand *src, + struct operand *dest) +{ + emit(buf, 0x0f); + emit_reg_reg(buf, 0x57, dest, src); +} + static void __emit_add_imm_reg(struct buffer *buf, long imm, enum machine_reg reg) { emit_alu_imm_reg(buf, 0x00, imm, reg); @@ -1243,6 +1250,7 @@ struct emitter emitters[] = { DECL_EMITTER(INSN_XOR_MEMBASE_REG, emit_xor_membase_reg, TWO_OPERANDS), DECL_EMITTER(INSN_XOR_IMM_REG, emit_xor_imm_reg, TWO_OPERANDS), DECL_EMITTER(INSN_XOR_REG_REG, emit_xor_reg_reg, TWO_OPERANDS), + DECL_EMITTER(INSN_XOR_XMM_REG_REG, emit_xor_xmm_reg_reg, TWO_OPERANDS), }; void fixup_static(struct vm_class *vmc) diff --git a/arch/x86/include/arch/instruction.h b/arch/x86/include/arch/instruction.h index d0b52db..056480f 100644 --- a/arch/x86/include/arch/instruction.h +++ b/arch/x86/include/arch/instruction.h @@ -125,6 +125,7 @@ enum insn_type { INSN_XOR_MEMBASE_REG, INSN_XOR_IMM_REG, INSN_XOR_REG_REG, + INSN_XOR_XMM_REG_REG, #ifdef CONFIG_X86_64 INSN64_ADD_IMM_REG, diff --git a/arch/x86/insn-selector_32.brg b/arch/x86/insn-selector_32.brg index 35ed3d3..edbdeac 100644 --- a/arch/x86/insn-selector_32.brg +++ b/arch/x86/insn-selector_32.brg @@ -357,7 +357,7 @@ reg: OP_MUL(reg, reg) 1 select_insn(s, tree, reg_reg_insn(INSN_MUL_REG_REG, state->left->reg1, state->right->reg1)); } -freg: OP_FMUL(reg, reg) 1 +freg: OP_FMUL(freg, freg) 1 { state->reg1 = state->left->reg1; @@ -408,7 +408,7 @@ reg: OP_DIV(reg, reg) 1 select_insn(s, tree, reg_reg_insn(INSN_DIV_REG_REG, state->right->reg1, result)); } -freg: OP_FDIV(reg, reg) 1 +freg: OP_FDIV(freg, freg) 1 { state->reg1 = state->left->reg1; @@ -473,6 +473,22 @@ reg: OP_NEG(reg) 1 } } +freg: OP_FNEG(freg) 1 +{ + struct var_info *result, *esp; + + esp = get_fixed_var(s->b_parent, REG_ESP); + + result = get_fpu_var(s->b_parent); + + select_insn(s, tree, imm_membase_insn(INSN_MOV_IMM_MEMBASE, 0x80000000, esp, -4)); + select_insn(s, tree, membase_reg_insn(INSN_MOV_MEMBASE_XMM, esp, -4, result)); + + select_insn(s, tree, reg_reg_insn(INSN_XOR_XMM_REG_REG, state->left->reg1, result)); + + state->reg1 = result; +} + reg: OP_SHL(reg, reg) 1 { struct var_info *ecx; @@ -745,7 +761,7 @@ reg: EXPR_INVOKEVIRTUAL(arg) 1 select_insn(s, tree, reg_reg_insn(INSN_MOV_REG_REG, edx, state->reg2)); } -reg: OP_CMPL(reg, reg) 1 +reg: OP_CMPL(freg, freg) 1 { struct var_info *esp, *eax; diff --git a/arch/x86/lir-printer.c b/arch/x86/lir-printer.c index fc99cdd..360eef9 100644 --- a/arch/x86/lir-printer.c +++ b/arch/x86/lir-printer.c @@ -604,6 +604,12 @@ static int print_xor_reg_reg(struct string *str, struct insn *insn) return print_reg_reg(str, insn); } +static int print_xor_xmm_reg_reg(struct string *str, struct insn *insn) +{ + print_func_name(str); + return print_reg_reg(str, insn); +} + typedef int (*print_insn_fn) (struct string *str, struct insn *insn); static print_insn_fn insn_printers[] = { @@ -678,6 +684,7 @@ static print_insn_fn insn_printers[] = { [INSN_XOR_MEMBASE_REG] = print_xor_membase_reg, [INSN_XOR_IMM_REG] = print_xor_imm_reg, [INSN_XOR_REG_REG] = print_xor_reg_reg, + [INSN_XOR_XMM_REG_REG] = print_xor_xmm_reg_reg, }; int lir_print(struct insn *insn, struct string *str) diff --git a/arch/x86/use-def.c b/arch/x86/use-def.c index 73fd389..ee22554 100644 --- a/arch/x86/use-def.c +++ b/arch/x86/use-def.c @@ -98,6 +98,7 @@ static struct insn_info insn_infos[] = { DECLARE_INFO(INSN_XOR_MEMBASE_REG, USE_SRC | DEF_DST), DECLARE_INFO(INSN_XOR_IMM_REG, USE_SRC | DEF_DST), DECLARE_INFO(INSN_XOR_REG_REG, USE_SRC | DEF_DST), + DECLARE_INFO(INSN_XOR_XMM_REG_REG, USE_SRC | DEF_DST), }; static inline struct insn_info *get_info(struct insn *insn) diff --git a/include/jit/expression.h b/include/jit/expression.h index d18aebd..916eac6 100644 --- a/include/jit/expression.h +++ b/include/jit/expression.h @@ -85,6 +85,7 @@ enum binary_operator { enum unary_operator { OP_NEG = BINOP_LAST, + OP_FNEG, OP_LAST, /* Not a real operator. Keep this last. */ }; diff --git a/jit/arithmetic-bc.c b/jit/arithmetic-bc.c index e07a3d1..32720fb 100644 --- a/jit/arithmetic-bc.c +++ b/jit/arithmetic-bc.c @@ -160,12 +160,12 @@ int convert_lneg(struct parse_context *ctx) int convert_fneg(struct parse_context *ctx) { - return convert_unary_op(ctx, J_FLOAT, OP_NEG); + return convert_unary_op(ctx, J_FLOAT, OP_FNEG); } int convert_dneg(struct parse_context *ctx) { - return convert_unary_op(ctx, J_DOUBLE, OP_NEG); + return convert_unary_op(ctx, J_DOUBLE, OP_FNEG); } int convert_ishl(struct parse_context *ctx) diff --git a/jit/tree-printer.c b/jit/tree-printer.c index 710b97f..f125575 100644 --- a/jit/tree-printer.c +++ b/jit/tree-printer.c @@ -408,6 +408,7 @@ static const char *op_names[] = { [OP_FADD] = "fadd", [OP_FSUB] = "fsub", [OP_FMUL] = "fmul", + [OP_FNEG] = "fneg", [OP_FDIV] = "fdiv", [OP_SHL] = "shl", [OP_SHL_64] = "shl64", diff --git a/regression/jvm/FloatArithmeticTest.java b/regression/jvm/FloatArithmeticTest.java index efa3b9e..edd6c14 100644 --- a/regression/jvm/FloatArithmeticTest.java +++ b/regression/jvm/FloatArithmeticTest.java @@ -62,11 +62,11 @@ public class FloatArithmeticTest extends TestCase { } public static void testFloatSubtractionImmediateLocal() { - float x = 11.000000f; - float y = 9.999999f; - float result = (1.0f - x) - (0.0f - y); + float x = 4.5f; + float y = 3.5f; + float result = (1.5f - x) - (0.0f - y); - assertEquals(-0.000001f, result); + assertEquals(0.5f, result); } public static void testFloatMultiplication() { @@ -103,7 +103,7 @@ public class FloatArithmeticTest extends TestCase { public static void testFloatNegation() { assertEquals(-1.5f, neg( 1.5f)); - assertEquals( 0.0f, neg( 0.0f)); + assertEquals( -0.0f, neg( 0.0f)); assertEquals( 1.3f, neg(-1.3f)); } @@ -112,7 +112,7 @@ public class FloatArithmeticTest extends TestCase { } public static void main(String[] args) { -/* + testFloatAddition(); testFloatAdditionLocalSlot(); testFloatSubtraction(); @@ -120,7 +120,7 @@ public class FloatArithmeticTest extends TestCase { testFloatMultiplication(); testFloatDivision(); testFloatNegation(); -*/ + exit(); } } diff --git a/regression/run-suite.sh b/regression/run-suite.sh index aa83d3d..688b595 100755 --- a/regression/run-suite.sh +++ b/regression/run-suite.sh @@ -63,6 +63,7 @@ if [ -z "$CLASS_LIST" ]; then run_java jvm.LoadConstantsTest 0 run_java jvm.IntegerArithmeticTest 0 run_java jvm.LongArithmeticTest 0 + run_java jvm.FloatArithmeticTest 0 run_java jvm.ConversionTest 0 run_java jvm.ObjectCreationAndManipulationTest 0 run_java jvm.SynchronizationTest 0 diff --git a/test/jit/arithmetic-bc-test.c b/test/jit/arithmetic-bc-test.c index 98feabe..056071b 100644 --- a/test/jit/arithmetic-bc-test.c +++ b/test/jit/arithmetic-bc-test.c @@ -134,8 +134,8 @@ void test_convert_neg(void) { assert_convert_unop(J_INT, OP_NEG, OPC_INEG); assert_convert_unop(J_LONG, OP_NEG, OPC_LNEG); - assert_convert_unop(J_FLOAT, OP_NEG, OPC_FNEG); - assert_convert_unop(J_DOUBLE, OP_NEG, OPC_DNEG); + assert_convert_unop(J_FLOAT, OP_FNEG, OPC_FNEG); + assert_convert_unop(J_DOUBLE, OP_FNEG, OPC_DNEG); } void test_convert_shl(void) -- 1.6.3.3 ------------------------------------------------------------------------------ _______________________________________________ Jatovm-devel mailing list Jatovm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jatovm-devel