Path: utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!tut.cis.ohio-state.edu!FOOBAR.COLORADO.EDU!grunwald From: grunwald@FOOBAR.COLORADO.EDU (Dirk Grunwald) Newsgroups: gnu.gcc.bug Subject: bug in MIPS movsf Message-ID: <8912050255.AA21995@foobar.Colorado.EDU> Date: 5 Dec 89 02:55:07 GMT Sender: daemon@tut.cis.ohio-state.edu Reply-To: grunwald@foobar.colorado.edu Distribution: gnu Organization: GNUs Not Usenet Lines: 68 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.