patch for m68k -O0 libstdc++ compiler abort

Jim Wilson wilson@cygnus.com
Tue Oct 13 17:58:00 GMT 1998


A m68k compiler fails while trying to compile libstdc++ without optimization.
I get this error:
(insn 73 71 75 (set (reg:XF 3 %d3)
        (reg:XF 6 %d6)) 63 {movxf+1} (nil)
    (nil))
../../devo/gcc/toplev.c:1455: Internal compiler error

There are two things wrong here:
1) We shouldn't have allocated a value that starts in the D registers and
   ends in the A registers.  This won't work if we matched a 'd' constraint.
2) The movxf pattern does not accept general reg to general reg moves.  This
   caused the failure.  Either it must handle such moves, or else we need to
   modify REGISTER_MOVE_COST to say that such moves are expensive, so that
   reload will fix them.  Handling GP register to GP register moves seems like
   the more reasonable option, since every other FP move pattern already allows
   them.

I wrote patches to fix both.

#1 probably doesn't have to be fixed, as the compiler will still work; it
will just generate code that looks funny.  It looks like a potential
maintenance problem though.  One possible negative thing is that by disallowing
D/A reg crossover, we essentially have fewer registers, and hence may get
worse code.  I don't think this is serious enough to worry about though.

I'll just checked in this patch patch.

Mon Oct 12 17:30:01 1998  Jim Wilson  <wilson@cygnus.com>

	* m68k.h (HARD_REGNO_MODE_OK): For FP regs, add REGNO >= 16 check.
	Add comment to document problems with TARGET_SUN_FPA version of this
	macro.
	* m68k.md (movxf+1): Support 'r'/'r' moves.

Index: m68k.h
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/config/m68k/m68k.h,v
retrieving revision 1.62
diff -p -r1.62 m68k.h
*** m68k.h	1998/10/09 23:03:26	1.62
--- m68k.h	1998/10/13 00:22:24
*************** extern int target_flags;
*** 471,478 ****
  
  #define HARD_REGNO_MODE_OK(REGNO, MODE) \
    (((REGNO) < 16					\
!    && !((REGNO) < 8 && (REGNO) + GET_MODE_SIZE ((MODE)) / 4 > 8))	\
!    || ((REGNO) < 24				        \
         && TARGET_68881                                  \
         && (GET_MODE_CLASS (MODE) == MODE_FLOAT		\
  	   || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT)))
--- 471,478 ----
  
  #define HARD_REGNO_MODE_OK(REGNO, MODE) \
    (((REGNO) < 16					\
!     && !((REGNO) < 8 && (REGNO) + GET_MODE_SIZE (MODE) / 4 > 8))	\
!    || ((REGNO) >= 16 && (REGNO) < 24				        \
         && TARGET_68881                                  \
         && (GET_MODE_CLASS (MODE) == MODE_FLOAT		\
  	   || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT)))
*************** extern int target_flags;
*** 486,491 ****
--- 486,496 ----
     (apparently) hold whatever you feel like putting in them.
     If using the fpa, don't put a double in d7/a0.  */
  
+ /* ??? This is confused.  The check to prohibit d7/a0 overlaps should always
+    be enabled regardless of whether TARGET_FPA is specified.  It isn't clear
+    what the other d/a register checks are for.  Every check using REGNO
+    actually needs to use a range, e.g. 24>=X<56 not <56.  There is probably
+    no one using this code anymore.  */
  #define HARD_REGNO_MODE_OK(REGNO, MODE) \
  (((REGNO) < 16								\
    && !(TARGET_FPA							\
Index: m68k.md
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/config/m68k/m68k.md,v
retrieving revision 1.68
diff -p -r1.68 m68k.md
*** m68k.md	1998/10/09 23:03:26	1.68
--- m68k.md	1998/10/13 00:22:24
***************
*** 1224,1231 ****
  }")
  
  (define_insn ""
!   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,!r,!f")
! 	(match_operand:XF 1 "nonimmediate_operand" "m,f,f,f,r"))]
    "TARGET_68881"
    "*
  {
--- 1224,1231 ----
  }")
  
  (define_insn ""
!   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,!r,!f,!r")
! 	(match_operand:XF 1 "nonimmediate_operand" "m,f,f,f,r,!r"))]
    "TARGET_68881"
    "*
  {
***************
*** 1247,1261 ****
          return \"fmove%.x %1,%0\";
        return \"fmove%.x %f1,%0\";
      }
!   if (REG_P (operands[0]))
      {
!       output_asm_insn (\"fmove%.x %f1,%-\;move%.l %+,%0\", operands);
!       operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
!       output_asm_insn (\"move%.l %+,%0\", operands);
!       operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
!       return \"move%.l %+,%0\";
      }
!   return \"fmove%.x %f1,%0\";
  }
  ")
  
--- 1247,1266 ----
          return \"fmove%.x %1,%0\";
        return \"fmove%.x %f1,%0\";
      }
!   if (FP_REG_P (operands[1]))
      {
!       if (REG_P (operands[0]))
! 	{
! 	  output_asm_insn (\"fmove%.x %f1,%-\;move%.l %+,%0\", operands);
! 	  operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
! 	  output_asm_insn (\"move%.l %+,%0\", operands);
! 	  operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
! 	  return \"move%.l %+,%0\";
! 	}
!       /* Must be memory destination.  */
!       return \"fmove%.x %f1,%0\";
      }
!   return output_move_double (operands);
  }
  ")
  



More information about the Gcc-patches mailing list