summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/config/sparc/sparc-protos.h2
-rw-r--r--gcc/config/sparc/sparc.c36
-rw-r--r--gcc/config/sparc/sparc.md186
4 files changed, 153 insertions, 83 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7eba0097c9d..9cd09b9dd4e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+2001-12-15 Dan Nicolaescu <dann@ics.uci.edu>
+
+ * config/sparc/sparc.c (mems_ok_for_ldd_peep): Rename from
+ addrs_ok_for_ldd_peep_withmem; take MEMs as parameters, not
+ addrs; eliminate restriction of only using fp and sp as base
+ registers.
+ * config/sparc/sparc-protos.h: Update.
+ * config/sparc/sparc.md (movdi): Use TARGET_V9 not TARGET_ARCH64.
+ (*cmp_cc_set, *cmp_ccx_set64, *movdi_zero): New insns derived
+ from old define_peepholes.
+ Convert all the ldd/std peepholes to peephole2.
+
2001-12-15 Ulrich Weigand <uweigand@de.ibm.com>
* s390.md (prologue, epilogue, *return_si, *return_di): New.
diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h
index fe658296fb5..7e0e1fcad9b 100644
--- a/gcc/config/sparc/sparc-protos.h
+++ b/gcc/config/sparc/sparc-protos.h
@@ -92,7 +92,7 @@ extern char *output_v9branch PARAMS ((rtx, int, int, int, int, int, rtx));
extern void emit_v9_brxx_insn PARAMS ((enum rtx_code, rtx, rtx));
extern void output_double_int PARAMS ((FILE *, rtx));
extern void print_operand PARAMS ((FILE *, rtx, int));
-extern int addrs_ok_for_ldd_peep PARAMS ((rtx, rtx));
+extern int mems_ok_for_ldd_peep PARAMS ((rtx, rtx));
extern int arith_double_4096_operand PARAMS ((rtx, enum machine_mode));
extern int arith_4096_operand PARAMS ((rtx, enum machine_mode));
extern int zero_operand PARAMS ((rtx, enum machine_mode));
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 2807add2849..48906d46bf4 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -5646,27 +5646,28 @@ registers_ok_for_ldd_peep (reg1, reg2)
return (REGNO (reg1) == REGNO (reg2) - 1);
}
-/* Return 1 if addr1 and addr2 are suitable for use in an ldd or
- std insn.
-
- This can only happen when addr1 and addr2 are consecutive memory
- locations (addr1 + 4 == addr2). addr1 must also be aligned on a
- 64 bit boundary (addr1 % 8 == 0).
-
- We know %sp and %fp are kept aligned on a 64 bit boundary. Other
- registers are assumed to *never* be properly aligned and are
- rejected.
-
- Knowing %sp and %fp are kept aligned on a 64 bit boundary, we
- need only check that the offset for addr1 % 8 == 0. */
+/* Return 1 if the addresses in mem1 and mem2 are suitable for use in
+ an ldd or std insn.
+
+ This can only happen when addr1 and addr2, the addresses in mem1
+ and mem2, are consecutive memory locations (addr1 + 4 == addr2).
+ addr1 must also be aligned on a 64-bit boundary. */
int
-addrs_ok_for_ldd_peep (addr1, addr2)
- rtx addr1, addr2;
+mems_ok_for_ldd_peep (mem1, mem2)
+ rtx mem1, mem2;
{
+ rtx addr1, addr2;
unsigned int reg1;
int offset1;
+ addr1 = XEXP (mem1, 0);
+ addr2 = XEXP (mem2, 0);
+
+ /* mem1 should be aligned on a 64-bit boundary */
+ if (MEM_ALIGN (mem1) < 64)
+ return 0;
+
/* Extract a register number and offset (if used) from the first addr. */
if (GET_CODE (addr1) == PLUS)
{
@@ -5699,11 +5700,6 @@ addrs_ok_for_ldd_peep (addr1, addr2)
|| GET_CODE (XEXP (addr2, 1)) != CONST_INT)
return 0;
- /* Only %fp and %sp are allowed. Additionally both addresses must
- use the same register. */
- if (reg1 != FRAME_POINTER_REGNUM && reg1 != STACK_POINTER_REGNUM)
- return 0;
-
if (reg1 != REGNO (XEXP (addr2, 0)))
return 0;
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index fc3f10bf0d9..dde4156f7b6 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -2383,7 +2383,7 @@
The const zero case is more complex, on v9
we can always perform it. */
if (register_operand (operands[1], DImode)
- || (TARGET_ARCH64
+ || (TARGET_V9
&& (operands[1] == const0_rtx)))
goto movdi_is_ok;
@@ -2444,6 +2444,13 @@
;
}")
+(define_insn "*movdi_zero"
+ [(set (match_operand:DI 0 "memory_operand" "")
+ (const_int 0))]
+ "TARGET_V9"
+ "stx\\t%%g0, %0"
+ [(set_attr "type" "store")])
+
;; Be careful, fmovd does not exist when !arch64.
;; We match MEM moves directly when we have correct even
;; numbered registers, but fall into splits otherwise.
@@ -7212,6 +7219,26 @@
"TARGET_ARCH64"
"xnorcc\\t%%g0, %1, %0"
[(set_attr "type" "compare")])
+
+(define_insn "*cmp_cc_set"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (match_operand:SI 1 "register_operand" "r"))
+ (set (reg:CC 100)
+ (compare:CC (match_dup 1)
+ (const_int 0)))]
+ ""
+ "orcc\\t%1, 0, %0"
+ [(set_attr "type" "compare")])
+
+(define_insn "*cmp_ccx_set64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (match_operand:DI 1 "register_operand" "r"))
+ (set (reg:CCX 100)
+ (compare:CCX (match_dup 1)
+ (const_int 0)))]
+ "TARGET_ARCH64"
+ "orcc\\t%1, 0, %0"
+ [(set_attr "type" "compare")])
;; Floating point arithmetic instructions.
@@ -8871,7 +8898,7 @@
;; The conditions in which we do this are very restricted and are
;; explained in the code for {registers,memory}_ok_for_ldd functions.
-(define_peephole
+(define_peephole2
[(set (match_operand:SI 0 "memory_operand" "")
(const_int 0))
(set (match_operand:SI 1 "memory_operand" "")
@@ -8879,10 +8906,12 @@
"TARGET_V9
&& ! MEM_VOLATILE_P (operands[0])
&& ! MEM_VOLATILE_P (operands[1])
- && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[1], 0))"
- "stx\\t%%g0, %0")
+ && mems_ok_for_ldd_peep (operands[0], operands[1])"
+ [(set (match_dup 0)
+ (const_int 0))]
+ "operands[0] = change_address (operands[0], DImode, NULL);")
-(define_peephole
+(define_peephole2
[(set (match_operand:SI 0 "memory_operand" "")
(const_int 0))
(set (match_operand:SI 1 "memory_operand" "")
@@ -8890,125 +8919,158 @@
"TARGET_V9
&& ! MEM_VOLATILE_P (operands[0])
&& ! MEM_VOLATILE_P (operands[1])
- && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[0], 0))"
- "stx\\t%%g0, %1")
+ && mems_ok_for_ldd_peep (operands[1], operands[0])"
+ [(set (match_dup 1)
+ (const_int 0))]
+ "operands[1] = change_address (operands[1], DImode, NULL);")
-(define_peephole
- [(set (match_operand:SI 0 "register_operand" "=rf")
+(define_peephole2
+ [(set (match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "memory_operand" ""))
- (set (match_operand:SI 2 "register_operand" "=rf")
+ (set (match_operand:SI 2 "register_operand" "")
(match_operand:SI 3 "memory_operand" ""))]
"registers_ok_for_ldd_peep (operands[0], operands[2])
&& ! MEM_VOLATILE_P (operands[1])
&& ! MEM_VOLATILE_P (operands[3])
- && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
- "ldd\\t%1, %0")
+ && mems_ok_for_ldd_peep (operands[1], operands[3])"
+ [(set (match_dup 0)
+ (match_dup 1))]
+ "operands[1] = change_address (operands[1], DImode, NULL);
+ operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
-(define_peephole
+(define_peephole2
[(set (match_operand:SI 0 "memory_operand" "")
- (match_operand:SI 1 "register_operand" "rf"))
+ (match_operand:SI 1 "register_operand" ""))
(set (match_operand:SI 2 "memory_operand" "")
- (match_operand:SI 3 "register_operand" "rf"))]
+ (match_operand:SI 3 "register_operand" ""))]
"registers_ok_for_ldd_peep (operands[1], operands[3])
&& ! MEM_VOLATILE_P (operands[0])
&& ! MEM_VOLATILE_P (operands[2])
- && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
- "std\\t%1, %0")
-
-(define_peephole
- [(set (match_operand:SF 0 "register_operand" "=fr")
+ && mems_ok_for_ldd_peep (operands[0], operands[2])"
+ [(set (match_dup 0)
+ (match_dup 1))]
+ "operands[0] = change_address (operands[0], DImode, NULL);
+ operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
+
+(define_peephole2
+ [(set (match_operand:SF 0 "register_operand" "")
(match_operand:SF 1 "memory_operand" ""))
- (set (match_operand:SF 2 "register_operand" "=fr")
+ (set (match_operand:SF 2 "register_operand" "")
(match_operand:SF 3 "memory_operand" ""))]
"registers_ok_for_ldd_peep (operands[0], operands[2])
&& ! MEM_VOLATILE_P (operands[1])
&& ! MEM_VOLATILE_P (operands[3])
- && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
- "ldd\\t%1, %0")
+ && mems_ok_for_ldd_peep (operands[1], operands[3])"
+ [(set (match_dup 0)
+ (match_dup 1))]
+ "operands[1] = change_address (operands[1], DFmode, NULL);
+ operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
-(define_peephole
+(define_peephole2
[(set (match_operand:SF 0 "memory_operand" "")
- (match_operand:SF 1 "register_operand" "fr"))
+ (match_operand:SF 1 "register_operand" ""))
(set (match_operand:SF 2 "memory_operand" "")
- (match_operand:SF 3 "register_operand" "fr"))]
+ (match_operand:SF 3 "register_operand" ""))]
"registers_ok_for_ldd_peep (operands[1], operands[3])
&& ! MEM_VOLATILE_P (operands[0])
&& ! MEM_VOLATILE_P (operands[2])
- && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
- "std\\t%1, %0")
+ && mems_ok_for_ldd_peep (operands[0], operands[2])"
+ [(set (match_dup 0)
+ (match_dup 1))]
+ "operands[0] = change_address (operands[0], DFmode, NULL);
+ operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
-(define_peephole
- [(set (match_operand:SI 0 "register_operand" "=rf")
+(define_peephole2
+ [(set (match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "memory_operand" ""))
- (set (match_operand:SI 2 "register_operand" "=rf")
+ (set (match_operand:SI 2 "register_operand" "")
(match_operand:SI 3 "memory_operand" ""))]
"registers_ok_for_ldd_peep (operands[2], operands[0])
&& ! MEM_VOLATILE_P (operands[3])
&& ! MEM_VOLATILE_P (operands[1])
- && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
- "ldd\\t%3, %2")
+ && mems_ok_for_ldd_peep (operands[3], operands[1])"
+ [(set (match_dup 2)
+ (match_dup 3))]
+ "operands[3] = change_address (operands[3], DImode, NULL);
+ operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
-(define_peephole
+(define_peephole2
[(set (match_operand:SI 0 "memory_operand" "")
- (match_operand:SI 1 "register_operand" "rf"))
+ (match_operand:SI 1 "register_operand" ""))
(set (match_operand:SI 2 "memory_operand" "")
- (match_operand:SI 3 "register_operand" "rf"))]
+ (match_operand:SI 3 "register_operand" ""))]
"registers_ok_for_ldd_peep (operands[3], operands[1])
&& ! MEM_VOLATILE_P (operands[2])
&& ! MEM_VOLATILE_P (operands[0])
- && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
- "std\\t%3, %2")
+ && mems_ok_for_ldd_peep (operands[2], operands[0])"
+ [(set (match_dup 2)
+ (match_dup 3))]
+ "operands[2] = change_address (operands[2], DImode, NULL);
+ operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
+ ")
-(define_peephole
- [(set (match_operand:SF 0 "register_operand" "=fr")
+(define_peephole2
+ [(set (match_operand:SF 0 "register_operand" "")
(match_operand:SF 1 "memory_operand" ""))
- (set (match_operand:SF 2 "register_operand" "=fr")
+ (set (match_operand:SF 2 "register_operand" "")
(match_operand:SF 3 "memory_operand" ""))]
"registers_ok_for_ldd_peep (operands[2], operands[0])
&& ! MEM_VOLATILE_P (operands[3])
&& ! MEM_VOLATILE_P (operands[1])
- && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
- "ldd\\t%3, %2")
+ && mems_ok_for_ldd_peep (operands[3], operands[1])"
+ [(set (match_dup 2)
+ (match_dup 3))]
+ "operands[3] = change_address (operands[3], DFmode, NULL);
+ operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
-(define_peephole
+(define_peephole2
[(set (match_operand:SF 0 "memory_operand" "")
- (match_operand:SF 1 "register_operand" "fr"))
+ (match_operand:SF 1 "register_operand" ""))
(set (match_operand:SF 2 "memory_operand" "")
- (match_operand:SF 3 "register_operand" "fr"))]
+ (match_operand:SF 3 "register_operand" ""))]
"registers_ok_for_ldd_peep (operands[3], operands[1])
&& ! MEM_VOLATILE_P (operands[2])
&& ! MEM_VOLATILE_P (operands[0])
- && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
- "std\\t%3, %2")
+ && mems_ok_for_ldd_peep (operands[2], operands[0])"
+ [(set (match_dup 2)
+ (match_dup 3))]
+ "operands[2] = change_address (operands[2], DFmode, NULL);
+ operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
;; Optimize the case of following a reg-reg move with a test
;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
;; This can result from a float to fix conversion.
-(define_peephole
- [(set (match_operand:SI 0 "register_operand" "=r")
- (match_operand:SI 1 "register_operand" "r"))
+(define_peephole2
+ [(set (match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "register_operand" ""))
(set (reg:CC 100)
- (compare:CC (match_operand:SI 2 "register_operand" "r")
+ (compare:CC (match_operand:SI 2 "register_operand" "")
(const_int 0)))]
"(rtx_equal_p (operands[2], operands[0])
|| rtx_equal_p (operands[2], operands[1]))
- && ! FP_REG_P (operands[0])
- && ! FP_REG_P (operands[1])"
- "orcc\\t%1, 0, %0")
+ && ! SPARC_FP_REG_P (REGNO (operands[0]))
+ && ! SPARC_FP_REG_P (REGNO (operands[1]))"
+ [(parallel [(set (match_dup 0) (match_dup 1))
+ (set (reg:CC 100)
+ (compare:CC (match_dup 1) (const_int 0)))])]
+ "")
-(define_peephole
- [(set (match_operand:DI 0 "register_operand" "=r")
- (match_operand:DI 1 "register_operand" "r"))
+(define_peephole2
+ [(set (match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "register_operand" ""))
(set (reg:CCX 100)
- (compare:CCX (match_operand:DI 2 "register_operand" "r")
+ (compare:CCX (match_operand:DI 2 "register_operand" "")
(const_int 0)))]
"TARGET_ARCH64
&& (rtx_equal_p (operands[2], operands[0])
|| rtx_equal_p (operands[2], operands[1]))
- && ! FP_REG_P (operands[0])
- && ! FP_REG_P (operands[1])"
- "orcc\\t%1, 0, %0")
+ && ! SPARC_FP_REG_P (REGNO (operands[0]))
+ && ! SPARC_FP_REG_P (REGNO (operands[1]))"
+ [(parallel [(set (match_dup 0) (match_dup 1))
+ (set (reg:CCX 100)
+ (compare:CC (match_dup 1) (const_int 0)))])]
+ "")
;; Return peepholes. First the "normal" ones.
;; These are necessary to catch insns ending up in the epilogue delay list.