NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: port-mips/57680: printf("%.1f") shows wrong results on R3000mipseb



The following reply was made to PR port-mips/57680; it has been noted by GNATS.

From: Taylor R Campbell <campbell%mumble.net@localhost>
To: Taylor R Campbell <riastradh%NetBSD.org@localhost>
Cc: Izumi Tsutsui <tsutsui%ceres.dti.ne.jp@localhost>, gnats-bugs%netbsd.org@localhost, tsutsui%ceres.dti.ne.jp@localhost
Subject: Re: port-mips/57680: printf("%.1f") shows wrong results on R3000mipseb
Date: Thu, 16 Nov 2023 02:28:09 +0000

 gas/config/tc-mips.c has the following fragment which looks like it
 should handle this case:
 
       else if ((!cop_interlocks && (pinfo1 & INSN_COPROC_MOVE))
                || (!cop_mem_interlocks && (pinfo1 & INSN_COPROC_MEMORY_DELA=
 Y)))
         {
           /* Handle cases where INSN1 writes to a known general coprocessor
              register.  There must be a one instruction delay before INSN2
              if INSN2 reads that register, otherwise no delay is needed.  */
           mask =3D fpr_write_mask (insn1);
           if (mask !=3D 0)
             {
               if (!insn2 || (mask & fpr_read_mask (insn2)) !=3D 0)
                 return 1;
             }
 
 However, if I use mipseb--netbsd-as from a newsmips tooldir to
 assemble the following fragment, a nop is inserted between the lw and
 add but not between the lwc1 and add.d:
 
         .set    reorder
 
 good:   lw      $a0,0($sp)
         add     $a1,$a0,$a0
 
 bad:    lwc1    $f1,0($sp)
         lwc1    $f0,4($sp)
         add.d   $f2,$f0,$f0
 
 Examining the output with objdump reveals:
 
 00000000 <good>:
    0:   8fa40000        lw      a0,0(sp)
    4:   00000000        nop
    8:   00842820        add     a1,a0,a0
 
 0000000c <bad>:
    c:   c7a10000        lwc1    $f1,0(sp)
   10:   c7a00004        lwc1    $f0,4(sp)
   14:   46200080        add.d   $f2,$f0,$f0
 
 Cursory examination of the rest of tc-mips.c and mips-opc.c suggests
 that the lwc1 instructions ought to have INSN_COPROC_MEMORY_DELAY set,
 and both fpr_write_mask for the lwc1 and fpr_read_mask for the add.d
 ought to include $f0/$f1.  But I haven't tried putting debug messages
 into gas to determine this conclusively.
 
 So it looks like this isn't just a matter of failing to recognize the
 dual-register business for double floating-point operations
 (fpr_read/write_mask appear to have logic for that), but rather,
 something is going awry with inserting nops in delay slots for lwc1
 altogether.
 


Home | Main Index | Thread Index | Old Index