DEBUG_AMD64_GSHAREDVT_PRINT ("source sig: (%s) return (%s)\n", mono_signature_get_desc (caller_sig, FALSE), mono_type_full_name (mono_signature_get_return_type (caller_sig))); // Leak
DEBUG_AMD64_GSHAREDVT_PRINT ("dest sig: (%s) return (%s)\n", mono_signature_get_desc (callee_sig, FALSE), mono_type_full_name (mono_signature_get_return_type (callee_sig)));
- if (gcinfo->ret.is_gsharedvt_return_value) {
+ if (gcinfo->ret.storage == ArgGsharedvtVariableInReg) {
/*
* The return type is gsharedvt
*/
if (cinfo->ret.storage == ArgValuetypeAddrInIReg) {
/* Both the caller and the callee pass the vtype ret address in r8 */
- g_assert (cinfo->ret.storage == gcinfo->ret.storage);
+ g_assert (gcinfo->ret.storage == ArgValuetypeAddrInIReg || gcinfo->ret.storage == ArgGsharedvtVariableInReg);
add_to_map (map, map_reg (cinfo->ret.reg), map_reg (cinfo->ret.reg));
}
info->calli = calli;
if (var_ret) {
- g_assert (gcinfo->ret.is_gsharedvt_return_value);
+ g_assert (gcinfo->ret.storage == ArgGsharedvtVariableInReg);
info->vret_arg_reg = map_reg (gcinfo->ret.reg);
DEBUG_AMD64_GSHAREDVT_PRINT ("mapping vreg_arg_reg to %d in reg %s\n", info->vret_arg_reg, mono_arch_regname (gcinfo->ret.reg));
} else {
return info;
}
-#endif
\ No newline at end of file
+#endif
cinfo = (CallInfo *)g_malloc0 (sizeof (CallInfo) + (sizeof (ArgInfo) * n));
cinfo->nargs = n;
+ cinfo->gsharedvt = mini_is_gsharedvt_variable_signature (sig);
gr = 0;
fr = 0;
break;
}
if (mini_is_gsharedvt_type (ret_type)) {
- cinfo->ret.storage = ArgValuetypeAddrInIReg;
- cinfo->ret.is_gsharedvt_return_value = 1;
+ cinfo->ret.storage = ArgGsharedvtVariableInReg;
break;
}
/* fall through */
case MONO_TYPE_VAR:
case MONO_TYPE_MVAR:
g_assert (mini_is_gsharedvt_type (ret_type));
- cinfo->ret.storage = ArgValuetypeAddrInIReg;
- cinfo->ret.is_gsharedvt_return_value = 1;
+ cinfo->ret.storage = ArgGsharedvtVariableInReg;
break;
case MONO_TYPE_VOID:
break;
* are sometimes made using calli without sig->hasthis set, like in the delegate
* invoke wrappers.
*/
- if (cinfo->ret.storage == ArgValuetypeAddrInIReg && !is_pinvoke && (sig->hasthis || (sig->param_count > 0 && MONO_TYPE_IS_REFERENCE (mini_get_underlying_type (sig->params [0]))))) {
+ ArgStorage ret_storage = cinfo->ret.storage;
+ if ((ret_storage == ArgValuetypeAddrInIReg || ret_storage == ArgGsharedvtVariableInReg) && !is_pinvoke && (sig->hasthis || (sig->param_count > 0 && MONO_TYPE_IS_REFERENCE (mini_get_underlying_type (sig->params [0]))))) {
if (sig->hasthis) {
add_general (&gr, &stack_size, cinfo->args + 0);
} else {
pstart = 1;
}
add_general (&gr, &stack_size, &cinfo->ret);
- cinfo->ret.storage = ArgValuetypeAddrInIReg;
+ cinfo->ret.storage = ret_storage;
cinfo->vret_arg_index = 1;
} else {
/* this */
if (sig->hasthis)
add_general (&gr, &stack_size, cinfo->args + 0);
- if (cinfo->ret.storage == ArgValuetypeAddrInIReg) {
+ if (ret_storage == ArgValuetypeAddrInIReg || ret_storage == ArgGsharedvtVariableInReg) {
add_general (&gr, &stack_size, &cinfo->ret);
- cinfo->ret.storage = ArgValuetypeAddrInIReg;
+ cinfo->ret.storage = ret_storage;
}
}
cfg->ret->dreg = cinfo->ret.reg;
break;
case ArgValuetypeAddrInIReg:
+ case ArgGsharedvtVariableInReg:
/* The register is volatile */
cfg->vret_addr->opcode = OP_REGOFFSET;
cfg->vret_addr->inst_basereg = cfg->frame_reg;
cfg->ret_var_is_local = TRUE;
sig_ret = mini_get_underlying_type (sig->ret);
- if (cinfo->ret.storage == ArgValuetypeAddrInIReg) {
+ if (cinfo->ret.storage == ArgValuetypeAddrInIReg || cinfo->ret.storage == ArgGsharedvtVariableInReg) {
cfg->vret_addr = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_ARG);
if (G_UNLIKELY (cfg->verbose_level > 1)) {
printf ("vret_addr = ");
break;
}
case ArgValuetypeAddrInIReg:
+ case ArgGsharedvtVariableInReg:
/* Vtype returned using a hidden argument */
linfo->ret.storage = LLVMArgVtypeRetAddr;
linfo->vret_arg_index = cinfo->vret_arg_index;
MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, ((MonoInst*)cfg->arch.vret_addr_loc)->dreg, call->vret_var->dreg);
}
break;
- case ArgValuetypeAddrInIReg: {
+ case ArgValuetypeAddrInIReg:
+ case ArgGsharedvtVariableInReg: {
MonoInst *vtarg;
MONO_INST_NEW (cfg, vtarg, OP_MOVE);
vtarg->sreg1 = call->vret_var->dreg;
pindex = 1;
}
- if (dinfo->cinfo->ret.storage == ArgValuetypeAddrInIReg)
+ if (dinfo->cinfo->ret.storage == ArgValuetypeAddrInIReg || dinfo->cinfo->ret.storage == ArgGsharedvtVariableInReg)
p->regs [greg ++] = PTR_TO_GREG(ret);
for (i = pindex; i < sig->param_count; i++) {
/* Fall through */
}
case MONO_TYPE_VALUETYPE:
- if (dinfo->cinfo->ret.storage == ArgValuetypeAddrInIReg) {
+ if (dinfo->cinfo->ret.storage == ArgValuetypeAddrInIReg || dinfo->cinfo->ret.storage == ArgGsharedvtVariableInReg) {
/* Nothing to do */
} else {
ArgInfo *ainfo = &dinfo->cinfo->ret;