glsl: Extract ir_binop_ldexp implementation to a separate function
Signed-off-by: Ian Romanick <ian.d.romanick@intel.com> Reviewed-by: Matt Turner <mattst88@gmail.com>
This commit is contained in:
@@ -519,6 +519,24 @@ find_msb_int(int32_t v)
|
|||||||
return find_msb_uint(v < 0 ? ~v : v);
|
return find_msb_uint(v < 0 ? ~v : v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static float
|
||||||
|
ldexpf_flush_subnormal(float x, int exp)
|
||||||
|
{
|
||||||
|
const float result = ldexpf(x, exp);
|
||||||
|
|
||||||
|
/* Flush subnormal values to zero. */
|
||||||
|
return !isnormal(result) ? copysignf(0.0f, x) : result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static double
|
||||||
|
ldexp_flush_subnormal(double x, int exp)
|
||||||
|
{
|
||||||
|
const double result = ldexp(x, exp);
|
||||||
|
|
||||||
|
/* Flush subnormal values to zero. */
|
||||||
|
return !isnormal(result) ? copysign(0.0, x) : result;
|
||||||
|
}
|
||||||
|
|
||||||
ir_constant *
|
ir_constant *
|
||||||
ir_expression::constant_expression_value(struct hash_table *variable_context)
|
ir_expression::constant_expression_value(struct hash_table *variable_context)
|
||||||
{
|
{
|
||||||
@@ -1617,17 +1635,16 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case ir_binop_ldexp:
|
case ir_binop_ldexp:
|
||||||
for (unsigned c = 0; c < components; c++) {
|
for (unsigned c = 0; c < op[0]->type->components(); c++) {
|
||||||
if (op[0]->type->base_type == GLSL_TYPE_DOUBLE) {
|
switch (this->type->base_type) {
|
||||||
data.d[c] = ldexp(op[0]->value.d[c], op[1]->value.i[c]);
|
case GLSL_TYPE_FLOAT:
|
||||||
/* Flush subnormal values to zero. */
|
data.f[c] = ldexpf_flush_subnormal(op[0]->value.f[c], op[1]->value.i[c]);
|
||||||
if (!isnormal(data.d[c]))
|
break;
|
||||||
data.d[c] = copysign(0.0, op[0]->value.d[c]);
|
case GLSL_TYPE_DOUBLE:
|
||||||
} else {
|
data.d[c] = ldexp_flush_subnormal(op[0]->value.d[c], op[1]->value.i[c]);
|
||||||
data.f[c] = ldexpf(op[0]->value.f[c], op[1]->value.i[c]);
|
break;
|
||||||
/* Flush subnormal values to zero. */
|
default:
|
||||||
if (!isnormal(data.f[c]))
|
assert(0);
|
||||||
data.f[c] = copysignf(0.0f, op[0]->value.f[c]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
Reference in New Issue
Block a user