[gnu.gcc.bug] bug in MIPS movsf

grunwald@FOOBAR.COLORADO.EDU (Dirk Grunwald) (12/05/89)

Think I found that bug I mentioned a while back.

The following
----------
int foo(int i, float f)
{
	return ( i + f );
}

main()
{
  printf("foo is %d\n", foo(10,10.5));
}
----------

produces "foo is 10." If you change the float f to a double, it works.
the problem is the useless statement I saw...
	mfc1 $6,$f4
in the output. This is actually part of the calling sequence -- we should
move scalar reg $6 (first float arg) to a float reg ($f4), but this does
it the other way around.

The patch is in mips.md, 

  (define_insn "movsf"
    [(set (match_operand:SF 0 "general_operand" "=f,rf,m,f,!rf")
  	(match_operand:SF 1 "general_operand" "f,m,rf,F,rf"))
     (clobber (reg:SI 24))]
    ""
    "*
  {
    if (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG)
      {
        if (REGNO (operands[0]) >= 32)
  	{
  	  if (REGNO (operands[1]) >= 32)
  	    return \"mov.s %0,%1\\t#movsf %1 -> %0 \";
  	  return \"mfc1 %1,%0\";
  	}
        if (REGNO (operands[1]) >= 32)
  	return \"mfc1 %0,%1\";
        return \"add%: %0,$0,%1\";
  
---- should be...
  (define_insn "movsf"
    [(set (match_operand:SF 0 "general_operand" "=f,rf,m,f,!rf")
  	(match_operand:SF 1 "general_operand" "f,m,rf,F,rf"))
     (clobber (reg:SI 24))]
    ""
    "*
  {
    if (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG)
      {
        if (REGNO (operands[0]) >= 32)
  	{
  	  if (REGNO (operands[1]) >= 32)
!  	    return \"mov.s %0,%1\\t#movsf %1 -> %0 \";	/* sf -> sf */
!  	  return \"mtc1 %1,%0\";			/* si -> sf */
  	}
        if (REGNO (operands[1]) >= 32)
!  	return \"mfc1 %0,%1\";				/* sf -> si */
        return \"add%: %0,$0,%1\";
  
------


this bug is present in 1.36 and 1.36.9.