2008-01-26 Zoltan Varga <vargaz@gmail.com>
authorZoltan Varga <vargaz@gmail.com>
Sat, 26 Jan 2008 21:47:09 +0000 (21:47 -0000)
committerZoltan Varga <vargaz@gmail.com>
Sat, 26 Jan 2008 21:47:09 +0000 (21:47 -0000)
* basic-long.cs: Move the fp related tests to basic-float.cs.

* mini-ops.h (OP_OUTARG_FREG_R4): New opcode.

* mini-ia64.c inssel-ia64.brg: Implement proper R4 argument passing.

svn path=/trunk/mono/; revision=94027

mono/mini/ChangeLog
mono/mini/basic-float.cs
mono/mini/inssel-ia64.brg
mono/mini/mini-ia64.c
mono/mini/mini-ops.h

index 514f1a2229c255a6df7c7a1d2c6353400c71411c..e03522be120a350a5a5911353ccc1799ad82fab9 100644 (file)
@@ -1,5 +1,11 @@
 2008-01-26  Zoltan Varga  <vargaz@gmail.com>
 
+       * basic-long.cs: Move the fp related tests to basic-float.cs.
+
+       * mini-ops.h (OP_OUTARG_FREG_R4): New opcode.
+
+       * mini-ia64.c inssel-ia64.brg: Implement proper R4 argument passing.
+
        * basic-calls.cs: Add a test for proper float argument passing.
 
        * mini-ia64.h (mono_ia64_context_get_ip): Do not substract 1 from the ip
index 17047ffbd9038198f4997084de1e0dad56b59455..5962b79b844ccb819b61becd7d5cacfc663367fb 100644 (file)
@@ -215,6 +215,36 @@ class Tests {
                return 4;
        }
 
+       public static int test_0_lconv_to_r8 () {
+               long a = 150;
+               double b = (double) a;
+
+               if (b != 150.0)
+                       return 1;
+               return 0;
+       }
+
+       public static int test_0_lconv_to_r4 () {
+               long a = 3000;
+               float b = (float) a;
+
+               if (b != 3000.0F)
+                       return 1;
+               return 0;
+       }
+
+       static void doit (double value, out long m) {
+               m = (long) value;
+       }
+
+       public static int test_0_ftol_clobber () {
+               long m;
+               doit (1.3, out m);
+               if (m != 1)
+                       return 2;
+               return 0;
+       }
+
        public static int test_0_rounding () {
                long ticks = 631502475130080000L;
                long ticksperday = 864000000000L;
index fb9662438870017506ce68656714b2bba0fc8532..5ab6dc2070085b3515fb660a162a068157cd44f3 100644 (file)
@@ -195,6 +195,17 @@ stmt: OP_OUTARG_FREG (freg) {
        mono_call_inst_add_outarg_reg (s, call, tree->dreg, tree->backend.reg3, TRUE);
 }
 
+stmt: OP_OUTARG_FREG_R4 (freg) {
+       MonoCallInst *call = (MonoCallInst*)tree->inst_right;
+
+       tree->opcode = OP_FCONV_TO_R4;
+       tree->sreg1 = state->left->reg1;
+       tree->dreg = mono_regstate_next_float (s->rs);
+       mono_bblock_add_inst (s->cbb, tree);
+
+       mono_call_inst_add_outarg_reg (s, call, tree->dreg, tree->backend.reg3, TRUE);
+}
+
 stmt: OP_OUTARG (reg) {
        MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI8_MEMBASE_REG, IA64_SP, tree->inst_imm, state->left->reg1);
 }
index 4e44866ab92e71081e767a627421bc4b3e5af5b3..7655f4fe43088ccaa8a5685d9d94c4f4b674df99 100644 (file)
@@ -160,6 +160,7 @@ ia64_patch (unsigned char* code, gpointer target);
 typedef enum {
        ArgInIReg,
        ArgInFloatReg,
+       ArgInFloatRegR4,
        ArgOnStack,
        ArgValuetypeAddrInIReg,
        ArgAggregate,
@@ -234,7 +235,7 @@ add_float (guint32 *gr, guint32 *fr, guint32 *stack_size, ArgInfo *ainfo, gboole
                (*stack_size) += sizeof (gpointer);
     }
     else {
-               ainfo->storage = ArgInFloatReg;
+               ainfo->storage = is_double ? ArgInFloatReg : ArgInFloatRegR4;
                ainfo->reg = 8 + *fr;
                (*fr) += 1;
                (*gr) += 1;
@@ -885,6 +886,7 @@ mono_arch_allocate_vars (MonoCompile *cfg)
                                inst->dreg = cfg->arch.reg_in0 + ainfo->reg;
                                break;
                        case ArgInFloatReg:
+                       case ArgInFloatRegR4:
                                /* 
                                 * Since float regs are volatile, we save the arguments to
                                 * the stack in the prolog.
@@ -967,6 +969,13 @@ add_outarg_reg (MonoCompile *cfg, MonoCallInst *call, MonoInst *arg, ArgStorage
                arg->backend.reg3 = reg;
                call->used_fregs |= 1 << reg;
                break;
+       case ArgInFloatRegR4:
+               arg->opcode = OP_OUTARG_FREG_R4;
+               arg->inst_left = tree;
+               arg->inst_right = (MonoInst*)call;
+               arg->backend.reg3 = reg;
+               call->used_fregs |= 1 << reg;
+               break;
        default:
                g_assert_not_reached ();
        }
@@ -1184,6 +1193,7 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb, MonoCallInst *call,
                                        add_outarg_reg (cfg, call, arg, ainfo->storage, cfg->arch.reg_out0 + ainfo->reg, in);
                                        break;
                                case ArgInFloatReg:
+                               case ArgInFloatRegR4:
                                        add_outarg_reg (cfg, call, arg, ainfo->storage, ainfo->reg, in);
                                        break;
                                case ArgOnStack:
@@ -3866,6 +3876,7 @@ mono_arch_emit_prolog (MonoCompile *cfg)
                        switch (ainfo->storage) {
                        case ArgInIReg:
                        case ArgInFloatReg:
+                       case ArgInFloatRegR4:
                                g_assert (inst->opcode == OP_REGOFFSET);
                                if (ia64_is_adds_imm (inst->inst_offset))
                                        ia64_adds_imm (code, GP_SCRATCH_REG, inst->inst_offset, inst->inst_basereg);
index 785dd7e719e23800f40beb660f155c2933d2e8fe..139dec107499ea40bc1f7f552fdbb9db6dc4aba2 100644 (file)
@@ -18,6 +18,7 @@ MINI_OP(OP_ARGLIST,   "oparglist")
 MINI_OP(OP_OUTARG,     "outarg")
 MINI_OP(OP_OUTARG_REG, "outarg_reg")
 MINI_OP(OP_OUTARG_FREG,        "outarg_freg")
+MINI_OP(OP_OUTARG_FREG_R4,     "outarg_freg_r4")
 MINI_OP(OP_OUTARG_IMM, "outarg_imm")
 MINI_OP(OP_OUTARG_R4,  "outarg_r4")
 MINI_OP(OP_OUTARG_R8,  "outarg_r8")