+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,
&& (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
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. */
"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"
;; 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")))
"
{
- 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]));
(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")])
(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";