From ee807d9cd23cc9337012a0c4bf286faa04ed51da Mon Sep 17 00:00:00 2001 From: danglin Date: Sat, 15 Jan 2005 18:57:29 +0000 Subject: [PATCH] * pa-protos.h (prefetch_operand): Delete. (prefetch_cc_operand, prefetch_nocc_operand): New declations. * pa.c (prefetch_operand): Delete. (prefetch_cc_operand, prefetch_nocc_operand): New functions. * pa.h (EXTRA_CONSTRAINT): Add `W' constraint. (PREDICATE_CODES): Delete prefetch_operand. Add prefetch_cc_operand and prefetch_nocc_operand. * pa.md (prefetch): Rework to avoid reload problems handling short displacements when a cache control completer needs to be provided. (prefetch_32, prefetch_64): Delete. (prefetch_cc, prefetch_nocc): New patterns. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@93702 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 14 +++++ gcc/config/pa/pa-protos.h | 3 +- gcc/config/pa/pa.c | 47 ++++++++++++-- gcc/config/pa/pa.h | 16 ++++- gcc/config/pa/pa.md | 156 ++++++++++++++++------------------------------ 5 files changed, 125 insertions(+), 111 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 48a6a76a2d4..81cfd921c03 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2005-01-15 John David Anglin + + * pa-protos.h (prefetch_operand): Delete. + (prefetch_cc_operand, prefetch_nocc_operand): New declations. + * pa.c (prefetch_operand): Delete. + (prefetch_cc_operand, prefetch_nocc_operand): New functions. + * pa.h (EXTRA_CONSTRAINT): Add `W' constraint. + (PREDICATE_CODES): Delete prefetch_operand. Add prefetch_cc_operand + and prefetch_nocc_operand. + * pa.md (prefetch): Rework to avoid reload problems handling short + displacements when a cache control completer needs to be provided. + (prefetch_32, prefetch_64): Delete. + (prefetch_cc, prefetch_nocc): New patterns. + 2005-01-15 David Edelsohn * config/rs6000/aix52.h (CPLUSPLUS_CPP_SPEC): Revert previous change. diff --git a/gcc/config/pa/pa-protos.h b/gcc/config/pa/pa-protos.h index a5bc0240b1e..bb49ca3b688 100644 --- a/gcc/config/pa/pa-protos.h +++ b/gcc/config/pa/pa-protos.h @@ -79,7 +79,8 @@ extern int arith_operand (rtx, enum machine_mode); extern int read_only_operand (rtx, enum machine_mode); extern int move_dest_operand (rtx, enum machine_mode); extern int move_src_operand (rtx, enum machine_mode); -extern int prefetch_operand (rtx, enum machine_mode); +extern int prefetch_cc_operand (rtx, enum machine_mode); +extern int prefetch_nocc_operand (rtx, enum machine_mode); extern int and_operand (rtx, enum machine_mode); extern int ior_operand (rtx, enum machine_mode); extern int arith32_operand (rtx, enum machine_mode); diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index 58642d10f28..7d0dff5ccf0 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -752,24 +752,59 @@ move_src_operand (rtx op, enum machine_mode mode) } /* Accept anything that can be used as the source operand for a prefetch - instruction. */ + instruction with a cache-control completer. */ int -prefetch_operand (rtx op, enum machine_mode mode) +prefetch_cc_operand (rtx op, enum machine_mode mode) { if (GET_CODE (op) != MEM) return 0; + op = XEXP (op, 0); + + /* We must reject virtual registers as we don't allow REG+D. */ + if (op == virtual_incoming_args_rtx + || op == virtual_stack_vars_rtx + || op == virtual_stack_dynamic_rtx + || op == virtual_outgoing_args_rtx + || op == virtual_cfa_rtx) + return 0; + + if (!REG_P (op) && !IS_INDEX_ADDR_P (op)) + return 0; + /* Until problems with management of the REG_POINTER flag are resolved, we need to delay creating prefetch insns with unscaled indexed addresses until CSE is not expected. */ if (!TARGET_NO_SPACE_REGS && !cse_not_expected - && GET_CODE (XEXP (op, 0)) == PLUS - && REG_P (XEXP (XEXP (op, 0), 0)) - && REG_P (XEXP (XEXP (op, 0), 1))) + && GET_CODE (op) == PLUS + && REG_P (XEXP (op, 0))) return 0; - return memory_address_p (mode, XEXP (op, 0)); + return memory_address_p (mode, op); +} + +/* Accept anything that can be used as the source operand for a prefetch + instruction with no cache-control completer. */ +int +prefetch_nocc_operand (rtx op, enum machine_mode mode) +{ + if (GET_CODE (op) != MEM) + return 0; + + op = XEXP (op, 0); + + /* Until problems with management of the REG_POINTER flag are resolved, + we need to delay creating prefetch insns with unscaled indexed addresses + until CSE is not expected. */ + if (!TARGET_NO_SPACE_REGS + && !cse_not_expected + && GET_CODE (op) == PLUS + && REG_P (XEXP (op, 0)) + && REG_P (XEXP (op, 1))) + return 0; + + return memory_address_p (mode, op); } /* Accept REG and any CONST_INT that can be moved in one instruction into a diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h index 450775910ef..61a33258e2c 100644 --- a/gcc/config/pa/pa.h +++ b/gcc/config/pa/pa.h @@ -1296,7 +1296,12 @@ extern int may_call_alloca; `T' is for floating-point loads and stores. - `U' is the constant 63. */ + `U' is the constant 63. + + `W' is a register indirect memory operand. We could allow short + displacements but GO_IF_LEGITIMATE_ADDRESS can't tell when a + long displacement is valid. This is only used for prefetch + instructions with the `sl' completer. */ #define EXTRA_CONSTRAINT(OP, C) \ ((C) == 'Q' ? \ @@ -1307,6 +1312,10 @@ extern int may_call_alloca; && !symbolic_memory_operand (OP, VOIDmode) \ && !IS_LO_SUM_DLT_ADDR_P (XEXP (OP, 0)) \ && !IS_INDEX_ADDR_P (XEXP (OP, 0)))) \ + : ((C) == 'W' ? \ + (GET_CODE (OP) == MEM \ + && REG_P (XEXP (OP, 0)) \ + && REG_OK_FOR_BASE_P (XEXP (OP, 0))) \ : ((C) == 'A' ? \ (GET_CODE (OP) == MEM \ && IS_LO_SUM_DLT_ADDR_P (XEXP (OP, 0))) \ @@ -1336,7 +1345,7 @@ extern int may_call_alloca; : ((C) == 'S' ? \ (GET_CODE (OP) == CONST_INT && INTVAL (OP) == 31) \ : ((C) == 'U' ? \ - (GET_CODE (OP) == CONST_INT && INTVAL (OP) == 63) : 0)))))) + (GET_CODE (OP) == CONST_INT && INTVAL (OP) == 63) : 0))))))) /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx @@ -2102,7 +2111,8 @@ forget_section (void) \ CONST_DOUBLE}}, \ {"move_dest_operand", {SUBREG, REG, MEM}}, \ {"move_src_operand", {SUBREG, REG, CONST_INT, MEM}}, \ - {"prefetch_operand", {MEM}}, \ + {"prefetch_cc_operand", {MEM}}, \ + {"prefetch_nocc_operand", {MEM}}, \ {"reg_or_cint_move_operand", {SUBREG, REG, CONST_INT}}, \ {"pic_label_operand", {LABEL_REF, CONST}}, \ {"fp_reg_operand", {REG}}, \ diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md index aa6d1ac864b..c79c982a53e 100644 --- a/gcc/config/pa/pa.md +++ b/gcc/config/pa/pa.md @@ -9283,134 +9283,88 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" (match_operand 2 "const_int_operand" "")] "TARGET_PA_20" { - /* The PA 2.0 prefetch instructions only support short displacements - when a cache control completer needs to be supplied. Thus, we - can't use LO_SUM DLT addresses with the spatial locality completer. */ - if (operands[2] == const0_rtx && IS_LO_SUM_DLT_ADDR_P (operands[0])) - FAIL; + int locality = INTVAL (operands[2]); - /* We change operand0 to a MEM as we don't have the infrastructure to - output all the supported address modes for ldw/ldd but we do have - it for MEMs. */ - operands[0] = gen_rtx_MEM (Pmode, operands[0]); - - if (!TARGET_NO_SPACE_REGS - && !cse_not_expected - && GET_CODE (XEXP (operands[0], 0)) == PLUS - && REG_P (XEXP (XEXP (operands[0], 0), 0)) - && REG_P (XEXP (XEXP (operands[0], 0), 1))) - operands[0] - = replace_equiv_address (operands[0], - copy_to_mode_reg (Pmode, - XEXP (operands[0], 0))); + if (locality < 0 || locality > 3) + abort (); - if (TARGET_64BIT) - emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2])); - else - emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2])); - DONE; -}) + /* Change operand[0] to a MEM as we don't have the infrastructure + to output all the supported address modes for ldw/ldd when we use + the address directly. However, we do have it for MEMs. */ + operands[0] = gen_rtx_MEM (QImode, operands[0]); -(define_insn "prefetch_64" - [(prefetch (match_operand:DI 0 "prefetch_operand" "A,RQ") - (match_operand:DI 1 "const_int_operand" "n,n") - (match_operand:DI 2 "const_int_operand" "n,n"))] - "TARGET_64BIT - && (operands[2] != const0_rtx - || GET_CODE (XEXP (operands[0], 0)) != PLUS - || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != CONST_INT - || INT_5_BITS (XEXP (XEXP (operands[0], 0), 1)))" -{ - /* The SL completor indicates good spatial locality but poor temporal - locality. The ldw instruction with a target of general register 0 - prefetches a cache line for a read. The ldd instruction prefetches - a cache line for a write. */ - static const char * const instr[2][2][2] = { + /* If the address isn't valid for the prefetch, replace it. */ + if (locality) { - { - "", - "ldw RT'%A0,%%r0", - }, - { - "", - "ldd RT'%A0,%%r0", - }, - }, + if (!prefetch_nocc_operand (operands[0], QImode)) + operands[0] + = replace_equiv_address (operands[0], + copy_to_mode_reg (Pmode, + XEXP (operands[0], 0))); + emit_insn (gen_prefetch_nocc (operands[0], operands[1], operands[2])); + } + else { - { - "ldw%M0,sl %0,%%r0", - "ldw%M0 %0,%%r0", - }, - { - "ldd%M0,sl %0,%%r0", - "ldd%M0 %0,%%r0", - } + if (!prefetch_cc_operand (operands[0], QImode)) + operands[0] + = replace_equiv_address (operands[0], + copy_to_mode_reg (Pmode, + XEXP (operands[0], 0))); + emit_insn (gen_prefetch_cc (operands[0], operands[1], operands[2])); } + DONE; +}) + +(define_insn "prefetch_cc" + [(prefetch (match_operand:QI 0 "prefetch_cc_operand" "RW") + (match_operand:SI 1 "const_int_operand" "n") + (match_operand:SI 2 "const_int_operand" "n"))] + "TARGET_PA_20 && operands[2] == const0_rtx" +{ + /* The SL cache-control completor indicates good spatial locality but + poor temporal locality. The ldw instruction with a target of general + register 0 prefetches a cache line for a read. The ldd instruction + prefetches a cache line for a write. */ + static const char * const instr[2] = { + "ldw%M0,sl %0,%%r0", + "ldd%M0,sl %0,%%r0" }; int read_or_write = INTVAL (operands[1]); - int locality = INTVAL (operands[2]); - if ((which_alternative != 0 && which_alternative != 1) - || (read_or_write != 0 && read_or_write != 1) - || (locality < 0 || locality > 3)) + if (read_or_write < 0 || read_or_write > 1) abort (); - if (which_alternative == 0 && locality == 0) - abort (); - - return instr [which_alternative][read_or_write][locality == 0 ? 0 : 1]; + return instr [read_or_write]; } [(set_attr "type" "load") (set_attr "length" "4")]) -(define_insn "prefetch_32" - [(prefetch (match_operand:SI 0 "prefetch_operand" "A,RQ") +(define_insn "prefetch_nocc" + [(prefetch (match_operand:QI 0 "prefetch_nocc_operand" "A,RQ") (match_operand:SI 1 "const_int_operand" "n,n") (match_operand:SI 2 "const_int_operand" "n,n"))] - "TARGET_PA_20 - && (operands[2] != const0_rtx - || GET_CODE (XEXP (operands[0], 0)) != PLUS - || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != CONST_INT - || INT_5_BITS (XEXP (XEXP (operands[0], 0), 1)))" -{ - /* The SL completor indicates good spatial locality but poor temporal - locality. The ldw instruction with a target of general register 0 - prefetches a cache line for a read. The ldd instruction prefetches - a cache line for a write. */ - static const char * const instr[2][2][2] = { + "TARGET_PA_20 && operands[2] != const0_rtx" +{ + /* The ldw instruction with a target of general register 0 prefetches + a cache line for a read. The ldd instruction prefetches a cache line + for a write. */ + static const char * const instr[2][2] = { { - { - "", - "ldw RT'%A0,%%r0", - }, - { - "", - "ldd RT'%A0,%%r0", - }, + "ldw RT'%A0,%%r0", + "ldd RT'%A0,%%r0", }, { - { - "ldw%M0,sl %0,%%r0", - "ldw%M0 %0,%%r0", - }, - { - "ldd%M0,sl %0,%%r0", - "ldd%M0 %0,%%r0", - } + "ldw%M0 %0,%%r0", + "ldd%M0 %0,%%r0", } }; int read_or_write = INTVAL (operands[1]); - int locality = INTVAL (operands[2]); if ((which_alternative != 0 && which_alternative != 1) - || (read_or_write != 0 && read_or_write != 1) - || (locality < 0 || locality > 3)) - abort (); - - if (which_alternative == 0 && locality == 0) + || (read_or_write < 0 || read_or_write > 1)) abort (); - return instr [which_alternative][read_or_write][locality == 0 ? 0 : 1]; + return instr [which_alternative][read_or_write]; } [(set_attr "type" "load") (set_attr "length" "4")]) -- 2.11.0