diff options
author | Jason Merrill <jason@redhat.com> | 2010-11-01 23:29:52 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2010-11-01 23:32:03 -0400 |
commit | d29b209e37cb85fdf1cb1d8e0ae263cc3c59312b (patch) | |
tree | 0e6b797a6c1a23c50603805706926a5eaa2184f1 /gcc/config/sh | |
parent | 2450a78a38a727e7ec673b132315c8379db3b27d (diff) | |
parent | c0000147b2aef6b69e2c6b6d29a9963910f6da98 (diff) | |
download | gcc-constexpr.tar.gz |
Merge remote branch 'trunk' into constexprconstexpr
Diffstat (limited to 'gcc/config/sh')
-rw-r--r-- | gcc/config/sh/sh.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index 54e7be84947..a1eec59153e 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -255,6 +255,7 @@ static int sh_pr_n_sets (void); static rtx sh_allocate_initial_value (rtx); static bool sh_legitimate_address_p (enum machine_mode, rtx, bool); static rtx sh_legitimize_address (rtx, rtx, enum machine_mode); +static rtx sh_delegitimize_address (rtx); static int shmedia_target_regs_stack_space (HARD_REG_SET *); static int shmedia_reserve_space_for_target_registers_p (int, HARD_REG_SET *); static int shmedia_target_regs_stack_adjust (HARD_REG_SET *); @@ -459,6 +460,9 @@ static const struct default_options sh_option_optimization_table[] = #undef TARGET_SCHED_INIT #define TARGET_SCHED_INIT sh_md_init +#undef TARGET_DELEGITIMIZE_ADDRESS +#define TARGET_DELEGITIMIZE_ADDRESS sh_delegitimize_address + #undef TARGET_LEGITIMIZE_ADDRESS #define TARGET_LEGITIMIZE_ADDRESS sh_legitimize_address @@ -9873,6 +9877,45 @@ sh_legitimize_reload_address (rtx *p, enum machine_mode mode, int opnum, return true; } +/* In the name of slightly smaller debug output, and to cater to + general assembler lossage, recognize various UNSPEC sequences + and turn them back into a direct symbol reference. */ + +static rtx +sh_delegitimize_address (rtx orig_x) +{ + rtx x, y; + + orig_x = delegitimize_mem_from_attrs (orig_x); + + x = orig_x; + if (MEM_P (x)) + x = XEXP (x, 0); + if (GET_CODE (x) == CONST) + { + y = XEXP (x, 0); + if (GET_CODE (y) == UNSPEC) + { + if (XINT (y, 1) == UNSPEC_GOT + || XINT (y, 1) == UNSPEC_GOTOFF) + return XVECEXP (y, 0, 0); + else if (TARGET_SHMEDIA + && (XINT (y, 1) == UNSPEC_EXTRACT_S16 + || XINT (y, 1) == UNSPEC_EXTRACT_U16)) + { + rtx offset = XVECEXP (y, 0, 1); + + x = gen_rtx_PLUS (Pmode, XVECEXP (y, 0, 0), offset); + if (MEM_P (orig_x)) + x = replace_equiv_address_nv (orig_x, x); + return x; + } + } + } + + return orig_x; +} + /* Mark the use of a constant in the literal table. If the constant has multiple labels, make it unique. */ static rtx |