OSDN Git Service

2002-06-19 Eric Christopher <echristo@redhat.com>
authorechristo <echristo@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 19 Jun 2002 23:18:00 +0000 (23:18 +0000)
committerechristo <echristo@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 19 Jun 2002 23:18:00 +0000 (23:18 +0000)
* config/mips/mips.c (symbol_operand): New function.
(mips_emit_prefetch): Ditto.
* config/mips/mips-protos.h: Define.
* config/mips/mips.h (ISA_HAS_PREFETCH): Define.
(CONSTANT_ADDRESS_P): Adjust, use TARGET_GAS.
(LEGITIMIZE_ADDRESS): Ditto.
* config/mips/mips.md (prefetch, prefetch_si_address,
prefetch_si, prefetch_di_address, prefetch_di): New patterns.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@54805 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/mips/mips-protos.h
gcc/config/mips/mips.c
gcc/config/mips/mips.h
gcc/config/mips/mips.md

index 06731ef..326e0cd 100644 (file)
@@ -1,5 +1,16 @@
 2002-06-19  Eric Christopher  <echristo@redhat.com>
 
+       * config/mips/mips.c (symbol_operand): New function.
+       (mips_emit_prefetch): Ditto.
+       * config/mips/mips-protos.h: Define.
+       * config/mips/mips.h (ISA_HAS_PREFETCH): Define.
+       (CONSTANT_ADDRESS_P): Adjust, use TARGET_GAS.
+       (LEGITIMIZE_ADDRESS): Ditto.
+       * config/mips/mips.md (prefetch, prefetch_si_address,
+       prefetch_si, prefetch_di_address, prefetch_di): New patterns.
+
+2002-06-19  Eric Christopher  <echristo@redhat.com>
+
        * config/fp-bit.h: Add unordered defines for gofast.
 
 2002-06-19  Vladimir Makarov  <vmakarov@redhat.com>
index 674db93..2de221b 100644 (file)
@@ -98,6 +98,7 @@ extern const char      *mips_fill_delay_slot PARAMS ((const char *,
                                                      rtx));
 extern const char      *mips_move_1word PARAMS ((rtx *, rtx, int));
 extern const char      *mips_move_2words PARAMS ((rtx *, rtx));
+extern const char      *mips_emit_prefetch PARAMS ((rtx *));
 extern const char      *mips_restore_gp PARAMS ((rtx *, rtx));
 extern const char      *output_block_move PARAMS ((rtx, rtx *, int,
                                                   enum block_move_type));
index fd166e8..5ee1805 100644 (file)
@@ -90,6 +90,8 @@ int coprocessor_operand                       PARAMS ((rtx,
                                                        enum machine_mode));
 int coprocessor2_operand                       PARAMS ((rtx,
                                                        enum machine_mode));
+int symbolic_operand                           PARAMS ((rtx,
+                                                        enum machine_mode));
 static int m16_check_op                                PARAMS ((rtx, int, int, int));
 static void block_move_loop                    PARAMS ((rtx, rtx,
                                                         unsigned int,
@@ -1384,6 +1386,26 @@ coprocessor2_operand (op, mode)
          && REGNO (op) <= COP2_REG_LAST);
 }
 
+/* Returns 1 if OP is a symbolic operand, i.e. a symbol_ref or a label_ref,
+   possibly with an offset.  */
+
+int
+symbolic_operand (op, mode)
+      register rtx op;
+      enum machine_mode mode;
+{
+  if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
+    return 0;
+  if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
+    return 1;
+  if (GET_CODE (op) == CONST
+      && GET_CODE (XEXP (op,0)) == PLUS
+      && GET_CODE (XEXP (XEXP (op,0), 0)) == SYMBOL_REF
+      && GET_CODE (XEXP (XEXP (op,0), 1)) == CONST_INT)
+    return 1;
+  return 0;
+}
+
 /* Return nonzero if we split the address into high and low parts.  */
 
 /* ??? We should also handle reg+array somewhere.  We get four
@@ -10394,6 +10416,37 @@ mips_issue_rate ()
   return rate;
 }
 
+const char *
+mips_emit_prefetch (operands)
+     rtx operands[];
+{
+ /* For the mips32/64 architectures the hint fields are arranged
+    by operation (load/store) and locality (normal/streamed/retained).
+    Irritatingly, numbers 2 and 3 are reserved leaving no simple
+    algorithm for figuring the hint.  */
+
+    int write = INTVAL (operands[1]);
+    int locality = INTVAL (operands[2]);
+
+    static const char * const alt[2][4] = {
+       {
+        "pref\t0,%a0",
+        "pref\t4,%a0",
+        "pref\t4,%a0",
+        "pref\t6,%a0"
+       },
+       {
+        "pref\t1,%a0",
+        "pref\t5,%a0",
+        "pref\t5,%a0",
+        "pref\t7,%a0"
+       }
+    };
+
+    return alt[write][locality];
+}
+
+
 \f
 #ifdef TARGET_IRIX6
 /* Output assembly to switch to section NAME with attribute FLAGS.  */
index 7db331b..54cf494 100644 (file)
@@ -685,7 +685,7 @@ extern void         sbss_section PARAMS ((void));
   SUBTARGET_TARGET_OPTIONS                                             \
   { "cpu=",    &mips_cpu_string,                                       \
       N_("Specify CPU for scheduling purposes")},                      \
-  { "tune=",    &mips_tune_string,                                   \
+  { "tune=",    &mips_tune_string,                                     \
       N_("Specify CPU for scheduling purposes")},                       \
   { "arch=",    &mips_arch_string,                                      \
       N_("Specify CPU for code generation purposes")},                  \
@@ -725,14 +725,14 @@ extern void               sbss_section PARAMS ((void));
 #define HAVE_SQRT_P()          (!ISA_MIPS1)
 
 /* ISA has instructions for managing 64 bit fp and gp regs (eg. mips3).  */
-#define ISA_HAS_64BIT_REGS     (ISA_MIPS3              \
-                                || ISA_MIPS4           \
+#define ISA_HAS_64BIT_REGS     (ISA_MIPS3                              \
+                                || ISA_MIPS4                           \
                                  || ISA_MIPS64)
 
 /* ISA has branch likely instructions (eg. mips2).  */
 /* Disable branchlikely for tx39 until compare rewrite.  They haven't
    been generated up to this point.  */
-#define ISA_HAS_BRANCHLIKELY   (!ISA_MIPS1                          \
+#define ISA_HAS_BRANCHLIKELY   (!ISA_MIPS1                             \
                                 && !TARGET_MIPS16)
 
 /* ISA has the conditional move instructions introduced in mips4.  */
@@ -781,6 +781,12 @@ extern void                sbss_section PARAMS ((void));
 #define ISA_HAS_DCLZ_DCLO       (ISA_MIPS64                            \
                                 && !TARGET_MIPS16)
 
+/* ISA has data prefetch instruction.  */
+#define ISA_HAS_PREFETCH       ((ISA_MIPS4                             \
+                                 || ISA_MIPS32                         \
+                                 || ISA_MIPS64)                        \
+                                && !TARGET_MIPS16)
+
 /* CC1_SPEC causes -mips3 and -mips4 to set -mfp64 and -mgp64; -mips1 or
    -mips2 sets -mfp32 and -mgp32.  This can be overridden by an explicit
    -mfp32, -mfp64, -mgp32 or -mgp64.  -mfp64 sets MASK_FLOAT64 in
@@ -1060,7 +1066,7 @@ extern int mips_abi;
 %{mips3:%{!msingle-float:%{!m4650:-mfp64}} -mgp64} \
 %{mips4:%{!msingle-float:%{!m4650:-mfp64}} -mgp64} \
 %{mips32:-mfp32 -mgp32} \
-%{mips64:%{!msingle-float:%{!m4650:-mfp64}} -mgp64} \
+%{mips64:%{!msingle-float:-mfp64} -mgp64} \
 %{mfp64:%{msingle-float:%emay not use both -mfp64 and -msingle-float}} \
 %{mfp64:%{m4650:%emay not use both -mfp64 and -m4650}} \
 %{mint64|mlong64|mlong32:-mexplicit-type-size }\
@@ -1343,21 +1349,21 @@ do {                                                    \
 
 #define PUT_SDB_FUNCTION_START(LINE)
 
-#define PUT_SDB_FUNCTION_END(LINE)            \
-do {                                                  \
-  extern FILE *asm_out_text_file;             \
+#define PUT_SDB_FUNCTION_END(LINE)                     \
+do {                                                   \
+  extern FILE *asm_out_text_file;                      \
   ASM_OUTPUT_SOURCE_LINE (asm_out_text_file, LINE + sdb_begin_function_line); \
 } while (0)
 
 #define PUT_SDB_EPILOGUE_END(NAME)
 
-#define PUT_SDB_SRC_FILE(FILENAME) \
+#define PUT_SDB_SRC_FILE(FILENAME)                     \
 do {                                                   \
   extern FILE *asm_out_text_file;                      \
-  output_file_directive (asm_out_text_file, (FILENAME)); \
+  output_file_directive (asm_out_text_file, (FILENAME));\
 } while (0)
 
-#define SDB_GENERATE_FAKE(BUFFER, NUMBER) \
+#define SDB_GENERATE_FAKE(BUFFER, NUMBER)              \
   sprintf ((BUFFER), ".%dfake", (NUMBER));
 
 /* Correct the offset of automatic variables and arguments.  Note that
@@ -1367,9 +1373,9 @@ do {                                                      \
    the frame pointer to be the stack pointer after the initial
    adjustment.  */
 
-#define DEBUGGER_AUTO_OFFSET(X)  \
+#define DEBUGGER_AUTO_OFFSET(X)                                \
   mips_debugger_offset (X, (HOST_WIDE_INT) 0)
-#define DEBUGGER_ARG_OFFSET(OFFSET, X)  \
+#define DEBUGGER_ARG_OFFSET(OFFSET, X)                 \
   mips_debugger_offset (X, (HOST_WIDE_INT) OFFSET)
 
 /* Tell collect that the object format is ECOFF */
@@ -2976,15 +2982,17 @@ typedef struct mips_args {
    assembler would use $at as a temp to load in the large offset.  In this
    case $at is already in use.  We convert such problem addresses to
    `la $5,s;sw $4,70000($5)' via LEGITIMIZE_ADDRESS.  */
-/* ??? SGI Irix 6 assembler fails for CONST address, so reject them.  */
+/* ??? SGI Irix 6 assembler fails for CONST address, so reject them
+   when !TARGET_GAS.  */
+/* We should be rejecting everything but const addresses.  */
 #define CONSTANT_ADDRESS_P(X)                                          \
   (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF             \
     || GET_CODE (X) == CONST_INT || GET_CODE (X) == HIGH               \
     || (GET_CODE (X) == CONST                                          \
        && ! (flag_pic && pic_address_needs_scratch (X))                \
-       && (mips_abi == ABI_32                                          \
-           || mips_abi == ABI_O64                                      \
-           || mips_abi == ABI_EABI)))
+       && (!TARGET_GAS)                                                \
+       && (mips_abi == ABI_N32                                         \
+           || mips_abi == ABI_64)))
 
 /* Define this, so that when PIC, reload won't try to reload invalid
    addresses which require two reload registers.  */
@@ -3075,9 +3083,9 @@ typedef struct mips_args {
   if (GET_CODE (xinsn) == CONST                                                \
       && ((flag_pic && pic_address_needs_scratch (xinsn))              \
          /* ??? SGI's Irix 6 assembler can't handle CONST.  */         \
-         || (mips_abi != ABI_32                                        \
-             && mips_abi != ABI_O64                                    \
-             && mips_abi != ABI_EABI)))                                \
+         || (!TARGET_GAS                                               \
+             && (mips_abi == ABI_N32                                   \
+                 || mips_abi == ABI_64))))                             \
     {                                                                  \
       rtx ptr_reg = gen_reg_rtx (Pmode);                               \
       rtx constant = XEXP (XEXP (xinsn, 0), 1);                                \
@@ -3447,11 +3455,11 @@ typedef struct mips_args {
       enum machine_mode xmode = GET_MODE (X);                          \
       if (xmode == SFmode)                                             \
        {                                                               \
-         if (TUNE_MIPS3000                             \
-             || TUNE_MIPS3900                          \
-             || TUNE_MIPS5000)                         \
+         if (TUNE_MIPS3000                                             \
+             || TUNE_MIPS3900                                          \
+             || TUNE_MIPS5000)                                         \
            return COSTS_N_INSNS (4);                                   \
-         else if (TUNE_MIPS6000)                               \
+         else if (TUNE_MIPS6000)                                       \
            return COSTS_N_INSNS (5);                                   \
          else                                                          \
            return COSTS_N_INSNS (7);                                   \
@@ -3459,23 +3467,23 @@ typedef struct mips_args {
                                                                        \
       if (xmode == DFmode)                                             \
        {                                                               \
-         if (TUNE_MIPS3000                             \
-             || TUNE_MIPS3900                          \
-             || TUNE_MIPS5000)                         \
+         if (TUNE_MIPS3000                                             \
+             || TUNE_MIPS3900                                          \
+             || TUNE_MIPS5000)                                         \
            return COSTS_N_INSNS (5);                                   \
-         else if (TUNE_MIPS6000)                               \
+         else if (TUNE_MIPS6000)                                       \
            return COSTS_N_INSNS (6);                                   \
          else                                                          \
            return COSTS_N_INSNS (8);                                   \
        }                                                               \
                                                                        \
-      if (TUNE_MIPS3000)                                       \
+      if (TUNE_MIPS3000)                                               \
        return COSTS_N_INSNS (12);                                      \
-      else if (TUNE_MIPS3900)                          \
+      else if (TUNE_MIPS3900)                                          \
        return COSTS_N_INSNS (2);                                       \
-      else if (TUNE_MIPS6000)                          \
+      else if (TUNE_MIPS6000)                                          \
        return COSTS_N_INSNS (17);                                      \
-      else if (TUNE_MIPS5000)                          \
+      else if (TUNE_MIPS5000)                                          \
        return COSTS_N_INSNS (5);                                       \
       else                                                             \
        return COSTS_N_INSNS (10);                                      \
@@ -3487,10 +3495,10 @@ typedef struct mips_args {
       enum machine_mode xmode = GET_MODE (X);                          \
       if (xmode == SFmode)                                             \
        {                                                               \
-         if (TUNE_MIPS3000                             \
-              || TUNE_MIPS3900)                                \
+         if (TUNE_MIPS3000                                             \
+              || TUNE_MIPS3900)                                                \
            return COSTS_N_INSNS (12);                                  \
-         else if (TUNE_MIPS6000)                               \
+         else if (TUNE_MIPS6000)                                       \
            return COSTS_N_INSNS (15);                                  \
          else                                                          \
            return COSTS_N_INSNS (23);                                  \
@@ -3498,10 +3506,10 @@ typedef struct mips_args {
                                                                        \
       if (xmode == DFmode)                                             \
        {                                                               \
-         if (TUNE_MIPS3000                             \
-              || TUNE_MIPS3900)                                \
+         if (TUNE_MIPS3000                                             \
+              || TUNE_MIPS3900)                                                \
            return COSTS_N_INSNS (19);                                  \
-         else if (TUNE_MIPS6000)                               \
+         else if (TUNE_MIPS6000)                                       \
            return COSTS_N_INSNS (16);                                  \
          else                                                          \
            return COSTS_N_INSNS (36);                                  \
@@ -3511,12 +3519,12 @@ typedef struct mips_args {
                                                                        \
   case UDIV:                                                           \
   case UMOD:                                                           \
-    if (TUNE_MIPS3000                                  \
-        || TUNE_MIPS3900)                                      \
+    if (TUNE_MIPS3000                                                  \
+        || TUNE_MIPS3900)                                              \
       return COSTS_N_INSNS (35);                                       \
-    else if (TUNE_MIPS6000)                            \
+    else if (TUNE_MIPS6000)                                            \
       return COSTS_N_INSNS (38);                                       \
-    else if (TUNE_MIPS5000)                            \
+    else if (TUNE_MIPS5000)                                            \
       return COSTS_N_INSNS (36);                                       \
     else                                                               \
       return COSTS_N_INSNS (69);                                       \
index 7335da0..fece404 100644 (file)
@@ -10540,6 +10540,51 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
 ;;  ....................
 ;;
 
+
+(define_expand "prefetch"
+  [(prefetch (match_operand 0 "address_operand" "")
+            (match_operand 1 "const_int_operand" "")
+            (match_operand 2 "const_int_operand" ""))]
+  "ISA_HAS_PREFETCH"
+"{
+     if (symbolic_operand (operands[0], GET_MODE (operands[0])))
+       operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
+}")
+
+(define_insn "prefetch_si_address"
+  [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
+                     (match_operand:SI 3 "const_int_operand" "i"))
+            (match_operand:SI 1 "const_int_operand" "n")
+            (match_operand:SI 2 "const_int_operand" "n"))]
+  "ISA_HAS_PREFETCH && Pmode == SImode"
+  "* return mips_emit_prefetch (operands);"
+  [(set_attr "type" "load")])
+
+(define_insn "prefetch_si"
+  [(prefetch (match_operand:SI 0 "register_operand" "r")
+            (match_operand:SI 1 "const_int_operand" "n")
+            (match_operand:SI 2 "const_int_operand" "n"))]
+  "ISA_HAS_PREFETCH && Pmode == SImode"
+  "* return mips_emit_prefetch (operands);"
+  [(set_attr "type" "load")])
+
+(define_insn "prefetch_di_address"
+  [(prefetch (plus:DI (match_operand:DI 0 "se_register_operand" "r")
+                     (match_operand:DI 3 "const_int_operand" "i"))
+            (match_operand:DI 1 "const_int_operand" "n")
+            (match_operand:DI 2 "const_int_operand" "n"))]
+  "ISA_HAS_PREFETCH && Pmode == DImode"
+  "* return mips_emit_prefetch (operands);"
+  [(set_attr "type" "load")])
+
+(define_insn "prefetch_di"
+  [(prefetch (match_operand:DI 0 "se_register_operand" "r")
+            (match_operand:DI 1 "const_int_operand" "n")
+            (match_operand:DI 2 "const_int_operand" "n"))]
+  "ISA_HAS_PREFETCH && Pmode == DImode"
+  "* return mips_emit_prefetch (operands);"
+  [(set_attr "type" "load")])
+
 (define_insn "nop"
   [(const_int 0)]
   ""