On 03/03/2017 09:13 AM, Ilia Mirkin wrote: > On Fri, Mar 3, 2017 at 11:57 AM, tournier.elie <tournier.e...@gmail.com> > wrote: >> On 3 March 2017 at 16:29, Ilia Mirkin <imir...@alum.mit.edu> wrote: >>> On Fri, Mar 3, 2017 at 11:22 AM, Elie Tournier <tournier.e...@gmail.com> >>> wrote: >>>> Signed-off-by: Elie Tournier <elie.tourn...@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.
This would be easy enough to test, and we probably should. We can check unpackDouble2x32(-packDouble2x32(uvec2_that_is_NAN)) == unpackDouble2x32(packDouble2x32(uvec2_that_is_NAN)). We could also check this on a CPU. > -ilia _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev