From 21c9500d3e100b6bef46632377fffe4044545238 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Mon, 19 May 2003 07:36:28 +0000 Subject: [PATCH] mips.h (ISA_HAS_LOAD_DELAY, [...]): New macros. * config/mips/mips.h (ISA_HAS_LOAD_DELAY, ISA_HAS_XFER_DELAY, ISA_HAS_FCMP_DELAY, ISA_HAS_HILO_INTERLOCKS): New macros. (PREDICATE_CODES): Add hilo_operand. * config/mips/mips.c (hilo_operand): New predicate. (mips_adjust_insn_length): Account for the number nops that might be needed to avoid hardware hazards. * config/mips/mips.md (dslot): Remove attribute. (hazard): New attribute. (can_delay): Use it. Check for calls, branches & jumps. (muldi3): Use the standard dmult pattern for mips16 code. (muldi3_internal, muldi3_internal2): Adjust conditions accordingly. From-SVN: r66952 --- gcc/ChangeLog | 14 ++++++++++++ gcc/config/mips/mips.c | 28 +++++++++++++++++++++++ gcc/config/mips/mips.h | 21 +++++++++++++++++- gcc/config/mips/mips.md | 49 +++++++++++++++++++++++++++-------------- 4 files changed, 95 insertions(+), 17 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0822e65e0e8..47405031138 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2003-05-19 Richard Sandiford + + * config/mips/mips.h (ISA_HAS_LOAD_DELAY, ISA_HAS_XFER_DELAY, + ISA_HAS_FCMP_DELAY, ISA_HAS_HILO_INTERLOCKS): New macros. + (PREDICATE_CODES): Add hilo_operand. + * config/mips/mips.c (hilo_operand): New predicate. + (mips_adjust_insn_length): Account for the number nops that might + be needed to avoid hardware hazards. + * config/mips/mips.md (dslot): Remove attribute. + (hazard): New attribute. + (can_delay): Use it. Check for calls, branches & jumps. + (muldi3): Use the standard dmult pattern for mips16 code. + (muldi3_internal, muldi3_internal2): Adjust conditions accordingly. + 2003-05-19 Richard Sandiford * config/mips/mips-protos.h (final_prescan_insn, diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 29c0cd693a7..b487f2b1486 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -1507,6 +1507,18 @@ const_float_1_operand (op, mode) return REAL_VALUES_EQUAL (d, dconst1); } +/* Return true if OP is either the HI or LO register. */ + +int +hilo_operand (op, mode) + rtx op; + enum machine_mode mode; +{ + return ((mode == VOIDmode || mode == GET_MODE (op)) + && REG_P (op) + && (REGNO (op) == HI_REGNUM || REGNO (op) == LO_REGNUM)); +} + /* Return nonzero if the code of this rtx pattern is EQ or NE. */ int @@ -9897,6 +9909,22 @@ mips_adjust_insn_length (insn, length) || GET_CODE (insn) == CALL_INSN))) length += 4; + /* See how many nops might be needed to avoid hardware hazards. */ + if (INSN_CODE (insn) >= 0) + switch (get_attr_hazard (insn)) + { + case HAZARD_NONE: + break; + + case HAZARD_DELAY: + length += 4; + break; + + case HAZARD_HILO: + length += 8; + break; + } + /* All MIPS16 instructions are a measly two bytes. */ if (TARGET_MIPS16) length /= 2; diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index e6d994510e0..2f1a4eeda09 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -945,6 +945,24 @@ extern void sbss_section PARAMS ((void)); && (ISA_MIPS32R2 \ )) +/* True if the result of a load is not available to the next instruction. + A nop will then be needed between instructions like "lw $4,..." + and "addiu $4,$4,1". */ +#define ISA_HAS_LOAD_DELAY (mips_isa == 1 \ + && !TARGET_MIPS3900 \ + && !TARGET_MIPS16) + +/* Likewise mtc1 and mfc1. */ +#define ISA_HAS_XFER_DELAY (mips_isa <= 3) + +/* Likewise floating-point comparisons. */ +#define ISA_HAS_FCMP_DELAY (mips_isa <= 3) + +/* True if mflo and mfhi can be immediately followed by instructions + which write to the HI and LO registers. Most targets require a + two-instruction gap. */ +#define ISA_HAS_HILO_INTERLOCKS (TARGET_MIPS5500 || TARGET_SB1) + /* 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 @@ -3374,7 +3392,8 @@ typedef struct mips_args { REG, MEM}}, \ {"consttable_operand", { LABEL_REF, SYMBOL_REF, CONST_INT, \ CONST_DOUBLE, CONST }}, \ - {"fcc_register_operand", { REG, SUBREG }}, + {"fcc_register_operand", { REG, SUBREG }}, \ + {"hilo_operand", { REG }}, /* A list of predicates that do special things with modes, and so should not elicit warnings for VOIDmode match_operand. */ diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 3284ba926e2..c91d27f14f4 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -193,17 +193,33 @@ "default,4kc,5kc,20kc,m4k,r3000,r3900,r6000,r4000,r4100,r4111,r4120,r4300,r4600,r4650,r5000,r5400,r5500,r8000,sb1,sr71000" (const (symbol_ref "mips_cpu_attr"))) -;; Does the instruction have a mandatory delay slot? -;; The 3900, is (mostly) mips1, but does not have a mandatory load delay -;; slot. -(define_attr "dslot" "no,yes" - (if_then_else (ior (eq_attr "type" "branch,jump,call,xfer,hilo,fcmp") - (and (eq_attr "type" "load") - (and (eq (symbol_ref "mips_isa") (const_int 1)) - (and (eq (symbol_ref "mips16") (const_int 0)) - (eq_attr "cpu" "!r3900"))))) - (const_string "yes") - (const_string "no"))) +;; The type of hardware hazard associated with this instruction. +;; DELAY means that the next instruction cannot read the result +;; of this one. HILO means that the next two instructions cannot +;; write to HI or LO. +(define_attr "hazard" "none,delay,hilo" + (cond [(and (eq_attr "type" "load") + (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0))) + (const_string "delay") + + (and (eq_attr "type" "xfer") + (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0))) + (const_string "delay") + + (and (eq_attr "type" "fcmp") + (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0))) + (const_string "delay") + + ;; The r4000 multiplication patterns include an mflo instruction. + (and (eq_attr "type" "imul") + (ne (symbol_ref "TARGET_MIPS4000") (const_int 0))) + (const_string "hilo") + + (and (eq_attr "type" "hilo") + (and (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int 0)) + (match_operand 1 "hilo_operand" ""))) + (const_string "hilo")] + (const_string "none"))) ;; Is it a single instruction? (define_attr "single_insn" "no,yes" @@ -211,8 +227,9 @@ ;; Can the instruction be put into a delay slot? (define_attr "can_delay" "no,yes" - (if_then_else (and (eq_attr "dslot" "no") - (eq_attr "single_insn" "yes")) + (if_then_else (and (eq_attr "type" "!branch,call,jump") + (and (eq_attr "hazard" "none") + (eq_attr "single_insn" "yes"))) (const_string "yes") (const_string "no"))) @@ -2274,7 +2291,7 @@ " { - if (GENERATE_MULT3_DI || TARGET_MIPS4000 || TARGET_MIPS16) + if (GENERATE_MULT3_DI || TARGET_MIPS4000) emit_insn (gen_muldi3_internal2 (operands[0], operands[1], operands[2])); else emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2])); @@ -2287,7 +2304,7 @@ (match_operand:DI 2 "register_operand" "d"))) (clobber (match_scratch:DI 3 "=h")) (clobber (match_scratch:DI 4 "=a"))] - "TARGET_64BIT && !TARGET_MIPS4000 && !TARGET_MIPS16" + "TARGET_64BIT && !TARGET_MIPS4000" "dmult\\t%1,%2" [(set_attr "type" "imul") (set_attr "mode" "DI")]) @@ -2299,7 +2316,7 @@ (clobber (match_scratch:DI 3 "=h")) (clobber (match_scratch:DI 4 "=l")) (clobber (match_scratch:DI 5 "=a"))] - "TARGET_64BIT && (GENERATE_MULT3_DI || TARGET_MIPS4000 || TARGET_MIPS16)" + "TARGET_64BIT && (GENERATE_MULT3_DI || TARGET_MIPS4000)" { if (GENERATE_MULT3_DI) return "dmult\t%0,%1,%2"; -- 2.30.2