+2017-09-12 Richard Sandiford <richard.sandiford@linaro.org>
+ Alan Hayward <alan.hayward@arm.com>
+ David Sherwood <david.sherwood@arm.com>
+
+ * target.def (hard_regno_nregs): New hook.
+ (class_max_nregs): Refer to it instead of HARD_REGNO_NREGS.
+ * targhooks.h (default_hard_regno_nregs): Declare.
+ * targhooks.c (default_hard_regno_nregs): New function.
+ * doc/tm.texi.in (HARD_REGNO_NREGS): Replace with...
+ (TARGET_HARD_REGNO_NREGS): ...this hook.
+ (HARD_REGNO_NREGS_HAS_PADDING): Update accordingly.
+ (CLASS_MAX_NREGS): Likewise.
+ * doc/tm.texi: Regenerate.
+ * reginfo.c (init_reg_modes_target): Use targetm.hard_regno_nregs
+ instead of HARD_REGNO_NREGS.
+ * rtl.h (REG_NREGS): Refer to TARGET_HARD_REGNO_NREGS rather than
+ HARD_REGNO_NREGS in the comment.
+ * config/aarch64/aarch64.h (HARD_REGNO_NREGS): Delete.
+ * config/aarch64/aarch64-protos.h (aarch64_hard_regno_nregs): Delete.
+ * config/aarch64/aarch64.c (aarch64_hard_regno_nregs): Make static.
+ Return an unsigned int.
+ (TARGET_HARD_REGNO_NREGS): Redefine.
+ * config/alpha/alpha.h (HARD_REGNO_NREGS): Delete.
+ * config/arc/arc.h (HARD_REGNO_NREGS): Delete.
+ * config/arc/arc.c (TARGET_HARD_REGNO_NREGS): Redefine.
+ (arc_hard_regno_nregs): New function.
+ * config/arm/arm.h (HARD_REGNO_NREGS): Delete.
+ * config/arm/arm.c (TARGET_HARD_REGNO_NREGS): Redefine.
+ (arm_hard_regno_nregs): New function.
+ * config/avr/avr.h (HARD_REGNO_NREGS): Delete.
+ * config/bfin/bfin.h (HARD_REGNO_NREGS): Delete.
+ * config/bfin/bfin.c (bfin_hard_regno_nregs): New function.
+ (TARGET_HARD_REGNO_NREGS): Redefine.
+ * config/c6x/c6x.h (HARD_REGNO_NREGS): Delete.
+ * config/cr16/cr16.h (LONG_REG_P): Use targetm.hard_regno_nregs.
+ (HARD_REGNO_NREGS): Delete.
+ * config/cr16/cr16.c (TARGET_HARD_REGNO_NREGS): Redefine.
+ (cr16_hard_regno_nregs): New function.
+ (cr16_memory_move_cost): Use it instead of HARD_REGNO_NREGS.
+ * config/cris/cris.h (HARD_REGNO_NREGS): Delete.
+ * config/cris/cris.c (TARGET_HARD_REGNO_NREGS): Redefine.
+ (cris_hard_regno_nregs): New function.
+ * config/epiphany/epiphany.h (HARD_REGNO_NREGS): Delete.
+ * config/fr30/fr30.h (HARD_REGNO_NREGS): Delete.
+ (CLASS_MAX_NREGS): Use targetm.hard_regno_nregs.
+ * config/frv/frv.h (HARD_REGNO_NREGS): Delete.
+ (CLASS_MAX_NREGS): Remove outdated copy of documentation.
+ * config/frv/frv-protos.h (frv_hard_regno_nregs): Delete.
+ * config/frv/frv.c (TARGET_HARD_REGNO_NREGS): Redefine.
+ (frv_hard_regno_nregs): Make static. Take and return an
+ unsigned int.
+ (frv_class_max_nregs): Remove outdated copy of documentation.
+ * config/ft32/ft32.h (HARD_REGNO_NREGS): Delete.
+ * config/h8300/h8300.h (HARD_REGNO_NREGS): Delete.
+ * config/h8300/h8300-protos.h (h8300_hard_regno_nregs): Delete.
+ * config/h8300/h8300.c (h8300_hard_regno_nregs): Delete.
+ * config/i386/i386.h (HARD_REGNO_NREGS): Delete.
+ * config/i386/i386.c (ix86_hard_regno_nregs): New function.
+ (TARGET_HARD_REGNO_NREGS): Redefine.
+ * config/ia64/ia64.h (HARD_REGNO_NREGS): Delete.
+ (CLASS_MAX_NREGS): Update comment.
+ * config/ia64/ia64.c (TARGET_HARD_REGNO_NREGS): Redefine.
+ (ia64_hard_regno_nregs): New function.
+ * config/iq2000/iq2000.h (HARD_REGNO_NREGS): Delete.
+ * config/lm32/lm32.h (HARD_REGNO_NREGS): Delete.
+ * config/m32c/m32c.h (HARD_REGNO_NREGS): Delete.
+ * config/m32c/m32c-protos.h (m32c_hard_regno_nregs): Delete.
+ * config/m32c/m32c.c (m32c_hard_regno_nregs_1): Take and return
+ an unsigned int.
+ (m32c_hard_regno_nregs): Likewise. Make static.
+ (TARGET_HARD_REGNO_NREGS): Redefine.
+ * config/m32r/m32r.h (HARD_REGNO_NREGS): Delete.
+ * config/m68k/m68k.h (HARD_REGNO_NREGS): Delete.
+ * config/m68k/m68k.c (TARGET_HARD_REGNO_NREGS): Redefine.
+ (m68k_hard_regno_nregs): New function.
+ * config/mcore/mcore.h (HARD_REGNO_NREGS): Delete.
+ * config/microblaze/microblaze.h (HARD_REGNO_NREGS): Delete.
+ * config/mips/mips.h (HARD_REGNO_NREGS): Delete.
+ * config/mips/mips-protos.h (mips_hard_regno_nregs): Delete.
+ * config/mips/mips.c (mips_hard_regno_nregs): Make static.
+ Take and return an unsigned int.
+ (TARGET_HARD_REGNO_NREGS): Redefine.
+ * config/mmix/mmix.h (HARD_REGNO_NREGS): Delete.
+ (CLASS_MAX_NREGS): Use targetm.hard_regno_nregs.
+ * config/mn10300/mn10300.h (HARD_REGNO_NREGS): Delete.
+ * config/moxie/moxie.h (HARD_REGNO_NREGS): Delete.
+ * config/msp430/msp430.h (HARD_REGNO_NREGS): Delete.
+ * config/msp430/msp430-protos.h (msp430_hard_regno_nregs): Delete.
+ * config/msp430/msp430.c (TARGET_HARD_REGNO_NREGS): Redefine.
+ (msp430_hard_regno_nregs): Make static. Take and return an
+ unsigned int.
+ * config/nds32/nds32.h (HARD_REGNO_NREGS): Delete.
+ * config/nds32/nds32-protos.h (nds32_hard_regno_nregs): Delete.
+ * config/nds32/nds32.c (nds32_hard_regno_nregs): Delete.
+ (nds32_hard_regno_mode_ok): Use targetm.hard_regno_nregs.
+ * config/nios2/nios2.h (HARD_REGNO_NREGS): Delete.
+ * config/nvptx/nvptx.h (HARD_REGNO_NREGS): Delete.
+ * config/nvptx/nvptx.c (nvptx_hard_regno_nregs): New function.
+ (TARGET_HARD_REGNO_NREGS): Redefine.
+ * config/pa/pa32-regs.h (HARD_REGNO_NREGS): Rename to...
+ (PA_HARD_REGNO_NREGS): ...this.
+ * config/pa/pa64-regs.h (HARD_REGNO_NREGS): Rename to...
+ (PA_HARD_REGNO_NREGS): ...this.
+ * config/pa/pa.c (TARGET_HARD_REGNO_NREGS): Redefine.
+ (pa_hard_regno_nregs): New function.
+ * config/pdp11/pdp11.h (HARD_REGNO_NREGS): Delete.
+ * config/pdp11/pdp11.c (TARGET_HARD_REGNO_NREGS): Redefine.
+ (pdp11_hard_regno_nregs): New function.
+ * config/powerpcspe/powerpcspe.h (HARD_REGNO_NREGS): Delete.
+ * config/powerpcspe/powerpcspe.c (TARGET_HARD_REGNO_NREGS): Redefine.
+ (rs6000_hard_regno_nregs_hook): New function.
+ * config/riscv/riscv.h (HARD_REGNO_NREGS): Delete.
+ * config/riscv/riscv-protos.h (riscv_hard_regno_nregs): Delete.
+ * config/riscv/riscv.c (riscv_hard_regno_nregs): Make static.
+ Take and return an unsigned int. Move earlier in file.
+ (TARGET_HARD_REGNO_NREGS): Redefine.
+ * config/rl78/rl78.h (HARD_REGNO_NREGS): Delete.
+ * config/rl78/rl78-protos.h (rl78_hard_regno_nregs): Delete.
+ * config/rl78/rl78.c (TARGET_HARD_REGNO_NREGS): Reefine.
+ (rl78_hard_regno_nregs): Make static. Take and return an
+ unsigned int.
+ * config/rs6000/rs6000.h (HARD_REGNO_NREGS): Delete.
+ * config/rs6000/rs6000.c (TARGET_HARD_REGNO_NREGS): Redefine.
+ (rs6000_hard_regno_nregs_hook): New function.
+ * config/rx/rx.h (HARD_REGNO_NREGS): Delete.
+ * config/rx/rx.c (rx_hard_regno_nregs): New function.
+ (TARGET_HARD_REGNO_NREGS): Redefine.
+ * config/s390/s390.h (HARD_REGNO_NREGS): Delete.
+ * config/s390/s390.c (REGNO_PAIR_OK): Use s390_hard_regno_nregs
+ instead of HARD_REGNO_NREGS.
+ (s390_hard_regno_nregs): New function.
+ (s390_hard_regno_mode_ok): Add comment from s390.h.
+ (TARGET_HARD_REGNO_NREGS): Redefine.
+ * config/sh/sh.h (HARD_REGNO_NREGS): Delete.
+ * config/sh/sh.c (TARGET_HARD_REGNO_NREGS): Redefine.
+ (sh_hard_regno_nregs): New function.
+ (sh_pass_in_reg_p): Use it.
+ * config/sparc/sparc.h (HARD_REGNO_NREGS): Delete.
+ * config/sparc/sparc.c (TARGET_HARD_REGNO_NREGS): Redefine.
+ (sparc_hard_regno_nregs): New function.
+ * config/spu/spu.h (HARD_REGNO_NREGS): Delete.
+ * config/spu/spu.c (spu_hard_regno_nregs): New function.
+ (spu_function_arg_advance): Use it, supplying a valid register number.
+ (TARGET_HARD_REGNO_NREGS): Redefine.
+ * config/stormy16/stormy16.h (HARD_REGNO_NREGS): Delete.
+ * config/tilegx/tilegx.h (HARD_REGNO_NREGS): Delete.
+ * config/tilepro/tilepro.h (HARD_REGNO_NREGS): Delete.
+ * config/v850/v850.h (HARD_REGNO_NREGS): Delete.
+ * config/vax/vax.h (HARD_REGNO_NREGS): Delete.
+ * config/visium/visium.h (HARD_REGNO_NREGS): Delete.
+ (CLASS_MAX_NREGS): Remove copy of old documentation.
+ * config/visium/visium.c (TARGET_HARD_REGNO_NREGS): Redefine.
+ (visium_hard_regno_nregs): New function.
+ (visium_hard_regno_mode_ok): Use it instead of HARD_REGNO_NREGS.
+ * config/xtensa/xtensa.h (HARD_REGNO_NREGS): Delete.
+ * config/xtensa/xtensa.c (TARGET_HARD_REGNO_NREGS): Redefine.
+ xtensa_hard_regno_nregs): New function.
+ * system.h (HARD_REGNO_NREGS): Poison.
+
2017-09-12 Richard Sandiford <richard.sandiford@linaro.org>
* config/arm/arm.h (THUMB_SECONDARY_INPUT_RELOAD_CLASS): Use
int aarch64_fpconst_pow_of_2 (rtx);
machine_mode aarch64_hard_regno_caller_save_mode (unsigned, unsigned,
machine_mode);
-int aarch64_hard_regno_nregs (unsigned, machine_mode);
int aarch64_uxt_size (int, HOST_WIDE_INT);
int aarch64_vec_fpconst_pow_of_2 (rtx);
rtx aarch64_eh_return_handler_rtx (void);
return false;
}
-/* Implement HARD_REGNO_NREGS. */
+/* Implement TARGET_HARD_REGNO_NREGS. */
-int
+static unsigned int
aarch64_hard_regno_nregs (unsigned regno, machine_mode mode)
{
switch (aarch64_regno_regclass (regno))
#undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
#define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 4
+#undef TARGET_HARD_REGNO_NREGS
+#define TARGET_HARD_REGNO_NREGS aarch64_hard_regno_nregs
#undef TARGET_HARD_REGNO_MODE_OK
#define TARGET_HARD_REGNO_MODE_OK aarch64_hard_regno_mode_ok
#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (LR_REGNUM)
-#define HARD_REGNO_NREGS(REGNO, MODE) aarch64_hard_regno_nregs (REGNO, MODE)
-
#define DWARF2_UNWIND_INFO 1
/* Use R0 through R3 to pass exception handling information. */
29, 30, 31, 63 /* gp, sp, ap, sfp */ \
}
-/* Return number of consecutive hard regs needed starting at reg REGNO
- to hold something of mode MODE.
- This is ordinarily the length in words of a value of mode MODE
- but can be less for certain modes in special long registers. */
-
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- CEIL (GET_MODE_SIZE (MODE), UNITS_PER_WORD)
-
/* Specify the registers used for certain standard purposes.
The values of these macros are register numbers. */
#undef TARGET_DWARF_REGISTER_SPAN
#define TARGET_DWARF_REGISTER_SPAN arc_dwarf_register_span
+#undef TARGET_HARD_REGNO_NREGS
+#define TARGET_HARD_REGNO_NREGS arc_hard_regno_nregs
#undef TARGET_HARD_REGNO_MODE_OK
#define TARGET_HARD_REGNO_MODE_OK arc_hard_regno_mode_ok
}
}
+/* Implement TARGET_HARD_REGNO_NREGS. */
+
+static unsigned int
+arc_hard_regno_nregs (unsigned int regno, machine_mode mode)
+{
+ if (GET_MODE_SIZE (mode) == 16
+ && regno >= ARC_FIRST_SIMD_VR_REG
+ && regno <= ARC_LAST_SIMD_VR_REG)
+ return 1;
+
+ return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
+}
+
/* Implement TARGET_HARD_REGNO_MODE_OK. */
static bool
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, \
27, 28, 29, 30, 31, 63}
-/* Return number of consecutive hard regs needed starting at reg REGNO
- to hold something of mode MODE.
- This is ordinarily the length in words of a value of mode MODE
- but can be less for certain modes in special long registers. */
-#define HARD_REGNO_NREGS(REGNO, MODE) \
-((GET_MODE_SIZE (MODE) == 16 \
- && REGNO >= ARC_FIRST_SIMD_VR_REG && REGNO <= ARC_LAST_SIMD_VR_REG) ? 1 \
- : (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
/* Internal macros to classify a register number as to whether it's a
general purpose register for compact insns (r0-r3,r12-r15), or
stack pointer (r28). */
int reloc);
static void arm_expand_divmod_libfunc (rtx, machine_mode, rtx, rtx, rtx *, rtx *);
static opt_scalar_float_mode arm_floatn_mode (int, bool);
+static unsigned int arm_hard_regno_nregs (unsigned int, machine_mode);
static bool arm_hard_regno_mode_ok (unsigned int, machine_mode);
static bool arm_modes_tieable_p (machine_mode, machine_mode);
\f
#undef TARGET_FIXED_CONDITION_CODE_REGS
#define TARGET_FIXED_CONDITION_CODE_REGS arm_fixed_condition_code_regs
+#undef TARGET_HARD_REGNO_NREGS
+#define TARGET_HARD_REGNO_NREGS arm_hard_regno_nregs
#undef TARGET_HARD_REGNO_MODE_OK
#define TARGET_HARD_REGNO_MODE_OK arm_hard_regno_mode_ok
}
}
+/* Implement TARGET_HARD_REGNO_NREGS. On the ARM core regs are
+ UNITS_PER_WORD bytes wide. */
+static unsigned int
+arm_hard_regno_nregs (unsigned int regno, machine_mode mode)
+{
+ if (TARGET_32BIT
+ && regno > PC_REGNUM
+ && regno != FRAME_POINTER_REGNUM
+ && regno != ARG_POINTER_REGNUM
+ && !IS_VFP_REGNUM (regno))
+ return 1;
+
+ return ARM_NUM_REGS (mode);
+}
+
/* Implement TARGET_HARD_REGNO_MODE_OK. */
static bool
arm_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
#define SUBTARGET_FRAME_POINTER_REQUIRED 0
#endif
-/* Return number of consecutive hard regs needed starting at reg REGNO
- to hold something of mode MODE.
- This is ordinarily the length in words of a value of mode MODE
- but can be less for certain modes in special long registers.
-
- On the ARM core regs are UNITS_PER_WORD bits wide. */
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- ((TARGET_32BIT \
- && REGNO > PC_REGNUM \
- && REGNO != FRAME_POINTER_REGNUM \
- && REGNO != ARG_POINTER_REGNUM) \
- && !IS_VFP_REGNUM (REGNO) \
- ? 1 : ARM_NUM_REGS (MODE))
-
#define VALID_IWMMXT_REG_MODE(MODE) \
(arm_vector_mode_supported_p (MODE) || (MODE) == DImode)
#define ADJUST_REG_ALLOC_ORDER avr_adjust_reg_alloc_order()
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
enum reg_class {
NO_REGS,
R0_REG, /* r0 */
CALL_INSN_FUNCTION_USAGE (call) = use;
}
\f
+/* Implement TARGET_HARD_REGNO_NREGS. */
+
+static unsigned int
+bfin_hard_regno_nregs (unsigned int regno, machine_mode mode)
+{
+ if (mode == PDImode && (regno == REG_A0 || regno == REG_A1))
+ return 1;
+ if (mode == V2PDImode && (regno == REG_A0 || regno == REG_A1))
+ return 2;
+ return CLASS_MAX_NREGS (GENERAL_REGS, mode);
+}
+
/* Implement TARGET_HARD_REGNO_MODE_OK.
Do not allow to store a value in REG_CC for any mode.
#undef TARGET_CAN_USE_DOLOOP_P
#define TARGET_CAN_USE_DOLOOP_P bfin_can_use_doloop_p
+#undef TARGET_HARD_REGNO_NREGS
+#define TARGET_HARD_REGNO_NREGS bfin_hard_regno_nregs
#undef TARGET_HARD_REGNO_MODE_OK
#define TARGET_HARD_REGNO_MODE_OK bfin_hard_regno_mode_ok
((MODE) == V2PDImode && (CLASS) == AREGS ? 2 \
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- ((MODE) == PDImode && ((REGNO) == REG_A0 || (REGNO) == REG_A1) ? 1 \
- : (MODE) == V2PDImode && ((REGNO) == REG_A0 || (REGNO) == REG_A1) ? 2 \
- : CLASS_MAX_NREGS (GENERAL_REGS, MODE))
-
/* A C expression that is nonzero if hard register TO can be
considered for use as a rename register for FROM register */
#define HARD_REGNO_RENAME_OK(FROM, TO) bfin_hard_regno_rename_ok (FROM, TO)
REG_A1, REG_A2, REG_B0, REG_B1, REG_B2, REG_ILC \
}
-#define HARD_REGNO_NREGS(regno, mode) \
- ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) \
- / UNITS_PER_WORD)
-
-
/* Register Classes. */
enum reg_class
#undef TARGET_ASM_UNALIGNED_DI_OP
#define TARGET_ASM_UNALIGNED_DI_OP TARGET_ASM_ALIGNED_DI_OP
+#undef TARGET_HARD_REGNO_NREGS
+#define TARGET_HARD_REGNO_NREGS cr16_hard_regno_nregs
#undef TARGET_HARD_REGNO_MODE_OK
#define TARGET_HARD_REGNO_MODE_OK cr16_hard_regno_mode_ok
#undef TARGET_MODES_TIEABLE_P
return NO_REGS;
}
+/* Implement TARGET_HARD_REGNO_NREGS. */
+
+static unsigned int
+cr16_hard_regno_nregs (unsigned int regno, machine_mode mode)
+{
+ if (regno >= CR16_FIRST_DWORD_REGISTER)
+ return CEIL (GET_MODE_SIZE (mode), CR16_UNITS_PER_DWORD);
+ return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
+}
+
/* Implement TARGET_HARD_REGNO_MODE_OK. On the CR16 architecture, all
registers can hold all modes, except that double precision floats
(and double ints) must fall on even-register boundaries. */
{
/* One LD or ST takes twice the time of a simple reg-reg move. */
if (reg_classes_intersect_p (rclass, GENERAL_REGS))
- return (4 * HARD_REGNO_NREGS (0, mode));
+ return (4 * cr16_hard_regno_nregs (0, mode));
else
return (100);
}
/* Returns 1 if the register is longer than word size, 0 otherwise. */
#define LONG_REG_P(REGNO) \
- (HARD_REGNO_NREGS (REGNO, GET_MODE_WIDER_MODE (word_mode).require ()) == 1)
-
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- ((REGNO >= CR16_FIRST_DWORD_REGISTER) \
- ? ((GET_MODE_SIZE (MODE) + CR16_UNITS_PER_DWORD - 1) / CR16_UNITS_PER_DWORD)\
- : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
+ (targetm.hard_regno_nregs (REGNO, \
+ GET_MODE_WIDER_MODE (word_mode).require ()) == 1)
#define NOTICE_UPDATE_CC(EXP, INSN) \
notice_update_cc ((EXP))
static rtx cris_libcall_value (machine_mode, const_rtx);
static bool cris_function_value_regno_p (const unsigned int);
static void cris_file_end (void);
+static unsigned int cris_hard_regno_nregs (unsigned int, machine_mode);
static bool cris_hard_regno_mode_ok (unsigned int, machine_mode);
/* This is the parsed result of the "-max-stack-stackframe=" option. If
#undef TARGET_FUNCTION_VALUE_REGNO_P
#define TARGET_FUNCTION_VALUE_REGNO_P cris_function_value_regno_p
+#undef TARGET_HARD_REGNO_NREGS
+#define TARGET_HARD_REGNO_NREGS cris_hard_regno_nregs
#undef TARGET_HARD_REGNO_MODE_OK
#define TARGET_HARD_REGNO_MODE_OK cris_hard_regno_mode_ok
sake of a trampoline. */
}
+/* Implement TARGET_HARD_REGNO_NREGS.
+
+ The VOIDmode test is so we can omit mode on anonymous insns. FIXME:
+ Still needed in 2.9x, at least for Axis-20000319. */
+
+static unsigned int
+cris_hard_regno_nregs (unsigned int, machine_mode mode)
+{
+ if (mode == VOIDmode)
+ return 1;
+ return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
+}
+
/* Implement TARGET_HARD_REGNO_MODE_OK.
CRIS permits all registers to hold all modes. Well, except for the
{15, 9, 13, 12, 11, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 17, 16, 14, 18, 19}
-/* Node: Values in Registers */
-
-/* The VOIDmode test is so we can omit mode on anonymous insns. FIXME:
- Still needed in 2.9x, at least for Axis-20000319. */
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- (MODE == VOIDmode \
- ? 1 : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
-
/* Node: Leaf Functions */
/* (no definitions) */
#define HARD_REGNO_RENAME_OK(SRC, DST) epiphany_regno_rename_ok (SRC, DST)
-/* Return number of consecutive hard regs needed starting at reg REGNO
- to hold something of mode MODE.
- This is ordinarily the length in words of a value of mode MODE
- but can be less for certain modes in special long registers. */
-#define HARD_REGNO_NREGS(REGNO, MODE) \
-((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
/* Register classes and constants. */
/* Define the classes of registers for register constraints in the
{"r13", 13}, {"r14", 14}, {"r15", 15}, {"usp", 15}, {"ps", 16}\
}
-/*}}}*/ \f
-/*{{{ How Values Fit in Registers. */
-
-/* A C expression for the number of consecutive hard registers, starting at
- register number REGNO, required to hold a value of mode MODE. */
-
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
/*}}}*/ \f
/*{{{ Register Classes. */
will reload one or both registers only if neither labeling works. */
#define REGNO_OK_FOR_INDEX_P(NUM) 1
-/* A C expression for the maximum number of consecutive registers of
- class CLASS needed to hold a value of mode MODE.
-
- This is closely related to the macro `HARD_REGNO_NREGS'. In fact, the value
- of the macro `CLASS_MAX_NREGS (CLASS, MODE)' should be the maximum value of
- `HARD_REGNO_NREGS (REGNO, MODE)' for all REGNO values in the class CLASS.
-
- This macro helps control the handling of multiple-word values in
- the reload pass. */
-#define CLASS_MAX_NREGS(CLASS, MODE) HARD_REGNO_NREGS (0, MODE)
+#define CLASS_MAX_NREGS(CLASS, MODE) targetm.hard_regno_nregs (0, MODE)
/*}}}*/ \f
/*{{{ Basic Stack Layout. */
extern enum reg_class frv_secondary_reload_class
(enum reg_class,
machine_mode, rtx);
-extern int frv_hard_regno_nregs (int, machine_mode);
extern int frv_class_max_nregs (enum reg_class rclass,
machine_mode mode);
extern machine_mode frv_select_cc_mode (enum rtx_code, rtx, rtx);
static void frv_conditional_register_usage (void);
static void frv_trampoline_init (rtx, tree, rtx);
static bool frv_class_likely_spilled_p (reg_class_t);
+static unsigned int frv_hard_regno_nregs (unsigned int, machine_mode);
static bool frv_hard_regno_mode_ok (unsigned int, machine_mode);
static bool frv_modes_tieable_p (machine_mode, machine_mode);
\f
#undef TARGET_LIBCALL_VALUE
#define TARGET_LIBCALL_VALUE frv_libcall_value
+#undef TARGET_HARD_REGNO_NREGS
+#define TARGET_HARD_REGNO_NREGS frv_hard_regno_nregs
#undef TARGET_HARD_REGNO_MODE_OK
#define TARGET_HARD_REGNO_MODE_OK frv_hard_regno_mode_ok
#undef TARGET_MODES_TIEABLE_P
}
\f
-/* A C expression for the number of consecutive hard registers, starting at
- register number REGNO, required to hold a value of mode MODE.
+/* Implement TARGET_HARD_REGNO_NREGS.
- On a machine where all registers are exactly one word, a suitable definition
- of this macro is
-
- #define HARD_REGNO_NREGS(REGNO, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \
- / UNITS_PER_WORD)) */
-
-/* On the FRV, make the CC_FP mode take 3 words in the integer registers, so
+ On the FRV, make the CC_FP mode take 3 words in the integer registers, so
that we can build the appropriate instructions to properly reload the
values. Also, make the byte-sized accumulator guards use one guard
for each byte. */
-int
-frv_hard_regno_nregs (int regno, machine_mode mode)
+static unsigned int
+frv_hard_regno_nregs (unsigned int regno, machine_mode mode)
{
if (ACCG_P (regno))
return GET_MODE_SIZE (mode);
}
\f
-/* A C expression for the maximum number of consecutive registers of
- class RCLASS needed to hold a value of mode MODE.
-
- This is closely related to the macro `HARD_REGNO_NREGS'. In fact, the value
- of the macro `CLASS_MAX_NREGS (RCLASS, MODE)' should be the maximum value of
- `HARD_REGNO_NREGS (REGNO, MODE)' for all REGNO values in the class RCLASS.
-
- This macro helps control the handling of multiple-word values in
- the reload pass.
-
- This declaration is required. */
+/* Implement CLASS_MAX_NREGS. */
int
frv_class_max_nregs (enum reg_class rclass, machine_mode mode)
}
\f
-/* How Values Fit in Registers. */
-
-/* A C expression for the number of consecutive hard registers, starting at
- register number REGNO, required to hold a value of mode MODE.
-
- On a machine where all registers are exactly one word, a suitable definition
- of this macro is
-
- #define HARD_REGNO_NREGS(REGNO, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \
- / UNITS_PER_WORD)) */
-
-/* On the FRV, make the CC modes take 3 words in the integer registers, so that
- we can build the appropriate instructions to properly reload the values. */
-#define HARD_REGNO_NREGS(REGNO, MODE) frv_hard_regno_nregs (REGNO, MODE)
-
/* Define this macro if the compiler should avoid copies to/from CCmode
registers. You should only define this macro if support fo copying to/from
CCmode is incomplete. */
#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) \
frv_secondary_reload_class (CLASS, MODE, X)
-/* A C expression for the maximum number of consecutive registers of
- class CLASS needed to hold a value of mode MODE.
-
- This is closely related to the macro `HARD_REGNO_NREGS'. In fact, the value
- of the macro `CLASS_MAX_NREGS (CLASS, MODE)' should be the maximum value of
- `HARD_REGNO_NREGS (REGNO, MODE)' for all REGNO values in the class CLASS.
-
- This macro helps control the handling of multiple-word values in
- the reload pass.
-
- This declaration is required. */
#define CLASS_MAX_NREGS(CLASS, MODE) frv_class_max_nregs (CLASS, MODE)
#define ZERO_P(x) (x == CONST0_RTX (GET_MODE (x)))
#define REGNO_REG_CLASS(R) ((R < FT32_PC) ? GENERAL_REGS : \
(R == FT32_CC ? CC_REGS : SPECIAL_REGS))
-/* A C expression for the number of consecutive hard registers,
- starting at register number REGNO, required to hold a value of mode
- MODE. */
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \
- / UNITS_PER_WORD)
-
/* The Overall Framework of an Assembler File */
#undef ASM_SPEC
extern int h8300_initial_elimination_offset (int, int);
extern int h8300_regs_ok_for_stm (int, rtx[]);
extern int h8300_hard_regno_rename_ok (unsigned int, unsigned int);
-extern int h8300_hard_regno_nregs (int, machine_mode);
extern bool h8300_move_ok (rtx, rtx);
struct cpp_reader;
return 0;
}
-/* Worker function for HARD_REGNO_NREGS.
-
- We pretend the MAC register is 32bits -- we don't have any data
- types on the H8 series to handle more than 32bits. */
-
-int
-h8300_hard_regno_nregs (int regno ATTRIBUTE_UNUSED, machine_mode mode)
-{
- return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
-}
-
/* Implement TARGET_HARD_REGNO_MODE_OK. */
static bool
/* r0 r1 r2 r3 r4 r5 r6 r7 mac ap rap fp */ \
{ 2, 3, 0, 1, 4, 5, 6, 8, 7, 9, 10, 11 }
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- h8300_hard_regno_nregs ((REGNO), (MODE))
-
/* A C expression that is nonzero if hard register NEW_REG can be
considered for use as a rename register for OLD_REG register */
return 2;
}
+/* Implement TARGET_HARD_REGNO_NREGS. This is ordinarily the length in
+ words of a value of mode MODE but can be less for certain modes in
+ special long registers.
+
+ Actually there are no two word move instructions for consecutive
+ registers. And only registers 0-3 may have mov byte instructions
+ applied to them. */
+
+static unsigned int
+ix86_hard_regno_nregs (unsigned int regno, machine_mode mode)
+{
+ if (GENERAL_REGNO_P (regno))
+ {
+ if (mode == XFmode)
+ return TARGET_64BIT ? 2 : 3;
+ if (mode == XCmode)
+ return TARGET_64BIT ? 4 : 6;
+ return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
+ }
+ if (COMPLEX_MODE_P (mode))
+ return 2;
+ if (mode == V64SFmode || mode == V64SImode)
+ return 4;
+ return 1;
+}
+
/* Implement TARGET_HARD_REGNO_MODE_OK. */
static bool
#undef TARGET_NOCE_CONVERSION_PROFITABLE_P
#define TARGET_NOCE_CONVERSION_PROFITABLE_P ix86_noce_conversion_profitable_p
+#undef TARGET_HARD_REGNO_NREGS
+#define TARGET_HARD_REGNO_NREGS ix86_hard_regno_nregs
#undef TARGET_HARD_REGNO_MODE_OK
#define TARGET_HARD_REGNO_MODE_OK ix86_hard_regno_mode_ok
#define OVERRIDE_ABI_FORMAT(FNDECL) ix86_call_abi_override (FNDECL)
-/* Return number of consecutive hard regs needed starting at reg REGNO
- to hold something of mode MODE.
- This is ordinarily the length in words of a value of mode MODE
- but can be less for certain modes in special long registers.
-
- Actually there are no two word move instructions for consecutive
- registers. And only registers 0-3 may have mov byte instructions
- applied to them. */
-
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- (GENERAL_REGNO_P (REGNO) \
- ? ((MODE) == XFmode \
- ? (TARGET_64BIT ? 2 : 3) \
- : ((MODE) == XCmode \
- ? (TARGET_64BIT ? 4 : 6) \
- : CEIL (GET_MODE_SIZE (MODE), UNITS_PER_WORD))) \
- : (COMPLEX_MODE_P (MODE) ? 2 : \
- (((MODE == V64SFmode) || (MODE == V64SImode)) ? 4 : 1)))
-
#define HARD_REGNO_NREGS_HAS_PADDING(REGNO, MODE) \
(TARGET_128BIT_LONG_DOUBLE && !TARGET_64BIT \
&& GENERAL_REGNO_P (REGNO) \
static bool ia64_vectorize_vec_perm_const_ok (machine_mode vmode,
const unsigned char *sel);
+static unsigned int ia64_hard_regno_nregs (unsigned int, machine_mode);
static bool ia64_hard_regno_mode_ok (unsigned int, machine_mode);
static bool ia64_modes_tieable_p (machine_mode, machine_mode);
#undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
#define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 0
+#undef TARGET_HARD_REGNO_NREGS
+#define TARGET_HARD_REGNO_NREGS ia64_hard_regno_nregs
#undef TARGET_HARD_REGNO_MODE_OK
#define TARGET_HARD_REGNO_MODE_OK ia64_hard_regno_mode_ok
return 1;
}
+/* Implement TARGET_HARD_REGNO_NREGS.
+
+ ??? We say that BImode PR values require two registers. This allows us to
+ easily store the normal and inverted values. We use CCImode to indicate
+ a single predicate register. */
+
+static unsigned int
+ia64_hard_regno_nregs (unsigned int regno, machine_mode mode)
+{
+ if (regno == PR_REG (0) && mode == DImode)
+ return 64;
+ if (PR_REGNO_P (regno) && (mode) == BImode)
+ return 2;
+ if ((PR_REGNO_P (regno) || GR_REGNO_P (regno)) && mode == CCImode)
+ return 1;
+ if (FR_REGNO_P (regno) && mode == XFmode)
+ return 1;
+ if (FR_REGNO_P (regno) && mode == RFmode)
+ return 1;
+ if (FR_REGNO_P (regno) && mode == XCmode)
+ return 2;
+ return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
+}
+
/* Implement TARGET_HARD_REGNO_MODE_OK. */
static bool
\f
/* How Values Fit in Registers */
-/* A C expression for the number of consecutive hard registers, starting at
- register number REGNO, required to hold a value of mode MODE. */
-
-/* ??? We say that BImode PR values require two registers. This allows us to
- easily store the normal and inverted values. We use CCImode to indicate
- a single predicate register. */
-
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- ((REGNO) == PR_REG (0) && (MODE) == DImode ? 64 \
- : PR_REGNO_P (REGNO) && (MODE) == BImode ? 2 \
- : (PR_REGNO_P (REGNO) || GR_REGNO_P (REGNO)) && (MODE) == CCImode ? 1\
- : FR_REGNO_P (REGNO) && (MODE) == XFmode ? 1 \
- : FR_REGNO_P (REGNO) && (MODE) == RFmode ? 1 \
- : FR_REGNO_P (REGNO) && (MODE) == XCmode ? 2 \
- : (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
/* Specify the modes required to caller save a given hard regno.
We need to ensure floating pt regs are not saved as DImode. */
/* A C expression for the maximum number of consecutive registers of
class CLASS needed to hold a value of mode MODE.
- This is closely related to the macro `HARD_REGNO_NREGS'. */
+ This is closely related to TARGET_HARD_REGNO_NREGS. */
#define CLASS_MAX_NREGS(CLASS, MODE) \
((MODE) == BImode && (CLASS) == PR_REGS ? 2 \
}
\f
-/* How Values Fit in Registers. */
-
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
#define AVOID_CCMODE_COPIES
0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 1, 0, 1, 0, 1, 1}
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
#define AVOID_CCMODE_COPIES
/*----------------------------------*/
void m32c_expand_neg_mulpsi3 (rtx *);
int m32c_expand_setmemhi (rtx *);
bool m32c_matches_constraint_p (rtx, int);
-int m32c_hard_regno_nregs (int, machine_mode);
bool m32c_illegal_subreg_p (rtx);
bool m32c_immd_dbl_mov (rtx *, machine_mode);
rtx m32c_incoming_return_addr_rtx (void);
/* How Values Fit in Registers */
-/* Implements HARD_REGNO_NREGS. This is complicated by the fact that
+/* Implements TARGET_HARD_REGNO_NREGS. This is complicated by the fact that
different registers are different sizes from each other, *and* may
be different sizes in different chip families. */
-static int
-m32c_hard_regno_nregs_1 (int regno, machine_mode mode)
+static unsigned int
+m32c_hard_regno_nregs_1 (unsigned int regno, machine_mode mode)
{
if (regno == FLG_REGNO && mode == CCmode)
return 1;
return 0;
}
-int
-m32c_hard_regno_nregs (int regno, machine_mode mode)
+static unsigned int
+m32c_hard_regno_nregs (unsigned int regno, machine_mode mode)
{
- int rv = m32c_hard_regno_nregs_1 (regno, mode);
+ unsigned int rv = m32c_hard_regno_nregs_1 (regno, mode);
return rv ? rv : 1;
}
#undef TARGET_FRAME_POINTER_REQUIRED
#define TARGET_FRAME_POINTER_REQUIRED hook_bool_void_true
+#undef TARGET_HARD_REGNO_NREGS
+#define TARGET_HARD_REGNO_NREGS m32c_hard_regno_nregs
#undef TARGET_HARD_REGNO_MODE_OK
#define TARGET_HARD_REGNO_MODE_OK m32c_hard_regno_mode_ok
#undef TARGET_MODES_TIEABLE_P
/* How Values Fit in Registers */
-#define HARD_REGNO_NREGS(R,M) m32c_hard_regno_nregs (R, M)
#define AVOID_CCMODE_COPIES
/* Register Classes */
}
#endif
-/* Return number of consecutive hard regs needed starting at reg REGNO
- to hold something of mode MODE.
- This is ordinarily the length in words of a value of mode MODE
- but can be less for certain modes in special long registers. */
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
#define HARD_REGNO_RENAME_OK(OLD_REG, NEW_REG) \
m32r_hard_regno_rename_ok (OLD_REG, NEW_REG)
\f
static void m68k_init_sync_libfuncs (void) ATTRIBUTE_UNUSED;
static enum flt_eval_method
m68k_excess_precision (enum excess_precision_type);
+static unsigned int m68k_hard_regno_nregs (unsigned int, machine_mode);
static bool m68k_hard_regno_mode_ok (unsigned int, machine_mode);
static bool m68k_modes_tieable_p (machine_mode, machine_mode);
\f
#undef TARGET_ATOMIC_TEST_AND_SET_TRUEVAL
#define TARGET_ATOMIC_TEST_AND_SET_TRUEVAL 128
+#undef TARGET_HARD_REGNO_NREGS
+#define TARGET_HARD_REGNO_NREGS m68k_hard_regno_nregs
#undef TARGET_HARD_REGNO_MODE_OK
#define TARGET_HARD_REGNO_MODE_OK m68k_hard_regno_mode_ok
return 1;
}
+/* Implement TARGET_HARD_REGNO_NREGS.
+
+ On the m68k, ordinary registers hold 32 bits worth;
+ for the 68881 registers, a single register is always enough for
+ anything that can be stored in them at all. */
+
+static unsigned int
+m68k_hard_regno_nregs (unsigned int regno, machine_mode mode)
+{
+ if (regno >= 16)
+ return GET_MODE_NUNITS (mode);
+ return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
+}
+
/* Implement TARGET_HARD_REGNO_MODE_OK. On the 68000, we let the cpu
registers can hold any mode, but restrict the 68881 registers to
floating-point modes. */
}
-/* On the m68k, ordinary registers hold 32 bits worth;
- for the 68881 registers, a single register is always enough for
- anything that can be stored in them at all. */
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- ((REGNO) >= 16 ? GET_MODE_NUNITS (MODE) \
- : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
-
/* A C expression that is nonzero if hard register NEW_REG can be
considered for use as a rename register for OLD_REG register. */
/* r7 r6 r5 r4 r3 r2 r15 r14 r13 r12 r11 r10 r9 r8 r1 r0 ap c fp x19*/ \
{ 7, 6, 5, 4, 3, 2, 15, 14, 13, 12, 11, 10, 9, 8, 1, 0, 16, 17, 18, 19}
-/* Return number of consecutive hard regs needed starting at reg REGNO
- to hold something of mode MODE.
- This is ordinarily the length in words of a value of mode MODE
- but can be less for certain modes in special long registers.
-
- On the MCore regs are UNITS_PER_WORD bits wide; */
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- (((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
-
/* Definitions for register eliminations.
We have two registers that can be eliminated on the MCore. First, the
#define GP_REG_P(REGNO) ((unsigned) ((REGNO) - GP_REG_FIRST) < GP_REG_NUM)
#define ST_REG_P(REGNO) ((REGNO) == ST_REG)
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
#define STACK_POINTER_REGNUM (GP_REG_FIRST + MB_ABI_STACK_POINTER_REGNUM)
#define STACK_POINTER_OFFSET FIRST_PARM_OFFSET(FNDECL)
extern const char *mips_msa_output_division (const char *, rtx *);
extern const char *mips_output_probe_stack_range (rtx, rtx);
extern bool mips_hard_regno_rename_ok (unsigned int, unsigned int);
-extern unsigned int mips_hard_regno_nregs (int, machine_mode);
extern bool mips_linked_madd_p (rtx_insn *, rtx_insn *);
extern bool mips_store_data_bypass_p (rtx_insn *, rtx_insn *);
extern int mips_dspalu_bypass_p (rtx, rtx);
return false;
}
-/* Implement HARD_REGNO_NREGS. */
+/* Implement TARGET_HARD_REGNO_NREGS. */
-unsigned int
-mips_hard_regno_nregs (int regno, machine_mode mode)
+static unsigned int
+mips_hard_regno_nregs (unsigned int regno, machine_mode mode)
{
if (ST_REG_P (regno))
/* The size of FP status registers is always 4, because they only hold
#undef TARGET_HARD_REGNO_SCRATCH_OK
#define TARGET_HARD_REGNO_SCRATCH_OK mips_hard_regno_scratch_ok
+#undef TARGET_HARD_REGNO_NREGS
+#define TARGET_HARD_REGNO_NREGS mips_hard_regno_nregs
#undef TARGET_HARD_REGNO_MODE_OK
#define TARGET_HARD_REGNO_MODE_OK mips_hard_regno_mode_ok
: COP3_REG_P (REGNO) ? '3' : '?')
-#define HARD_REGNO_NREGS(REGNO, MODE) mips_hard_regno_nregs (REGNO, MODE)
-
#define HARD_REGNO_RENAME_OK(OLD_REG, NEW_REG) \
mips_hard_regno_rename_ok (OLD_REG, NEW_REG)
/* The default one. */
#define REG_ALLOC_ORDER MMIX_MMIXWARE_ABI_REG_ALLOC_ORDER
-/* Node: Values in Registers */
-
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \
- / UNITS_PER_WORD)
-
/* Node: Leaf Functions */
/* (empty) */
#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) \
mmix_secondary_reload_class (CLASS, MODE, X, 0)
-#define CLASS_MAX_NREGS(CLASS, MODE) HARD_REGNO_NREGS (CLASS, MODE)
+#define CLASS_MAX_NREGS(CLASS, MODE) targetm.hard_regno_nregs (CLASS, MODE)
/* Node: Frame Layout */
, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 50, 51 \
}
-/* Return number of consecutive hard regs needed starting at reg REGNO
- to hold something of mode MODE.
-
- This is ordinarily the length in words of a value of mode MODE
- but can be less for certain modes in special long registers. */
-
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
/* 4 data, and effectively 3 address registers is small as far as I'm
concerned. */
#define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true
#define REGNO_REG_CLASS(R) ((R < MOXIE_PC) ? GENERAL_REGS : \
(R == MOXIE_CC ? CC_REGS : SPECIAL_REGS))
-/* A C expression for the number of consecutive hard registers,
- starting at register number REGNO, required to hold a value of mode
- MODE. */
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \
- / UNITS_PER_WORD)
-
/* The Overall Framework of an Assembler File */
#undef ASM_SPEC
void msp430_expand_prologue (void);
const char * msp430x_extendhisi (rtx *);
void msp430_fixup_compare_operands (machine_mode, rtx *);
-int msp430_hard_regno_nregs (int, machine_mode);
int msp430_hard_regno_nregs_has_padding (int, machine_mode);
int msp430_hard_regno_nregs_with_padding (int, machine_mode);
bool msp430_hwmult_enabled (void);
/* Register Usage */
-/* Implements HARD_REGNO_NREGS. MSP430X registers can hold a single
- PSImode value, but not an SImode value. */
-int
-msp430_hard_regno_nregs (int regno ATTRIBUTE_UNUSED,
- machine_mode mode)
+#undef TARGET_HARD_REGNO_NREGS
+#define TARGET_HARD_REGNO_NREGS msp430_hard_regno_nregs
+
+static unsigned int
+msp430_hard_regno_nregs (unsigned int, machine_mode mode)
{
if (mode == PSImode && msp430x)
return 1;
#define FUNCTION_PROFILER(FILE, LABELNO) \
fprintf (FILE, "\tcall\t__mcount\n");
\f
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- msp430_hard_regno_nregs (REGNO, MODE)
-\f
/* Exception Handling */
/* R12,R13,R14 - EH data
extern void nds32_init_expanders (void);
-\f
-/* Register Usage. */
-
-/* -- How Values Fit in Registers. */
-
-extern int nds32_hard_regno_nregs (int, machine_mode);
-
\f
/* Register Classes. */
/* -- How Values Fit in Registers. */
-int
-nds32_hard_regno_nregs (int regno ATTRIBUTE_UNUSED,
- machine_mode mode)
-{
- return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
-}
-
/* Implement TARGET_HARD_REGNO_MODE_OK. */
static bool
nds32_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
{
/* Restrict double-word quantities to even register pairs. */
- if (HARD_REGNO_NREGS (regno, mode) == 1
+ if (targetm.hard_regno_nregs (regno, mode) == 1
|| !((regno) & 1))
return true;
own cost calculations. */
#define HONOR_REG_ALLOC_ORDER optimize_size
-/* The number of consecutive hard regs needed starting at
- reg "regno" for holding a value of mode "mode". */
-#define HARD_REGNO_NREGS(regno, mode) nds32_hard_regno_nregs (regno, mode)
-
\f
/* Register Classes. */
/* 30 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
}
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
/* Order in which to allocate registers. Each register must be
listed once. This is the default ordering for R1 and non-CDX R2
code. For CDX, we overwrite this in ADJUST_REG_ALLOC_ORDER. */
return false;
}
+/* Implement TARGET_HARD_REGNO_NREGS. */
+
+static unsigned int
+nvptx_hard_regno_nregs (unsigned int, machine_mode)
+{
+ return 1;
+}
+
#undef TARGET_OPTION_OVERRIDE
#define TARGET_OPTION_OVERRIDE nvptx_option_override
#undef TARGET_MODES_TIEABLE_P
#define TARGET_MODES_TIEABLE_P nvptx_modes_tieable_p
+#undef TARGET_HARD_REGNO_NREGS
+#define TARGET_HARD_REGNO_NREGS nvptx_hard_regno_nregs
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-nvptx.h"
#define FIXED_REGISTERS { 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
#define CALL_USED_REGISTERS { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
-#define HARD_REGNO_NREGS(REG, MODE) \
- ((void)(REG), (void)(MODE), 1)
#define CANNOT_CHANGE_MODE_CLASS(M1, M2, CLS) \
((void)(M1), (void)(M2), (void)(CLS), true)
static bool pa_legitimate_address_p (machine_mode, rtx, bool);
static bool pa_callee_copies (cumulative_args_t, machine_mode,
const_tree, bool);
+static unsigned int pa_hard_regno_nregs (unsigned int, machine_mode);
static bool pa_hard_regno_mode_ok (unsigned int, machine_mode);
static bool pa_modes_tieable_p (machine_mode, machine_mode);
#undef TARGET_LRA_P
#define TARGET_LRA_P hook_bool_void_false
+#undef TARGET_HARD_REGNO_NREGS
+#define TARGET_HARD_REGNO_NREGS pa_hard_regno_nregs
#undef TARGET_HARD_REGNO_MODE_OK
#define TARGET_HARD_REGNO_MODE_OK pa_hard_regno_mode_ok
#undef TARGET_MODES_TIEABLE_P
return !TARGET_CALLER_COPIES;
}
+/* Implement TARGET_HARD_REGNO_NREGS. */
+
+static unsigned int
+pa_hard_regno_nregs (unsigned int regno ATTRIBUTE_UNUSED, machine_mode mode)
+{
+ return PA_HARD_REGNO_NREGS (regno, mode);
+}
+
/* Implement TARGET_HARD_REGNO_MODE_OK. */
static bool
point registers are 64 bits wide. Snake fp regs are treated as
32 bits wide since the left and right parts are independently
accessible. */
-#define HARD_REGNO_NREGS(REGNO, MODE) \
+#define PA_HARD_REGNO_NREGS(REGNO, MODE) \
(FP_REGNO_P (REGNO) \
? (!TARGET_PA_11 \
? COMPLEX_MODE_P (MODE) ? 2 : 1 \
WORD_SIZE bits. Note that SCmode values are placed in a single FPR.
Thus, any patterns defined to operate on these values would have to
use the 32-bit addressability of the FPR registers. */
-#define HARD_REGNO_NREGS(REGNO, MODE) \
+#define PA_HARD_REGNO_NREGS(REGNO, MODE) \
((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
/* These are the valid FP modes. */
#undef TARGET_SCALAR_MODE_SUPPORTED_P
#define TARGET_SCALAR_MODE_SUPPORTED_P pdp11_scalar_mode_supported_p
+#undef TARGET_HARD_REGNO_NREGS
+#define TARGET_HARD_REGNO_NREGS pdp11_hard_regno_nregs
#undef TARGET_HARD_REGNO_MODE_OK
#define TARGET_HARD_REGNO_MODE_OK pdp11_hard_regno_mode_ok
return (TARGET_BRANCH_CHEAP ? 0 : 1);
}
+/* Implement TARGET_HARD_REGNO_NREGS. */
+
+static unsigned int
+pdp11_hard_regno_nregs (unsigned int regno, machine_mode mode)
+{
+ if (regno <= PC_REGNUM)
+ return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
+ return 1;
+}
+
/* Implement TARGET_HARD_REGNO_MODE_OK. On the pdp, the cpu registers
can hold any mode other than float (because otherwise we may end up
being asked to move from CPU to FPU register, which isn't a valid
0, 0, 0, 0, 0, 0, 1, 1 }
-/* Return number of consecutive hard regs needed starting at reg REGNO
- to hold something of mode MODE.
- This is ordinarily the length in words of a value of mode MODE
- but can be less for certain modes in special long registers.
-*/
-
-#define HARD_REGNO_NREGS(REGNO, MODE) \
-((REGNO <= PC_REGNUM)? \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) \
- :1)
-
-
/* Specify the registers used for certain standard purposes.
The values of these macros are register numbers. */
#undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
#define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 1
+#undef TARGET_HARD_REGNO_NREGS
+#define TARGET_HARD_REGNO_NREGS rs6000_hard_regno_nregs_hook
#undef TARGET_HARD_REGNO_MODE_OK
#define TARGET_HARD_REGNO_MODE_OK rs6000_hard_regno_mode_ok
return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
}
+/* Implement TARGET_HARD_REGNO_NREGS. */
+
+static unsigned int
+rs6000_hard_regno_nregs_hook (unsigned int regno, machine_mode mode)
+{
+ return rs6000_hard_regno_nregs[mode][regno];
+}
+
/* Implement TARGET_HARD_REGNO_MODE_OK. */
static bool
(INT_REGNO_P (N) || ALTIVEC_REGNO_P (N) \
|| (TARGET_VSX && FP_REGNO_P (N))) \
-/* Return number of consecutive hard regs needed starting at reg REGNO
- to hold something of mode MODE. */
-
-#define HARD_REGNO_NREGS(REGNO, MODE) rs6000_hard_regno_nregs[(MODE)][(REGNO)]
-
/* When setting up caller-save slots (MODE == VOIDmode) ensure we allocate
enough space to account for vectors in FP regs. However, TFmode/TDmode
should not use VSX instructions to do a caller save. */
extern void riscv_expand_epilogue (bool);
extern bool riscv_can_use_return_insn (void);
extern rtx riscv_function_value (const_tree, const_tree, machine_mode);
-extern unsigned int riscv_hard_regno_nregs (int, machine_mode);
/* Routines implemented in riscv-c.c. */
void riscv_cpu_cpp_builtins (cpp_reader *);
return SECONDARY_MEMORY_NEEDED (from, to, mode) ? 8 : 2;
}
+/* Implement TARGET_HARD_REGNO_NREGS. */
+
+static unsigned int
+riscv_hard_regno_nregs (unsigned int regno, machine_mode mode)
+{
+ if (FP_REG_P (regno))
+ return (GET_MODE_SIZE (mode) + UNITS_PER_FP_REG - 1) / UNITS_PER_FP_REG;
+
+ /* All other registers are word-sized. */
+ return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+}
+
/* Implement TARGET_HARD_REGNO_MODE_OK. */
static bool
&& GET_MODE_CLASS (mode2) == MODE_FLOAT));
}
-/* Implement HARD_REGNO_NREGS. */
-
-unsigned int
-riscv_hard_regno_nregs (int regno, machine_mode mode)
-{
- if (FP_REG_P (regno))
- return (GET_MODE_SIZE (mode) + UNITS_PER_FP_REG - 1) / UNITS_PER_FP_REG;
-
- /* All other registers are word-sized. */
- return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
-}
-
/* Implement CLASS_MAX_NREGS. */
static unsigned char
#undef TARGET_EXPAND_BUILTIN
#define TARGET_EXPAND_BUILTIN riscv_expand_builtin
+#undef TARGET_HARD_REGNO_NREGS
+#define TARGET_HARD_REGNO_NREGS riscv_hard_regno_nregs
#undef TARGET_HARD_REGNO_MODE_OK
#define TARGET_HARD_REGNO_MODE_OK riscv_hard_regno_mode_ok
#define FP_REG_RTX_P(X) (REG_P (X) && FP_REG_P (REGNO (X)))
-#define HARD_REGNO_NREGS(REGNO, MODE) riscv_hard_regno_nregs (REGNO, MODE)
-
/* Use s0 as the frame pointer if it is so requested. */
#define HARD_FRAME_POINTER_REGNUM 8
#define STACK_POINTER_REGNUM 2
void rl78_expand_epilogue (void);
void rl78_expand_prologue (void);
int rl78_far_p (rtx x);
-int rl78_hard_regno_nregs (int, machine_mode);
bool rl78_hl_b_c_addr_p (rtx);
int rl78_initial_elimination_offset (int, int);
bool rl78_as_legitimate_address (machine_mode, rtx,
return false;
}
-/* Implements HARD_REGNO_NREGS. */
-int
-rl78_hard_regno_nregs (int regno, machine_mode mode)
+#undef TARGET_HARD_REGNO_NREGS
+#define TARGET_HARD_REGNO_NREGS rl78_hard_regno_nregs
+
+static unsigned int
+rl78_hard_regno_nregs (unsigned int regno, machine_mode mode)
{
int rs = register_sizes[regno];
if (rs < 1)
fprintf (FILE, "\tbsr\t__mcount\n");
\f
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- rl78_hard_regno_nregs (REGNO, MODE)
-\f
-
#define TEXT_SECTION_ASM_OP ".text"
#define DATA_SECTION_ASM_OP ".data"
#define BSS_SECTION_ASM_OP ".bss"
#undef TARGET_OPTION_FUNCTION_VERSIONS
#define TARGET_OPTION_FUNCTION_VERSIONS common_function_versions
+#undef TARGET_HARD_REGNO_NREGS
+#define TARGET_HARD_REGNO_NREGS rs6000_hard_regno_nregs_hook
#undef TARGET_HARD_REGNO_MODE_OK
#define TARGET_HARD_REGNO_MODE_OK rs6000_hard_regno_mode_ok
return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
}
+/* Implement TARGET_HARD_REGNO_NREGS. */
+
+static unsigned int
+rs6000_hard_regno_nregs_hook (unsigned int regno, machine_mode mode)
+{
+ return rs6000_hard_regno_nregs[mode][regno];
+}
+
/* Implement TARGET_HARD_REGNO_MODE_OK. */
static bool
(INT_REGNO_P (N) || ALTIVEC_REGNO_P (N) \
|| (TARGET_VSX && FP_REGNO_P (N))) \
-/* Return number of consecutive hard regs needed starting at reg REGNO
- to hold something of mode MODE. */
-
-#define HARD_REGNO_NREGS(REGNO, MODE) rs6000_hard_regno_nregs[(MODE)][(REGNO)]
-
/* When setting up caller-save slots (MODE == VOIDmode) ensure we allocate
enough space to account for vectors in FP regs. However, TFmode/TDmode
should not use VSX instructions to do a caller save. */
emit_insn (gen_mvtc (GEN_INT (CTRLREG_PSW), m_prev_psw_reg));
}
+/* Implement TARGET_HARD_REGNO_NREGS. */
+
+static unsigned int
+rx_hard_regno_nregs (unsigned int, machine_mode mode)
+{
+ return CLASS_MAX_NREGS (0, mode);
+}
+
/* Implement TARGET_HARD_REGNO_MODE_OK. */
static bool
#undef TARGET_LRA_P
#define TARGET_LRA_P rx_enable_lra
+#undef TARGET_HARD_REGNO_NREGS
+#define TARGET_HARD_REGNO_NREGS rx_hard_regno_nregs
#undef TARGET_HARD_REGNO_MODE_OK
#define TARGET_HARD_REGNO_MODE_OK rx_hard_regno_mode_ok
fprintf (FILE, "\tbsr\t__mcount\n");
\f
-#define HARD_REGNO_NREGS(REGNO, MODE) CLASS_MAX_NREGS (0, MODE)
-
-\f
-
#define REGISTER_NAMES \
{ \
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
CONST_OK_FOR_CONSTRAINT_P((x), 'O', "On")
#define REGNO_PAIR_OK(REGNO, MODE) \
- (HARD_REGNO_NREGS ((REGNO), (MODE)) == 1 || !((REGNO) & 1))
+ (s390_hard_regno_nregs ((REGNO), (MODE)) == 1 || !((REGNO) & 1))
/* That's the read ahead of the dynamic branch prediction unit in
bytes on a z10 (or higher) CPU. */
return;
}
-/* Implement TARGET_HARD_REGNO_MODE_OK. */
+/* Implement TARGET_HARD_REGNO_NREGS. Because all registers in a class
+ have the same size, this is equivalent to CLASS_MAX_NREGS. */
+
+static unsigned int
+s390_hard_regno_nregs (unsigned int regno, machine_mode mode)
+{
+ return s390_class_max_nregs (REGNO_REG_CLASS (regno), mode);
+}
+
+/* Implement TARGET_HARD_REGNO_MODE_OK.
+
+ Integer modes <= word size fit into any GPR.
+ Integer modes > word size fit into successive GPRs, starting with
+ an even-numbered register.
+ SImode and DImode fit into FPRs as well.
+
+ Floating point modes <= word size fit into any FPR or GPR.
+ Floating point modes > word size (i.e. DFmode on 32-bit) fit
+ into any FPR, or an even-odd GPR pair.
+ TFmode fits only into an even-odd FPR pair.
+
+ Complex floating point modes fit either into two FPRs, or into
+ successive GPRs (again starting with an even number).
+ TCmode fits only into two successive even-odd FPR pairs.
+
+ Condition code modes fit only into the CC register. */
static bool
s390_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
#undef TARGET_HARD_REGNO_SCRATCH_OK
#define TARGET_HARD_REGNO_SCRATCH_OK s390_hard_regno_scratch_ok
+#undef TARGET_HARD_REGNO_NREGS
+#define TARGET_HARD_REGNO_NREGS s390_hard_regno_nregs
#undef TARGET_HARD_REGNO_MODE_OK
#define TARGET_HARD_REGNO_MODE_OK s390_hard_regno_mode_ok
#undef TARGET_MODES_TIEABLE_P
15, 32, 33, 34, 35, 36, 37 }
-/* Fitting values into registers. */
-
-/* Integer modes <= word size fit into any GPR.
- Integer modes > word size fit into successive GPRs, starting with
- an even-numbered register.
- SImode and DImode fit into FPRs as well.
-
- Floating point modes <= word size fit into any FPR or GPR.
- Floating point modes > word size (i.e. DFmode on 32-bit) fit
- into any FPR, or an even-odd GPR pair.
- TFmode fits only into an even-odd FPR pair.
-
- Complex floating point modes fit either into two FPRs, or into
- successive GPRs (again starting with an even number).
- TCmode fits only into two successive even-odd FPR pairs.
-
- Condition code modes fit only into the CC register. */
-
-/* Because all registers in a class have the same size HARD_REGNO_NREGS
- is equivalent to CLASS_MAX_NREGS. */
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- s390_class_max_nregs (REGNO_REG_CLASS (REGNO), (MODE))
-
#define HARD_REGNO_RENAME_OK(FROM, TO) \
s390_hard_regno_rename_ok ((FROM), (TO))
static bool sh_fixed_condition_code_regs (unsigned int* p1, unsigned int* p2);
static void sh_init_sync_libfuncs (void) ATTRIBUTE_UNUSED;
+static unsigned int sh_hard_regno_nregs (unsigned int, machine_mode);
static bool sh_hard_regno_mode_ok (unsigned int, machine_mode);
static bool sh_modes_tieable_p (machine_mode, machine_mode);
\f
#undef TARGET_CANNOT_FORCE_CONST_MEM
#define TARGET_CANNOT_FORCE_CONST_MEM sh_cannot_force_const_mem_p
+#undef TARGET_HARD_REGNO_NREGS
+#define TARGET_HARD_REGNO_NREGS sh_hard_regno_nregs
#undef TARGET_HARD_REGNO_MODE_OK
#define TARGET_HARD_REGNO_MODE_OK sh_hard_regno_mode_ok
+ int_size_in_bytes (type))
<= NPARM_REGS (SImode) * UNITS_PER_WORD)
: ((sh_round_reg (cum, mode)
- + HARD_REGNO_NREGS (BASE_ARG_REG (mode), mode))
+ + sh_hard_regno_nregs (BASE_ARG_REG (mode), mode))
<= NPARM_REGS (mode)))
: sh_round_reg (cum, mode) < NPARM_REGS (mode)));
}
return target;
}
+/* Implement TARGET_HARD_REGNO_NREGS. On the SH all but the XD regs are
+ UNITS_PER_WORD bits wide. */
+
+static unsigned int
+sh_hard_regno_nregs (unsigned int regno, machine_mode mode)
+{
+ if (XD_REGISTER_P (regno))
+ return CEIL (GET_MODE_SIZE (mode), 2 * UNITS_PER_WORD);
+ return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
+}
+
/* Implement TARGET_HARD_REGNO_MODE_OK.
We can allow any mode in any general register. The special registers
1, 1, 0, 0, \
}
-/* Return number of consecutive hard regs needed starting at reg REGNO
- to hold something of mode MODE.
- This is ordinarily the length in words of a value of mode MODE
- but can be less for certain modes in special long registers.
-
- On the SH all but the XD regs are UNITS_PER_WORD bits wide. */
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- (XD_REGISTER_P (REGNO) \
- ? ((GET_MODE_SIZE (MODE) + (2*UNITS_PER_WORD - 1)) / (2*UNITS_PER_WORD)) \
- : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
-
/* Specify the modes required to caller save a given hard regno. */
#define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \
sh_hard_regno_caller_save_mode ((REGNO), (NREGS), (MODE))
static void sparc_atomic_assign_expand_fenv (tree *, tree *, tree *);
static bool sparc_fixed_condition_code_regs (unsigned int *, unsigned int *);
static unsigned int sparc_min_arithmetic_precision (void);
+static unsigned int sparc_hard_regno_nregs (unsigned int, machine_mode);
static bool sparc_hard_regno_mode_ok (unsigned int, machine_mode);
static bool sparc_modes_tieable_p (machine_mode, machine_mode);
#undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
#define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 1
+#undef TARGET_HARD_REGNO_NREGS
+#define TARGET_HARD_REGNO_NREGS sparc_hard_regno_nregs
#undef TARGET_HARD_REGNO_MODE_OK
#define TARGET_HARD_REGNO_MODE_OK sparc_hard_regno_mode_ok
return size;
}
+/* Implement TARGET_HARD_REGNO_NREGS.
+
+ On SPARC, ordinary registers hold 32 bits worth; this means both
+ integer and floating point registers. On v9, integer regs hold 64
+ bits worth; floating point regs hold 32 bits worth (this includes the
+ new fp regs as even the odd ones are included in the hard register
+ count). */
+
+static unsigned int
+sparc_hard_regno_nregs (unsigned int regno, machine_mode mode)
+{
+ if (regno == SPARC_GSR_REG)
+ return 1;
+ if (TARGET_ARCH64)
+ {
+ if (SPARC_INT_REG_P (regno) || regno == FRAME_POINTER_REGNUM)
+ return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
+ return CEIL (GET_MODE_SIZE (mode), 4);
+ }
+ return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
+}
+
/* Implement TARGET_HARD_REGNO_MODE_OK.
??? Because of the funny way we pass parameters we should allow certain
\
1, 1, 1, 1, 1, 1, 1}
-/* Return number of consecutive hard regs needed starting at reg REGNO
- to hold something of mode MODE.
- This is ordinarily the length in words of a value of mode MODE
- but can be less for certain modes in special long registers.
-
- On SPARC, ordinary registers hold 32 bits worth;
- this means both integer and floating point registers.
- On v9, integer regs hold 64 bits worth; floating point regs hold
- 32 bits worth (this includes the new fp regs as even the odd ones are
- included in the hard register count). */
-
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- ((REGNO) == SPARC_GSR_REG ? 1 : \
- (TARGET_ARCH64 \
- ? (SPARC_INT_REG_P (REGNO) || (REGNO) == FRAME_POINTER_REGNUM \
- ? (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD \
- : (GET_MODE_SIZE (MODE) + 3) / 4) \
- : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)))
-
/* Due to the ARCH64 discrepancy above we must override this next
macro too. */
#define REGMODE_NATURAL_SIZE(MODE) sparc_regmode_natural_size (MODE)
REAL_MODE_FORMAT (SFmode) = &spu_single_format;
}
\f
+/* Implement TARGET_HARD_REGNO_NREGS. */
+
+static unsigned int
+spu_hard_regno_nregs (unsigned int, machine_mode mode)
+{
+ return CEIL (GET_MODE_BITSIZE (mode), MAX_FIXED_MODE_SIZE);
+}
+
/* Handle an attribute requiring a FUNCTION_DECL; arguments as in
struct attribute_spec.handler. */
? ((int_size_in_bytes (type) + 15) / 16)
: mode == VOIDmode
? 1
- : HARD_REGNO_NREGS (cum, mode));
+ : spu_hard_regno_nregs (FIRST_ARG_REGNUM, mode));
}
/* Implement TARGET_FUNCTION_ARG_PADDING. */
#undef TARGET_MODES_TIEABLE_P
#define TARGET_MODES_TIEABLE_P spu_modes_tieable_p
+#undef TARGET_HARD_REGNO_NREGS
+#define TARGET_HARD_REGNO_NREGS spu_hard_regno_nregs
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-spu.h"
1, 1, 1 \
}
-\f
-/* Values in Registers */
-
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- ((GET_MODE_BITSIZE(MODE)+MAX_FIXED_MODE_SIZE-1)/MAX_FIXED_MODE_SIZE)
-
\f
/* Register Classes */
#define REG_ALLOC_ORDER { 7, 6, 5, 4, 3, 2, 1, 0, 9, 8, 10, 11, 12, 13, 14, 15, 16 }
-\f
-/* How Values Fit in Registers. */
-
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
\f
/* Register Classes. */
66, 67 \
}
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
/* Register that holds an address into the text segment that can be
used by pic code. */
#define TILEGX_PIC_TEXT_LABEL_REGNUM (flag_pic ? 50 : INVALID_REGNUM)
66 \
}
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
/* Register that holds an address into the text segment that can be
used by pic code. */
#define TILEPRO_PIC_TEXT_LABEL_REGNUM (flag_pic ? 50 : INVALID_REGNUM)
34, 35 \
}
-/* Return number of consecutive hard regs needed starting at reg REGNO
- to hold something of mode MODE.
-
- This is ordinarily the length in words of a value of mode MODE
- but can be less for certain modes in special long registers. */
-
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
\f
/* Define the classes of registers for register constraints in the
machine description. Also define ranges of constants.
Aside from that, you can include as many other registers as you like. */
#define CALL_USED_REGISTERS {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1}
-/* Return number of consecutive hard regs needed starting at reg REGNO
- to hold something of mode MODE.
- This is ordinarily the length in words of a value of mode MODE
- but can be less for certain modes in special long registers.
- On the VAX, all registers are one word long. */
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
/* Specify the registers used for certain standard purposes.
The values of these macros are register numbers. */
static unsigned int visium_reorg (void);
+static unsigned int visium_hard_regno_nregs (unsigned int, machine_mode);
+
static bool visium_hard_regno_mode_ok (unsigned int, machine_mode);
static bool visium_modes_tieable_p (machine_mode, machine_mode);
#undef TARGET_FLAGS_REGNUM
#define TARGET_FLAGS_REGNUM FLAGS_REGNUM
+#undef TARGET_HARD_REGNO_NREGS
+#define TARGET_HARD_REGNO_NREGS visium_hard_regno_nregs
+
#undef TARGET_HARD_REGNO_MODE_OK
#define TARGET_HARD_REGNO_MODE_OK visium_hard_regno_mode_ok
return 1;
}
+/* Implement TARGET_HARD_REGNO_NREGS. */
+
+static unsigned int
+visium_hard_regno_nregs (unsigned int regno, machine_mode mode)
+{
+ if (regno == MDB_REGNUM)
+ return CEIL (GET_MODE_SIZE (mode), 2 * UNITS_PER_WORD);
+ return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
+}
+
/* Implement TARGET_HARD_REGNO_MODE_OK.
Modes with sizes which cross from the one register class to the
return mode == SFmode || (mode == SImode && TARGET_FPU_IEEE);
return (GET_MODE_CLASS (mode) == MODE_INT
- && HARD_REGNO_NREGS (regno, mode) == 1);
+ && visium_hard_regno_nregs (regno, mode) == 1);
}
/* Implement TARGET_MODES_TIEABLE_P. */
50, 51, 52, /* flags, arg, frame */ \
0, 34 } /* r0, f0 */
-/* `HARD_REGNO_NREGS (REGNO, MODE)'
-
- A C expression for the number of consecutive hard registers,
- starting at register number REGNO, required to hold a value of mode
- MODE. */
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- ((REGNO) == MDB_REGNUM ? \
- ((GET_MODE_SIZE (MODE) + 2 * UNITS_PER_WORD - 1) / (2 * UNITS_PER_WORD)) \
- : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
-
/* `HARD_REGNO_RENAME_OK (OLD_REG, NEW_REG)'
A C expression which is nonzero if hard register NEW_REG can be
#define CANNOT_CHANGE_MODE_CLASS(FROM,TO,CLASS) \
(CLASS == MDB ? (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)) : 0)
-/* `CLASS_MAX_NREGS (CLASS, MODE)'
-
- A C expression for the maximum number of consecutive registers of
- class CLASS needed to hold a value of mode MODE.
-
- This is closely related to the macro `HARD_REGNO_NREGS'. In fact,
- the value of the macro `CLASS_MAX_NREGS (CLASS, MODE)' should be
- the maximum value of `HARD_REGNO_NREGS (REGNO, MODE)' for all REGNO
- values in the class CLASS.
-
- This macro helps control the handling of multiple-word values in
- the reload pass. */
#define CLASS_MAX_NREGS(CLASS, MODE) \
((CLASS) == MDB ? \
((GET_MODE_SIZE (MODE) + 2 * UNITS_PER_WORD - 1) / (2 * UNITS_PER_WORD)) \
machine_mode mode);
static void xtensa_conditional_register_usage (void);
+static unsigned int xtensa_hard_regno_nregs (unsigned int, machine_mode);
static bool xtensa_hard_regno_mode_ok (unsigned int, machine_mode);
static bool xtensa_modes_tieable_p (machine_mode, machine_mode);
#undef TARGET_CONDITIONAL_REGISTER_USAGE
#define TARGET_CONDITIONAL_REGISTER_USAGE xtensa_conditional_register_usage
+#undef TARGET_HARD_REGNO_NREGS
+#define TARGET_HARD_REGNO_NREGS xtensa_hard_regno_nregs
#undef TARGET_HARD_REGNO_MODE_OK
#define TARGET_HARD_REGNO_MODE_OK xtensa_hard_regno_mode_ok
}
}
+/* Implement TARGET_HARD_REGNO_NREGS. */
+
+static unsigned int
+xtensa_hard_regno_nregs (unsigned int regno, machine_mode mode)
+{
+ if (FP_REG_P (regno))
+ return CEIL (GET_MODE_SIZE (mode), UNITS_PER_FPREG);
+ return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
+}
+
/* Implement TARGET_HARD_REGNO_MODE_OK. */
static bool
#define FP_REG_P(REGNO) ((unsigned) ((REGNO) - FP_REG_FIRST) < FP_REG_NUM)
#define ACC_REG_P(REGNO) ((unsigned) ((REGNO) - ACC_REG_FIRST) < ACC_REG_NUM)
-/* Return number of consecutive hard regs needed starting at reg REGNO
- to hold something of mode MODE. */
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- (FP_REG_P (REGNO) ? \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_FPREG - 1) / UNITS_PER_FPREG) : \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
-
/* Register to use for pushing function arguments. */
#define STACK_POINTER_REGNUM (GP_REG_FIRST + 1)
(specifically, which machine modes) each register can hold, and how many
consecutive registers are needed for a given mode.
-@defmac HARD_REGNO_NREGS (@var{regno}, @var{mode})
-A C expression for the number of consecutive hard registers, starting
+@deftypefn {Target Hook} {unsigned int} TARGET_HARD_REGNO_NREGS (unsigned int @var{regno}, machine_mode @var{mode})
+This hook returns the number of consecutive hard registers, starting
at register number @var{regno}, required to hold a value of mode
-@var{mode}. This macro must never return zero, even if a register
+@var{mode}. This hook must never return zero, even if a register
cannot hold the requested mode - indicate that with
@code{TARGET_HARD_REGNO_MODE_OK} and/or @code{CANNOT_CHANGE_MODE_CLASS}
instead.
-On a machine where all registers are exactly one word, a suitable
-definition of this macro is
-
-@smallexample
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \
- / UNITS_PER_WORD)
-@end smallexample
-@end defmac
+The default definition returns the number of words in @var{mode}.
+@end deftypefn
@defmac HARD_REGNO_NREGS_HAS_PADDING (@var{regno}, @var{mode})
A C expression that is nonzero if a value of mode @var{mode}, stored
in registers starting at register number @var{regno} (as determined by
multiplying GCC's notion of the size of the register when containing
this mode by the number of registers returned by
-@code{HARD_REGNO_NREGS}). By default this is zero.
+@code{TARGET_HARD_REGNO_NREGS}). By default this is zero.
For example, if a floating-point value is stored in three 32-bit
registers but takes up 128 bits in memory, then this would be
A target hook returns the maximum number of consecutive registers
of class @var{rclass} needed to hold a value of mode @var{mode}.
-This is closely related to the macro @code{HARD_REGNO_NREGS}. In fact,
-the value returned by @code{TARGET_CLASS_MAX_NREGS (@var{rclass},
+This is closely related to the macro @code{TARGET_HARD_REGNO_NREGS}.
+In fact, the value returned by @code{TARGET_CLASS_MAX_NREGS (@var{rclass},
@var{mode})} target hook should be the maximum value of
-@code{HARD_REGNO_NREGS (@var{regno}, @var{mode})} for all @var{regno}
+@code{TARGET_HARD_REGNO_NREGS (@var{regno}, @var{mode})} for all @var{regno}
values in the class @var{rclass}.
This target hook helps control the handling of multiple-word values
A C expression for the maximum number of consecutive registers
of class @var{class} needed to hold a value of mode @var{mode}.
-This is closely related to the macro @code{HARD_REGNO_NREGS}. In fact,
+This is closely related to the macro @code{TARGET_HARD_REGNO_NREGS}. In fact,
the value of the macro @code{CLASS_MAX_NREGS (@var{class}, @var{mode})}
-should be the maximum value of @code{HARD_REGNO_NREGS (@var{regno},
+should be the maximum value of @code{TARGET_HARD_REGNO_NREGS (@var{regno},
@var{mode})} for all @var{regno} values in the class @var{class}.
This macro helps control the handling of multiple-word values
(specifically, which machine modes) each register can hold, and how many
consecutive registers are needed for a given mode.
-@defmac HARD_REGNO_NREGS (@var{regno}, @var{mode})
-A C expression for the number of consecutive hard registers, starting
-at register number @var{regno}, required to hold a value of mode
-@var{mode}. This macro must never return zero, even if a register
-cannot hold the requested mode - indicate that with
-@code{TARGET_HARD_REGNO_MODE_OK} and/or @code{CANNOT_CHANGE_MODE_CLASS}
-instead.
-
-On a machine where all registers are exactly one word, a suitable
-definition of this macro is
-
-@smallexample
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \
- / UNITS_PER_WORD)
-@end smallexample
-@end defmac
+@hook TARGET_HARD_REGNO_NREGS
@defmac HARD_REGNO_NREGS_HAS_PADDING (@var{regno}, @var{mode})
A C expression that is nonzero if a value of mode @var{mode}, stored
in registers starting at register number @var{regno} (as determined by
multiplying GCC's notion of the size of the register when containing
this mode by the number of registers returned by
-@code{HARD_REGNO_NREGS}). By default this is zero.
+@code{TARGET_HARD_REGNO_NREGS}). By default this is zero.
For example, if a floating-point value is stored in three 32-bit
registers but takes up 128 bits in memory, then this would be
A C expression for the maximum number of consecutive registers
of class @var{class} needed to hold a value of mode @var{mode}.
-This is closely related to the macro @code{HARD_REGNO_NREGS}. In fact,
+This is closely related to the macro @code{TARGET_HARD_REGNO_NREGS}. In fact,
the value of the macro @code{CLASS_MAX_NREGS (@var{class}, @var{mode})}
-should be the maximum value of @code{HARD_REGNO_NREGS (@var{regno},
+should be the maximum value of @code{TARGET_HARD_REGNO_NREGS (@var{regno},
@var{mode})} for all @var{regno} values in the class @var{class}.
This macro helps control the handling of multiple-word values
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
for (j = 0; j < MAX_MACHINE_MODE; j++)
this_target_regs->x_hard_regno_nregs[i][j]
- = HARD_REGNO_NREGS (i, (machine_mode)j);
+ = targetm.hard_regno_nregs (i, (machine_mode) j);
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
{
#define SET_REGNO(RTX, N) (df_ref_change_reg_with_loc (RTX, N))
/* Return the number of consecutive registers in a REG. This is always
- 1 for pseudo registers and is determined by HARD_REGNO_NREGS for
+ 1 for pseudo registers and is determined by TARGET_HARD_REGNO_NREGS for
hard registers. */
#define REG_NREGS(RTX) (REG_CHECK (RTX)->nregs)
CLEAR_BY_PIECES_P MOVE_BY_PIECES_P SET_BY_PIECES_P \
STORE_BY_PIECES_P TARGET_FLT_EVAL_METHOD \
HARD_REGNO_CALL_PART_CLOBBERED HARD_REGNO_MODE_OK \
- MODES_TIEABLE_P FUNCTION_ARG_PADDING SLOW_UNALIGNED_ACCESS
+ MODES_TIEABLE_P FUNCTION_ARG_PADDING SLOW_UNALIGNED_ACCESS \
+ HARD_REGNO_NREGS
/* Target macros only used for code built for the target, that have
moved to libgcc-tm.h or have never been present elsewhere. */
"A target hook returns the maximum number of consecutive registers\n\
of class @var{rclass} needed to hold a value of mode @var{mode}.\n\
\n\
-This is closely related to the macro @code{HARD_REGNO_NREGS}. In fact,\n\
-the value returned by @code{TARGET_CLASS_MAX_NREGS (@var{rclass},\n\
+This is closely related to the macro @code{TARGET_HARD_REGNO_NREGS}.\n\
+In fact, the value returned by @code{TARGET_CLASS_MAX_NREGS (@var{rclass},\n\
@var{mode})} target hook should be the maximum value of\n\
-@code{HARD_REGNO_NREGS (@var{regno}, @var{mode})} for all @var{regno}\n\
+@code{TARGET_HARD_REGNO_NREGS (@var{regno}, @var{mode})} for all @var{regno}\n\
values in the class @var{rclass}.\n\
\n\
This target hook helps control the handling of multiple-word values\n\
void, (void),
hook_void_void)
+DEFHOOK
+(hard_regno_nregs,
+ "This hook returns the number of consecutive hard registers, starting\n\
+at register number @var{regno}, required to hold a value of mode\n\
+@var{mode}. This hook must never return zero, even if a register\n\
+cannot hold the requested mode - indicate that with\n\
+@code{TARGET_HARD_REGNO_MODE_OK} and/or @code{CANNOT_CHANGE_MODE_CLASS}\n\
+instead.\n\
+\n\
+The default definition returns the number of words in @var{mode}.",
+ unsigned int, (unsigned int regno, machine_mode mode),
+ default_hard_regno_nregs)
+
DEFHOOK
(hard_regno_mode_ok,
"This hook returns true if it is permissible to store a value\n\
gcc_unreachable ();
}
+/* The defualt implementation of TARGET_HARD_REGNO_NREGS. */
+
+unsigned int
+default_hard_regno_nregs (unsigned int, machine_mode mode)
+{
+ return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
+}
+
bool
default_hard_regno_scratch_ok (unsigned int regno ATTRIBUTE_UNUSED)
{
extern tree default_mangle_decl_assembler_name (tree, tree);
extern tree default_emutls_var_fields (tree, tree *);
extern tree default_emutls_var_init (tree, tree, tree);
+extern unsigned int default_hard_regno_nregs (unsigned int, machine_mode);
extern bool default_hard_regno_scratch_ok (unsigned int);
extern bool default_mode_dependent_address_p (const_rtx, addr_space_t);
extern bool default_target_option_valid_attribute_p (tree, tree, tree, int);