Commit 21c9500d by Richard Sandiford Committed by Richard Sandiford

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
parent f29d1b66
2003-05-19 Richard Sandiford <rsandifo@redhat.com> 2003-05-19 Richard Sandiford <rsandifo@redhat.com>
* 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 <rsandifo@redhat.com>
* config/mips/mips-protos.h (final_prescan_insn, * config/mips/mips-protos.h (final_prescan_insn,
mips_count_memory_refs, mips_fill_delay_slot): Remove. mips_count_memory_refs, mips_fill_delay_slot): Remove.
* config/mips/mips.h (delay_type, dslots_load_total, * config/mips/mips.h (delay_type, dslots_load_total,
......
...@@ -1507,6 +1507,18 @@ const_float_1_operand (op, mode) ...@@ -1507,6 +1507,18 @@ const_float_1_operand (op, mode)
return REAL_VALUES_EQUAL (d, dconst1); 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. */ /* Return nonzero if the code of this rtx pattern is EQ or NE. */
int int
...@@ -9897,6 +9909,22 @@ mips_adjust_insn_length (insn, length) ...@@ -9897,6 +9909,22 @@ mips_adjust_insn_length (insn, length)
|| GET_CODE (insn) == CALL_INSN))) || GET_CODE (insn) == CALL_INSN)))
length += 4; 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. */ /* All MIPS16 instructions are a measly two bytes. */
if (TARGET_MIPS16) if (TARGET_MIPS16)
length /= 2; length /= 2;
......
...@@ -945,6 +945,24 @@ extern void sbss_section PARAMS ((void)); ...@@ -945,6 +945,24 @@ extern void sbss_section PARAMS ((void));
&& (ISA_MIPS32R2 \ && (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 /* 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 -mips2 sets -mfp32 and -mgp32. This can be overridden by an explicit
-mfp32, -mfp64, -mgp32 or -mgp64. -mfp64 sets MASK_FLOAT64 in -mfp32, -mfp64, -mgp32 or -mgp64. -mfp64 sets MASK_FLOAT64 in
...@@ -3374,7 +3392,8 @@ typedef struct mips_args { ...@@ -3374,7 +3392,8 @@ typedef struct mips_args {
REG, MEM}}, \ REG, MEM}}, \
{"consttable_operand", { LABEL_REF, SYMBOL_REF, CONST_INT, \ {"consttable_operand", { LABEL_REF, SYMBOL_REF, CONST_INT, \
CONST_DOUBLE, CONST }}, \ 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 /* A list of predicates that do special things with modes, and so
should not elicit warnings for VOIDmode match_operand. */ should not elicit warnings for VOIDmode match_operand. */
......
...@@ -193,17 +193,33 @@ ...@@ -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" "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"))) (const (symbol_ref "mips_cpu_attr")))
;; Does the instruction have a mandatory delay slot? ;; The type of hardware hazard associated with this instruction.
;; The 3900, is (mostly) mips1, but does not have a mandatory load delay ;; DELAY means that the next instruction cannot read the result
;; slot. ;; of this one. HILO means that the next two instructions cannot
(define_attr "dslot" "no,yes" ;; write to HI or LO.
(if_then_else (ior (eq_attr "type" "branch,jump,call,xfer,hilo,fcmp") (define_attr "hazard" "none,delay,hilo"
(and (eq_attr "type" "load") (cond [(and (eq_attr "type" "load")
(and (eq (symbol_ref "mips_isa") (const_int 1)) (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0)))
(and (eq (symbol_ref "mips16") (const_int 0)) (const_string "delay")
(eq_attr "cpu" "!r3900")))))
(const_string "yes") (and (eq_attr "type" "xfer")
(const_string "no"))) (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? ;; Is it a single instruction?
(define_attr "single_insn" "no,yes" (define_attr "single_insn" "no,yes"
...@@ -211,8 +227,9 @@ ...@@ -211,8 +227,9 @@
;; Can the instruction be put into a delay slot? ;; Can the instruction be put into a delay slot?
(define_attr "can_delay" "no,yes" (define_attr "can_delay" "no,yes"
(if_then_else (and (eq_attr "dslot" "no") (if_then_else (and (eq_attr "type" "!branch,call,jump")
(eq_attr "single_insn" "yes")) (and (eq_attr "hazard" "none")
(eq_attr "single_insn" "yes")))
(const_string "yes") (const_string "yes")
(const_string "no"))) (const_string "no")))
...@@ -2274,7 +2291,7 @@ ...@@ -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])); emit_insn (gen_muldi3_internal2 (operands[0], operands[1], operands[2]));
else else
emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2])); emit_insn (gen_muldi3_internal (operands[0], operands[1], operands[2]));
...@@ -2287,7 +2304,7 @@ ...@@ -2287,7 +2304,7 @@
(match_operand:DI 2 "register_operand" "d"))) (match_operand:DI 2 "register_operand" "d")))
(clobber (match_scratch:DI 3 "=h")) (clobber (match_scratch:DI 3 "=h"))
(clobber (match_scratch:DI 4 "=a"))] (clobber (match_scratch:DI 4 "=a"))]
"TARGET_64BIT && !TARGET_MIPS4000 && !TARGET_MIPS16" "TARGET_64BIT && !TARGET_MIPS4000"
"dmult\\t%1,%2" "dmult\\t%1,%2"
[(set_attr "type" "imul") [(set_attr "type" "imul")
(set_attr "mode" "DI")]) (set_attr "mode" "DI")])
...@@ -2299,7 +2316,7 @@ ...@@ -2299,7 +2316,7 @@
(clobber (match_scratch:DI 3 "=h")) (clobber (match_scratch:DI 3 "=h"))
(clobber (match_scratch:DI 4 "=l")) (clobber (match_scratch:DI 4 "=l"))
(clobber (match_scratch:DI 5 "=a"))] (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) if (GENERATE_MULT3_DI)
return "dmult\t%0,%1,%2"; return "dmult\t%0,%1,%2";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment