Patchwork [committed] Fix builtin prefetch on PA

login
register
mail settings
Submitter John David Anglin
Date July 3, 2010, 11:02 p.m.
Message ID <20100703230212.9D697505C@hiauly1.hia.nrc.ca>
Download mbox | patch
Permalink /patch/57825/
State New
Headers show

Comments

John David Anglin - July 3, 2010, 11:02 p.m.
This fixes target/44597.  I don't believe it's possible to support
all the available memory modes for the PA 2.0 prefetch instructions
without support for secondary reloads.

This patch simplifies the prefetch support to just use the register indirect
mode.  Hopefully, reload can handle this.

Tested on hppa64-hp-hpux11.11 and hppa2.0w-hp-hpux11.11 with no observed
regressions.  Committed to trunk, 4.5, 4.4 and 4.3.

Dave

Patch

Index: config/pa/predicates.md
===================================================================
--- config/pa/predicates.md	(revision 161653)
+++ config/pa/predicates.md	(working copy)
@@ -240,64 +240,6 @@ 
   return memory_address_p (mode, XEXP (op, 0));
 })
 
-;; Accept anything that can be used as the source operand for a
-;; prefetch instruction with a cache-control completer.
-
-(define_predicate "prefetch_cc_operand"
-  (match_code "mem")
-{
-  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 (op) == PLUS
-      && REG_P (XEXP (op, 0)))
-    return 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.
-
-(define_predicate "prefetch_nocc_operand"
-  (match_code "mem")
-{
-  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 general register.
 
Index: config/pa/pa.md
===================================================================
--- config/pa/pa.md	(revision 161653)
+++ config/pa/pa.md	(working copy)
@@ -9544,90 +9544,39 @@ 
    (match_operand 2 "const_int_operand" "")]
   "TARGET_PA_20"
 {
-  int locality = INTVAL (operands[2]);
-
-  gcc_assert (locality >= 0 && locality <= 3);
-
-  /* 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]);
-
-  /* If the address isn't valid for the prefetch, replace it.  */
-  if (locality)
-    {
-      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
-    {
-      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]));
-    }
+  operands[0] = copy_addr_to_reg (operands[0]);
+  emit_insn (gen_prefetch_20 (operands[0], operands[1], operands[2]));
   DONE;
 })
 
-(define_insn "prefetch_cc"
-  [(prefetch (match_operand:QI 0 "prefetch_cc_operand" "RW")
+(define_insn "prefetch_20"
+  [(prefetch (match_operand 0 "pmode_register_operand" "r")
 	     (match_operand:SI 1 "const_int_operand" "n")
 	     (match_operand:SI 2 "const_int_operand" "n"))]
-  "TARGET_PA_20 && operands[2] == const0_rtx"
+  "TARGET_PA_20"
 {
-  /* The SL cache-control completor indicates good spatial locality but
+  /* The SL cache-control completer 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]);
-
-  gcc_assert (read_or_write >= 0 && read_or_write <= 1);
-
-  return instr [read_or_write];
-}
-  [(set_attr "type" "load")
-   (set_attr "length" "4")])
-
-(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"
-{
-  /* 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,sl 0(%0),%%r0",
+      "ldd,sl 0(%0),%%r0"
     },
     {
-      "ldw%M0 %0,%%r0",
-      "ldd%M0 %0,%%r0",
+      "ldw 0(%0),%%r0",
+      "ldd 0(%0),%%r0"
     }
   };
-  int read_or_write = INTVAL (operands[1]);
+  int read_or_write = INTVAL (operands[1]) == 0 ? 0 : 1;
+  int locality = INTVAL (operands[2]) == 0 ? 0 : 1;
 
-  gcc_assert (which_alternative == 0 || which_alternative == 1);
-  gcc_assert (read_or_write >= 0 && read_or_write <= 1);
-
-  return instr [which_alternative][read_or_write];
+  return instr [locality][read_or_write];
 }
   [(set_attr "type" "load")
    (set_attr "length" "4")])
 
-
 ;; TLS Support
 (define_insn "tgd_load"
  [(set (match_operand:SI 0 "register_operand" "=r")