diff options
author | Bob Wilson <bob.wilson@acm.org> | 2002-01-23 21:03:53 +0000 |
---|---|---|
committer | Bob Wilson <bwilson@gcc.gnu.org> | 2002-01-23 21:03:53 +0000 |
commit | 039843087a884e96058fd0fcde72339974d49e81 (patch) | |
tree | 474190a92649d5af6ccd7a6f3ed51d377009630f /gcc/integrate.c | |
parent | 5b1a76105bb377230a838ddeb0c94d384b33e97b (diff) | |
download | gcc-039843087a884e96058fd0fcde72339974d49e81.tar.gz |
elf.h: New file.
* config/xtensa/elf.h: New file.
* config/xtensa/lib1funcs.asm: New file.
* config/xtensa/lib2funcs.S: New file.
* config/xtensa/linux.h: New file.
* config/xtensa/t-xtensa: New file.
* config/xtensa/xtensa-config.h: New file.
* config/xtensa/xtensa-protos.h: New file.
* config/xtensa/xtensa.c: New file.
* config/xtensa/xtensa.h: New file.
* config/xtensa/xtensa.md: New file.
* config.gcc (xtensa-*-elf*): New target.
(xtensa-*-linux*): New target.
* cse.c (canon_hash): Compare rtx pointers instead of register
numbers. This is required for the Xtensa port.
* integrate.c (copy_insn_list): Handle case where the static
chain is in memory and the memory address has to be copied to
a register.
* doc/invoke.texi (Option Summary): Add Xtensa options.
(Xtensa Options): New node.
* doc/md.texi (Machine Constraints): Add Xtensa machine constraints.
* gcc.c-torture/compile/20001226-1.x: xfail for Xtensa.
From-SVN: r49155
Diffstat (limited to 'gcc/integrate.c')
-rw-r--r-- | gcc/integrate.c | 50 |
1 files changed, 44 insertions, 6 deletions
diff --git a/gcc/integrate.c b/gcc/integrate.c index b1fecc4788d..10d98f2f8a8 100644 --- a/gcc/integrate.c +++ b/gcc/integrate.c @@ -1318,6 +1318,7 @@ copy_insn_list (insns, map, static_chain_value) #ifdef HAVE_cc0 rtx cc0_insn = 0; #endif + rtx static_chain_mem = 0; /* Copy the insns one by one. Do this in two passes, first the insns and then their REG_NOTES. */ @@ -1381,25 +1382,62 @@ copy_insn_list (insns, map, static_chain_value) && REG_FUNCTION_VALUE_P (XEXP (pattern, 0))) break; - /* If this is setting the static chain rtx, omit it. */ + /* Look for the address of the static chain slot. The + rtx_equal_p comparisons against the + static_chain_incoming_rtx below may fail if the static + chain is in memory and the address specified is not + "legitimate". This happens on Xtensa where the static + chain is at a negative offset from argp and where only + positive offsets are legitimate. When the RTL is + generated, the address is "legitimized" by copying it + into a register, causing the rtx_equal_p comparisons to + fail. This workaround looks for code that sets a + register to the address of the static chain. Subsequent + memory references via that register can then be + identified as static chain references. We assume that + the register is only assigned once, and that the static + chain address is only live in one register at a time. */ + else if (static_chain_value != 0 && set != 0 + && GET_CODE (static_chain_incoming_rtx) == MEM && GET_CODE (SET_DEST (set)) == REG - && rtx_equal_p (SET_DEST (set), - static_chain_incoming_rtx)) + && rtx_equal_p (SET_SRC (set), + XEXP (static_chain_incoming_rtx, 0))) + { + static_chain_mem = + gen_rtx_MEM (GET_MODE (static_chain_incoming_rtx), + SET_DEST (set)); + + /* emit the instruction in case it is used for something + other than setting the static chain; if it's not used, + it can always be removed as dead code */ + copy = emit_insn (copy_rtx_and_substitute (pattern, map, 0)); + } + + /* If this is setting the static chain rtx, omit it. */ + else if (static_chain_value != 0 + && set != 0 + && (rtx_equal_p (SET_DEST (set), + static_chain_incoming_rtx) + || (static_chain_mem + && rtx_equal_p (SET_DEST (set), static_chain_mem)))) break; /* If this is setting the static chain pseudo, set it from the value we want to give it instead. */ else if (static_chain_value != 0 && set != 0 - && rtx_equal_p (SET_SRC (set), - static_chain_incoming_rtx)) + && (rtx_equal_p (SET_SRC (set), + static_chain_incoming_rtx) + || (static_chain_mem + && rtx_equal_p (SET_SRC (set), static_chain_mem)))) { rtx newdest = copy_rtx_and_substitute (SET_DEST (set), map, 1); copy = emit_move_insn (newdest, static_chain_value); - static_chain_value = 0; + if (GET_CODE (static_chain_incoming_rtx) != MEM) + static_chain_value = 0; } /* If this is setting the virtual stack vars register, this must |