diff options
author | Ulrich Weigand <uweigand@de.ibm.com> | 2002-08-15 09:55:31 +0000 |
---|---|---|
committer | Ulrich Weigand <uweigand@gcc.gnu.org> | 2002-08-15 09:55:31 +0000 |
commit | 61f02ff548608d1fe98c35f724575cb87865946b (patch) | |
tree | 1f3840a03d2c684772d5f02cea5d49744d4f9753 /gcc | |
parent | 6848fc973f311a7459b20305a71d17049b0d799d (diff) | |
download | gcc-61f02ff548608d1fe98c35f724575cb87865946b.zip gcc-61f02ff548608d1fe98c35f724575cb87865946b.tar.gz gcc-61f02ff548608d1fe98c35f724575cb87865946b.tar.bz2 |
s390.c (legitimize_address): Optimize loading of large displacements.
* config/s390/s390.c (legitimize_address): Optimize loading
of large displacements.
From-SVN: r56345
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/config/s390/s390.c | 25 |
2 files changed, 30 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ab35fcf..71ae78d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2002-08-15 Ulrich Weigand <uweigand@de.ibm.com> + + * config/s390/s390.c (legitimize_address): Optimize loading + of large displacements. + 2002-08-14 Douglas B Rupp <rupp@gnat.com> * config/alpha/alpha-protos.h: Update. diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 6a29b76..85952c5 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -2084,6 +2084,31 @@ legitimize_address (x, oldx, mode) x = eliminate_constant_term (x, &constant_term); + /* Optimize loading of large displacements by splitting them + into the multiple of 4K and the rest; this allows the + former to be CSE'd if possible. + + Don't do this if the displacement is added to a register + pointing into the stack frame, as the offsets will + change later anyway. */ + + if (GET_CODE (constant_term) == CONST_INT + && (INTVAL (constant_term) < 0 + || INTVAL (constant_term) >= 4096) + && !(REG_P (x) && REGNO_PTR_FRAME_P (REGNO (x)))) + { + HOST_WIDE_INT lower = INTVAL (constant_term) & 0xfff; + HOST_WIDE_INT upper = INTVAL (constant_term) ^ lower; + + rtx temp = gen_reg_rtx (Pmode); + rtx val = force_operand (GEN_INT (upper), temp); + if (val != temp) + emit_move_insn (temp, val); + + x = gen_rtx_PLUS (Pmode, x, temp); + constant_term = GEN_INT (lower); + } + if (GET_CODE (x) == PLUS) { if (GET_CODE (XEXP (x, 0)) == REG) |