mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-02 20:20:09 +01:00
nir/algebraic: Add better lowering of ldexp
This commit is contained in:
parent
b75d770963
commit
08fe89864b
1 changed files with 27 additions and 2 deletions
|
|
@ -276,8 +276,6 @@ optimizations = [
|
|||
(('frem', a, b), ('fsub', a, ('fmul', b, ('ftrunc', ('fdiv', a, b)))), 'options->lower_fmod'),
|
||||
(('uadd_carry', a, b), ('b2i', ('ult', ('iadd', a, b), a)), 'options->lower_uadd_carry'),
|
||||
(('usub_borrow', a, b), ('b2i', ('ult', a, b)), 'options->lower_usub_borrow'),
|
||||
(('ldexp', 'x', 'exp'),
|
||||
('fmul', 'x', ('ishl', ('imin', ('imax', ('iadd', 'exp', 0x7f), 0), 0xff), 23))),
|
||||
|
||||
(('bitfield_insert', 'base', 'insert', 'offset', 'bits'),
|
||||
('bcsel', ('ilt', 31, 'bits'), 'insert',
|
||||
|
|
@ -359,6 +357,33 @@ optimizations = [
|
|||
'options->lower_unpack_snorm_4x8'),
|
||||
]
|
||||
|
||||
def fexp2i(exp):
|
||||
# We assume that exp is already in range.
|
||||
return ('ishl', ('iadd', exp, 127), 23)
|
||||
|
||||
def ldexp32(f, exp):
|
||||
# First, we clamp exp to a reasonable range. The maximum range that we
|
||||
# need is the largest range for an exponent, ([-127, 128] if you include
|
||||
# inf and 0) plus the number of mantissa bits in either direction to
|
||||
# account for denormals. This means that we need at least a range of
|
||||
# [-150, 151]. For our implementation, however, what we really care
|
||||
# about is that neither exp/2 nor exp-exp/2 go out of the regular range
|
||||
# for floating-point exponents.
|
||||
exp = ('imin', ('imax', exp, -252), 254)
|
||||
|
||||
# Now we compute two powers of 2, one for exp/2 and one for exp-exp/2.
|
||||
# While the spec technically defines ldexp as f * 2.0^exp, simply
|
||||
# multiplying once doesn't work when denormals are involved because
|
||||
# 2.0^exp may not be representable even though ldexp(f, exp) is (see
|
||||
# comments above about range). Instead, we create two powers of two and
|
||||
# multiply by them each in turn. That way the effective range of our
|
||||
# exponent is doubled.
|
||||
pow2_1 = fexp2i(('ishr', exp, 1))
|
||||
pow2_2 = fexp2i(('isub', exp, ('ishr', exp, 1)))
|
||||
return ('fmul', ('fmul', f, pow2_1), pow2_2)
|
||||
|
||||
optimizations += [(('ldexp', 'x', 'exp'), ldexp32('x', 'exp'))]
|
||||
|
||||
# Unreal Engine 4 demo applications open-codes bitfieldReverse()
|
||||
def bitfield_reverse(u):
|
||||
step1 = ('ior', ('ishl', u, 16), ('ushr', u, 16))
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue