aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/fr30
diff options
context:
space:
mode:
authorLars Poeschel <larsi@wh2.tu-dresden.de>2007-03-29 10:23:27 +0000
committerNick Clifton <nickc@redhat.com>2007-03-29 10:23:27 +0000
commit5d3a9f48e8067641e790a3e27ca62c4f8e3f005e (patch)
tree6df58a06db2d6a8fc546c8708baf17483b6590fd /gcc/config/fr30
parentf74333eed03517168ec0ee4b7adf1ff876bfbbe0 (diff)
* config/fr30/fr30.md (movdi): Do not accept immediates as the destination of this insn.
* config/fr30/fr30.c (fr30_move_double): Use emit_move_insn rather than calling gen_rtx_SET directly. Use r0 to hold the value of 'address + 4' rather than a stack based temporary which can be mis-optimized away. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@123326 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/fr30')
-rw-r--r--gcc/config/fr30/fr30.c34
-rw-r--r--gcc/config/fr30/fr30.md18
2 files changed, 27 insertions, 25 deletions
diff --git a/gcc/config/fr30/fr30.c b/gcc/config/fr30/fr30.c
index d5e65e8ac2a..9d3558d5d27 100644
--- a/gcc/config/fr30/fr30.c
+++ b/gcc/config/fr30/fr30.c
@@ -1,5 +1,5 @@
/* FR30 specific functions.
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007
Free Software Foundation, Inc.
Contributed by Cygnus Solutions.
@@ -890,12 +890,11 @@ fr30_move_double (rtx * operands)
rtx src1;
gcc_assert (GET_CODE (addr) == REG);
-
+
src0 = operand_subword (src, 0, TRUE, mode);
src1 = operand_subword (src, 1, TRUE, mode);
-
- emit_insn (gen_rtx_SET (VOIDmode, adjust_address (dest, SImode, 0),
- src0));
+
+ emit_move_insn (adjust_address (dest, SImode, 0), src0);
if (REGNO (addr) == STACK_POINTER_REGNUM
|| REGNO (addr) == FRAME_POINTER_REGNUM)
@@ -905,30 +904,31 @@ fr30_move_double (rtx * operands)
else
{
rtx new_mem;
-
+ rtx scratch_reg_r0 = gen_rtx_REG (SImode, 0);
+
/* We need a scratch register to hold the value of 'address + 4'.
- We ought to allow gcc to find one for us, but for now, just
- push one of the source registers. */
- emit_insn (gen_movsi_push (src0));
- emit_insn (gen_movsi_internal (src0, addr));
- emit_insn (gen_addsi_small_int (src0, src0, GEN_INT (UNITS_PER_WORD)));
-
- new_mem = gen_rtx_MEM (SImode, src0);
+ We use r0 for this purpose. It is used for example for long
+ jumps and is already marked to not be used by normal register
+ allocation. */
+ emit_insn (gen_movsi_internal (scratch_reg_r0, addr));
+ emit_insn (gen_addsi_small_int (scratch_reg_r0, scratch_reg_r0,
+ GEN_INT (UNITS_PER_WORD)));
+ new_mem = gen_rtx_MEM (SImode, scratch_reg_r0);
MEM_COPY_ATTRIBUTES (new_mem, dest);
-
- emit_insn (gen_rtx_SET (VOIDmode, new_mem, src1));
- emit_insn (gen_movsi_pop (src0));
+ emit_move_insn (new_mem, src1);
+ emit_insn (gen_blockage ());
}
}
else
/* This should have been prevented by the constraints on movdi_insn. */
gcc_unreachable ();
-
+
val = get_insns ();
end_sequence ();
return val;
}
+
/*}}}*/
/* Local Variables: */
/* folded-file: t */
diff --git a/gcc/config/fr30/fr30.md b/gcc/config/fr30/fr30.md
index 6921e7e3de9..83cad93ed00 100644
--- a/gcc/config/fr30/fr30.md
+++ b/gcc/config/fr30/fr30.md
@@ -1,5 +1,5 @@
;; FR30 machine description.
-;; Copyright (C) 1998, 1999, 2000, 2002, 2004, 2005
+;; Copyright (C) 1998, 1999, 2000, 2002, 2004, 2005, 2007
;; Free Software Foundation, Inc.
;; Contributed by Cygnus Solutions.
@@ -380,22 +380,23 @@
;; (This code is stolen from the M32R port.)
(define_expand "movdi"
- [(set (match_operand:DI 0 "general_operand" "")
- (match_operand:DI 1 "general_operand" ""))]
+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
+ (match_operand:DI 1 "general_operand" ""))]
""
"
/* Everything except mem = const or mem = mem can be done easily. */
-
+
if (GET_CODE (operands[0]) == MEM)
operands[1] = force_reg (DImode, operands[1]);
- ")
+ "
+)
;; We use an insn and a split so that we can generate
;; RTL rather than text from fr30_move_double().
(define_insn "*movdi_insn"
[(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,m,r")
- (match_operand:DI 1 "di_operand" "r,m,r,nF"))]
+ (match_operand:DI 1 "di_operand" "r,m,r,nF"))]
"register_operand (operands[0], DImode) || register_operand (operands[1], DImode)"
"#"
[(set_attr "length" "4,8,12,12")]
@@ -403,10 +404,11 @@
(define_split
[(set (match_operand:DI 0 "nonimmediate_di_operand" "")
- (match_operand:DI 1 "di_operand" ""))]
+ (match_operand:DI 1 "di_operand" ""))]
"reload_completed"
[(match_dup 2)]
- "operands[2] = fr30_move_double (operands);")
+ "operands[2] = fr30_move_double (operands);"
+)
;;}}}
;;{{{ Load & Store Multiple Registers