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