From 1bbad4c651f823a0e39a69fec01206f557f625e1 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 28 Apr 2002 22:33:00 -0700 Subject: [PATCH] re PR target/6500 (Sparc.md's prefetch is buggy) 2002-04-28 David S. Miller PR target/6500 * config/sparc/sparc.md (prefetch): Emit properly for 32-bit vs. 64-bit TARGET_V9. Do not use prefetch page, use prefetch for several {reads,writes} instead. * config/sparc/sparc.h (PREFETCH_BLOCK, SIMULTANEOUS_PREFETCHES): Define. From-SVN: r52876 --- gcc/ChangeLog | 9 ++++++ gcc/config/sparc/sparc.h | 7 +++++ gcc/config/sparc/sparc.md | 61 ++++++++++++++++++++++++++++++++------- 3 files changed, 67 insertions(+), 10 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d8380e91590..130ce8ea472 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2002-04-28 David S. Miller + + PR target/6500 + * config/sparc/sparc.md (prefetch): Emit properly for 32-bit vs. + 64-bit TARGET_V9. Do not use prefetch page, use prefetch for + several {reads,writes} instead. + * config/sparc/sparc.h (PREFETCH_BLOCK, SIMULTANEOUS_PREFETCHES): + Define. + 2002-04-27 David S. Miller PR target/6494 diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 52644c62acd..d246c5a29df 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -2667,6 +2667,13 @@ do { \ case FLOAT: \ case FIX: \ return 19; + +#define PREFETCH_BLOCK \ + ((sparc_cpu == PROCESSOR_ULTRASPARC) ? 64 : 32) + +/* ??? UltraSPARC-III note: Can set this to 8 for ultra3. */ +#define SIMULTANEOUS_PREFETCHES \ + ((sparc_cpu == PROCESSOR_ULTRASPARC) ? 2 : 3) /* Control the assembler format that we output. */ diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index 2ceffeef118..65b390eaa62 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -9376,24 +9376,38 @@ && sparc_cpu != PROCESSOR_ULTRASPARC" "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7") -(define_insn "prefetch" +;; ??? UltraSPARC-III note: A memory operation loading into the floating point register +;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory +;; ??? operations. With DFA we might be able to model this, but it requires a lot of +;; ??? state. +(define_expand "prefetch" + [(match_operand 0 "address_operand" "") + (match_operand 1 "const_int_operand" "") + (match_operand 2 "const_int_operand" "")] + "TARGET_V9" + " +{ + if (TARGET_ARCH64) + 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 "address_operand" "p") (match_operand:DI 1 "const_int_operand" "n") (match_operand:DI 2 "const_int_operand" "n"))] - "TARGET_V9" + "" { - static const char * const prefetch_instr[2][4] = { + static const char * const prefetch_instr[2][2] = { { "prefetch\\t[%a0], 1", /* no locality: prefetch for one read */ - "prefetch\\t[%a0], 0", /* medium locality: prefetch for several reads */ - "prefetch\\t[%a0], 0", /* medium locality: prefetch for several reads */ - "prefetch\\t[%a0], 4", /* high locality: prefetch page */ + "prefetch\\t[%a0], 0", /* medium to high locality: prefetch for several reads */ }, { "prefetch\\t[%a0], 3", /* no locality: prefetch for one write */ - "prefetch\\t[%a0], 2", /* medium locality: prefetch for several writes */ - "prefetch\\t[%a0], 2", /* medium locality: prefetch for several writes */ - "prefetch\\t[%a0], 4", /* high locality: prefetch page */ + "prefetch\\t[%a0], 2", /* medium to high locality: prefetch for several writes */ } }; int read_or_write = INTVAL (operands[1]); @@ -9403,7 +9417,34 @@ abort (); if (locality < 0 || locality > 3) abort (); - return prefetch_instr [read_or_write][locality]; + return prefetch_instr [read_or_write][locality == 0 ? 0 : 1]; +} + [(set_attr "type" "load")]) + +(define_insn "prefetch_32" + [(prefetch (match_operand:SI 0 "address_operand" "p") + (match_operand:SI 1 "const_int_operand" "n") + (match_operand:SI 2 "const_int_operand" "n"))] + "" +{ + static const char * const prefetch_instr[2][2] = { + { + "prefetch\\t[%a0], 1", /* no locality: prefetch for one read */ + "prefetch\\t[%a0], 0", /* medium to high locality: prefetch for several reads */ + }, + { + "prefetch\\t[%a0], 3", /* no locality: prefetch for one write */ + "prefetch\\t[%a0], 2", /* medium to high locality: prefetch for several writes */ + } + }; + int read_or_write = INTVAL (operands[1]); + int locality = INTVAL (operands[2]); + + if (read_or_write != 0 && read_or_write != 1) + abort (); + if (locality < 0 || locality > 3) + abort (); + return prefetch_instr [read_or_write][locality == 0 ? 0 : 1]; } [(set_attr "type" "load")])