These rules are required to compile this code:

    int x = 1;
    int value = x - 1;

And this code:

    int x = 0x1a;
    int y = 0x0d;
    int result = (0x1f - x) - (0x11 - y);

Signed-off-by: Tomek Grabiec <[email protected]>
---
 arch/x86/emit-code_32.c                     |   40 +++++++++++++++++++++++++--
 arch/x86/include/arch/instruction.h         |    4 +++
 arch/x86/insn-selector_32.brg               |   28 +++++++++++++++++++
 arch/x86/use-def.c                          |    4 +++
 regression/jamvm/IntegerArithmeticTest.java |    9 ++++++
 regression/jamvm/LongArithmeticTest.java    |    9 ++++++
 6 files changed, 91 insertions(+), 3 deletions(-)

diff --git a/arch/x86/emit-code_32.c b/arch/x86/emit-code_32.c
index b559dc3..5160cce 100644
--- a/arch/x86/emit-code_32.c
+++ b/arch/x86/emit-code_32.c
@@ -358,12 +358,42 @@ static void emit_alu_imm_reg(struct buffer *buf, unsigned 
char opc_ext,
        emit_imm(buf, imm);
 }
 
-static void emit_sub_imm_reg(struct buffer *buf, unsigned long imm,
-                            enum machine_reg reg)
+static void __emit_sub_imm_reg(struct buffer *buf, unsigned long imm,
+                              enum machine_reg reg)
 {
        emit_alu_imm_reg(buf, 0x05, imm, reg);
 }
 
+static void emit_sub_imm_reg(struct buffer *buf, struct operand *src,
+                            struct operand *dest)
+{
+       __emit_sub_imm_reg(buf, src->imm, mach_reg(&dest->reg));
+}
+
+static void emit_sub_reg_reg(struct buffer *buf, struct operand *src,
+                            struct operand *dest)
+{
+       emit_reg_reg(buf, 0x29, src, dest);
+}
+
+static void __emit_sbb_imm_reg(struct buffer *buf, unsigned long imm,
+                              enum machine_reg reg)
+{
+       emit_alu_imm_reg(buf, 0x03, imm, reg);
+}
+
+static void emit_sbb_imm_reg(struct buffer *buf, struct operand *src,
+                            struct operand *dest)
+{
+       __emit_sbb_imm_reg(buf, src->imm, mach_reg(&dest->reg));
+}
+
+static void emit_sbb_reg_reg(struct buffer *buf, struct operand *src,
+                            struct operand *dest)
+{
+       emit_reg_reg(buf, 0x1B, src, dest);
+}
+
 void emit_prolog(struct buffer *buf, unsigned long nr_locals)
 {
        /* Unconditionally push callee-saved registers */
@@ -375,7 +405,7 @@ void emit_prolog(struct buffer *buf, unsigned long 
nr_locals)
        __emit_mov_reg_reg(buf, REG_ESP, REG_EBP);
 
        if (nr_locals)
-               emit_sub_imm_reg(buf, nr_locals * sizeof(unsigned long), 
REG_ESP);
+               __emit_sub_imm_reg(buf, nr_locals * sizeof(unsigned long), 
REG_ESP);
 }
 
 static void emit_pop_reg(struct buffer *buf, struct operand *operand)
@@ -804,10 +834,14 @@ static struct emitter emitters[] = {
        DECL_EMITTER(INSN_POP_REG, emit_pop_reg, SINGLE_OPERAND),
        DECL_EMITTER(INSN_SAR_IMM_REG, emit_sar_imm_reg, TWO_OPERANDS),
        DECL_EMITTER(INSN_SAR_REG_REG, emit_sar_reg_reg, TWO_OPERANDS),
+       DECL_EMITTER(INSN_SBB_IMM_REG, emit_sbb_imm_reg, TWO_OPERANDS),
        DECL_EMITTER(INSN_SBB_MEMBASE_REG, emit_sbb_membase_reg, TWO_OPERANDS),
+       DECL_EMITTER(INSN_SBB_REG_REG, emit_sbb_reg_reg, TWO_OPERANDS),
        DECL_EMITTER(INSN_SHL_REG_REG, emit_shl_reg_reg, TWO_OPERANDS),
        DECL_EMITTER(INSN_SHR_REG_REG, emit_shr_reg_reg, TWO_OPERANDS),
+       DECL_EMITTER(INSN_SUB_IMM_REG, emit_sub_imm_reg, TWO_OPERANDS),
        DECL_EMITTER(INSN_SUB_MEMBASE_REG, emit_sub_membase_reg, TWO_OPERANDS),
+       DECL_EMITTER(INSN_SUB_REG_REG, emit_sub_reg_reg, TWO_OPERANDS),
        DECL_EMITTER(INSN_XOR_MEMBASE_REG, emit_xor_membase_reg, TWO_OPERANDS),
        DECL_EMITTER(INSN_XOR_IMM_REG, emit_xor_imm_reg, TWO_OPERANDS),
 };
diff --git a/arch/x86/include/arch/instruction.h 
b/arch/x86/include/arch/instruction.h
index cbeaad9..ac75e40 100644
--- a/arch/x86/include/arch/instruction.h
+++ b/arch/x86/include/arch/instruction.h
@@ -95,10 +95,14 @@ enum insn_type {
        INSN_POP_REG,
        INSN_SAR_IMM_REG,
        INSN_SAR_REG_REG,
+       INSN_SBB_IMM_REG,
        INSN_SBB_MEMBASE_REG,
+       INSN_SBB_REG_REG,
        INSN_SHL_REG_REG,
        INSN_SHR_REG_REG,
+       INSN_SUB_IMM_REG,
        INSN_SUB_MEMBASE_REG,
+       INSN_SUB_REG_REG,
        INSN_XOR_MEMBASE_REG,
        INSN_XOR_IMM_REG,
 };
diff --git a/arch/x86/insn-selector_32.brg b/arch/x86/insn-selector_32.brg
index 9c41511..0413593 100644
--- a/arch/x86/insn-selector_32.brg
+++ b/arch/x86/insn-selector_32.brg
@@ -234,6 +234,34 @@ reg:       OP_SUB(reg, EXPR_LOCAL) 1
        }
 }
 
+reg:   OP_SUB(reg, EXPR_VALUE) 1
+{
+       struct expression *expr;
+
+       expr = to_expr(tree);
+
+       binop_reg_value_low(state, s, tree, INSN_SUB_IMM_REG);
+
+       if (expr->vm_type == J_LONG) {
+               binop_reg_value_high(state, s, tree, INSN_SBB_IMM_REG);
+       }
+}
+
+reg:   OP_SUB(reg, reg) 1
+{
+       struct expression *expr;
+
+       expr = to_expr(tree);
+
+       state->reg1 = state->left->reg1;
+       binop_reg_reg_low(state, s, tree, INSN_SUB_REG_REG);
+
+       if (expr->vm_type == J_LONG) {
+               state->reg2 = state->left->reg2;
+               binop_reg_reg_high(state, s, tree, INSN_SBB_REG_REG);
+       }
+}
+
 reg:   OP_MUL(reg, EXPR_LOCAL) 1
 {
        struct var_info *eax;
diff --git a/arch/x86/use-def.c b/arch/x86/use-def.c
index 8bab6d8..37d5bfc 100644
--- a/arch/x86/use-def.c
+++ b/arch/x86/use-def.c
@@ -68,10 +68,14 @@ static struct insn_info insn_infos[] = {
        DECLARE_INFO(INSN_POP_REG, USE_NONE | DEF_SRC),
        DECLARE_INFO(INSN_SAR_IMM_REG, DEF_DST),
        DECLARE_INFO(INSN_SAR_REG_REG, USE_SRC | DEF_DST),
+       DECLARE_INFO(INSN_SBB_IMM_REG, USE_NONE | DEF_DST),
        DECLARE_INFO(INSN_SBB_MEMBASE_REG, USE_SRC | DEF_DST),
+       DECLARE_INFO(INSN_SBB_REG_REG, USE_SRC | DEF_DST),
        DECLARE_INFO(INSN_SHL_REG_REG, USE_SRC | DEF_DST),
        DECLARE_INFO(INSN_SHR_REG_REG, USE_SRC | DEF_DST),
+       DECLARE_INFO(INSN_SUB_IMM_REG, USE_NONE | DEF_DST),
        DECLARE_INFO(INSN_SUB_MEMBASE_REG, USE_SRC | DEF_DST),
+       DECLARE_INFO(INSN_SUB_REG_REG, USE_SRC | DEF_DST),
        DECLARE_INFO(INSN_XOR_MEMBASE_REG, USE_SRC | DEF_DST),
        DECLARE_INFO(INSN_XOR_IMM_REG, USE_SRC | DEF_DST),
 };
diff --git a/regression/jamvm/IntegerArithmeticTest.java 
b/regression/jamvm/IntegerArithmeticTest.java
index 2772773..2973259 100644
--- a/regression/jamvm/IntegerArithmeticTest.java
+++ b/regression/jamvm/IntegerArithmeticTest.java
@@ -220,6 +220,14 @@ public class IntegerArithmeticTest extends TestCase {
         return value += 2;
     }
 
+    public static void testIntegerSubtractionImmRegAndRegReg() {
+        int x = 0x1a;
+        int y = 0x0d;
+        int result = (0x1f - x) - (0x11 - y);
+
+        assertEquals(1, result);
+    }
+
     public static void main(String[] args) {
         testIntegerAddition();
         testIntegerAdditionOverflow();
@@ -243,6 +251,7 @@ public class IntegerArithmeticTest extends TestCase {
         testIntegerBitwiseAnd();
         testIntegerBitwiseExclusiveOr();
         testIntegerIncrementLocalByConstant();
+        testIntegerSubtractionImmRegAndRegReg();
 
         Runtime.getRuntime().halt(retval);
     }
diff --git a/regression/jamvm/LongArithmeticTest.java 
b/regression/jamvm/LongArithmeticTest.java
index 30d9246..9024660 100644
--- a/regression/jamvm/LongArithmeticTest.java
+++ b/regression/jamvm/LongArithmeticTest.java
@@ -234,6 +234,14 @@ public class LongArithmeticTest extends TestCase {
         assertEquals(0x57, result);
     }
 
+    public static void testLongSubtractionImmRegAndRegReg() {
+        long x = 0x1a;
+        long y = 0x0d;
+        long result = (0x1f - x) - (0x11 - y);
+
+        assertEquals(1, result);
+    }
+
     public static void main(String[] args) {
         testLongAddition();
         testLongAdditionOverflow();
@@ -259,6 +267,7 @@ public class LongArithmeticTest extends TestCase {
         testLongBitwiseExclusiveOr();
         testLongIncrementLocalByConstant();
         testLongAdditionLocalSlot();
+        testLongSubtractionImmRegAndRegReg();
 
         Runtime.getRuntime().halt(retval);
     }
-- 
1.6.0.6


------------------------------------------------------------------------------
The NEW KODAK i700 Series Scanners deliver under ANY circumstances! Your
production scanning environment may not be a perfect world - but thanks to
Kodak, there's a perfect scanner to get the job done! With the NEW KODAK i700
Series Scanner you'll get full speed at 300 dpi even with all image 
processing features enabled. http://p.sf.net/sfu/kodak-com
_______________________________________________
Jatovm-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jatovm-devel

Reply via email to