NaCl amd64 codegen fixes
authorElijah Taylor <elijahtaylor@google.com>
Thu, 31 Jan 2013 21:09:48 +0000 (13:09 -0800)
committerZoltan Varga <vargaz@gmail.com>
Thu, 21 Mar 2013 04:16:56 +0000 (05:16 +0100)
- mostly more code fixes to deal with a 64-bit ILP32 machine

mono/mini/decompose.c
mono/mini/method-to-ir.c
mono/mini/mini-amd64.c

index 7504a05bea51a90bb0d53cfc121268bfde645819..93a2535a479dcc40f4deaac7d4cca9e5b334edf9 100644 (file)
@@ -326,7 +326,7 @@ mono_decompose_opcode (MonoCompile *cfg, MonoInst *ins)
                break;
        case OP_ICONV_TO_OVF_U4:
        case OP_ICONV_TO_OVF_I4_UN:
-#if SIZEOF_REGISTER == 4
+#if SIZEOF_VOID_P == 4
        case OP_ICONV_TO_OVF_U:
        case OP_ICONV_TO_OVF_I_UN:
 #endif
@@ -339,21 +339,21 @@ mono_decompose_opcode (MonoCompile *cfg, MonoInst *ins)
        case OP_ICONV_TO_U4:
        case OP_ICONV_TO_OVF_I4:
        case OP_ICONV_TO_OVF_U4_UN:
-#if SIZEOF_REGISTER == 4
+#if SIZEOF_VOID_P == 4
        case OP_ICONV_TO_OVF_I:
        case OP_ICONV_TO_OVF_U_UN:
 #endif
                ins->opcode = OP_MOVE;
                break;
        case OP_ICONV_TO_I:
-#if SIZEOF_REGISTER == 8
+#if SIZEOF_VOID_P == 8
                ins->opcode = OP_SEXT_I4;
 #else
                ins->opcode = OP_MOVE;
 #endif
                break;
        case OP_ICONV_TO_U:
-#if SIZEOF_REGISTER == 8
+#if SIZEOF_VOID_P == 8
                ins->opcode = OP_ZEXT_I4;
 #else
                ins->opcode = OP_MOVE;
@@ -1218,9 +1218,13 @@ mono_decompose_vtype_opts (MonoCompile *cfg)
                                                case 2:
                                                        MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI2_MEMBASE_REG, dest->dreg, 0, call2->inst.dreg);
                                                        break;
+                                               case 3:
                                                case 4:
                                                        MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, dest->dreg, 0, call2->inst.dreg);
                                                        break;
+                                               case 5:
+                                               case 6:
+                                               case 7:
                                                case 8:
 #if SIZEOF_REGISTER == 4
                                                        /*
index 442017d4b56b35ad1dc6aa5b19718b43d1a4bd02..2b8a72a7ff0dcd050e9c5cd76039697430389a4b 100644 (file)
@@ -157,7 +157,7 @@ static MonoMethodSignature *helper_sig_monitor_enter_exit_trampoline_llvm = NULL
 #define FREG 'f'
 #define VREG 'v'
 #define XREG 'x'
-#if SIZEOF_REGISTER == 8
+#if SIZEOF_REGISTER == 8 && SIZEOF_REGISTER == SIZEOF_VOIDP
 #define LREG IREG
 #else
 #define LREG 'l'
@@ -12468,6 +12468,7 @@ mono_spill_global_vars (MonoCompile *cfg, gboolean *need_local_opts)
 
                                        ins->dreg = alloc_dreg (cfg, stacktypes [regtype]);
 
+#if SIZEOF_REGISTER != 8
                                        if (regtype == 'l') {
                                                NEW_STORE_MEMBASE (cfg, store_ins, OP_STOREI4_MEMBASE_REG, var->inst_basereg, var->inst_offset + MINI_LS_WORD_OFFSET, ins->dreg + 1);
                                                mono_bblock_insert_after_ins (bb, ins, store_ins);
@@ -12475,7 +12476,9 @@ mono_spill_global_vars (MonoCompile *cfg, gboolean *need_local_opts)
                                                mono_bblock_insert_after_ins (bb, ins, store_ins);
                                                def_ins = store_ins;
                                        }
-                                       else {
+                                       else
+#endif
+                                       {
                                                g_assert (store_opcode != OP_STOREV_MEMBASE);
 
                                                /* Try to fuse the store into the instruction itself */
@@ -12634,6 +12637,7 @@ mono_spill_global_vars (MonoCompile *cfg, gboolean *need_local_opts)
                                                sregs [srcindex] = sreg;
                                                //mono_inst_set_src_registers (ins, sregs);
 
+#if SIZEOF_REGISTER != 8
                                                if (regtype == 'l') {
                                                        NEW_LOAD_MEMBASE (cfg, load_ins, OP_LOADI4_MEMBASE, sreg + 2, var->inst_basereg, var->inst_offset + MINI_MS_WORD_OFFSET);
                                                        mono_bblock_insert_before_ins (bb, ins, load_ins);
@@ -12641,7 +12645,9 @@ mono_spill_global_vars (MonoCompile *cfg, gboolean *need_local_opts)
                                                        mono_bblock_insert_before_ins (bb, ins, load_ins);
                                                        use_ins = load_ins;
                                                }
-                                               else {
+                                               else
+#endif
+                                               {
 #if SIZEOF_REGISTER == 4
                                                        g_assert (load_opcode != OP_LOADI8_MEMBASE);
 #endif
index 656129c333127179369427f55be5fc2fd67ee128..9ee27020155e69dff7b606b23fd5adebb20d9aba 100644 (file)
@@ -999,6 +999,9 @@ get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSign
                                break;
                        }
                        /* fall through */
+#if defined( __native_client_codegen__ )
+               case MONO_TYPE_TYPEDBYREF:
+#endif
                case MONO_TYPE_VALUETYPE: {
                        guint32 tmp_gr = 0, tmp_fr = 0, tmp_stacksize = 0;
 
@@ -1009,10 +1012,12 @@ get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSign
                        }
                        break;
                }
+#if !defined( __native_client_codegen__ )
                case MONO_TYPE_TYPEDBYREF:
                        /* Same as a valuetype with size 24 */
                        cinfo->vtype_retaddr = TRUE;
                        break;
+#endif
                case MONO_TYPE_VOID:
                        break;
                default:
@@ -1116,7 +1121,7 @@ get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSign
                        add_valuetype (gsctx, sig, ainfo, sig->params [i], FALSE, &gr, &fr, &stack_size);
                        break;
                case MONO_TYPE_TYPEDBYREF:
-#ifdef HOST_WIN32
+#if defined( HOST_WIN32 ) || defined( __native_client_codegen__ )
                        add_valuetype (gsctx, sig, ainfo, sig->params [i], FALSE, &gr, &fr, &stack_size);
 #else
                        stack_size += sizeof (MonoTypedRef);
@@ -1657,7 +1662,7 @@ mono_arch_fill_argument_info (MonoCompile *cfg)
                case ArgInIReg:
                case ArgInFloatSSEReg:
                case ArgInDoubleSSEReg:
-                       if ((MONO_TYPE_ISSTRUCT (sig->ret) && !mono_class_from_mono_type (sig->ret)->enumtype) || (sig->ret->type == MONO_TYPE_TYPEDBYREF)) {
+                       if ((MONO_TYPE_ISSTRUCT (sig->ret) && !mono_class_from_mono_type (sig->ret)->enumtype) || ((sig->ret->type == MONO_TYPE_TYPEDBYREF) && cinfo->vtype_retaddr)) {
                                cfg->vret_addr->opcode = OP_REGVAR;
                                cfg->vret_addr->inst_c0 = cinfo->ret.reg;
                        }
@@ -1771,7 +1776,7 @@ mono_arch_allocate_vars (MonoCompile *cfg)
                case ArgInIReg:
                case ArgInFloatSSEReg:
                case ArgInDoubleSSEReg:
-                       if ((MONO_TYPE_ISSTRUCT (sig->ret) && !mono_class_from_mono_type (sig->ret)->enumtype) || (sig->ret->type == MONO_TYPE_TYPEDBYREF)) {
+                       if ((MONO_TYPE_ISSTRUCT (sig->ret) && !mono_class_from_mono_type (sig->ret)->enumtype) || ((sig->ret->type == MONO_TYPE_TYPEDBYREF) && cinfo->vtype_retaddr)) {
                                if (cfg->globalra) {
                                        cfg->vret_addr->opcode = OP_REGVAR;
                                        cfg->vret_addr->inst_c0 = cinfo->ret.reg;
@@ -3042,7 +3047,10 @@ emit_call_body (MonoCompile *cfg, guint8 *code, guint32 patch_type, gconstpointe
 #ifdef MONO_ARCH_NOMAP32BIT
                near_call = FALSE;
 #endif
-
+#if defined(__native_client__)
+               /* Always use near_call == TRUE for Native Client */
+               near_call = TRUE;
+#endif
                /* The 64bit XEN kernel does not honour the MAP_32BIT flag. (#522894) */
                if (optimize_for_xen)
                        near_call = FALSE;
@@ -4077,6 +4085,12 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        amd64_alu_reg_reg (code, X86_CMP, ins->sreg1, ins->sreg2);
                        break;
                case OP_COMPARE_IMM:
+#if defined(__mono_ilp32__)
+                        /* Comparison of pointer immediates should be 4 bytes to avoid sign-extend problems */
+                       g_assert (amd64_is_imm32 (ins->inst_imm));
+                       amd64_alu_reg_imm_size (code, X86_CMP, ins->sreg1, ins->inst_imm, 4);
+                       break;
+#endif
                case OP_LCOMPARE_IMM:
                        g_assert (amd64_is_imm32 (ins->inst_imm));
                        amd64_alu_reg_imm (code, X86_CMP, ins->sreg1, ins->inst_imm);
@@ -8127,7 +8141,7 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
                        if (item->check_target_idx || fail_case) {
                                if (!item->compare_done || fail_case) {
                                        if (amd64_is_imm32 (item->key))
-                                               amd64_alu_reg_imm (code, X86_CMP, MONO_ARCH_IMT_REG, (guint32)(gssize)item->key);
+                                               amd64_alu_reg_imm_size (code, X86_CMP, MONO_ARCH_IMT_REG, (guint32)(gssize)item->key, sizeof(gpointer));
                                        else {
                                                amd64_mov_reg_imm (code, MONO_ARCH_IMT_SCRATCH_REG, item->key);
                                                amd64_alu_reg_reg (code, X86_CMP, MONO_ARCH_IMT_REG, MONO_ARCH_IMT_SCRATCH_REG);
@@ -8153,7 +8167,7 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
                                /* enable the commented code to assert on wrong method */
 #if 0
                                if (amd64_is_imm32 (item->key))
-                                       amd64_alu_reg_imm (code, X86_CMP, MONO_ARCH_IMT_REG, (guint32)(gssize)item->key);
+                                       amd64_alu_reg_imm_size (code, X86_CMP, MONO_ARCH_IMT_REG, (guint32)(gssize)item->key, sizeof(gpointer));
                                else {
                                        amd64_mov_reg_imm (code, MONO_ARCH_IMT_SCRATCH_REG, item->key);
                                        amd64_alu_reg_reg (code, X86_CMP, MONO_ARCH_IMT_REG, MONO_ARCH_IMT_SCRATCH_REG);
@@ -8178,7 +8192,7 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
                        }
                } else {
                        if (amd64_is_imm32 (item->key))
-                               amd64_alu_reg_imm (code, X86_CMP, MONO_ARCH_IMT_REG, (guint32)(gssize)item->key);
+                               amd64_alu_reg_imm_size (code, X86_CMP, MONO_ARCH_IMT_REG, (guint32)(gssize)item->key, sizeof (gpointer));
                        else {
                                amd64_mov_reg_imm (code, MONO_ARCH_IMT_SCRATCH_REG, item->key);
                                amd64_alu_reg_reg (code, X86_CMP, MONO_ARCH_IMT_REG, MONO_ARCH_IMT_SCRATCH_REG);