Skip to content

Commit

Permalink
-gen gcc: emit all floating-point constants in C99-compatible hex for…
Browse files Browse the repository at this point in the history
…mat.

e.g. 3.5 -> "0x1.Cp+1"
This prevents precision loss from emitting decimal constants.
  • Loading branch information
countingpine committed Sep 22, 2014
1 parent 9e4900a commit de854d5
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 9 deletions.
47 changes: 47 additions & 0 deletions src/compiler/hlp.bas
Expand Up @@ -99,6 +99,53 @@ function hFloatToHex _
end if
end function

function hFloatToHex_C99 _
( _
byval value as double _
) as string

'' float hex format defined in C99 spec: e.g. 0x1.fp+3

dim as ulongint n = *cptr( ulongint ptr, @value )

dim as integer sign = n shr 63
dim as integer exp2 = (n shr 52) and (1u shl 11 - 1)
dim as ulongint mantissa = n and (1ull shl 52 - 1)

dim as string ret

if( sign <> 0 ) then
'' negative
ret = "-0x"
else
'' positive
ret = "0x"
end if

exp2 -= 1023
if( exp2 > -1023 ) then
'' normalized
ret += "1." + hex( mantissa, 13 )
if right( ret, 1 ) = "0" then ret = rtrim( ret, "0" )
else
if mantissa = 0 then
'' zero
ret += "0"
exp2 = 0
else
'' denormed
exp2 += 1
ret += "0." + hex( mantissa, 13 )
if right( ret, 1 ) = "0" then ret = rtrim( ret, "0" )
end if
end if

ret += "p" & (*iif( exp2 >= 0, @"+", @"-" )) + str( abs( exp2 ) )

return ret

end function

'':::::
function hFBrelop2IRrelop _
( _
Expand Down
5 changes: 5 additions & 0 deletions src/compiler/hlp.bi
Expand Up @@ -77,6 +77,11 @@ declare function hFloatToHex _
byval dtype as integer _
) as string

declare function hFloatToHex_C99 _
( _
byval value as double _
) as string

declare function hCheckFileFormat _
( _
byval f as integer _
Expand Down
11 changes: 2 additions & 9 deletions src/compiler/ir-hlc.bas
Expand Up @@ -1990,15 +1990,8 @@ private function hEmitFloat _

case else

'' Singles and Doubles both given Double precision to prevent being mis-converted
s = str( value )

'' Append .0 if there is no dot or exponent yet,
'' to prevent gcc from treating it as int
'' (e.g. 1 -> 1.0, but 0.1 or 1e-100 can stay as-is)
if( instr( s, any "e." ) = 0 ) then
s += ".0"
end if
'' Convert to exact representation using C99-compatible hex format
s = hFloatToHex_C99( value )

'' float type suffix
if( dtype = FB_DATATYPE_SINGLE ) then
Expand Down

0 comments on commit de854d5

Please sign in to comment.