[committed] Fix builtin prefetch on PA

Submitted by John David Anglin on July 3, 2010, 11:02 p.m.

Details

Message ID 20100703230212.9D697505C@hiauly1.hia.nrc.ca
State New
Headers show

Commit Message

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 hide | download patch | download mbox

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")