Signed-off-by: Arthur Huillet <[email protected]>
---
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/jatovm-devel