Commit 2aad5d68 by Dan Nicolaescu Committed by Richard Henderson

sparc.c (mems_ok_for_ldd_peep): Rename from addrs_ok_for_ldd_peep_withmem...

        * 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.

From-SVN: r48059
parent 4023fb28
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> 2001-12-15 Ulrich Weigand <uweigand@de.ibm.com>
* s390.md (prologue, epilogue, *return_si, *return_di): New. * s390.md (prologue, epilogue, *return_si, *return_di): New.
......
...@@ -92,7 +92,7 @@ extern char *output_v9branch PARAMS ((rtx, int, int, int, int, int, rtx)); ...@@ -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 emit_v9_brxx_insn PARAMS ((enum rtx_code, rtx, rtx));
extern void output_double_int PARAMS ((FILE *, rtx)); extern void output_double_int PARAMS ((FILE *, rtx));
extern void print_operand PARAMS ((FILE *, rtx, int)); 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_double_4096_operand PARAMS ((rtx, enum machine_mode));
extern int arith_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)); extern int zero_operand PARAMS ((rtx, enum machine_mode));
......
...@@ -5646,27 +5646,28 @@ registers_ok_for_ldd_peep (reg1, reg2) ...@@ -5646,27 +5646,28 @@ registers_ok_for_ldd_peep (reg1, reg2)
return (REGNO (reg1) == REGNO (reg2) - 1); return (REGNO (reg1) == REGNO (reg2) - 1);
} }
/* Return 1 if addr1 and addr2 are suitable for use in an ldd or /* Return 1 if the addresses in mem1 and mem2 are suitable for use in
std insn. an ldd or std insn.
This can only happen when addr1 and addr2 are consecutive memory This can only happen when addr1 and addr2, the addresses in mem1
locations (addr1 + 4 == addr2). addr1 must also be aligned on a and mem2, are consecutive memory locations (addr1 + 4 == addr2).
64 bit boundary (addr1 % 8 == 0). addr1 must also be aligned on a 64-bit boundary. */
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. */
int int
addrs_ok_for_ldd_peep (addr1, addr2) mems_ok_for_ldd_peep (mem1, mem2)
rtx addr1, addr2; rtx mem1, mem2;
{ {
rtx addr1, addr2;
unsigned int reg1; unsigned int reg1;
int offset1; 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. */ /* Extract a register number and offset (if used) from the first addr. */
if (GET_CODE (addr1) == PLUS) if (GET_CODE (addr1) == PLUS)
{ {
...@@ -5699,11 +5700,6 @@ addrs_ok_for_ldd_peep (addr1, addr2) ...@@ -5699,11 +5700,6 @@ addrs_ok_for_ldd_peep (addr1, addr2)
|| GET_CODE (XEXP (addr2, 1)) != CONST_INT) || GET_CODE (XEXP (addr2, 1)) != CONST_INT)
return 0; 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))) if (reg1 != REGNO (XEXP (addr2, 0)))
return 0; return 0;
......
...@@ -2383,7 +2383,7 @@ ...@@ -2383,7 +2383,7 @@
The const zero case is more complex, on v9 The const zero case is more complex, on v9
we can always perform it. */ we can always perform it. */
if (register_operand (operands[1], DImode) if (register_operand (operands[1], DImode)
|| (TARGET_ARCH64 || (TARGET_V9
&& (operands[1] == const0_rtx))) && (operands[1] == const0_rtx)))
goto movdi_is_ok; goto movdi_is_ok;
...@@ -2444,6 +2444,13 @@ ...@@ -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. ;; Be careful, fmovd does not exist when !arch64.
;; We match MEM moves directly when we have correct even ;; We match MEM moves directly when we have correct even
;; numbered registers, but fall into splits otherwise. ;; numbered registers, but fall into splits otherwise.
...@@ -7212,6 +7219,26 @@ ...@@ -7212,6 +7219,26 @@
"TARGET_ARCH64" "TARGET_ARCH64"
"xnorcc\\t%%g0, %1, %0" "xnorcc\\t%%g0, %1, %0"
[(set_attr "type" "compare")]) [(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. ;; Floating point arithmetic instructions.
...@@ -8871,7 +8898,7 @@ ...@@ -8871,7 +8898,7 @@
;; The conditions in which we do this are very restricted and are ;; The conditions in which we do this are very restricted and are
;; explained in the code for {registers,memory}_ok_for_ldd functions. ;; explained in the code for {registers,memory}_ok_for_ldd functions.
(define_peephole (define_peephole2
[(set (match_operand:SI 0 "memory_operand" "") [(set (match_operand:SI 0 "memory_operand" "")
(const_int 0)) (const_int 0))
(set (match_operand:SI 1 "memory_operand" "") (set (match_operand:SI 1 "memory_operand" "")
...@@ -8879,10 +8906,12 @@ ...@@ -8879,10 +8906,12 @@
"TARGET_V9 "TARGET_V9
&& ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[0])
&& ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[1])
&& addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[1], 0))" && mems_ok_for_ldd_peep (operands[0], operands[1])"
"stx\\t%%g0, %0") [(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" "") [(set (match_operand:SI 0 "memory_operand" "")
(const_int 0)) (const_int 0))
(set (match_operand:SI 1 "memory_operand" "") (set (match_operand:SI 1 "memory_operand" "")
...@@ -8890,125 +8919,158 @@ ...@@ -8890,125 +8919,158 @@
"TARGET_V9 "TARGET_V9
&& ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[0])
&& ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[1])
&& addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[0], 0))" && mems_ok_for_ldd_peep (operands[1], operands[0])"
"stx\\t%%g0, %1") [(set (match_dup 1)
(const_int 0))]
"operands[1] = change_address (operands[1], DImode, NULL);")
(define_peephole (define_peephole2
[(set (match_operand:SI 0 "register_operand" "=rf") [(set (match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "memory_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" ""))] (match_operand:SI 3 "memory_operand" ""))]
"registers_ok_for_ldd_peep (operands[0], operands[2]) "registers_ok_for_ldd_peep (operands[0], operands[2])
&& ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[1])
&& ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[3])
&& addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))" && mems_ok_for_ldd_peep (operands[1], operands[3])"
"ldd\\t%1, %0") [(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" "") [(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" "") (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]) "registers_ok_for_ldd_peep (operands[1], operands[3])
&& ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[0])
&& ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[2])
&& addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))" && mems_ok_for_ldd_peep (operands[0], operands[2])"
"std\\t%1, %0") [(set (match_dup 0)
(match_dup 1))]
(define_peephole "operands[0] = change_address (operands[0], DImode, NULL);
[(set (match_operand:SF 0 "register_operand" "=fr") operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
(define_peephole2
[(set (match_operand:SF 0 "register_operand" "")
(match_operand:SF 1 "memory_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" ""))] (match_operand:SF 3 "memory_operand" ""))]
"registers_ok_for_ldd_peep (operands[0], operands[2]) "registers_ok_for_ldd_peep (operands[0], operands[2])
&& ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[1])
&& ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[3])
&& addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))" && mems_ok_for_ldd_peep (operands[1], operands[3])"
"ldd\\t%1, %0") [(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" "") [(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" "") (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]) "registers_ok_for_ldd_peep (operands[1], operands[3])
&& ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[0])
&& ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[2])
&& addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))" && mems_ok_for_ldd_peep (operands[0], operands[2])"
"std\\t%1, %0") [(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 (define_peephole2
[(set (match_operand:SI 0 "register_operand" "=rf") [(set (match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "memory_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" ""))] (match_operand:SI 3 "memory_operand" ""))]
"registers_ok_for_ldd_peep (operands[2], operands[0]) "registers_ok_for_ldd_peep (operands[2], operands[0])
&& ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[3])
&& ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[1])
&& addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))" && mems_ok_for_ldd_peep (operands[3], operands[1])"
"ldd\\t%3, %2") [(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" "") [(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" "") (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]) "registers_ok_for_ldd_peep (operands[3], operands[1])
&& ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[2])
&& ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[0])
&& addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))" && mems_ok_for_ldd_peep (operands[2], operands[0])"
"std\\t%3, %2") [(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 (define_peephole2
[(set (match_operand:SF 0 "register_operand" "=fr") [(set (match_operand:SF 0 "register_operand" "")
(match_operand:SF 1 "memory_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" ""))] (match_operand:SF 3 "memory_operand" ""))]
"registers_ok_for_ldd_peep (operands[2], operands[0]) "registers_ok_for_ldd_peep (operands[2], operands[0])
&& ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[3])
&& ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[1])
&& addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))" && mems_ok_for_ldd_peep (operands[3], operands[1])"
"ldd\\t%3, %2") [(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" "") [(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" "") (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]) "registers_ok_for_ldd_peep (operands[3], operands[1])
&& ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[2])
&& ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[0])
&& addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))" && mems_ok_for_ldd_peep (operands[2], operands[0])"
"std\\t%3, %2") [(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 ;; 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. ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
;; This can result from a float to fix conversion. ;; This can result from a float to fix conversion.
(define_peephole (define_peephole2
[(set (match_operand:SI 0 "register_operand" "=r") [(set (match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "register_operand" "r")) (match_operand:SI 1 "register_operand" ""))
(set (reg:CC 100) (set (reg:CC 100)
(compare:CC (match_operand:SI 2 "register_operand" "r") (compare:CC (match_operand:SI 2 "register_operand" "")
(const_int 0)))] (const_int 0)))]
"(rtx_equal_p (operands[2], operands[0]) "(rtx_equal_p (operands[2], operands[0])
|| rtx_equal_p (operands[2], operands[1])) || rtx_equal_p (operands[2], operands[1]))
&& ! FP_REG_P (operands[0]) && ! SPARC_FP_REG_P (REGNO (operands[0]))
&& ! FP_REG_P (operands[1])" && ! SPARC_FP_REG_P (REGNO (operands[1]))"
"orcc\\t%1, 0, %0") [(parallel [(set (match_dup 0) (match_dup 1))
(set (reg:CC 100)
(compare:CC (match_dup 1) (const_int 0)))])]
"")
(define_peephole (define_peephole2
[(set (match_operand:DI 0 "register_operand" "=r") [(set (match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "register_operand" "r")) (match_operand:DI 1 "register_operand" ""))
(set (reg:CCX 100) (set (reg:CCX 100)
(compare:CCX (match_operand:DI 2 "register_operand" "r") (compare:CCX (match_operand:DI 2 "register_operand" "")
(const_int 0)))] (const_int 0)))]
"TARGET_ARCH64 "TARGET_ARCH64
&& (rtx_equal_p (operands[2], operands[0]) && (rtx_equal_p (operands[2], operands[0])
|| rtx_equal_p (operands[2], operands[1])) || rtx_equal_p (operands[2], operands[1]))
&& ! FP_REG_P (operands[0]) && ! SPARC_FP_REG_P (REGNO (operands[0]))
&& ! FP_REG_P (operands[1])" && ! SPARC_FP_REG_P (REGNO (operands[1]))"
"orcc\\t%1, 0, %0") [(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. ;; Return peepholes. First the "normal" ones.
;; These are necessary to catch insns ending up in the epilogue delay list. ;; These are necessary to catch insns ending up in the epilogue delay list.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment