We are using movsbl instruction to sign-extend the byte value.
This instruction uses r/m8 addressing for source. There is no
equivalent for lowest byte of %esi and %edi in this addressing,
codes for those register are representing %dh and %bh registers.

This bug caused that CharsetEncoder.encode() did not work properly
preventing System.out.println() from correct behavior.

Signed-off-by: Tomek Grabiec <tgrab...@gmail.com>
---
 arch/x86/emit-code.c       |    8 +++++++-
 arch/x86/insn-selector.brg |   12 ++++++++++--
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/arch/x86/emit-code.c b/arch/x86/emit-code.c
index 803a787..ad8b3fc 100644
--- a/arch/x86/emit-code.c
+++ b/arch/x86/emit-code.c
@@ -706,8 +706,14 @@ static void emit_mov_reg_reg(struct buffer *buf, struct 
operand *src,
 static void emit_movsx_8_reg_reg(struct buffer *buf, struct operand *src,
                             struct operand *dest)
 {
+       enum machine_reg src_reg = mach_reg(&src->reg);
+
        emit(buf, 0x0f);
-       __emit_reg_reg(buf, 0xbe, mach_reg(&dest->reg), mach_reg(&src->reg));
+
+       /* We probably don't want %dh and %bh here. */
+       assert(src_reg != MACH_REG_ESI && src_reg != MACH_REG_EDI);
+
+       __emit_reg_reg(buf, 0xbe, mach_reg(&dest->reg), src_reg);
 }
 
 static void emit_movsx_16_reg_reg(struct buffer *buf, struct operand *src,
diff --git a/arch/x86/insn-selector.brg b/arch/x86/insn-selector.brg
index b4c04e2..fb9508e 100644
--- a/arch/x86/insn-selector.brg
+++ b/arch/x86/insn-selector.brg
@@ -1270,9 +1270,17 @@ reg:     EXPR_CONVERSION(reg)
        } else if (src->vm_type == J_LONG && expr->vm_type == J_INT) {
                state->reg1 = state->left->reg1;
        } else if (src->vm_type == J_INT && expr->vm_type == J_BYTE) {
-               state->reg1 = get_var(s->b_parent, J_INT);
+               /*
+                * We cannot use random register here because we
+                * cannot address lowest byte of %esi and %edi in r/m8
+                * addressing. Solution is to use a fixed
+                * register.
+                */
+               struct var_info *tmp = get_fixed_var(s->b_parent, MACH_REG_ECX);
 
-               select_insn(s, tree, reg_reg_insn(INSN_MOVSX_8_REG_REG, 
state->left->reg1, state->reg1));
+               state->reg1 = state->left->reg1;
+               select_insn(s, tree, reg_reg_insn(INSN_MOV_REG_REG, 
state->left->reg1, tmp));
+               select_insn(s, tree, reg_reg_insn(INSN_MOVSX_8_REG_REG, tmp, 
state->left->reg1));
        } else if (src->vm_type == J_INT && expr->vm_type == J_CHAR) {
                state->reg1 = get_var(s->b_parent, J_INT);
 
-- 
1.6.0.6


------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with 
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel

Reply via email to