aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Christopher <echristo@redhat.com>2002-06-19 23:18:00 +0000
committerEric Christopher <echristo@gcc.gnu.org>2002-06-19 23:18:00 +0000
commit8f2e3902df05cd786280fa561b9b448de4547583 (patch)
treef5a12fcb17f46b0537b1d83585d230821421755e
parentba3292dbb7ccbe4941d2fd1661f99d1d4da5e75d (diff)
downloadgcc-8f2e3902df05cd786280fa561b9b448de4547583.zip
gcc-8f2e3902df05cd786280fa561b9b448de4547583.tar.gz
gcc-8f2e3902df05cd786280fa561b9b448de4547583.tar.bz2
mips.c (symbol_operand): New function.
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. From-SVN: r54805
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/mips/mips-protos.h1
-rw-r--r--gcc/config/mips/mips.c53
-rw-r--r--gcc/config/mips/mips.h92
-rw-r--r--gcc/config/mips/mips.md45
5 files changed, 160 insertions, 42 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 06731ef..326e0cd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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>
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index 674db93..2de221b 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -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));
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index fd166e8..5ee1805 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -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];
+}
+
+
#ifdef TARGET_IRIX6
/* Output assembly to switch to section NAME with attribute FLAGS. */
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 7db331b..54cf494 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -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); \
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 7335da0..fece404 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -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)]
""