int *must_preallocate, int *ecf_flags,
bool *may_tailcall, bool call_from_thunk_p)
{
+ location_t loc = EXPR_LOCATION (exp);
/* 1 if scanning parms front to back, -1 if scanning back to front. */
int inc;
if (!call_from_thunk_p && DECL_P (base) && !TREE_STATIC (base))
*may_tailcall = false;
- args[i].tree_value = build_fold_addr_expr (args[i].tree_value);
+ args[i].tree_value = build_fold_addr_expr_loc (loc,
+ args[i].tree_value);
type = TREE_TYPE (args[i].tree_value);
if (*ecf_flags & ECF_CONST)
*ecf_flags &= ~(ECF_PURE | ECF_LOOPING_CONST_OR_PURE);
args[i].tree_value
- = build_fold_addr_expr (make_tree (type, copy));
+ = build_fold_addr_expr_loc (loc, make_tree (type, copy));
type = TREE_TYPE (args[i].tree_value);
*may_tailcall = false;
}
}
- mode = TYPE_MODE (type);
unsignedp = TYPE_UNSIGNED (type);
-
- if (targetm.calls.promote_function_args (fndecl
- ? TREE_TYPE (fndecl)
- : fntype))
- mode = promote_mode (type, mode, &unsignedp, 1);
+ mode = promote_function_mode (type, TYPE_MODE (type), &unsignedp,
+ fndecl ? TREE_TYPE (fndecl) : fntype, 0);
args[i].unsignedp = unsignedp;
args[i].mode = mode;
for (i = 0; i < num_actuals; i++)
{
+ tree type;
enum machine_mode mode;
if (TREE_CODE (args[i].tree_value) != CALL_EXPR)
continue;
/* If this is an addressable type, we cannot pre-evaluate it. */
- gcc_assert (!TREE_ADDRESSABLE (TREE_TYPE (args[i].tree_value)));
+ type = TREE_TYPE (args[i].tree_value);
+ gcc_assert (!TREE_ADDRESSABLE (type));
args[i].initial_value = args[i].value
= expand_normal (args[i].tree_value);
- mode = TYPE_MODE (TREE_TYPE (args[i].tree_value));
+ mode = TYPE_MODE (type);
if (mode != args[i].mode)
{
+ int unsignedp = args[i].unsignedp;
args[i].value
= convert_modes (args[i].mode, mode,
args[i].value, args[i].unsignedp);
-#if defined(PROMOTE_FUNCTION_MODE) && !defined(PROMOTE_MODE)
+
/* CSE will replace this only if it contains args[i].value
pseudo, so convert it down to the declared mode using
a SUBREG. */
if (REG_P (args[i].value)
- && GET_MODE_CLASS (args[i].mode) == MODE_INT)
+ && GET_MODE_CLASS (args[i].mode) == MODE_INT
+ && promote_mode (type, mode, &unsignedp) != args[i].mode)
{
args[i].initial_value
= gen_lowpart_SUBREG (mode, args[i].value);
SUBREG_PROMOTED_UNSIGNED_SET (args[i].initial_value,
args[i].unsignedp);
}
-#endif
}
}
}
&& args[i].partial == 0)
continue;
- if (GET_CODE (offset) == CONST_INT)
+ if (CONST_INT_P (offset))
addr = plus_constant (arg_reg, INTVAL (offset));
else
addr = gen_rtx_PLUS (Pmode, arg_reg, offset);
boundary = args[i].locate.boundary;
if (args[i].locate.where_pad != downward)
align = boundary;
- else if (GET_CODE (offset) == CONST_INT)
+ else if (CONST_INT_P (offset))
{
align = INTVAL (offset) * BITS_PER_UNIT | boundary;
align = align & -align;
}
set_mem_align (args[i].stack, align);
- if (GET_CODE (slot_offset) == CONST_INT)
+ if (CONST_INT_P (slot_offset))
addr = plus_constant (arg_reg, INTVAL (slot_offset));
else
addr = gen_rtx_PLUS (Pmode, arg_reg, slot_offset);
i = 0;
else if (GET_CODE (addr) == PLUS
&& XEXP (addr, 0) == crtl->args.internal_arg_pointer
- && GET_CODE (XEXP (addr, 1)) == CONST_INT)
+ && CONST_INT_P (XEXP (addr, 1)))
i = INTVAL (XEXP (addr, 1));
/* Return true for arg pointer based indexed addressing. */
else if (GET_CODE (addr) == PLUS
tree caller_res = DECL_RESULT (current_function_decl);
caller_unsignedp = TYPE_UNSIGNED (TREE_TYPE (caller_res));
- caller_mode = caller_promoted_mode = DECL_MODE (caller_res);
+ caller_mode = DECL_MODE (caller_res);
callee_unsignedp = TYPE_UNSIGNED (TREE_TYPE (funtype));
- callee_mode = callee_promoted_mode = TYPE_MODE (TREE_TYPE (funtype));
- if (targetm.calls.promote_function_return (TREE_TYPE (current_function_decl)))
- caller_promoted_mode
- = promote_mode (TREE_TYPE (caller_res), caller_mode,
- &caller_unsignedp, 1);
- if (targetm.calls.promote_function_return (funtype))
- callee_promoted_mode
- = promote_mode (TREE_TYPE (funtype), callee_mode,
- &callee_unsignedp, 1);
+ callee_mode = TYPE_MODE (TREE_TYPE (funtype));
+ caller_promoted_mode
+ = promote_function_mode (TREE_TYPE (caller_res), caller_mode,
+ &caller_unsignedp,
+ TREE_TYPE (current_function_decl), 1);
+ callee_promoted_mode
+ = promote_function_mode (TREE_TYPE (caller_res), callee_mode,
+ &callee_unsignedp,
+ TREE_TYPE (funtype), 1);
if (caller_mode != VOIDmode
&& (caller_promoted_mode != callee_promoted_mode
|| ((caller_mode != caller_promoted_mode
else
target = copy_to_reg (avoid_likely_spilled_reg (valreg));
- if (targetm.calls.promote_function_return(funtype))
+ /* If we promoted this return value, make the proper SUBREG.
+ TARGET might be const0_rtx here, so be careful. */
+ if (REG_P (target)
+ && TYPE_MODE (TREE_TYPE (exp)) != BLKmode
+ && GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)))
{
- /* If we promoted this return value, make the proper SUBREG.
- TARGET might be const0_rtx here, so be careful. */
- if (REG_P (target)
- && TYPE_MODE (TREE_TYPE (exp)) != BLKmode
- && GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)))
+ tree type = TREE_TYPE (exp);
+ int unsignedp = TYPE_UNSIGNED (type);
+ int offset = 0;
+ enum machine_mode pmode;
+
+ /* Ensure we promote as expected, and get the new unsignedness. */
+ pmode = promote_function_mode (type, TYPE_MODE (type), &unsignedp,
+ funtype, 1);
+ gcc_assert (GET_MODE (target) == pmode);
+
+ if ((WORDS_BIG_ENDIAN || BYTES_BIG_ENDIAN)
+ && (GET_MODE_SIZE (GET_MODE (target))
+ > GET_MODE_SIZE (TYPE_MODE (type))))
{
- tree type = TREE_TYPE (exp);
- int unsignedp = TYPE_UNSIGNED (type);
- int offset = 0;
- enum machine_mode pmode;
-
- pmode = promote_mode (type, TYPE_MODE (type), &unsignedp, 1);
- /* If we don't promote as expected, something is wrong. */
- gcc_assert (GET_MODE (target) == pmode);
-
- if ((WORDS_BIG_ENDIAN || BYTES_BIG_ENDIAN)
- && (GET_MODE_SIZE (GET_MODE (target))
- > GET_MODE_SIZE (TYPE_MODE (type))))
- {
- offset = GET_MODE_SIZE (GET_MODE (target))
- - GET_MODE_SIZE (TYPE_MODE (type));
- if (! BYTES_BIG_ENDIAN)
- offset = (offset / UNITS_PER_WORD) * UNITS_PER_WORD;
- else if (! WORDS_BIG_ENDIAN)
- offset %= UNITS_PER_WORD;
- }
- target = gen_rtx_SUBREG (TYPE_MODE (type), target, offset);
- SUBREG_PROMOTED_VAR_P (target) = 1;
- SUBREG_PROMOTED_UNSIGNED_SET (target, unsignedp);
+ offset = GET_MODE_SIZE (GET_MODE (target))
+ - GET_MODE_SIZE (TYPE_MODE (type));
+ if (! BYTES_BIG_ENDIAN)
+ offset = (offset / UNITS_PER_WORD) * UNITS_PER_WORD;
+ else if (! WORDS_BIG_ENDIAN)
+ offset %= UNITS_PER_WORD;
}
+
+ target = gen_rtx_SUBREG (TYPE_MODE (type), target, offset);
+ SUBREG_PROMOTED_VAR_P (target) = 1;
+ SUBREG_PROMOTED_UNSIGNED_SET (target, unsignedp);
}
/* If size of args is variable or this was a constructor call for a stack
}
else
{
- /* Convert to the proper mode if PROMOTE_MODE has been active. */
+ /* Convert to the proper mode if a promotion has been active. */
if (GET_MODE (valreg) != outmode)
{
int unsignedp = TYPE_UNSIGNED (tfom);
- gcc_assert (targetm.calls.promote_function_return (tfom));
- gcc_assert (promote_mode (tfom, outmode, &unsignedp, 0)
+ gcc_assert (promote_function_mode (tfom, outmode, &unsignedp,
+ fndecl ? TREE_TYPE (fndecl) : fntype, 1)
== GET_MODE (valreg));
-
valreg = convert_modes (outmode, GET_MODE (valreg), valreg, 0);
}
|| (GET_CODE (XEXP (x, 0)) == PLUS
&& XEXP (XEXP (x, 0), 0) ==
crtl->args.internal_arg_pointer
- && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT))
+ && CONST_INT_P (XEXP (XEXP (x, 0), 1))))
{
if (XEXP (x, 0) != crtl->args.internal_arg_pointer)
i = INTVAL (XEXP (XEXP (x, 0), 1));
/* expand_call should ensure this. */
gcc_assert (!arg->locate.offset.var
&& arg->locate.size.var == 0
- && GET_CODE (size_rtx) == CONST_INT);
+ && CONST_INT_P (size_rtx));
if (arg->locate.offset.constant > i)
{