From d1812381bc58bb06b4dd44e38e2d1fe63c767d76 Mon Sep 17 00:00:00 2001 From: danglin Date: Thu, 1 Jul 2004 02:24:56 +0000 Subject: [PATCH] * pa-protos.h (prefetch_operand): Add prototype. * pa.c (prefetch_operand): New function. * pa.h (prefetch_operand): Add to PREDICATE_CODES. * pa.md (prefetch, prefetch_32, prefetch_64): New prefetch patterns. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@83950 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 7 +++ gcc/config/pa/pa-protos.h | 1 + gcc/config/pa/pa.c | 21 +++++++++ gcc/config/pa/pa.h | 1 + gcc/config/pa/pa.md | 118 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 148 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8d63cd7a2a9..c1a19dda5b4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2004-06-30 John David Anglin + + * pa-protos.h (prefetch_operand): Add prototype. + * pa.c (prefetch_operand): New function. + * pa.h (prefetch_operand): Add to PREDICATE_CODES. + * pa.md (prefetch, prefetch_32, prefetch_64): New prefetch patterns. + 2004-06-30 Richard Henderson * function.h (struct function): Remove x_whole_function_mode_p. diff --git a/gcc/config/pa/pa-protos.h b/gcc/config/pa/pa-protos.h index 5bc5a6b653a..cfe07c7b248 100644 --- a/gcc/config/pa/pa-protos.h +++ b/gcc/config/pa/pa-protos.h @@ -80,6 +80,7 @@ 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 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 3aee1adecbd..9ece6dd9532 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -617,6 +617,27 @@ move_src_operand (rtx op, enum machine_mode mode) return memory_address_p (mode, XEXP (op, 0)); } +/* Accept anything that can be used as the source operand for a prefetch + instruction. */ +int +prefetch_operand (rtx op, enum machine_mode mode) +{ + if (GET_CODE (op) != MEM) + 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))) + return 0; + + return memory_address_p (mode, XEXP (op, 0)); +} + /* Accept REG and any CONST_INT that can be moved in one instruction into a general register. */ int diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h index 5edc151d26d..1b6a2c8f2f0 100644 --- a/gcc/config/pa/pa.h +++ b/gcc/config/pa/pa.h @@ -2023,6 +2023,7 @@ do { \ CONST_DOUBLE}}, \ {"move_dest_operand", {SUBREG, REG, MEM}}, \ {"move_src_operand", {SUBREG, REG, CONST_INT, MEM}}, \ + {"prefetch_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 23e5d513078..25389966c8e 100644 --- a/gcc/config/pa/pa.md +++ b/gcc/config/pa/pa.md @@ -9352,3 +9352,121 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" } DONE; }") + +(define_expand "prefetch" + [(match_operand 0 "address_operand" "") + (match_operand 1 "const_int_operand" "") + (match_operand 2 "const_int_operand" "")] + "TARGET_PA_20" +{ + /* 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 (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; +}) + +(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" +{ + /* 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] = { + { + { + "ldw,sl RT'%A0,%%r0", + "ldw RT'%A0,%%r0", + }, + { + "ldd,sl 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", + } + } + }; + 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 (); + + return instr [which_alternative][read_or_write][locality == 0 ? 0 : 1]; +} + [(set_attr "type" "load") + (set_attr "length" "4")]) + +(define_insn "prefetch_32" + [(prefetch (match_operand:SI 0 "prefetch_operand" "A,RQ") + (match_operand:SI 1 "const_int_operand" "n,n") + (match_operand:SI 2 "const_int_operand" "n,n"))] + "TARGET_PA_20" +{ + /* 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] = { + { + { + "ldw,sl RT'%A0,%%r0", + "ldw RT'%A0,%%r0", + }, + { + "ldd,sl 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", + } + } + }; + 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 (); + + return instr [which_alternative][read_or_write][locality == 0 ? 0 : 1]; +} + [(set_attr "type" "load") + (set_attr "length" "4")]) -- 2.11.4.GIT