Hello Richard,

> > How much other changes will be currently accepted here? There is other
> > stuff which I want to prepare and submit here, e.g.:
> > 1. disable use of dmult and ddiv (ABI n32).
> > 2. use trunc.w.s instead of cvt.w.s (to get single float working for
> > normal range calculations; i.e. calculating without inf or nan).
> > 3. fix use of ll/sc in libgomp, either increase mips ISA level or use
> > syscall (which is broken in Linux 2.6.35.4).
> > 4. fix libgcc to build a real muldi3 function for ABI n32 (not the
> > multi3 function which is stored in muldi3.o file).
> > 5. add support for configure parameters --float=single and
> > --float=double in addition to --float=soft and --float=hard.
> > 6. rework floating point to support single float with ABI n32 (either
> > break the ABI or store floating point values in general purpose
> > registers like soft float).
> > 7. change libgcc or mips.md in way so that the non IEEE 754 compatible
> > FPU of the r5900 gets compatible.
>
> Well, I'm afraid that's hard to say in advance.  It really depends
> on what the changes look like.  (1) and (2) sound harmless enough,
> although (1) should probably only be done in conjunction with (4).
> I'm not sure what (3) involves.  (5) sounds like a good idea.
> (6) is worth doing, but anything ABI-related gets extra-paranoid
> treatment. :-)

The attached patch fixes (1) and (4). This makes mips64r5900el usable with 
r5900. If (4) is a problem (i.e. patching libgcc/Makefile.in), it would be good 
if at least (1) is accepted.
The patch for mips.md after line 1992 (adds TARGET_64BIT) is a more general 
fix. This is not needed for r5900 support, but I think this should be fixed.
The same applies for patch after 2233 (adds ISA_HAS_DMULT). The fix here would 
be also adding TARGET_64BIT, but for r5900 we need ISA_HAS_DMULT here. Other 
changes in mips.md should not change the behaviour of GCC on non r5900 
toolchains.

Best regards
Jürgen
Index: gcc/config/mips/mips.h
===================================================================
--- gcc/config/mips/mips.h	(Revision 199708)
+++ gcc/config/mips/mips.h	(Arbeitskopie)
@@ -807,6 +807,7 @@
 #define ISA_HAS_MUL3		((TARGET_MIPS3900                       \
 				  || TARGET_MIPS5400			\
 				  || TARGET_MIPS5500			\
+				  || TARGET_MIPS5900			\
 				  || TARGET_MIPS7000			\
 				  || TARGET_MIPS9000			\
 				  || TARGET_MAD				\
@@ -819,8 +820,28 @@
 /* ISA has a three-operand multiplication instruction.  */
 #define ISA_HAS_DMUL3		(TARGET_64BIT				\
 				 && TARGET_OCTEON			\
+				 && !TARGET_MIPS5900                    \
 				 && !TARGET_MIPS16)
 
+/* ISA supports instructions dmult and dmultu. */
+#define ISA_HAS_DMULT           (TARGET_64BIT				\
+				 && !TARGET_MIPS5900)
+
+/* ISA supports instructions mult and multu.
+   This always supported, but the macro is needed for ISA_HAS_<D>MULT
+   in mips.md.  */
+#define ISA_HAS_MULT		(1)
+
+/* ISA supports instructions ddiv and ddivu. */
+#define ISA_HAS_DDIV            (TARGET_64BIT				\
+				 && !TARGET_MIPS5900)
+
+/* ISA supports instructions div and divu.
+   This always supported, but the macro is needed for ISA_HAS_<D>DIV
+   in mips.md.  */
+#define ISA_HAS_DIV		(1)
+
+
 #define ISA_HAS_DIV3		((TARGET_LOONGSON_2EF			\
 				  || TARGET_LOONGSON_3A)		\
 				 && !TARGET_MIPS16)
Index: gcc/config/mips/mips.md
===================================================================
--- gcc/config/mips/mips.md	(Revision 199708)
+++ gcc/config/mips/mips.md	(Arbeitskopie)
@@ -1481,7 +1481,7 @@
   [(set (match_operand:GPR 0 "register_operand")
 	(mult:GPR (match_operand:GPR 1 "register_operand")
 		  (match_operand:GPR 2 "register_operand")))]
-  ""
+  "ISA_HAS_<D>MULT"
 {
   rtx lo;
 
@@ -1527,7 +1527,7 @@
 {
   if (which_alternative == 1)
     return "<d>mult\t%1,%2";
-  if (<MODE>mode == SImode && TARGET_MIPS3900)
+  if (<MODE>mode == SImode && (TARGET_MIPS3900 || TARGET_MIPS5900))
     return "mult\t%0,%1,%2";
   return "<d>mul\t%0,%1,%2";
 }
@@ -1561,7 +1561,7 @@
   [(set (match_operand:GPR 0 "muldiv_target_operand" "=l")
 	(mult:GPR (match_operand:GPR 1 "register_operand" "d")
 		  (match_operand:GPR 2 "register_operand" "d")))]
-  "!TARGET_FIX_R4000"
+  "ISA_HAS_<D>MULT && !TARGET_FIX_R4000"
   "<d>mult\t%1,%2"
   [(set_attr "type" "imul")
    (set_attr "mode" "<MODE>")])
@@ -1571,7 +1571,7 @@
 	(mult:GPR (match_operand:GPR 1 "register_operand" "d")
 		  (match_operand:GPR 2 "register_operand" "d")))
    (clobber (match_scratch:GPR 3 "=l"))]
-  "TARGET_FIX_R4000"
+  "ISA_HAS_<D>MULT && TARGET_FIX_R4000"
   "<d>mult\t%1,%2\;mflo\t%0"
   [(set_attr "type" "imul")
    (set_attr "mode" "<MODE>")
@@ -1992,7 +1992,7 @@
 	(mult:DI (any_extend:DI (match_operand:SI 1 "register_operand"))
 		 (any_extend:DI (match_operand:SI 2 "register_operand"))))
    (clobber (match_operand:DI 3 "register_operand"))]
-  ""
+  "TARGET_64BIT"
 {
   rtx hilo;
 
@@ -2038,7 +2038,7 @@
 	(mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
 		 (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
    (clobber (match_scratch:DI 3 "=l"))]
-  "TARGET_64BIT && ISA_HAS_DMUL3"
+  "ISA_HAS_DMUL3"
   "dmul\t%0,%1,%2"
   [(set_attr "type" "imul3")
    (set_attr "mode" "DI")])
@@ -2192,7 +2192,7 @@
 	  (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
 		   (any_extend:TI (match_operand:DI 2 "register_operand")))
 	  (const_int 64))))]
-  "TARGET_64BIT && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
+  "ISA_HAS_DMULT && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
 {
   if (TARGET_MIPS16)
     emit_insn (gen_<su>muldi3_highpart_split (operands[0], operands[1],
@@ -2211,7 +2211,7 @@
 		   (any_extend:TI (match_operand:DI 2 "register_operand" "d")))
 	  (const_int 64))))
    (clobber (match_scratch:DI 3 "=l"))]
-  "TARGET_64BIT
+  "ISA_HAS_DMULT
    && !TARGET_MIPS16
    && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
   { return TARGET_FIX_R4000 ? "dmult<u>\t%1,%2\n\tmfhi\t%0" : "#"; }
@@ -2233,7 +2233,7 @@
 	  (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
 		   (any_extend:TI (match_operand:DI 2 "register_operand")))
 	  (const_int 64))))]
-  ""
+  "ISA_HAS_DMULT"
 {
   rtx hilo;
 
@@ -2247,7 +2247,7 @@
   [(set (match_operand:TI 0 "register_operand")
 	(mult:TI (any_extend:TI (match_operand:DI 1 "register_operand"))
 		 (any_extend:TI (match_operand:DI 2 "register_operand"))))]
-  "TARGET_64BIT && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
+  "ISA_HAS_DMULT && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
 {
   rtx hilo;
 
@@ -2269,7 +2269,7 @@
   [(set (match_operand:TI 0 "muldiv_target_operand" "=x")
 	(mult:TI (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
 		 (any_extend:TI (match_operand:DI 2 "register_operand" "d"))))]
-  "TARGET_64BIT
+  "ISA_HAS_DMULT
    && !TARGET_FIX_R4000
    && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
   "dmult<u>\t%1,%2"
@@ -2281,7 +2281,7 @@
 	(mult:TI (any_extend:TI (match_operand:DI 1 "register_operand" "d"))
 		 (any_extend:TI (match_operand:DI 2 "register_operand" "d"))))
    (clobber (match_scratch:TI 3 "=x"))]
-  "TARGET_64BIT
+  "ISA_HAS_DMULT
    && TARGET_FIX_R4000
    && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)"
   "dmult<u>\t%1,%2\;mflo\t%L0\;mfhi\t%M0"
@@ -2577,7 +2577,7 @@
    (set (match_operand:GPR 3 "register_operand" "=d")
 	(mod:GPR (match_dup 1)
 		 (match_dup 2)))]
-  "!TARGET_FIX_VR4120"
+  "ISA_HAS_<D>DIV && !TARGET_FIX_VR4120"
   "#"
   "&& ((TARGET_MIPS16 && cse_not_expected) || reload_completed)"
   [(const_int 0)]
@@ -2599,7 +2599,7 @@
    (set (match_operand:GPR 3 "register_operand" "=d")
 	(umod:GPR (match_dup 1)
 		  (match_dup 2)))]
-  ""
+  "ISA_HAS_<D>DIV"
   "#"
   "(TARGET_MIPS16 && cse_not_expected) || reload_completed"
   [(const_int 0)]
@@ -2617,7 +2617,7 @@
   [(set (match_operand:GPR 0 "register_operand")
 	(any_mod:GPR (match_operand:GPR 1 "register_operand")
 		     (match_operand:GPR 2 "register_operand")))]
-  ""
+  "ISA_HAS_<D>DIV"
 {
   rtx hilo;
 
@@ -2644,7 +2644,7 @@
 	  [(any_div:GPR (match_operand:GPR 1 "register_operand" "d")
 			(match_operand:GPR 2 "register_operand" "d"))]
 	  UNSPEC_SET_HILO))]
-  ""
+  "ISA_HAS_<GPR:D>DIV"
   { return mips_output_division ("<GPR:d>div<u>\t%.,%1,%2", operands); }
   [(set_attr "type" "idiv")
    (set_attr "mode" "<GPR:MODE>")])
Index: libgcc/Makefile.in
===================================================================
--- libgcc/Makefile.in	(Revision 199708)
+++ libgcc/Makefile.in	(Arbeitskopie)
@@ -293,6 +293,11 @@
 inst_libdir = $(libsubdir)$(MULTISUBDIR)
 inst_slibdir = $(slibdir)$(MULTIOSSUBDIR)
 
+# Get mips type: __mips or __mips64 is defined as GCC macro:
+MIPSTYPE := $(shell $(CC) $(CFLAGS) -dM -E - < /dev/null | \
+		grep -e "\<__mips\>" -e "\<__mips64\>" | \
+		(read define type value; echo $$type))
+
 gcc_compile_bare = $(CC) $(INTERNAL_CFLAGS)
 compile_deps = -MT $@ -MD -MP -MF $(basename $@).dep
 gcc_compile = $(gcc_compile_bare) -o $@ $(compile_deps)
@@ -401,8 +406,9 @@
 LIB2ADDEHSHARED += $(srcdir)/emutls.c
 
 # Library members defined in libgcc2.c.
-lib2funcs = _muldi3 _negdi2 _lshrdi3 _ashldi3 _ashrdi3 _cmpdi2 _ucmpdi2	   \
-	    _clear_cache _trampoline __main _absvsi2 \
+lib2difuncs = _muldi3
+lib2funcs = $(lib2difuncs) _negdi2 _lshrdi3 _ashldi3 _ashrdi3 _cmpdi2	   \
+	    _ucmpdi2 _clear_cache _trampoline __main _absvsi2		   \
 	    _absvdi2 _addvsi3 _addvdi3 _subvsi3 _subvdi3 _mulvsi3 _mulvdi3 \
 	    _negvsi2 _negvdi2 _ctors _ffssi2 _ffsdi2 _clz _clzsi2 _clzdi2  \
 	    _ctzsi2 _ctzdi2 _popcount_tab _popcountsi2 _popcountdi2	   \
@@ -427,7 +433,8 @@
 
 # These might cause a divide overflow trap and so are compiled with
 # unwinder info.
-LIB2_DIVMOD_FUNCS = _divdi3 _moddi3 _udivdi3 _umoddi3 _udiv_w_sdiv _udivmoddi4
+LIB2_DIVMODDI_FUNCS = _divdi3 _moddi3 _udivdi3 _umoddi3 _udivmoddi4
+LIB2_DIVMOD_FUNCS = $(LIB2_DIVMODDI_FUNCS) _udiv_w_sdiv
 
 # Remove any objects from lib2funcs and LIB2_DIVMOD_FUNCS that are
 # defined as optimized assembly code in LIB1ASMFUNCS or as C code
@@ -459,13 +466,29 @@
 $(lib2funcs-o): %$(objext): $(srcdir)/libgcc2.c
 	$(gcc_compile) -DL$* -c $< $(vis_hide)
 libgcc-objects += $(lib2funcs-o)
+ifeq ($(MIPSTYPE),__mips64)
+# Build functions needed by MIPS r5900.
+lib2difuncs-o = $(patsubst %,%$(objext),$(addsuffix _32bit,$(lib2difuncs)))
+$(lib2difuncs-o): %$(objext): $(srcdir)/libgcc2.c
+	$(gcc_compile) -DL$(subst _32bit,,$*) -DLIBGCC2_UNITS_PER_WORD=4 \
+	  -c $< $(vis_hide)
+libgcc-objects += $(lib2difuncs-o)
+endif
 
 ifeq ($(enable_shared),yes)
 lib2funcs-s-o = $(patsubst %,%_s$(objext),$(lib2funcs))
 $(lib2funcs-s-o): %_s$(objext): $(srcdir)/libgcc2.c
 	$(gcc_s_compile) -DL$* -c $<
 libgcc-s-objects += $(lib2funcs-s-o)
+ifeq ($(MIPSTYPE),__mips64)
+# Build functions needed by MIPS r5900.
+lib2difuncs-s-o = $(patsubst %,%_s$(objext),$(addsuffix _32bit,$(lib2difuncs)))
+$(lib2difuncs-s-o): %_s$(objext): $(srcdir)/libgcc2.c
+	$(gcc_s_compile) -DL$(subst _32bit,,$*) -DLIBGCC2_UNITS_PER_WORD=4 \
+	  -c $<
+libgcc-s-objects += $(lib2difuncs-s-o)
 endif
+endif
 
 ifneq ($(LIB2_SIDITI_CONV_FUNCS),)
 # Build libgcc2.c for each conversion function, with a specific
@@ -501,6 +524,15 @@
 	$(gcc_compile) -DL$* -c $< \
 	  $(LIB2_DIVMOD_EXCEPTION_FLAGS) $(vis_hide)
 libgcc-objects += $(lib2-divmod-o)
+ifeq ($(MIPSTYPE),__mips64)
+# Build functions needed by MIPS r5900.
+lib2-divmoddi-o = \
+	$(patsubst %,%$(objext),$(addsuffix _32bit,$(LIB2_DIVMODDI_FUNCS)))
+$(lib2-divmoddi-o): %$(objext): $(srcdir)/libgcc2.c
+	$(gcc_compile) -DL$(subst _32bit,,$*) -DLIBGCC2_UNITS_PER_WORD=4 \
+	  -c $< $(LIB2_DIVMOD_EXCEPTION_FLAGS) $(vis_hide)
+libgcc-objects += $(lib2-divmoddi-o)
+endif
 
 ifeq ($(enable_shared),yes)
 lib2-divmod-s-o = $(patsubst %,%_s$(objext),$(LIB2_DIVMOD_FUNCS))
@@ -508,7 +540,16 @@
 	$(gcc_s_compile) -DL$* -c $< \
 	  $(LIB2_DIVMOD_EXCEPTION_FLAGS)
 libgcc-s-objects += $(lib2-divmod-s-o)
+ifeq ($(MIPSTYPE),__mips64)
+# Build functions needed by MIPS r5900.
+lib2-divmoddi-s-o = \
+	$(patsubst %,%_s$(objext),$(addsuffix _32bit,$(LIB2_DIVMODDI_FUNCS)))
+$(lib2-divmoddi-s-o): %_s$(objext): $(srcdir)/libgcc2.c
+	$(gcc_s_compile) -DL$(subst _32bit,,$*) -DLIBGCC2_UNITS_PER_WORD=4 \
+	  -c $< $(LIB2_DIVMOD_EXCEPTION_FLAGS)
+libgcc-s-objects += $(lib2-divmoddi-s-o)
 endif
+endif
 
 ifeq ($(TPBIT),)
 # _sf_to_tf and _df_to_tf require tp-bit.c being compiled in.

Reply via email to