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
This commit is contained in:
Richard Sandiford 2003-05-19 07:36:28 +00:00 committed by Richard Sandiford
parent f29d1b660c
commit 21c9500d3e
4 changed files with 95 additions and 17 deletions

View File

@ -1,3 +1,17 @@
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,

View File

@ -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;

View File

@ -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. */

View File

@ -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";