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: Izumi Tsutsui <tsutsui%ceres.dti.ne.jp@localhost>
To: riastradh%NetBSD.org@localhost
Cc: gnats-bugs%netbsd.org@localhost, tsutsui%ceres.dti.ne.jp@localhost
Subject: Re: port-mips/57680: printf("%.1f") shows wrong results on R3000mipseb
Date: Wed, 15 Nov 2023 18:58:49 +0900

 riastradh@ wrote:
 
 >  > > Wasn't there a difference about inline vs non-inline __rfs, which
 >  > > should presumably affect where the cfc1 instruction is?
 >  > 
 >  > It looks the differences of nops after lwc1 are not relevant to
 >  > cfc1 used in __rfs().
 >  
 >  It sounds like there are two separate parts to the differences between
 >  generated code in the working and non-working libc:
 >  
 >  (a) inline __rfs including cfc1, vs out-of-line call to __rfs, and
 >  (b) nops in lwc1 delay slots.
 
 Yes.
 
 >  Both changes are _triggered_ by putting `inline' vs `__noinline' on
 >  the definition in the source code, but I'm talking about the
 >  differences in the generated code, not the differences in the source
 >  code.
 
 Ok.
 
 >  If you take the _non-working_ intermediate .s file with inline __rfs
 >  in the source code, and insert nops where the _working_ one has nops
 >  after lwc1, and then assemble and link it all, does that result work?
 
 I've added intermidiate .s files by --save-temps to gist:
 
 - https://gist.github.com/tsutsui/85b03f26aa1bfd3fdd884bce8fd8c1e7#file-dtoa-save-temps-inline-s
    dtoa.s by 'gcc --save-temps' from the original libc source,
    i.e. non-working printf
 
 - https://gist.github.com/tsutsui/85b03f26aa1bfd3fdd884bce8fd8c1e7#file-dtoa-save-temps-noinline-s
    dtoa.s by 'gcc --save-temps' with __noinline __rfs in <mips/fenv.h>,
    working printf
 
 - https://gist.github.com/tsutsui/85b03f26aa1bfd3fdd884bce8fd8c1e7#file-dtoa-save-temps-s-diff
    diff between the above two --save-temps .s files
 
 It looks:
  - the inline version uses ".set reorder" by default and it puts
    ".set noreorder" and ".set nomacro" around branch instructions
    (to handle branch delay slot?)
 
  - the inline version also put '#nop' (commented out nop) after
    lwc1 instructions (not confirmed where this comes from)
 
  - the noinline version uses ".set noreorder" by default and
    put 'nop' (without '#') after lwc1 instructions
 
 It looks there are something wrong in mips gcc?
 
 >  Something else to try: assert that fegetround() returned FE_TONEAREST.
 >  Nothing is linked against libm in your test cases, so nothing should
 >  be changing the rounding mode, right?  So it should always return
 >  FE_TONEAREST.  If the assertion fails, that will suggest the machine
 >  state is set up in correctly or we're misusing cfc1 somehow; if the
 >  assertion passes, perhaps the __rfs/cfc1/fegetround business is a red
 >  herring, and it's actually a problem with some other part of the code
 >  (or with the compiler's code generation).
 
 A simple printf shows Rounding=1 so the fegetround() in dtoa.c should
 return FE_TONEAREST, as expected.
 
 ---
 Izumi Tsutsui
 


Home | Main Index | Thread Index | Old Index