diff options
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/config/sparc/sparc-protos.h | 2 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.c | 36 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.md | 186 |
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. |