mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-17 05:58:54 +08:00
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:
parent
f29d1b660c
commit
21c9500d3e
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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. */
|
||||
|
@ -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";
|
||||
|
Loading…
Reference in New Issue
Block a user