From 8f2e3902df05cd786280fa561b9b448de4547583 Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Wed, 19 Jun 2002 23:18:00 +0000 Subject: [PATCH] mips.c (symbol_operand): New function. 2002-06-19 Eric Christopher * 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 --- gcc/ChangeLog | 11 ++++++ gcc/config/mips/mips-protos.h | 1 + gcc/config/mips/mips.c | 53 +++++++++++++++++++++++++ gcc/config/mips/mips.h | 92 +++++++++++++++++++++++-------------------- gcc/config/mips/mips.md | 45 +++++++++++++++++++++ 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 + * 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 + * config/fp-bit.h: Add unordered defines for gofast. 2002-06-19 Vladimir Makarov 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)] "" -- 2.7.4