[Mesa-dev] [RFC 02/11] glsl: Add "built-in" function to do neg(fp64)
Ilia Mirkin
imirkin at alum.mit.edu
Fri Mar 3 17:13:05 UTC 2017
On Fri, Mar 3, 2017 at 11:57 AM, tournier.elie <tournier.elie at gmail.com> wrote:
> On 3 March 2017 at 16:29, Ilia Mirkin <imirkin at alum.mit.edu> wrote:
>> On Fri, Mar 3, 2017 at 11:22 AM, Elie Tournier <tournier.elie at gmail.com> wrote:
>>> Signed-off-by: Elie Tournier <elie.tournier at collabora.com>
>>> ---
>>> src/compiler/glsl/builtin_float64.h | 19 +++++++++++++++++++
>>> src/compiler/glsl/builtin_functions.cpp | 4 ++++
>>> src/compiler/glsl/builtin_functions.h | 3 +++
>>> src/compiler/glsl/float64.glsl | 10 ++++++++++
>>> 4 files changed, 36 insertions(+)
>>>
>>> diff --git a/src/compiler/glsl/builtin_float64.h b/src/compiler/glsl/builtin_float64.h
>>> index c1ec89d210..6df91e10f5 100644
>>> --- a/src/compiler/glsl/builtin_float64.h
>>> +++ b/src/compiler/glsl/builtin_float64.h
>>> @@ -17,3 +17,22 @@ fabs64(void *mem_ctx, builtin_available_predicate avail)
>>> sig->replace_parameters(&sig_parameters);
>>> return sig;
>>> }
>>> +ir_function_signature *
>>> +fneg64(void *mem_ctx, builtin_available_predicate avail)
>>> +{
>>> + ir_function_signature *const sig =
>>> + new(mem_ctx) ir_function_signature(glsl_type::uvec2_type, avail);
>>> + ir_factory body(&sig->body, mem_ctx);
>>> + sig->is_defined = true;
>>> +
>>> + exec_list sig_parameters;
>>> +
>>> + ir_variable *const r000C = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "a", ir_var_function_in);
>>> + sig_parameters.push_tail(r000C);
>>> + body.emit(assign(r000C, bit_xor(swizzle_x(r000C), body.constant(2147483648u)), 0x01));
>>> +
>>> + body.emit(ret(r000C));
>>> +
>>> + sig->replace_parameters(&sig_parameters);
>>> + return sig;
>>> +}
>>> diff --git a/src/compiler/glsl/builtin_functions.cpp b/src/compiler/glsl/builtin_functions.cpp
>>> index b0b1781725..a189b84190 100644
>>> --- a/src/compiler/glsl/builtin_functions.cpp
>>> +++ b/src/compiler/glsl/builtin_functions.cpp
>>> @@ -3133,6 +3133,10 @@ builtin_builder::create_builtins()
>>> generate_ir::fabs64(mem_ctx, integer_functions_supported),
>>> NULL);
>>>
>>> + add_function("__builtin_fneg64",
>>> + generate_ir::fneg64(mem_ctx, integer_functions_supported),
>>> + NULL);
>>> +
>>> #undef F
>>> #undef FI
>>> #undef FIUD_VEC
>>> diff --git a/src/compiler/glsl/builtin_functions.h b/src/compiler/glsl/builtin_functions.h
>>> index abe02d97b6..37c6cc33c2 100644
>>> --- a/src/compiler/glsl/builtin_functions.h
>>> +++ b/src/compiler/glsl/builtin_functions.h
>>> @@ -66,6 +66,9 @@ sign64(void *mem_ctx, builtin_available_predicate avail);
>>> ir_function_signature *
>>> fabs64(void *mem_ctx, builtin_available_predicate avail);
>>>
>>> +ir_function_signature *
>>> +fneg64(void *mem_ctx, builtin_available_predicate avail);
>>> +
>>> }
>>>
>>> #endif /* BULITIN_FUNCTIONS_H */
>>> diff --git a/src/compiler/glsl/float64.glsl b/src/compiler/glsl/float64.glsl
>>> index b8f0c2e444..82875e9407 100644
>>> --- a/src/compiler/glsl/float64.glsl
>>> +++ b/src/compiler/glsl/float64.glsl
>>> @@ -26,3 +26,13 @@ fabs64( uvec2 a )
>>> a.x &= 0x7FFFFFFFu;
>>> return a;
>>> }
>>> +
>>> +/* Negate value of a Float64 :
>>> + * Toggle the sign bit
>>> + */
>>> +uvec2
>>> +fneg64( uvec2 a )
>>> +{
>>> + a.x ^= (1u<<31);
>>
>> Is this right for NaN? Presumably neg(NaN) should == NaN.
>
> The IEEE 754 standard say :
>
> " 6.3 The sign bit
>
> When either an input or result is NaN, this standard does not
> interpret the sign of a NaN. Note, however,
> that operations on bit strings copy, negate, abs, copySign specify the
> sign bit of a NaN result,
> sometimes based upon the sign bit of a NaN operand. The logical
> predicate totalOrder is also affected by
> the sign bit of a NaN operand. For all other operations, this standard
> does not specify the sign bit of a NaN
> result, even when there is only one input NaN, or when the NaN is
> produced from an invalid operation. "
>
> So neg(NaN) == NaN
Right ... I guess I meant that there's a certain amount of
normalization that's required to be applied to results of floating
point operations. I was wondering if the sign bit of a NaN had to be
cleared, so that it would be in canonical form. (Just like you'd set
all of the mantissa bits, even though setting any of them results in a
NaN when exp == 0x7ff.) You've been digging in the FP64 standard a lot
more than I have, so if you think it's acceptable to have a fp64
function return a NaN with the sign bit set, that's fine by me.
-ilia
More information about the mesa-dev
mailing list