This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Xtensa: avoid use of register a7 as a reload register


The following patch fixes a serious problem in the Xtensa port, where register a7 is used as a reload register in a function prologue where it is not safe to do so. I've added a new register class to identify the registers that are to be used for reloads. Tested with the xtensa-elf target, and applied to the mainline and 3.2 and 3.0 branches.

2002-09-30  Bob Wilson  <bob.wilson@acm.org>

        * config/xtensa/xtensa.h (REG_CLASS_NAMES, REG_CLASS_CONTENTS):
        Add new RL_REGS register class.
        (PREFERRED_RELOAD_CLASS, PREFERRED_OUTPUT_RELOAD_CLASS):
        Call xtensa_preferred_reload_class for both input and output reloads.
        * config/xtensa/xtensa.c (xtensa_regno_to_class): Use new RL_REGS class.
        (xtensa_preferred_reload_class): Handle output reloads; use RL_REGS
        instead of either AR_REGS or GR_REGS classes.
        (xtensa_secondary_reload_class): Use new RL_REGS class.
        * config/xtensa/xtensa-protos.h (xtensa_preferred_reload_class): Update.

Index: config/xtensa/xtensa-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/xtensa/xtensa-protos.h,v
retrieving revision 1.4
diff -c -3 -r1.4 xtensa-protos.h
*** config/xtensa/xtensa-protos.h	16 Jul 2002 20:59:08 -0000	1.4
--- config/xtensa/xtensa-protos.h	30 Sep 2002 20:08:34 -0000
***************
*** 1,5 ****
  /* Prototypes of target machine for GNU compiler for Xtensa.
!    Copyright (C) 2001 Free Software Foundation, Inc.
     Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
  
  This file is part of GCC.
--- 1,5 ----
  /* Prototypes of target machine for GNU compiler for Xtensa.
!    Copyright 2001,2002 Free Software Foundation, Inc.
     Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
  
  This file is part of GCC.
***************
*** 89,95 ****
  extern rtx xtensa_return_addr PARAMS ((int, rtx));
  extern rtx xtensa_builtin_saveregs PARAMS ((void));
  extern enum reg_class xtensa_preferred_reload_class
!   PARAMS ((rtx, enum reg_class));
  extern enum reg_class xtensa_secondary_reload_class
    PARAMS ((enum reg_class, enum machine_mode, rtx, int));
  extern int a7_overlap_mentioned_p PARAMS ((rtx x));
--- 89,95 ----
  extern rtx xtensa_return_addr PARAMS ((int, rtx));
  extern rtx xtensa_builtin_saveregs PARAMS ((void));
  extern enum reg_class xtensa_preferred_reload_class
!   PARAMS ((rtx, enum reg_class, int));
  extern enum reg_class xtensa_secondary_reload_class
    PARAMS ((enum reg_class, enum machine_mode, rtx, int));
  extern int a7_overlap_mentioned_p PARAMS ((rtx x));
Index: config/xtensa/xtensa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/xtensa/xtensa.c,v
retrieving revision 1.19
diff -c -3 -r1.19 xtensa.c
*** config/xtensa/xtensa.c	4 Sep 2002 16:22:51 -0000	1.19
--- config/xtensa/xtensa.c	30 Sep 2002 20:08:34 -0000
***************
*** 1,5 ****
  /* Subroutines for insn-output.c for Tensilica's Xtensa architecture.
!    Copyright (C) 2001 Free Software Foundation, Inc.
     Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
  
  This file is part of GCC.
--- 1,5 ----
  /* Subroutines for insn-output.c for Tensilica's Xtensa architecture.
!    Copyright 2001,2002 Free Software Foundation, Inc.
     Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
  
  This file is part of GCC.
***************
*** 107,116 ****
  /* Map hard register number to register class */
  const enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER] =
  {
!   GR_REGS,	SP_REG,		GR_REGS,	GR_REGS,
!   GR_REGS,	GR_REGS,	GR_REGS,	GR_REGS,
!   GR_REGS,	GR_REGS,	GR_REGS,	GR_REGS,
!   GR_REGS,	GR_REGS,	GR_REGS,	GR_REGS,
    AR_REGS,	AR_REGS,	BR_REGS,
    FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
    FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
--- 107,116 ----
  /* Map hard register number to register class */
  const enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER] =
  {
!   RL_REGS,	SP_REG,		RL_REGS,	RL_REGS,
!   RL_REGS,	RL_REGS,	RL_REGS,	GR_REGS,
!   RL_REGS,	RL_REGS,	RL_REGS,	RL_REGS,
!   RL_REGS,	RL_REGS,	RL_REGS,	RL_REGS,
    AR_REGS,	AR_REGS,	BR_REGS,
    FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
    FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
***************
*** 2614,2629 ****
  
  
  enum reg_class
! xtensa_preferred_reload_class (x, class)
       rtx x;
       enum reg_class class;
  {
!   if (CONSTANT_P (x) && GET_CODE (x) == CONST_DOUBLE)
      return NO_REGS;
  
!   /* Don't use sp for reloads! */
!   if (class == AR_REGS)
!     return GR_REGS;
  
    return class;
  }
--- 2614,2635 ----
  
  
  enum reg_class
! xtensa_preferred_reload_class (x, class, isoutput)
       rtx x;
       enum reg_class class;
+      int isoutput;
  {
!   if (!isoutput && CONSTANT_P (x) && GET_CODE (x) == CONST_DOUBLE)
      return NO_REGS;
  
!   /* Don't use the stack pointer or hard frame pointer for reloads!
!      The hard frame pointer would normally be OK except that it may
!      briefly hold an incoming argument in the prologue, and reload
!      won't know that it is live because the hard frame pointer is
!      treated specially.  */
! 
!   if (class == AR_REGS || class == GR_REGS)
!     return RL_REGS;
  
    return class;
  }
***************
*** 2645,2657 ****
    if (!isoutput)
      {
        if (class == FP_REGS && constantpool_mem_p (x))
! 	return GR_REGS;
      }
  
    if (ACC_REG_P (regno))
!     return (class == GR_REGS ? NO_REGS : GR_REGS);
    if (class == ACC_REG)
!     return (GP_REG_P (regno) ? NO_REGS : GR_REGS);
  
    return NO_REGS;
  }
--- 2651,2663 ----
    if (!isoutput)
      {
        if (class == FP_REGS && constantpool_mem_p (x))
! 	return RL_REGS;
      }
  
    if (ACC_REG_P (regno))
!     return ((class == GR_REGS || class == RL_REGS) ? NO_REGS : RL_REGS);
    if (class == ACC_REG)
!     return (GP_REG_P (regno) ? NO_REGS : RL_REGS);
  
    return NO_REGS;
  }
Index: config/xtensa/xtensa.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/xtensa/xtensa.h,v
retrieving revision 1.21
diff -c -3 -r1.21 xtensa.h
*** config/xtensa/xtensa.h	20 Sep 2002 06:36:36 -0000	1.21
--- config/xtensa/xtensa.h	30 Sep 2002 20:08:34 -0000
***************
*** 1,5 ****
  /* Definitions of Tensilica's Xtensa target machine for GNU compiler.
!    Copyright (C) 2001 Free Software Foundation, Inc.
     Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
  
  This file is part of GCC.
--- 1,5 ----
  /* Definitions of Tensilica's Xtensa target machine for GNU compiler.
!    Copyright 2001,2002 Free Software Foundation, Inc.
     Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
  
  This file is part of GCC.
***************
*** 554,559 ****
--- 554,560 ----
    FP_REGS,			/* floating point registers */
    ACC_REG,			/* MAC16 accumulator */
    SP_REG,			/* sp register (aka a1) */
+   RL_REGS,			/* preferred reload regs (not sp or fp) */
    GR_REGS,			/* integer registers except sp */
    AR_REGS,			/* all integer registers */
    ALL_REGS,			/* all registers */
***************
*** 574,579 ****
--- 575,581 ----
    "FP_REGS",								\
    "ACC_REG",								\
    "SP_REG",								\
+   "RL_REGS",								\
    "GR_REGS",								\
    "AR_REGS",								\
    "ALL_REGS"								\
***************
*** 589,594 ****
--- 591,597 ----
    { 0xfff80000, 0x00000007 }, /* floating-point registers */ \
    { 0x00000000, 0x00000008 }, /* MAC16 accumulator */ \
    { 0x00000002, 0x00000000 }, /* stack pointer register */ \
+   { 0x0000ff7d, 0x00000000 }, /* preferred reload registers */ \
    { 0x0000fffd, 0x00000000 }, /* general-purpose registers */ \
    { 0x0003ffff, 0x00000000 }, /* integer registers */ \
    { 0xffffffff, 0x0000000f }  /* all registers */ \
***************
*** 704,713 ****
     : FALSE)
  
  #define PREFERRED_RELOAD_CLASS(X, CLASS)				\
!   xtensa_preferred_reload_class (X, CLASS)
  
  #define PREFERRED_OUTPUT_RELOAD_CLASS(X, CLASS)				\
!   (CLASS)
    
  #define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X)			\
    xtensa_secondary_reload_class (CLASS, MODE, X, 0)
--- 707,716 ----
     : FALSE)
  
  #define PREFERRED_RELOAD_CLASS(X, CLASS)				\
!   xtensa_preferred_reload_class (X, CLASS, 0)
  
  #define PREFERRED_OUTPUT_RELOAD_CLASS(X, CLASS)				\
!   xtensa_preferred_reload_class (X, CLASS, 1)
    
  #define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X)			\
    xtensa_secondary_reload_class (CLASS, MODE, X, 0)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]