This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
SH movdf: clobbering output register too early
- To: gcc-patches at gcc dot gnu dot org
- Subject: SH movdf: clobbering output register too early
- From: Alexandre Oliva <aoliva at redhat dot com>
- Date: 05 Jan 2001 18:17:12 -0200
- Organization: GCC Team, Red Hat
Some functions in newlib would miscompile because the insn:
(set (reg:DF r1) (mem:DF (plus:SI (reg:SI r0) (reg:SI r1))))
would be split to:
(set (reg:SI r1) (mem:SI (plus:SI (reg:SI r0) (reg:SI r1))))
(set (reg:SI r0) (plus:SI (reg:SI r0) (const_int 4)))
(set (reg:SI r2) (mem:SI (plus:SI (reg:SI r0) (reg:SI r1))))
(set (reg:SI r0) (plus:SI (reg:SI r0) (const_int -4)))
But, by the time r2 would be set, r1 had already been clobbered. This
patch fixes this problem. I'm checking it in.
Index: gcc/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* config/sh/sh.md (movdf): When splitting load into pair of
registers, don't clobber the register used in the address too
early.
Index: gcc/config/sh/sh.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/sh/sh.md,v
retrieving revision 1.71
diff -u -p -r1.71 sh.md
--- gcc/config/sh/sh.md 2001/01/05 03:46:12 1.71
+++ gcc/config/sh/sh.md 2001/01/05 20:06:03
@@ -2745,15 +2745,29 @@
offset = 4;
mem = copy_rtx (mem);
PUT_MODE (mem, SImode);
- word0 = gen_rtx(SUBREG, SImode, regop, 0);
- emit_insn (store_p
- ? gen_movsi_ie (mem, word0) : gen_movsi_ie (word0, mem));
- emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
- mem = copy_rtx (mem);
- word1 = gen_rtx(SUBREG, SImode, regop, 1);
- emit_insn (store_p
- ? gen_movsi_ie (mem, word1) : gen_movsi_ie (word1, mem));
- emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
+ word0 = alter_subreg (gen_rtx (SUBREG, SImode, regop, 0));
+ word1 = alter_subreg (gen_rtx (SUBREG, SImode, regop, 1));
+ if (store_p || ! refers_to_regno_p (REGNO (word0),
+ REGNO (word0) + 1, addr, 0))
+ {
+ emit_insn (store_p
+ ? gen_movsi_ie (mem, word0)
+ : gen_movsi_ie (word0, mem));
+ emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
+ mem = copy_rtx (mem);
+ emit_insn (store_p
+ ? gen_movsi_ie (mem, word1)
+ : gen_movsi_ie (word1, mem));
+ emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
+ }
+ else
+ {
+ emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
+ emit_insn (gen_movsi_ie (word1, mem));
+ emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
+ mem = copy_rtx (mem);
+ emit_insn (gen_movsi_ie (word0, mem));
+ }
DONE;
}
}
--
Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist *Please* write to mailing lists, not to me