* 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
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
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;
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);
}
typedef enum {
ArgInIReg,
ArgInFloatReg,
+ ArgInFloatRegR4,
ArgOnStack,
ArgValuetypeAddrInIReg,
ArgAggregate,
(*stack_size) += sizeof (gpointer);
}
else {
- ainfo->storage = ArgInFloatReg;
+ ainfo->storage = is_double ? ArgInFloatReg : ArgInFloatRegR4;
ainfo->reg = 8 + *fr;
(*fr) += 1;
(*gr) += 1;
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.
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 ();
}
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:
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);
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")