OSDN Git Service

(cpu, memory, imuldiv, adder, mult, divide): Add
authorwilson <wilson@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 8 Jun 1996 22:41:49 +0000 (22:41 +0000)
committerwilson <wilson@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 8 Jun 1996 22:41:49 +0000 (22:41 +0000)
vr4100 and vr4300 support.
(muldf3, mulsf3): Add vr4300 support.
(muldf3_internal, muldf_r4300, mulsf3_internal, mulsf_r4300): New
patterns.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@12250 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/config/mips/mips.md

index 973aaed..f75e737 100644 (file)
@@ -93,7 +93,7 @@
 ;;          (const_string "default"))))
 
 ;; ??? Fix everything that tests this attribute.
-(define_attr "cpu" "default,r3000,r6000,r4000,r4600,r4650,r8000"
+(define_attr "cpu" "default,r3000,r6000,r4000,r4100,r4300,r4600,r4650,r8000"
   (const (symbol_ref "mips_cpu_attr")))
 
 ;; Attribute defining whether or not we can use the branch-likely instructions
 ;; Make the default case (PROCESSOR_DEFAULT) handle the worst case
 
 (define_function_unit "memory" 1 0
-  (and (eq_attr "type" "load") (eq_attr "cpu" "!r3000,r4600,r4650"))
+  (and (eq_attr "type" "load") (eq_attr "cpu" "!r3000,r4600,r4650,r4100,r4300"))
   3 0)
 
 (define_function_unit "memory" 1 0
   (and (eq_attr "type" "load") (eq_attr "cpu" "r3000,r4600,r4650"))
   2 0)
 
+(define_function_unit "memory" 1 0
+  (and (eq_attr "type" "load") (eq_attr "cpu" "r4100,r4300"))
+  1 0)
+
 (define_function_unit "memory"   1 0 (eq_attr "type" "store") 1 0)
 
 (define_function_unit "memory"   1 0 (eq_attr "type" "xfer") 2 0)
   1 3)
 
 (define_function_unit "imuldiv"  1 0
-  (and (eq_attr "type" "imul") (eq_attr "cpu" "!r3000,r4000,r4600,r4650"))
+  (and (eq_attr "type" "imul") (eq_attr "cpu" "!r3000,r4000,r4600,r4650,r4100,r4300"))
   17 17)
 
 (define_function_unit "imuldiv"  1 0
   4 4)
 
 (define_function_unit "imuldiv"  1 0
-  (and (eq_attr "type" "idiv") (eq_attr "cpu" "!r3000,r4000,r4600,r4650"))
+  (and (eq_attr "type" "imul") (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100")))
+  1 1)
+
+(define_function_unit "imuldiv"  1 0
+  (and (eq_attr "type" "imul") (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100")))
+  4 4)
+
+(define_function_unit "imuldiv"  1 0
+  (and (eq_attr "type" "imul") (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300")))
+  5 5)
+
+(define_function_unit "imuldiv"  1 0
+  (and (eq_attr "type" "imul") (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
+  8 8)
+
+(define_function_unit "imuldiv"  1 0
+  (and (eq_attr "type" "idiv") (eq_attr "cpu" "!r3000,r4000,r4600,r4650,r4100,r4300"))
   38 38)
 
 (define_function_unit "imuldiv"  1 0
   (and (eq_attr "type" "idiv") (eq_attr "cpu" "r4000"))
   69 69)
 
+(define_function_unit "imuldiv" 1 0
+  (and (eq_attr "type" "idiv") (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4100")))
+  35 35)
+
+(define_function_unit "imuldiv" 1 0
+  (and (eq_attr "type" "idiv") (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4100")))
+  67 67)
+
+(define_function_unit "imuldiv" 1 0
+  (and (eq_attr "type" "idiv") (and (eq_attr "mode" "SI") (eq_attr "cpu" "r4300")))
+  37 37)
+
+(define_function_unit "imuldiv" 1 0
+  (and (eq_attr "type" "idiv") (and (eq_attr "mode" "DI") (eq_attr "cpu" "r4300")))
+  69 69)
+
+;; The R4300 does *NOT* have a seperate Floating Point Unit, instead
+;; the FP hardware is part of the normal ALU circuitry.  This means FP
+;; instructions affect the pipe-line, and no functional unit
+;; parallelism can occur on R4300 processors.  To force GCC into coding
+;; for only a single functional unit, we force the R4300 FP
+;; instructions to be processed in the "imuldiv" unit.
+
 (define_function_unit "adder" 1 1
-  (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r6000"))
+  (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r6000,r4300"))
   3 0)
 
 (define_function_unit "adder" 1 1
   2 0)
 
 (define_function_unit "adder" 1 1
-  (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r6000"))
+  (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r6000,r4300"))
   4 0)
 
 (define_function_unit "adder" 1 1
   3 0)
 
 (define_function_unit "adder" 1 1
-  (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "!r3000,r4600,r4650"))
+  (and (eq_attr "type" "fabs,fneg") (eq_attr "cpu" "!r3000,r4600,r4650,r4300"))
   2 0)
 
 (define_function_unit "adder" 1 1
   1 0)
 
 (define_function_unit "mult" 1 1
-  (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r3000,r6000,r4600,r4650")))
+  (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r3000,r6000,r4600,r4650,r4300")))
   7 0)
 
 (define_function_unit "mult" 1 1
   8 0)
 
 (define_function_unit "mult" 1 1
-  (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r6000")))
+  (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r6000,r4300")))
   8 0)
 
 (define_function_unit "mult" 1 1
   6 0)
 
 (define_function_unit "divide" 1 1
-  (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r3000,r6000,r4600,r4650")))
+  (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r3000,r6000,r4600,r4650,r4300")))
   23 0)
 
 (define_function_unit "divide" 1 1
   32 0)
 
 (define_function_unit "divide" 1 1
-  (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r6000,r4600,r4650")))
+  (and (eq_attr "type" "fdiv") (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r6000,r4600,r4650,r4300")))
   36 0)
 
 (define_function_unit "divide" 1 1
 
 ;;; ??? Is this number right?
 (define_function_unit "divide" 1 1
-  (and (eq_attr "type" "fsqrt") (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650")))
+  (and (eq_attr "type" "fsqrt") (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650,r4300")))
   54 0)
 (define_function_unit "divide" 1 1
   (and (eq_attr "type" "fsqrt") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4600,r4650")))
 
 ;;; ??? Is this number right?
 (define_function_unit "divide" 1 1
-  (and (eq_attr "type" "fsqrt") (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650")))
+  (and (eq_attr "type" "fsqrt") (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650,r4300")))
   112 0)
 (define_function_unit "divide" 1 1
   (and (eq_attr "type" "fsqrt") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4600,r4650")))
   60 0)
 
+;; R4300 FP instruction classes treated as part of the "imuldiv"
+;; functional unit:
+
+(define_function_unit "imuldiv" 1 0
+  (and (eq_attr "type" "fadd") (eq_attr "cpu" "r4300"))
+  3 3)
+
+(define_function_unit "imuldiv" 1 0
+  (and (eq_attr "type" "fmul") (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
+  5 5)
+(define_function_unit "imuldiv" 1 0
+  (and (eq_attr "type" "fmul") (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
+  8 8)
+
+(define_function_unit "imuldiv" 1 0
+  (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt"))
+       (and (eq_attr "mode" "SF") (eq_attr "cpu" "r4300")))
+  29 29)
+(define_function_unit "imuldiv" 1 0
+  (and (and (eq_attr "type" "fdiv") (eq_attr "type" "fsqrt"))
+       (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
+  58 58)
 \f
 ;; The following functional units do not use the cpu type, and use
 ;; much less memory in genattrtab.c.
 ;;  ....................
 ;;
 
-(define_insn "muldf3"
+;; Vr4300 has a CPU bug where multiplies with certain operands may
+;; corrupt immediately following multiplies. This is a simple fix to
+;; insert NOPs.
+
+(define_expand "muldf3"
   [(set (match_operand:DF 0 "register_operand" "=f")
        (mult:DF (match_operand:DF 1 "register_operand" "f")
                 (match_operand:DF 2 "register_operand" "f")))]
   "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
+  "
+{
+  if (mips_cpu != PROCESSOR_R4300)
+    emit_insn (gen_muldf3_internal (operands[0], operands[1], operands[2]));
+  else
+    emit_insn (gen_muldf3_r4300 (operands[0], operands[1], operands[2]));
+  DONE;
+}")
+
+(define_insn "muldf3_internal"
+  [(set (match_operand:DF 0 "register_operand" "=f")
+       (mult:DF (match_operand:DF 1 "register_operand" "f")
+                (match_operand:DF 2 "register_operand" "f")))]
+  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && mips_cpu != PROCESSOR_R4300"
   "mul.d\\t%0,%1,%2"
   [(set_attr "type"    "fmul")
    (set_attr "mode"    "DF")
    (set_attr "length"  "1")])
 
-(define_insn "mulsf3"
+(define_insn "muldf3_r4300"
+  [(set (match_operand:DF 0 "register_operand" "=f")
+       (mult:DF (match_operand:DF 1 "register_operand" "f")
+                (match_operand:DF 2 "register_operand" "f")))]
+  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && mips_cpu == PROCESSOR_R4300"
+  "*
+{
+  output_asm_insn (\"mul.d\\t%0,%1,%2\", operands);
+  if (TARGET_4300_MUL_FIX)
+    output_asm_insn (\"nop\", operands);
+  return \"\";
+}"
+  [(set_attr "type"    "fmul")
+   (set_attr "mode"    "DF")
+   (set_attr "length"  "2")])  ;; mul.d + nop
+
+(define_expand "mulsf3"
   [(set (match_operand:SF 0 "register_operand" "=f")
        (mult:SF (match_operand:SF 1 "register_operand" "f")
                 (match_operand:SF 2 "register_operand" "f")))]
   "TARGET_HARD_FLOAT"
+  "
+{
+  if (mips_cpu != PROCESSOR_R4300)
+    emit_insn( gen_mulsf3_internal (operands[0], operands[1], operands[2]));
+  else
+    emit_insn( gen_mulsf3_r4300 (operands[0], operands[1], operands[2]));
+  DONE;
+}")
+
+(define_insn "mulsf3_internal"
+  [(set (match_operand:SF 0 "register_operand" "=f")
+       (mult:SF (match_operand:SF 1 "register_operand" "f")
+                (match_operand:SF 2 "register_operand" "f")))]
+  "TARGET_HARD_FLOAT && mips_cpu != PROCESSOR_R4300"
   "mul.s\\t%0,%1,%2"
   [(set_attr "type"    "fmul")
    (set_attr "mode"    "SF")
    (set_attr "length"  "1")])
 
+(define_insn "mulsf3_r4300"
+  [(set (match_operand:SF 0 "register_operand" "=f")
+       (mult:SF (match_operand:SF 1 "register_operand" "f")
+                (match_operand:SF 2 "register_operand" "f")))]
+  "TARGET_HARD_FLOAT && mips_cpu == PROCESSOR_R4300"
+  "*
+{
+  output_asm_insn (\"mul.s\\t%0,%1,%2\", operands);
+  if (TARGET_4300_MUL_FIX)
+    output_asm_insn (\"nop\", operands);
+  return \"\";
+}"
+  [(set_attr "type"    "fmul")
+   (set_attr "mode"    "SF")
+   (set_attr "length"  "2")])  ;; mul.s + nop
+
 ;; ??? The R4000 (only) has a cpu bug.  If a double-word shift executes while
 ;; a multiply is in progress, it may give an incorrect result.  Avoid
 ;; this by keeping the mflo with the mult on the R4000.