+/* Round a register number up to a proper boundary for an arg of mode
+ MODE.
+ The SH doesn't care about double alignment, so we only
+ round doubles to even regs when asked to explicitly. */
+static int
+sh_round_reg (const CUMULATIVE_ARGS& cum, machine_mode mode)
+{
+ /* FIXME: This used to be a macro and has been copy pasted into this
+ function as is. Make this more readable. */
+ return
+ (((TARGET_ALIGN_DOUBLE
+ || ((TARGET_SH4 || TARGET_SH2A_DOUBLE)
+ && (mode == DFmode || mode == DCmode)
+ && cum.arg_count[(int) SH_ARG_FLOAT] < NPARM_REGS (mode)))
+ && GET_MODE_UNIT_SIZE (mode) > UNITS_PER_WORD)
+ ? (cum.arg_count[(int) GET_SH_ARG_CLASS (mode)]
+ + (cum.arg_count[(int) GET_SH_ARG_CLASS (mode)] & 1))
+ : cum.arg_count[(int) GET_SH_ARG_CLASS (mode)]);
+}
+
+/* Return true if arg of the specified mode should be be passed in a register
+ or false otherwise. */
+static bool
+sh_pass_in_reg_p (const CUMULATIVE_ARGS& cum, machine_mode mode,
+ const_tree type)
+{
+ /* FIXME: This used to be a macro and has been copy pasted into this
+ function as is. Make this more readable. */
+ return
+ ((type == 0
+ || (! TREE_ADDRESSABLE (type)
+ && (! (TARGET_HITACHI || cum.renesas_abi)
+ || ! (AGGREGATE_TYPE_P (type)
+ || (!TARGET_FPU_ANY
+ && (GET_MODE_CLASS (mode) == MODE_FLOAT
+ && GET_MODE_SIZE (mode) > GET_MODE_SIZE (SFmode)))))))
+ && ! cum.force_mem
+ && (TARGET_SH2E
+ ? ((mode) == BLKmode
+ ? ((cum.arg_count[(int) SH_ARG_INT] * UNITS_PER_WORD
+ + int_size_in_bytes (type))
+ <= NPARM_REGS (SImode) * UNITS_PER_WORD)
+ : ((sh_round_reg (cum, mode)
+ + HARD_REGNO_NREGS (BASE_ARG_REG (mode), mode))
+ <= NPARM_REGS (mode)))
+ : sh_round_reg (cum, mode) < NPARM_REGS (mode)));
+}
+