On Sat, Jul 20, 2019 at 12:13 PM Michael Meissner
<meiss...@linux.ibm.com> wrote:
>
> I will be iterating on patch #9 and sending out a replacement shortly.
>
> This is patch #10.  It moves the various data structures from rs6000.c to
> rs6000-internal.h.  In the future, it will allow us to move more things from
> rs6000.c to other files.  In particular, I plan on adding a rs6000-prefixed.c
> file that has the specific support for prefixed instructions.
>
> It would also allow various functions for handling adressing and register
> assignment, etc. that could also be moved to a separate file as well.
>
> This patch just moves the data structure definitions and helper functions
> (mode_supports_*) to rs6000-internal.h.  The static data structures are 
> changed
> to external, and definitions of the function are put in rs6000.c.  I did add 
> 00
> to the bit mask definitions for RELOAD_REG_* because I plan to add at least 
> one
> more mask (for DS-form addresses) in the future, and it will the values lined
> up.
>
> I have done a bootstrap on a little endian power8 system running Linux and
> there were no regressions in the test suite.  Can I check this into the trunk?

This patch needs to add rs6000-internal.h to tm_file in gcc/config.gcc
for all of the powerpc/rs6000 targets.  It also may need tm_p_file and
tm_d_file definitions.

Thanks, David

>
> 2019-07-20  Michael Meissner  <meiss...@linux.ibm.com>
>
>         * config/rs6000/rs6000-internal.h (rs6000_hard_regno_mode_ok_p):
>         Move various declarations relating to addressing and register
>         allocation to rs6000-internal.h from rs6000.c so that in the
>         future we can move things out of rs6000.c.  Make the static arrays
>         global, and define them in rs6000.c.
>         (enum rs6000_reg_type): Likewise.
>         (reg_class_to_reg_type): Likewise.
>         (IS_STD_REG_TYPE): Likewise.
>         (IS_FP_VECT_REG_TYPE): Likewise.
>         (enum rs6000_reload_reg_type): Likewise.
>         (FIRST_RELOAD_REG_CLASS): Likewise.
>         (LAST_RELOAD_REG_CLASS): Likewise.
>         (struct reload_reg_map_type): Likewise.
>         (reload_reg_map): Likewise.
>         (RELOAD_REG_* macros): Likewise.
>         (struct rs6000_reg_addr): Likewise.
>         (reg_addr): Likewise.
>         (mode_supports_pre_incdec_): Likewise.
>         (mode_supports_pre_modify_p): Likewise.
>         (mode_supports_vmx_dform): Likewise.
>         (mode_supports_dq_form): Likewise.
>         (mode_supports_prefixed_address_p): Likewise.
>         * config/rs6000/rs6000.c (rs6000_hard_regno_mode_ok_p): Likewise.
>         (enum rs6000_reg_type): Likewise.
>         (reg_class_to_reg_type): Likewise.
>         (IS_STD_REG_TYPE): Likewise.
>         (IS_FP_VECT_REG_TYPE): Likewise.
>         (enum rs6000_reload_reg_type): Likewise.
>         (FIRST_RELOAD_REG_CLASS): Likewise.
>         (LAST_RELOAD_REG_CLASS): Likewise.
>         (struct reload_reg_map_type): Likewise.
>         (reload_reg_map): Likewise.
>         (RELOAD_REG_* macros): Likewise.
>         (struct rs6000_reg_addr): Likewise.
>         (reg_addr): Likewise.
>         (mode_supports_pre_incdec_): Likewise.
>         (mode_supports_pre_modify_p): Likewise.
>         (mode_supports_vmx_dform): Likewise.
>         (mode_supports_dq_form): Likewise.
>         (mode_supports_prefixed_address_p): Likewise.
>
> Index: gcc/config/rs6000/rs6000-internal.h
> ===================================================================
> --- gcc/config/rs6000/rs6000-internal.h (revision 273617)
> +++ gcc/config/rs6000/rs6000-internal.h (working copy)
> @@ -22,6 +22,134 @@
>  #ifndef GCC_RS6000_INTERNAL_H
>  #define GCC_RS6000_INTERNAL_H
>
> +/* Value is TRUE if register/mode pair is acceptable.  */
> +extern bool rs6000_hard_regno_mode_ok_p
> +  [NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
> +
> +/* Simplfy register classes into simpler classifications.  We assume
> +   GPR_REG_TYPE - FPR_REG_TYPE are ordered so that we can use a simple range
> +   check for standard register classes (gpr/floating/altivec/vsx) and
> +   floating/vector classes (float/altivec/vsx).  */
> +
> +enum rs6000_reg_type {
> +  NO_REG_TYPE,
> +  PSEUDO_REG_TYPE,
> +  GPR_REG_TYPE,
> +  VSX_REG_TYPE,
> +  ALTIVEC_REG_TYPE,
> +  FPR_REG_TYPE,
> +  SPR_REG_TYPE,
> +  CR_REG_TYPE
> +};
> +
> +/* Map register class to register type.  */
> +extern enum rs6000_reg_type reg_class_to_reg_type[N_REG_CLASSES];
> +
> +/* First/last register type for the 'normal' register types (i.e. general
> +   purpose, floating point, altivec, and VSX registers).  */
> +#define IS_STD_REG_TYPE(RTYPE) IN_RANGE(RTYPE, GPR_REG_TYPE, FPR_REG_TYPE)
> +
> +#define IS_FP_VECT_REG_TYPE(RTYPE) IN_RANGE(RTYPE, VSX_REG_TYPE, 
> FPR_REG_TYPE)
> +
> +
> +/* Register classes we care about in secondary reload or go if legitimate
> +   address.  We only need to worry about GPR, FPR, and Altivec registers 
> here,
> +   along an ANY field that is the OR of the 3 register classes.  */
> +
> +enum rs6000_reload_reg_type {
> +  RELOAD_REG_GPR,                      /* General purpose registers.  */
> +  RELOAD_REG_FPR,                      /* Traditional floating point regs.  
> */
> +  RELOAD_REG_VMX,                      /* Altivec (VMX) registers.  */
> +  RELOAD_REG_ANY,                      /* OR of GPR, FPR, Altivec masks.  */
> +  N_RELOAD_REG
> +};
> +
> +/* For setting up register classes, loop through the 3 register classes 
> mapping
> +   into real registers, and skip the ANY class, which is just an OR of the
> +   bits.  */
> +#define FIRST_RELOAD_REG_CLASS RELOAD_REG_GPR
> +#define LAST_RELOAD_REG_CLASS  RELOAD_REG_VMX
> +
> +/* Map reload register type to a register in the register class.  */
> +struct reload_reg_map_type {
> +  const char *name;                    /* Register class name.  */
> +  int reg;                             /* Register in the register class.  */
> +};
> +
> +extern const struct reload_reg_map_type reload_reg_map[N_RELOAD_REG];
> +
> +/* Mask bits for each register class, indexed per mode.  Historically the
> +   compiler has been more restrictive which types can do PRE_MODIFY instead 
> of
> +   PRE_INC and PRE_DEC, so keep track of sepaate bits for these two.  */
> +typedef unsigned char addr_mask_type;
> +
> +#define RELOAD_REG_VALID       0x0001  /* Mode valid in register..  */
> +#define RELOAD_REG_MULTIPLE    0x0002  /* Mode takes multiple registers.  */
> +#define RELOAD_REG_INDEXED     0x0004  /* Reg+reg addressing.  */
> +#define RELOAD_REG_OFFSET      0x0008  /* Reg+offset addressing. */
> +#define RELOAD_REG_PRE_INCDEC  0x0010  /* PRE_INC/PRE_DEC valid.  */
> +#define RELOAD_REG_PRE_MODIFY  0x0020  /* PRE_MODIFY valid.  */
> +#define RELOAD_REG_AND_M16     0x0040  /* AND -16 addressing.  */
> +#define RELOAD_REG_QUAD_OFFSET 0x0080  /* quad offset is limited.  */
> +
> +/* Register type masks based on the type, of valid addressing modes.  */
> +struct rs6000_reg_addr {
> +  enum insn_code reload_load;          /* INSN to reload for loading. */
> +  enum insn_code reload_store;         /* INSN to reload for storing.  */
> +  enum insn_code reload_fpr_gpr;       /* INSN to move from FPR to GPR.  */
> +  enum insn_code reload_gpr_vsx;       /* INSN to move from GPR to VSX.  */
> +  enum insn_code reload_vsx_gpr;       /* INSN to move from VSX to GPR.  */
> +  addr_mask_type addr_mask[(int)N_RELOAD_REG]; /* Valid address masks.  */
> +  bool scalar_in_vmx_p;                        /* Scalar value can go in 
> VMX.  */
> +};
> +
> +extern struct rs6000_reg_addr reg_addr[NUM_MACHINE_MODES];
> +
> +/* Helper function to say whether a mode supports PRE_INC or PRE_DEC.  */
> +static inline bool
> +mode_supports_pre_incdec_p (machine_mode mode)
> +{
> +  return ((reg_addr[mode].addr_mask[RELOAD_REG_ANY] & RELOAD_REG_PRE_INCDEC)
> +         != 0);
> +}
> +
> +/* Helper function to say whether a mode supports PRE_MODIFY.  */
> +static inline bool
> +mode_supports_pre_modify_p (machine_mode mode)
> +{
> +  return ((reg_addr[mode].addr_mask[RELOAD_REG_ANY] & RELOAD_REG_PRE_MODIFY)
> +         != 0);
> +}
> +
> +/* Return true if we have D-form addressing in altivec registers.  */
> +static inline bool
> +mode_supports_vmx_dform (machine_mode mode)
> +{
> +  return ((reg_addr[mode].addr_mask[RELOAD_REG_VMX] & RELOAD_REG_OFFSET) != 
> 0);
> +}
> +
> +/* Return true if we have D-form addressing in VSX registers.  This 
> addressing
> +   is more limited than normal d-form addressing in that the offset must be
> +   aligned on a 16-byte boundary.  */
> +static inline bool
> +mode_supports_dq_form (machine_mode mode)
> +{
> +  return ((reg_addr[mode].addr_mask[RELOAD_REG_ANY] & RELOAD_REG_QUAD_OFFSET)
> +         != 0);
> +}
> +
> +/* Helper function to return whether a MODE can do prefixed loads/stores.
> +   VOIDmode is used when we are loading the pc-relative address into a base
> +   register, but we are not using it as part of a memory operation.  As modes
> +   add support for prefixed memory, they will be added here.  */
> +
> +static inline bool
> +mode_supports_prefixed_address_p (machine_mode mode)
> +{
> +  return mode == VOIDmode;
> +}
> +
> +
>  /* Structure used to define the rs6000 stack */
>  typedef struct rs6000_stack {
>    int reload_completed;                /* stack info won't change from here 
> on */
> Index: gcc/config/rs6000/rs6000.c
> ===================================================================
> --- gcc/config/rs6000/rs6000.c  (revision 273617)
> +++ gcc/config/rs6000/rs6000.c  (working copy)
> @@ -155,8 +155,7 @@ bool rs6000_returns_struct = false;
>  #endif
>
>  /* Value is TRUE if register/mode pair is acceptable.  */
> -static bool rs6000_hard_regno_mode_ok_p
> -  [NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
> +bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
>
>  /* Maximum number of registers needed for a given register class and mode.  
> */
>  unsigned char rs6000_class_max_nregs[NUM_MACHINE_MODES][LIM_REG_CLASSES];
> @@ -295,122 +294,22 @@ bool cpu_builtin_p = false;
>     don't link in rs6000-c.c, so we can't call it directly.  */
>  void (*rs6000_target_modify_macros_ptr) (bool, HOST_WIDE_INT, HOST_WIDE_INT);
>
> -/* Simplfy register classes into simpler classifications.  We assume
> -   GPR_REG_TYPE - FPR_REG_TYPE are ordered so that we can use a simple range
> -   check for standard register classes (gpr/floating/altivec/vsx) and
> -   floating/vector classes (float/altivec/vsx).  */
> -
> -enum rs6000_reg_type {
> -  NO_REG_TYPE,
> -  PSEUDO_REG_TYPE,
> -  GPR_REG_TYPE,
> -  VSX_REG_TYPE,
> -  ALTIVEC_REG_TYPE,
> -  FPR_REG_TYPE,
> -  SPR_REG_TYPE,
> -  CR_REG_TYPE
> -};
> -
>  /* Map register class to register type.  */
> -static enum rs6000_reg_type reg_class_to_reg_type[N_REG_CLASSES];
> -
> -/* First/last register type for the 'normal' register types (i.e. general
> -   purpose, floating point, altivec, and VSX registers).  */
> -#define IS_STD_REG_TYPE(RTYPE) IN_RANGE(RTYPE, GPR_REG_TYPE, FPR_REG_TYPE)
> -
> -#define IS_FP_VECT_REG_TYPE(RTYPE) IN_RANGE(RTYPE, VSX_REG_TYPE, 
> FPR_REG_TYPE)
> -
> +enum rs6000_reg_type reg_class_to_reg_type[N_REG_CLASSES];
>
>  /* Register classes we care about in secondary reload or go if legitimate
>     address.  We only need to worry about GPR, FPR, and Altivec registers 
> here,
>     along an ANY field that is the OR of the 3 register classes.  */
> -
> -enum rs6000_reload_reg_type {
> -  RELOAD_REG_GPR,                      /* General purpose registers.  */
> -  RELOAD_REG_FPR,                      /* Traditional floating point regs.  
> */
> -  RELOAD_REG_VMX,                      /* Altivec (VMX) registers.  */
> -  RELOAD_REG_ANY,                      /* OR of GPR, FPR, Altivec masks.  */
> -  N_RELOAD_REG
> -};
> -
> -/* For setting up register classes, loop through the 3 register classes 
> mapping
> -   into real registers, and skip the ANY class, which is just an OR of the
> -   bits.  */
> -#define FIRST_RELOAD_REG_CLASS RELOAD_REG_GPR
> -#define LAST_RELOAD_REG_CLASS  RELOAD_REG_VMX
> -
> -/* Map reload register type to a register in the register class.  */
> -struct reload_reg_map_type {
> -  const char *name;                    /* Register class name.  */
> -  int reg;                             /* Register in the register class.  */
> -};
> -
> -static const struct reload_reg_map_type reload_reg_map[N_RELOAD_REG] = {
> +const struct reload_reg_map_type reload_reg_map[N_RELOAD_REG] = {
>    { "Gpr",     FIRST_GPR_REGNO },      /* RELOAD_REG_GPR.  */
>    { "Fpr",     FIRST_FPR_REGNO },      /* RELOAD_REG_FPR.  */
>    { "VMX",     FIRST_ALTIVEC_REGNO },  /* RELOAD_REG_VMX.  */
>    { "Any",     -1 },                   /* RELOAD_REG_ANY.  */
>  };
>
> -/* Mask bits for each register class, indexed per mode.  Historically the
> -   compiler has been more restrictive which types can do PRE_MODIFY instead 
> of
> -   PRE_INC and PRE_DEC, so keep track of sepaate bits for these two.  */
> -typedef unsigned char addr_mask_type;
> -
> -#define RELOAD_REG_VALID       0x01    /* Mode valid in register..  */
> -#define RELOAD_REG_MULTIPLE    0x02    /* Mode takes multiple registers.  */
> -#define RELOAD_REG_INDEXED     0x04    /* Reg+reg addressing.  */
> -#define RELOAD_REG_OFFSET      0x08    /* Reg+offset addressing. */
> -#define RELOAD_REG_PRE_INCDEC  0x10    /* PRE_INC/PRE_DEC valid.  */
> -#define RELOAD_REG_PRE_MODIFY  0x20    /* PRE_MODIFY valid.  */
> -#define RELOAD_REG_AND_M16     0x40    /* AND -16 addressing.  */
> -#define RELOAD_REG_QUAD_OFFSET 0x80    /* quad offset is limited.  */
> -
> -/* Register type masks based on the type, of valid addressing modes.  */
> -struct rs6000_reg_addr {
> -  enum insn_code reload_load;          /* INSN to reload for loading. */
> -  enum insn_code reload_store;         /* INSN to reload for storing.  */
> -  enum insn_code reload_fpr_gpr;       /* INSN to move from FPR to GPR.  */
> -  enum insn_code reload_gpr_vsx;       /* INSN to move from GPR to VSX.  */
> -  enum insn_code reload_vsx_gpr;       /* INSN to move from VSX to GPR.  */
> -  addr_mask_type addr_mask[(int)N_RELOAD_REG]; /* Valid address masks.  */
> -  bool scalar_in_vmx_p;                        /* Scalar value can go in 
> VMX.  */
> -};
> -
> -static struct rs6000_reg_addr reg_addr[NUM_MACHINE_MODES];
> -
> -/* Helper function to say whether a mode supports PRE_INC or PRE_DEC.  */
> -static inline bool
> -mode_supports_pre_incdec_p (machine_mode mode)
> -{
> -  return ((reg_addr[mode].addr_mask[RELOAD_REG_ANY] & RELOAD_REG_PRE_INCDEC)
> -         != 0);
> -}
> -
> -/* Helper function to say whether a mode supports PRE_MODIFY.  */
> -static inline bool
> -mode_supports_pre_modify_p (machine_mode mode)
> -{
> -  return ((reg_addr[mode].addr_mask[RELOAD_REG_ANY] & RELOAD_REG_PRE_MODIFY)
> -         != 0);
> -}
> -
> -/* Return true if we have D-form addressing in altivec registers.  */
> -static inline bool
> -mode_supports_vmx_dform (machine_mode mode)
> -{
> -  return ((reg_addr[mode].addr_mask[RELOAD_REG_VMX] & RELOAD_REG_OFFSET) != 
> 0);
> -}
> -
> -/* Return true if we have D-form addressing in VSX registers.  This 
> addressing
> -   is more limited than normal d-form addressing in that the offset must be
> -   aligned on a 16-byte boundary.  */
> -static inline bool
> -mode_supports_dq_form (machine_mode mode)
> -{
> -  return ((reg_addr[mode].addr_mask[RELOAD_REG_ANY] & RELOAD_REG_QUAD_OFFSET)
> -         != 0);
> -}
> +/* Various low level information needed for addressing formats, register
> +   allocation, etc. indexed by mode.  */
> +struct rs6000_reg_addr reg_addr[NUM_MACHINE_MODES];
>
>  /* Given that there exists at least one variable that is set (produced)
>     by OUT_INSN and read (consumed) by IN_INSN, return true iff
> @@ -13587,17 +13486,6 @@ rs6000_pltseq_template (rtx *operands, i
>  }
>  #endif
>
> -/* Helper function to return whether a MODE can do prefixed loads/stores.
> -   VOIDmode is used when we are loading the pc-relative address into a base
> -   register, but we are not using it as part of a memory operation.  As modes
> -   add support for prefixed memory, they will be added here.  */
> -
> -static bool
> -mode_supports_prefixed_address_p (machine_mode mode)
> -{
> -  return mode == VOIDmode;
> -}
> -
>  /* Function to return true if ADDR is a valid prefixed memory address that 
> uses
>     mode MODE.  */
>
>
> --
> Michael Meissner, IBM
> IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
> email: meiss...@linux.ibm.com, phone: +1 (978) 899-4797

Reply via email to