summaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authoramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>2003-08-06 19:33:13 +0000
committeramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>2003-08-06 19:33:13 +0000
commit7a1492b53f03778d3c8ea314925b3b7061a7e7a0 (patch)
treed029cd33239bc1d98c961ba9500987ee1ed0d9e1 /gcc/config
parentb1aac5f561adc5e77d7609c33384416f8211ae5c (diff)
downloadgcc-7a1492b53f03778d3c8ea314925b3b7061a7e7a0.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@70204 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/sh/sh.c9
-rw-r--r--gcc/config/sh/sh.h57
-rw-r--r--gcc/config/sh/sh.md11
3 files changed, 65 insertions, 12 deletions
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index cc75c2f5899..8128d4731f8 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -8835,6 +8835,15 @@ scavenge_reg (HARD_REG_SET *s)
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);
}
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index cf97d9129bc..cc94be2f740 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -1018,7 +1018,7 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
? (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)
@@ -2335,11 +2335,6 @@ while (0)
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)
/* 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)
+/* 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) \
- (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) \
- : 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 \
- + (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 \
- ? (TARGET_SH5 ? 241 : 17) \
+ ? (TARGET_SH5 ? 18 : 17) \
: (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)
+/* 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. */
@@ -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) \
- (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, \
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index 8e012d75f7b..d4dd5d1287d 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -3471,6 +3471,17 @@
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")