These rules are incorrect because we have rules like this:

STMT_RETURN(freg)
{
}

STMT_RETURN(reg)
{
}

and monoburg can not pick the right one if we have unconditional
register conversion rules between reg and freg.

Solution for this, as proposed by Pekka Enberg, is to create separate
expression types for float, when there is such necessity, so that
there is no conversion between reg and freg other than explicit
conversion expression. For example, we have EXPR_INSTANCE_FIELD for GPR
storage and EXPR_FLOAT_INSTANCE_FIELD for FPU storage and two rules:

reg: EXPR_LOCAL_FIELD
{
}

freg: EXPR_FLOAT_LCOAL_FIELD
{
}

Reported-by: Vegard Nossum <vegard.nos...@gmail.com>
Analyzed-by: Vegard Nossum <vegard.nos...@gmail.com>
Analyzed-by: Pekka Enberg <penb...@cs.helsinki.fi>
Signed-off-by: Tomek Grabiec <tgrab...@gmail.com>
---
 arch/x86/insn-selector.brg |  347 ++++++++++++++++++++++++++++++++++++++++----
 include/jit/expression.h   |    4 +
 include/vm/types.h         |    7 +
 jit/expression.c           |   40 +++++-
 jit/tree-printer.c         |   80 ++++++++++-
 5 files changed, 444 insertions(+), 34 deletions(-)

diff --git a/arch/x86/insn-selector.brg b/arch/x86/insn-selector.brg
index c359b70..b510da7 100644
--- a/arch/x86/insn-selector.brg
+++ b/arch/x86/insn-selector.brg
@@ -34,6 +34,7 @@
 #include <vm/method.h>
 #include <vm/object.h>
 #include <vm/stack-trace.h>
+#include <vm/trace.h>
 
 #define MBCGEN_TYPE struct basic_block
 #define MBCOST_DATA struct basic_block
@@ -146,34 +147,6 @@ freg:      EXPR_FVALUE     0
        select_insn(s, tree, membase_reg_insn(INSN_MOV_MEMBASE_XMM, esp, -4, 
result));
 }
 
-reg:   freg 1
-{
-       struct var_info *result, *in, *esp;
-
-       in = state->reg1;
-       result = get_var(s->b_parent, J_INT);
-       state->reg1 = result;
-
-       esp = get_fixed_var(s->b_parent, REG_xSP);
-
-       select_insn(s, tree, reg_membase_insn(INSN_MOV_XMM_MEMBASE, in, esp, 
-4));
-       select_insn(s, tree, membase_reg_insn(INSN_MOV_MEMBASE_REG, esp, -4, 
result));
-}
-
-freg:  reg 1
-{
-       struct var_info *result, *in, *esp;
-
-       in = state->reg1;
-       result = get_var(s->b_parent, J_FLOAT);
-       state->reg1 = result;
-
-       esp = get_fixed_var(s->b_parent, REG_xSP);
-
-       select_insn(s, tree, reg_membase_insn(INSN_MOV_REG_MEMBASE, in, esp, 
-4));
-       select_insn(s, tree, membase_reg_insn(INSN_MOV_MEMBASE_XMM, esp, -4, 
result));
-}
-
 reg:   EXPR_VALUE      0
 {
        struct expression *expr;
@@ -276,6 +249,15 @@ reg:   EXPR_TEMPORARY 0
        }
 }
 
+freg:   EXPR_FLOAT_TEMPORARY 0
+{
+       struct expression *expr;
+
+       expr = to_expr(tree);
+
+       state->reg1 = expr->tmp_low;
+}
+
 reg:   OP_ADD(reg, EXPR_LOCAL) 1
 {
        binop_reg_local_low(state, s, tree, INSN_ADD_MEMBASE_REG);
@@ -954,6 +936,45 @@ reg:       EXPR_CLASS_FIELD 1
        }
 }
 
+freg:  EXPR_FLOAT_CLASS_FIELD 1
+{
+       struct expression *expr;
+       struct var_info *out;
+       struct insn *mov_insn;
+
+       struct vm_field *vmf;
+       struct vm_class *vmc;
+       enum vm_class_state vmc_state;
+
+       expr   = to_expr(tree);
+
+       out = get_var(s->b_parent, expr->vm_type);
+       state->reg1 = out;
+
+       vmf = expr->class_field;
+       vmc = vmf->class;
+
+       vm_monitor_lock(&vmc->monitor);
+       vmc_state = vmc->state;
+       vm_monitor_unlock(&vmc->monitor);
+
+       if (vmc_state >= VM_CLASS_INITIALIZING) {
+               /* Class is already initialized; no need for fix-up. We also
+                * don't want the fixup if we're already inside the
+                * initializer. */
+               mov_insn = memdisp_reg_insn(INSN_MOV_MEMDISP_XMM,
+                       (unsigned long) vmc->static_values + vmf->offset, out);
+       } else {
+               mov_insn = memdisp_reg_insn(INSN_MOV_MEMDISP_XMM,
+                       (unsigned long) static_guard_page, out);
+
+               /* XXX: Check return value */
+               add_getstatic_fixup_site(mov_insn, vmf, s->b_parent);
+       }
+
+       select_insn(s, tree, mov_insn);
+}
+
 reg:   EXPR_INSTANCE_FIELD(reg) 1
 {
        struct var_info *base;
@@ -974,6 +995,21 @@ reg:       EXPR_INSTANCE_FIELD(reg) 1
        }
 }
 
+freg:  EXPR_FLOAT_INSTANCE_FIELD(reg) 1
+{
+       struct var_info *base;
+       struct expression *expr;
+       unsigned long offset;
+
+       expr = to_expr(tree);
+
+       base = state->left->reg1;
+       state->reg1 = get_var(s->b_parent, expr->vm_type);
+
+       offset = sizeof(struct vm_object) + expr->instance_field->offset;
+       select_insn(s, tree, membase_reg_insn(INSN_MOV_MEMBASE_XMM, base, 
offset, state->reg1));
+}
+
 %ifdef CONFIG_X86_32
 reg:   EXPR_NEW
 {
@@ -1396,6 +1432,27 @@ arg:     EXPR_ARG(reg)
 
        state->reg1 = NULL;
 }
+
+arg:   EXPR_ARG(freg)
+{
+       struct var_info *src, *esp;
+       struct expression *expr, *arg_expr;
+       int size;
+
+       expr = to_expr(tree);
+       arg_expr = to_expr(expr->arg_expression);
+
+       src = state->left->reg1;
+       esp = get_fixed_var(s->b_parent, REG_xSP);
+
+       size = get_vmtype_size(arg_expr->vm_type);
+
+       select_insn(s, tree,
+                   reg_membase_insn(INSN_MOV_XMM_MEMBASE, src, esp, -size));
+       select_insn(s, tree, imm_reg_insn(INSN_SUB_IMM_REG, size, esp));
+
+       state->reg1 = NULL;
+}
 %else
 arg:   EXPR_ARG(reg) 1
 {
@@ -1416,6 +1473,30 @@ arg:     EXPR_ARG(reg) 1
 
        state->reg1 = NULL;
 }
+
+arg:   EXPR_ARG(freg)
+{
+       struct var_info *src, *esp;
+       struct expression *expr, *arg_expr;
+
+       expr = to_expr(tree);
+       arg_expr = to_expr(expr->arg_expression);
+
+       src = state->left->reg1;
+       esp = get_fixed_var(s->b_parent, REG_xSP);
+
+       if (expr->arg_reg != REG_UNASSIGNED) {
+               dst = get_fixed_var(s->b_parent, expr->arg_reg);
+               select_insn(s, tree, reg_reg_insn(INSN_MOV_XMM_XMM, src, dst));
+       } else {
+               int size = get_vmtype_size(arg_expr->vm_type);
+               select_insn(s, tree, reg_membase_insn(INSN_MOV_XMM_MEMBASE,
+                                                     src, esp, -size));
+               select_insn(s, tree, imm_reg_insn(INSN_SUB_IMM_REG, size, esp));
+       }
+
+       state->reg1 = NULL;
+}
 %endif
 
 arg:   EXPR_ARGS_LIST(arg, arg)
@@ -1506,6 +1587,10 @@ stmt:    STMT_EXPRESSION(reg)
 {
 }
 
+stmt:  STMT_EXPRESSION(freg)
+{
+}
+
 stmt:  STMT_STORE(EXPR_CLASS_FIELD, reg)
 {
        struct expression *store_dest;
@@ -1555,6 +1640,48 @@ stmt:    STMT_STORE(EXPR_CLASS_FIELD, reg)
        }
 }
 
+stmt:  STMT_STORE(EXPR_FLOAT_CLASS_FIELD, freg)
+{
+       struct expression *store_dest;
+       struct expression *store_src;
+       struct statement *stmt;
+       struct var_info *src;
+       struct insn *mov_insn;
+
+       struct vm_field *vmf;
+       struct vm_class *vmc;
+       enum vm_class_state vmc_state;
+
+       stmt = to_stmt(tree);
+       store_dest = to_expr(stmt->store_dest);
+       store_src  = to_expr(stmt->store_src);
+
+       src = state->right->reg1;
+
+       vmf = store_dest->class_field;
+       vmc = vmf->class;
+
+       vm_monitor_lock(&vmc->monitor);
+       vmc_state = vmc->state;
+       vm_monitor_unlock(&vmc->monitor);
+
+       if (vmc_state >= VM_CLASS_INITIALIZING) {
+               /* Class is already initialized; no need for fix-up. We also
+                * don't want the fixup if we're already inside the
+                * initializer. */
+               mov_insn = reg_memdisp_insn(INSN_MOV_XMM_MEMDISP,
+                       src, (unsigned long) vmc->static_values + vmf->offset);
+       } else {
+               mov_insn = reg_memdisp_insn(INSN_MOV_XMM_MEMDISP,
+                       src, (unsigned long) static_guard_page);
+
+               /* XXX: Check return value */
+               add_putstatic_fixup_site(mov_insn, vmf, s->b_parent);
+       }
+
+       select_insn(s, tree, mov_insn);
+}
+
 inst_field: EXPR_INSTANCE_FIELD(reg) 1
 {
        struct expression *expr;
@@ -1565,6 +1692,16 @@ inst_field: EXPR_INSTANCE_FIELD(reg) 1
        state->reg2 = (void*)(sizeof(struct vm_object) + 
expr->instance_field->offset);
 }
 
+float_inst_field: EXPR_FLOAT_INSTANCE_FIELD(reg) 1
+{
+       struct expression *expr;
+
+       expr = to_expr(tree);
+
+       state->reg1 = state->left->reg1;
+       state->reg2 = (void*)(sizeof(struct vm_object) + 
expr->instance_field->offset);
+}
+
 stmt:  STMT_STORE(inst_field, reg)
 {
        struct var_info *src, *base;
@@ -1587,6 +1724,24 @@ stmt:    STMT_STORE(inst_field, reg)
        }
 }
 
+stmt:  STMT_STORE(float_inst_field, freg)
+{
+       struct var_info *src, *base;
+       struct expression *store_src;
+       struct statement *stmt;
+       unsigned long offset;
+
+       stmt = to_stmt(tree);
+       store_src = to_expr(stmt->store_src);
+       src = state->right->reg1;
+
+       base = state->left->reg1;
+       offset = (unsigned long)state->left->reg2;
+
+       select_insn(s, tree,
+                   reg_membase_insn(INSN_MOV_XMM_MEMBASE, src, base, offset));
+}
+
 stmt:  STMT_STORE(EXPR_LOCAL, reg)
 {
        struct compilation_unit *cu = s->b_parent;
@@ -1612,6 +1767,23 @@ stmt:    STMT_STORE(EXPR_LOCAL, reg)
        }
 }
 
+stmt:  STMT_STORE(EXPR_FLOAT_LOCAL, freg)
+{
+       struct compilation_unit *cu = s->b_parent;
+       struct expression *local;
+       struct stack_slot *slot;
+       struct statement *stmt;
+       struct var_info *src;
+
+       src = state->right->reg1;
+
+       stmt = to_stmt(tree);
+       local = to_expr(stmt->store_dest);
+       slot = get_local_slot(cu->stack_frame, local->local_index);
+
+       select_insn(s, tree, reg_memlocal_insn(INSN_MOV_FREG_MEMLOCAL, src, 
slot));
+}
+
 %ifdef CONFIG_X86_32
 stmt:  STMT_STORE(EXPR_TEMPORARY, EXPR_LOCAL) 1
 {
@@ -1636,6 +1808,25 @@ stmt:  STMT_STORE(EXPR_TEMPORARY, EXPR_LOCAL) 1
        }
 
 }
+
+stmt:  STMT_STORE(EXPR_FLOAT_TEMPORARY, EXPR_FLOAT_LOCAL) 1
+{
+       struct expression *exprdest, *exprsrc;
+       struct stack_slot *slot;
+       struct statement *stmt;
+       struct var_info *dest;
+
+       stmt = to_stmt(tree);
+
+       exprsrc = to_expr(stmt->store_src);
+       exprdest = to_expr(stmt->store_dest);
+
+       slot = get_local_slot(s->b_parent->stack_frame, exprsrc->local_index);
+
+       dest = exprdest->tmp_low;
+
+       select_insn(s, tree, memlocal_reg_insn(INSN_MOV_MEMLOCAL_FREG, slot, 
dest));
+}
 %else
 stmt:  STMT_STORE(EXPR_TEMPORARY, EXPR_LOCAL) 1
 {
@@ -1667,6 +1858,34 @@ stmt:  STMT_STORE(EXPR_TEMPORARY, EXPR_LOCAL) 1
                select_insn(s, tree, reg_reg_insn(INSN_MOV_REG_REG, src, dest));
        }
 }
+
+stmt:  STMT_STORE(EXPR_FLOAT_TEMPORARY, EXPR_FLOAT_LOCAL) 1
+{
+       struct expression *exprdest, *exprsrc;
+       struct stack_slot *slot;
+       struct statement *stmt;
+       struct var_info *dest;
+
+       stmt = to_stmt(tree);
+
+       exprsrc = to_expr(stmt->store_src);
+       exprdest = to_expr(stmt->store_dest);
+
+       slot = get_local_slot(s->b_parent->stack_frame, exprsrc->local_index);
+
+       dest = exprdest->tmp_low;
+
+       reg = method->args_map[exprsrc->local_index].reg;
+       if (reg == REG_UNASSIGNED) {
+               index = method->args_map[exprsrc->local_index].stack_index;
+               slot = get_local_slot(s->b_parent->stack_frame, index);
+               select_insn(s, tree, memlocal_reg_insn(INSN_MOV_MEMLOCAL_FREG,
+                                                      slot, dest));
+       } else {
+               src = get_fixed_var(s->b_parent, reg);
+               select_insn(s, tree, reg_reg_insn(INSN_MOV_XMM_XMM, src, dest));
+       }
+}
 %endif
 
 stmt:  STMT_STORE(EXPR_TEMPORARY, reg) 1
@@ -1690,6 +1909,21 @@ stmt:  STMT_STORE(EXPR_TEMPORARY, reg) 1
        }
 }
 
+stmt:  STMT_STORE(EXPR_FLOAT_TEMPORARY, freg) 1
+{
+       struct expression *temp;
+       struct var_info *src, *dest;
+       struct statement *stmt;
+
+       stmt = to_stmt(tree);
+
+       temp = to_expr(stmt->store_dest);
+
+       dest = temp->tmp_low;
+       src = state->right->reg1;
+       select_insn(s, tree, reg_reg_insn(INSN_MOV_XMM_XMM, src, dest));
+}
+
 array_deref:   EXPR_ARRAY_DEREF(reg, reg) 2
 {
        struct var_info *base, *state_base;
@@ -1727,6 +1961,25 @@ stmt:    STMT_STORE(array_deref, reg)
        select_insn(s, tree, reg_memindex_insn(INSN_MOV_REG_MEMINDEX, src, 
base, index, scale));
 }
 
+stmt:  STMT_STORE(array_deref, freg)
+{
+       struct var_info *src, *base, *index;
+       struct expression *dest_expr;
+       struct statement *stmt;
+       unsigned char scale;
+
+       stmt = to_stmt(tree);
+       dest_expr = to_expr(stmt->store_dest);
+
+       scale = type_to_scale(dest_expr->vm_type);
+
+       base = state->left->reg1;
+       index = state->left->reg2;
+       src = state->right->reg1;
+
+       select_insn(s, tree, reg_memindex_insn(INSN_MOV_XMM_MEMINDEX, src, 
base, index, scale));
+}
+
 stmt:  STMT_STORE(reg, array_deref)
 {
        struct var_info *dest, *base, *index;
@@ -1748,6 +2001,27 @@ stmt:    STMT_STORE(reg, array_deref)
        select_insn(s, tree, memindex_reg_insn(INSN_MOV_MEMINDEX_REG, base, 
index, scale, dest));
 }
 
+stmt:  STMT_STORE(freg, array_deref)
+{
+       struct var_info *dest, *base, *index;
+       struct expression *src_expr;
+       struct statement *stmt;
+       unsigned char scale;
+
+       stmt = to_stmt(tree);
+       src_expr = to_expr(stmt->store_src);
+
+       scale = type_to_scale(src_expr->vm_type);
+
+       base = state->right->reg1;
+       index = state->right->reg2;
+       dest = state->left->reg1;
+
+       state->reg1 = dest;
+
+       select_insn(s, tree, memindex_reg_insn(INSN_MOV_MEMINDEX_XMM, base, 
index, scale, dest));
+}
+
 stmt:  STMT_ARRAY_STORE_CHECK(reg, reg) 1
 {
        struct expression *src_expr;
@@ -1769,6 +2043,20 @@ stmt:    STMT_ARRAY_STORE_CHECK(reg, reg) 1
        method_args_cleanup(s, tree, 2);
 }
 
+stmt:  STMT_ARRAY_STORE_CHECK(freg, reg) 1
+{
+       struct expression *src_expr;
+       struct statement *stmt;
+
+       stmt = to_stmt(tree);
+       src_expr = to_expr(stmt->store_check_src);
+
+       select_insn(s, tree, imm_insn(INSN_PUSH_IMM, src_expr->vm_type));
+       select_insn(s, tree, reg_insn(INSN_PUSH_REG, state->right->reg1));
+       select_insn(s, tree, rel_insn(INSN_CALL_REL, (unsigned long) 
array_store_check_vmtype));
+       method_args_cleanup(s, tree, 2);
+}
+
 stmt:  STMT_ATHROW(reg)
 {
        struct var_info *reg_eax = get_fixed_var(s->b_parent, REG_xAX);
@@ -2504,8 +2792,9 @@ int select_instructions(struct compilation_unit *cu)
        get_fixed_var(cu, REG_xCX);
        get_fixed_var(cu, REG_xDX);
 
-       for_each_basic_block(bb, &cu->bb_list)
+       for_each_basic_block(bb, &cu->bb_list) {
                insn_select(bb);
+       }
 
   out:
        return err;
diff --git a/include/jit/expression.h b/include/jit/expression.h
index 3198d4f..209f5c5 100644
--- a/include/jit/expression.h
+++ b/include/jit/expression.h
@@ -16,6 +16,10 @@ struct parse_context;
 
 enum expression_type {
        EXPR_VALUE,
+       EXPR_FLOAT_LOCAL,
+       EXPR_FLOAT_TEMPORARY,
+       EXPR_FLOAT_CLASS_FIELD,
+       EXPR_FLOAT_INSTANCE_FIELD,
        EXPR_FVALUE,
        EXPR_LOCAL,
        EXPR_TEMPORARY,
diff --git a/include/vm/types.h b/include/vm/types.h
index e97bfbd..dc944d9 100644
--- a/include/vm/types.h
+++ b/include/vm/types.h
@@ -1,6 +1,8 @@
 #ifndef __VM_TYPES_H
 #define __VM_TYPES_H
 
+#include <stdbool.h>
+
 enum vm_type {
        J_VOID,
        J_REFERENCE,
@@ -26,4 +28,9 @@ int vmtype_to_bytecode_type(enum vm_type);
 int get_vmtype_size(enum vm_type);
 const char *get_vm_type_name(enum vm_type);
 
+static inline bool vm_type_is_float(enum vm_type type)
+{
+       return type == J_FLOAT || type == J_DOUBLE;
+}
+
 #endif
diff --git a/jit/expression.c b/jit/expression.c
index 6863f2c..302316f 100644
--- a/jit/expression.c
+++ b/jit/expression.c
@@ -45,6 +45,7 @@ int expr_nr_kids(struct expression *expr)
        case EXPR_CONVERSION_TO_FLOAT:
        case EXPR_CONVERSION_FROM_FLOAT:
        case EXPR_INSTANCE_FIELD:
+       case EXPR_FLOAT_INSTANCE_FIELD:
        case EXPR_INVOKE:
        case EXPR_INVOKEINTERFACE:
        case EXPR_INVOKEVIRTUAL:
@@ -62,6 +63,9 @@ int expr_nr_kids(struct expression *expr)
        case EXPR_MULTIARRAY_SIZE_CHECK:
                return 1;
        case EXPR_VALUE:
+       case EXPR_FLOAT_LOCAL:
+       case EXPR_FLOAT_TEMPORARY:
+       case EXPR_FLOAT_CLASS_FIELD:
        case EXPR_FVALUE:
        case EXPR_LOCAL:
        case EXPR_TEMPORARY:
@@ -122,11 +126,15 @@ int expr_is_pure(struct expression *expr)
        case EXPR_VALUE:
        case EXPR_FVALUE:
        case EXPR_LOCAL:
+       case EXPR_FLOAT_LOCAL:
        case EXPR_TEMPORARY:
+       case EXPR_FLOAT_TEMPORARY:
        case EXPR_CLASS_FIELD:
+       case EXPR_FLOAT_CLASS_FIELD:
        case EXPR_NO_ARGS:
        case EXPR_EXCEPTION_REF:
        case EXPR_INSTANCE_FIELD:
+       case EXPR_FLOAT_INSTANCE_FIELD:
        case EXPR_MIMIC_STACK_SLOT:
                return true;
 
@@ -215,7 +223,13 @@ struct expression *fvalue_expr(enum vm_type vm_type, 
double fvalue)
 
 struct expression *local_expr(enum vm_type vm_type, unsigned long local_index)
 {
-       struct expression *expr = alloc_expression(EXPR_LOCAL, vm_type);
+       struct expression *expr;
+
+       if (vm_type_is_float(vm_type))
+               expr = alloc_expression(EXPR_FLOAT_LOCAL, vm_type);
+       else
+               expr = alloc_expression(EXPR_LOCAL, vm_type);
+
        if (expr)
                expr->local_index = local_index;
 
@@ -224,7 +238,13 @@ struct expression *local_expr(enum vm_type vm_type, 
unsigned long local_index)
 
 struct expression *temporary_expr(enum vm_type vm_type, struct var_info 
*tmp_high, struct var_info *tmp_low)
 {
-       struct expression *expr = alloc_expression(EXPR_TEMPORARY, vm_type);
+       struct expression *expr;
+
+       if (vm_type_is_float(vm_type))
+               expr = alloc_expression(EXPR_FLOAT_TEMPORARY, vm_type);
+       else
+               expr = alloc_expression(EXPR_TEMPORARY, vm_type);
+
        if (expr) {
                expr->tmp_high = tmp_high;
                expr->tmp_low = tmp_low;
@@ -310,7 +330,13 @@ struct expression *conversion_from_float_expr(enum vm_type 
vm_type,
 
 struct expression *class_field_expr(enum vm_type vm_type, struct vm_field 
*class_field)
 {
-       struct expression *expr = alloc_expression(EXPR_CLASS_FIELD, vm_type);
+       struct expression *expr;
+
+       if (vm_type_is_float(vm_type))
+               expr = alloc_expression(EXPR_FLOAT_CLASS_FIELD, vm_type);
+       else
+               expr = alloc_expression(EXPR_CLASS_FIELD, vm_type);
+
        if (expr)
                expr->class_field = class_field;
        return expr;
@@ -320,7 +346,13 @@ struct expression *instance_field_expr(enum vm_type 
vm_type,
                                       struct vm_field *instance_field,
                                       struct expression *objectref_expression)
 {
-       struct expression *expr = alloc_expression(EXPR_INSTANCE_FIELD, 
vm_type);
+       struct expression *expr;
+
+       if (vm_type_is_float(vm_type))
+               expr = alloc_expression(EXPR_FLOAT_INSTANCE_FIELD, vm_type);
+       else
+               expr = alloc_expression(EXPR_INSTANCE_FIELD, vm_type);
+
        if (expr) {
                expr->objectref_expression = &objectref_expression->node;
                expr->instance_field = instance_field;
diff --git a/jit/tree-printer.c b/jit/tree-printer.c
index 2473470..f88a56a 100644
--- a/jit/tree-printer.c
+++ b/jit/tree-printer.c
@@ -88,7 +88,9 @@ static int simple_expr(struct expression *expr)
        return type == EXPR_VALUE || type == EXPR_FVALUE || type == EXPR_LOCAL
            || type == EXPR_TEMPORARY || type == EXPR_CLASS_FIELD
            || type == EXPR_NO_ARGS || type == EXPR_EXCEPTION_REF
-           || type == EXPR_MIMIC_STACK_SLOT;
+           || type == EXPR_MIMIC_STACK_SLOT || type == EXPR_FLOAT_LOCAL
+           || type == EXPR_FLOAT_TEMPORARY || type == EXPR_FLOAT_CLASS_FIELD
+           || type == EXPR_FLOAT_INSTANCE_FIELD;
 }
 
 static int __tree_print(int, struct tree_node *, struct string *);
@@ -368,6 +370,14 @@ static int print_value_expr(int lvl, struct string *str,
                          expr->value);
 }
 
+static int print_float_local_expr(int lvl, struct string *str,
+                           struct expression *expr)
+{
+       return str_append(str, "[float-local %s %lu]",
+                         type_names[expr->vm_type],
+                         expr->local_index);
+}
+
 static int print_fvalue_expr(int lvl, struct string *str,
                             struct expression *expr)
 {
@@ -405,6 +415,30 @@ out:
        return err;
 }
 
+static int print_float_temporary_expr(int lvl, struct string *str,
+                                     struct expression *expr)
+{
+       int err;
+
+       err = str_append(str, "[float-temporary %s ",
+                        type_names[expr->vm_type]);
+       if (err)
+               goto out;
+
+       if (expr->tmp_high) {
+               err = str_append(str, "0x%lx (high), ", expr->tmp_high);
+               if (err)
+                       goto out;
+       }
+
+       err = str_append(str, "0x%lx (low)]", expr->tmp_low);
+       if (err)
+               goto out;
+
+out:
+       return err;
+}
+
 static int print_mimic_stack_slot_expr(int lvl, struct string *str,
                                       struct expression *expr)
 {
@@ -560,6 +594,15 @@ static int print_class_field_expr(int lvl, struct string 
*str,
                          expr->class_field->name);
 }
 
+static int print_float_class_field_expr(int lvl, struct string *str,
+                                       struct expression *expr)
+{
+       return str_append(str, "[float_class_field %s %p '%s.%s']",
+                         type_names[expr->vm_type], expr->class_field,
+                         expr->class_field->class->name,
+                         expr->class_field->name);
+}
+
 static int print_instance_field_expr(int lvl, struct string *str,
                                     struct expression *expr)
 {
@@ -591,6 +634,37 @@ out:
        return err;
 }
 
+static int print_float_instance_field_expr(int lvl, struct string *str,
+                                          struct expression *expr)
+{
+       int err;
+
+       err = append_formatted(lvl, str, "FLOAT_INSTANCE_FIELD:\n");
+       if (err)
+               goto out;
+
+       err =
+           append_simple_attr(lvl + 1, str, "vm_type",
+                              type_names[expr->vm_type]);
+       if (err)
+               goto out;
+
+       err =
+           append_simple_attr(lvl + 1, str, "instance_field", "%p '%s.%s'",
+                              expr->instance_field,
+                              expr->instance_field->class->name,
+                              expr->instance_field->name);
+       if (err)
+               goto out;
+
+       err =
+           append_tree_attr(lvl + 1, str, "objectref_expression",
+                            expr->objectref_expression);
+
+out:
+       return err;
+}
+
 static int print_invoke_expr(int lvl, struct string *str,
                             struct expression *expr)
 {
@@ -925,6 +999,8 @@ typedef int (*print_expr_fn) (int, struct string * str, 
struct expression *);
 
 static print_expr_fn expr_printers[] = {
        [EXPR_VALUE] = print_value_expr,
+       [EXPR_FLOAT_LOCAL] = print_float_local_expr,
+       [EXPR_FLOAT_TEMPORARY] = print_float_temporary_expr,
        [EXPR_FVALUE] = print_fvalue_expr,
        [EXPR_LOCAL] = print_local_expr,
        [EXPR_TEMPORARY] = print_temporary_expr,
@@ -935,7 +1011,9 @@ static print_expr_fn expr_printers[] = {
        [EXPR_CONVERSION_FROM_FLOAT] = print_conversion_expr,
        [EXPR_CONVERSION_TO_FLOAT] = print_conversion_expr,
        [EXPR_CLASS_FIELD] = print_class_field_expr,
+       [EXPR_FLOAT_CLASS_FIELD] = print_float_class_field_expr,
        [EXPR_INSTANCE_FIELD] = print_instance_field_expr,
+       [EXPR_FLOAT_INSTANCE_FIELD] = print_float_instance_field_expr,
        [EXPR_INVOKE] = print_invoke_expr,
        [EXPR_INVOKEINTERFACE] = print_invokeinterface_expr,
        [EXPR_INVOKEVIRTUAL] = print_invokevirtual_expr,
-- 
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