OSDN Git Service

2003-08-06 J"orn Rennecke <joern.rennecke@superh.com>
authoramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 6 Aug 2003 19:33:13 +0000 (19:33 +0000)
committeramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 6 Aug 2003 19:33:13 +0000 (19:33 +0000)
Fix SHcompact exception handling:
* sh.c (sh_get_pr_initial_val): If PR is or miight be clobbered
by the prologue, return a MEM with return_address_pointer_rtx
as address.
* sh.h (HARD_REGNO_MODE_OK): PR is OK for SImode.
(RETURN_ADDR_OFFSET): Don't define.
(SH_DBX_REGISTER_NUMBER): Use SHmedia numbers for SHmedia
registers that are visible in compact mode.  Show that SHmedia
registers still exist in compact mode, even if there are not
readily accessible.
(ASM_PREFERRED_EH_DATA_FORMAT): Supply DW_EH_PE_indirect
if GLOBAL.  Use DW_EH_PE_textrel (nominally) for CODE,
and DW_EH_PE_pcrel for pic data.
(ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX): If DW_EH_PE_textrel,
set SYMBOL_FLAG_FUNCTION in symbol, and actually use
DW_EH_PE_pcrel / DW_EH_PE_absptr encoding.
(ALLOCATE_INITIAL_VALUE): Put PR on stack if prologue clobbers it.
* sh.md (movsi_media-1): New splitter.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@70204 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/sh/sh.c
gcc/config/sh/sh.h
gcc/config/sh/sh.md

index 410a4db..2041409 100644 (file)
@@ -1,3 +1,24 @@
+2003-08-06  J"orn Rennecke <joern.rennecke@superh.com>
+
+       Fix SHcompact exception handling:
+       * sh.c (sh_get_pr_initial_val): If PR is or miight be clobbered
+       by the prologue, return a MEM with return_address_pointer_rtx
+       as address.
+       * sh.h (HARD_REGNO_MODE_OK): PR is OK for SImode.
+       (RETURN_ADDR_OFFSET): Don't define.
+       (SH_DBX_REGISTER_NUMBER): Use SHmedia numbers for SHmedia
+       registers that are visible in compact mode.  Show that SHmedia
+       registers still exist in compact mode, even if there are not
+       readily accessible.
+       (ASM_PREFERRED_EH_DATA_FORMAT): Supply DW_EH_PE_indirect
+       if GLOBAL.  Use DW_EH_PE_textrel (nominally) for CODE,
+       and DW_EH_PE_pcrel for pic data.
+       (ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX): If DW_EH_PE_textrel,
+       set SYMBOL_FLAG_FUNCTION in symbol, and actually use
+       DW_EH_PE_pcrel / DW_EH_PE_absptr encoding.
+       (ALLOCATE_INITIAL_VALUE): Put PR on stack if prologue clobbers it.
+       * sh.md (movsi_media-1): New splitter.
+
 2003-08-06  Graeme Peterson <gp@qnx.com>
 
        * config/i386/nto.h: New.
 2003-08-06  Graeme Peterson <gp@qnx.com>
 
        * config/i386/nto.h: New.
index cc75c2f..8128d47 100644 (file)
@@ -8835,6 +8835,15 @@ scavenge_reg (HARD_REG_SET *s)
 rtx
 sh_get_pr_initial_val (void)
 {
 rtx
 sh_get_pr_initial_val (void)
 {
+  /* ??? Unfortunately, get_hard_reg_initial_val doesn't always work for the
+     PR register on SHcompact, because it might be clobbered by the prologue.
+     We don't know if that's the case before rtl generation is finished.  */
+  if (TARGET_SHCOMPACT
+      && (rtx_equal_function_value_matters
+         || (current_function_args_info.call_cookie
+              & ~ CALL_COOKIE_RET_TRAMP (1))
+         || current_function_has_nonlocal_label))
+    return gen_rtx_MEM (SImode, return_address_pointer_rtx);
   return
     get_hard_reg_initial_val (Pmode, TARGET_SHMEDIA ? PR_MEDIA_REG : PR_REG);
 }
   return
     get_hard_reg_initial_val (Pmode, TARGET_SHMEDIA ? PR_MEDIA_REG : PR_REG);
 }
index cf97d91..cc94be2 100644 (file)
@@ -1018,7 +1018,7 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
    ? (MODE) == DFmode \
    : TARGET_REGISTER_P (REGNO) \
    ? ((MODE) == DImode || (MODE) == SImode) \
    ? (MODE) == DFmode \
    : TARGET_REGISTER_P (REGNO) \
    ? ((MODE) == DImode || (MODE) == SImode) \
-   : (REGNO) == PR_REG ? 0                     \
+   : (REGNO) == PR_REG ? (MODE) == SImode \
    : (REGNO) == FPSCR_REG ? (MODE) == PSImode \
    : 1)
 
    : (REGNO) == FPSCR_REG ? (MODE) == PSImode \
    : 1)
 
@@ -2335,11 +2335,6 @@ while (0)
    the stack.  */
 #define INCOMING_RETURN_ADDR_RTX \
   gen_rtx_REG (Pmode, TARGET_SHMEDIA ? PR_MEDIA_REG : PR_REG)
    the stack.  */
 #define INCOMING_RETURN_ADDR_RTX \
   gen_rtx_REG (Pmode, TARGET_SHMEDIA ? PR_MEDIA_REG : PR_REG)
-
-/* libstdc++-v3/libsupc++/eh_personality.cc:__gxx_personality_v0
-   can get confused by SHmedia return addresses when it does:
-   ip = _Unwind_GetIP (context) - 1;  */
-#define RETURN_ADDR_OFFSET (TARGET_SH5 ? -1 : 0)
 \f
 /* Generate necessary RTL for __builtin_saveregs().  */
 #define EXPAND_BUILTIN_SAVEREGS() sh_builtin_saveregs ()
 \f
 /* Generate necessary RTL for __builtin_saveregs().  */
 #define EXPAND_BUILTIN_SAVEREGS() sh_builtin_saveregs ()
@@ -3101,18 +3096,30 @@ while (0)
    register exists, so we should return -1 for invalid register numbers.  */
 #define DBX_REGISTER_NUMBER(REGNO) SH_DBX_REGISTER_NUMBER (REGNO)
 
    register exists, so we should return -1 for invalid register numbers.  */
 #define DBX_REGISTER_NUMBER(REGNO) SH_DBX_REGISTER_NUMBER (REGNO)
 
+/* SHcompact PR_REG used to use the encoding 241, and SHcompact FP registers
+   used to use the encodings 245..260, but that doesn't make sense:
+   PR_REG and PR_MEDIA_REG are actually the same register, and likewise
+   the FP registers stay the same when switching between compact and media
+   mode.  Hence, we also need to use the same dwarf frame coloumns.
+   Likewise, we need to support unwind information for SHmedia registers
+   even in compact code.  */
 #define SH_DBX_REGISTER_NUMBER(REGNO) \
 #define SH_DBX_REGISTER_NUMBER(REGNO) \
-  (GENERAL_REGISTER_P (REGNO) \
+  (IN_RANGE ((REGNO), \
+            (unsigned HOST_WIDE_INT) FIRST_GENERAL_REG, \
+            FIRST_GENERAL_REG + (TARGET_SH5 ? 63U :15U)) \
    ? ((unsigned) (REGNO) - FIRST_GENERAL_REG) \
    ? ((unsigned) (REGNO) - FIRST_GENERAL_REG) \
-   : FP_REGISTER_P (REGNO) \
+  : ((int) (REGNO) >= FIRST_FP_REG \
+     && ((int) (REGNO) \
+        <= (FIRST_FP_REG + \
+            ((TARGET_SH5 && TARGET_FPU_ANY) ? 63 : TARGET_SH2E ? 15 : -1)))) \
    ? ((unsigned) (REGNO) - FIRST_FP_REG \
    ? ((unsigned) (REGNO) - FIRST_FP_REG \
-      + (TARGET_SH5 ? (TARGET_SHCOMPACT ? 245 : 77) : 25)) \
+      + (TARGET_SH5 ? 77 : 25)) \
    : XD_REGISTER_P (REGNO) \
    ? ((unsigned) (REGNO) - FIRST_XD_REG + (TARGET_SH5 ? 289 : 87)) \
    : TARGET_REGISTER_P (REGNO) \
    ? ((unsigned) (REGNO) - FIRST_TARGET_REG + 68) \
    : (REGNO) == PR_REG \
    : XD_REGISTER_P (REGNO) \
    ? ((unsigned) (REGNO) - FIRST_XD_REG + (TARGET_SH5 ? 289 : 87)) \
    : TARGET_REGISTER_P (REGNO) \
    ? ((unsigned) (REGNO) - FIRST_TARGET_REG + 68) \
    : (REGNO) == PR_REG \
-   ? (TARGET_SH5 ? 241 : 17) \
+   ? (TARGET_SH5 ? 18 : 17) \
    : (REGNO) == PR_MEDIA_REG \
    ? (TARGET_SH5 ? 18 : (unsigned) -1) \
    : (REGNO) == T_REG \
    : (REGNO) == PR_MEDIA_REG \
    ? (TARGET_SH5 ? 18 : (unsigned) -1) \
    : (REGNO) == T_REG \
@@ -3472,6 +3479,27 @@ extern int rtx_equal_function_value_matters;
 #define EH_RETURN_STACKADJ_REGNO STATIC_CHAIN_REGNUM
 #define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, EH_RETURN_STACKADJ_REGNO)
 
 #define EH_RETURN_STACKADJ_REGNO STATIC_CHAIN_REGNUM
 #define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, EH_RETURN_STACKADJ_REGNO)
 
+/* We have to distinguish between code and data, so that we apply
+   datalabel where and only where appropriate.  Use textrel for code.  */
+#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
+ ((flag_pic && (GLOBAL) ? DW_EH_PE_indirect : 0) \
+  | ((CODE) ? DW_EH_PE_textrel : flag_pic ? DW_EH_PE_pcrel : DW_EH_PE_absptr))
+
+/* Handle special EH pointer encodings.  Absolute, pc-relative, and
+   indirect are handled automatically.  */
+#define ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX(FILE, ENCODING, SIZE, ADDR, DONE) \
+  do { \
+    if (((ENCODING) & 0x70) == DW_EH_PE_textrel) \
+      { \
+       encoding &= ~DW_EH_PE_textrel; \
+       encoding |= flag_pic ? DW_EH_PE_pcrel : DW_EH_PE_absptr; \
+       if (GET_CODE (ADDR) != SYMBOL_REF) \
+         abort (); \
+       SYMBOL_REF_FLAGS (ADDR) |= SYMBOL_FLAG_FUNCTION; \
+       if (0) goto DONE; \
+      } \
+  } while (0)
+
 #if (defined CRT_BEGIN || defined CRT_END) && ! __SHMEDIA__
 /* SH constant pool breaks the devices in crtstuff.c to control section
    in where code resides.  We have to write it as asm code.  */
 #if (defined CRT_BEGIN || defined CRT_END) && ! __SHMEDIA__
 /* SH constant pool breaks the devices in crtstuff.c to control section
    in where code resides.  We have to write it as asm code.  */
@@ -3487,8 +3515,13 @@ extern int rtx_equal_function_value_matters;
 #endif /* (defined CRT_BEGIN || defined CRT_END) && ! __SHMEDIA__ */
 
 #define ALLOCATE_INITIAL_VALUE(hard_reg) \
 #endif /* (defined CRT_BEGIN || defined CRT_END) && ! __SHMEDIA__ */
 
 #define ALLOCATE_INITIAL_VALUE(hard_reg) \
-  (REGNO (hard_reg) == (TARGET_SH5 ? PR_MEDIA_REG : PR_REG) \
-   ? (current_function_is_leaf && ! sh_pr_n_sets () \
+  (REGNO (hard_reg) == (TARGET_SHMEDIA ? PR_MEDIA_REG : PR_REG) \
+   ? (current_function_is_leaf \
+      && ! sh_pr_n_sets () \
+      && ! (TARGET_SHCOMPACT \
+           && ((current_function_args_info.call_cookie \
+                & ~ CALL_COOKIE_RET_TRAMP (1)) \
+               || current_function_has_nonlocal_label)) \
       ? (hard_reg) \
       : gen_rtx_MEM (Pmode, TARGET_SH5 \
                            ? (plus_constant (arg_pointer_rtx, \
       ? (hard_reg) \
       : gen_rtx_MEM (Pmode, TARGET_SH5 \
                            ? (plus_constant (arg_pointer_rtx, \
index 8e012d7..d4dd5d1 100644 (file)
        fake    %1,%0"
   [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
 
        fake    %1,%0"
   [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
 
+(define_split
+  [(set (match_operand:SI 0 "general_movdst_operand" "")
+       (mem:SI (reg:SI RAP_REG)))]
+  "TARGET_SHCOMPACT
+   && ! rtx_equal_function_value_matters
+   && ! ((current_function_args_info.call_cookie
+         & ~ CALL_COOKIE_RET_TRAMP (1))
+        || current_function_has_nonlocal_label)"
+  [(set (match_dup 0) (match_dup 1))]
+  "operands[1] = sh_get_pr_initial_val ();")
+
 (define_insn "*movsi_media"
   [(set (match_operand:SI 0 "general_movdst_operand"
                "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
 (define_insn "*movsi_media"
   [(set (match_operand:SI 0 "general_movdst_operand"
                "=r,r,r,r,m,f,m,f,r,f,*b,r,b")