[Mesa-dev] [PATCH 2/9] glsl: add u64->fp64 and i64->fp64 builtins.

Roland Scheidegger sroland at vmware.com
Thu Feb 1 17:40:45 UTC 2018


I suppose this is a bit inefficient if the hw actually supports some
double ops?
I mean for uint->double you could just convert the low 8 bits and high
24 bits (or different split) separately to float, convert both to double
and add them. (I think should work for int->double exactly the same
despite the sign bit.)
But in any case, for hw not supporting double ops at all this looks like
the right approach.

Roland

Am 01.02.2018 um 04:33 schrieb Dave Airlie:
> From: Elie Tournier <tournier.elie at gmail.com>
> 
> This adds the first two fp64 builtins.
> They are for int/uint to fp64 conversions.
> 
> cayman hw can't do it, and this avoids me having to lower it in
> the backend, and also starts to provide some of the soft fp64
> infrastructure.
> 
> [airlied: extracted from Elie's tree]
> Signed-off-by: Dave Airlie <airlied at redhat.com>
> ---
>  src/compiler/Makefile.sources           |   1 +
>  src/compiler/glsl/builtin_float64.h     | 872 ++++++++++++++++++++++++++++++++
>  src/compiler/glsl/builtin_functions.cpp |   8 +
>  src/compiler/glsl/builtin_functions.h   |   6 +
>  src/compiler/glsl/float64.glsl          | 126 +++++
>  src/compiler/glsl/generate_ir.cpp       |   2 +-
>  6 files changed, 1014 insertions(+), 1 deletion(-)
>  create mode 100644 src/compiler/glsl/builtin_float64.h
>  create mode 100644 src/compiler/glsl/float64.glsl
> 
> diff --git a/src/compiler/Makefile.sources b/src/compiler/Makefile.sources
> index bb93ba68a2..9623b3ea62 100644
> --- a/src/compiler/Makefile.sources
> +++ b/src/compiler/Makefile.sources
> @@ -22,6 +22,7 @@ LIBGLSL_FILES = \
>  	glsl/builtin_functions.cpp \
>  	glsl/builtin_functions.h \
>  	glsl/builtin_int64.h \
> +	glsl/builtin_float64.h \
>  	glsl/builtin_types.cpp \
>  	glsl/builtin_variables.cpp \
>  	glsl/generate_ir.cpp \
> diff --git a/src/compiler/glsl/builtin_float64.h b/src/compiler/glsl/builtin_float64.h
> new file mode 100644
> index 0000000000..5747d22418
> --- /dev/null
> +++ b/src/compiler/glsl/builtin_float64.h
> @@ -0,0 +1,872 @@
> +ir_function_signature *
> +countLeadingZeros32(void *mem_ctx, builtin_available_predicate avail)
> +{
> +   ir_function_signature *const sig =
> +      new(mem_ctx) ir_function_signature(glsl_type::int_type, avail);
> +   ir_factory body(&sig->body, mem_ctx);
> +   sig->is_defined = true;
> +
> +   exec_list sig_parameters;
> +
> +   ir_variable *const r000B = new(mem_ctx) ir_variable(glsl_type::uint_type, "a", ir_var_function_in);
> +   sig_parameters.push_tail(r000B);
> +   ir_variable *const r000C = body.make_temp(glsl_type::int_type, "return_value");
> +   ir_variable *const r000D = new(mem_ctx) ir_variable(glsl_type::int_type, "shiftCount", ir_var_auto);
> +   body.emit(r000D);
> +   /* IF CONDITION */
> +   ir_expression *const r000F = equal(r000B, body.constant(0u));
> +   ir_if *f000E = new(mem_ctx) ir_if(operand(r000F).val);
> +   exec_list *const f000E_parent_instructions = body.instructions;
> +
> +      /* THEN INSTRUCTIONS */
> +      body.instructions = &f000E->then_instructions;
> +
> +      body.emit(assign(r000C, body.constant(int(32)), 0x01));
> +
> +
> +      /* ELSE INSTRUCTIONS */
> +      body.instructions = &f000E->else_instructions;
> +
> +      body.emit(assign(r000D, body.constant(int(0)), 0x01));
> +
> +      /* IF CONDITION */
> +      ir_expression *const r0011 = bit_and(r000B, body.constant(4294901760u));
> +      ir_expression *const r0012 = equal(r0011, body.constant(0u));
> +      ir_if *f0010 = new(mem_ctx) ir_if(operand(r0012).val);
> +      exec_list *const f0010_parent_instructions = body.instructions;
> +
> +         /* THEN INSTRUCTIONS */
> +         body.instructions = &f0010->then_instructions;
> +
> +         body.emit(assign(r000D, body.constant(int(16)), 0x01));
> +
> +         body.emit(assign(r000B, lshift(r000B, body.constant(int(16))), 0x01));
> +
> +
> +      body.instructions = f0010_parent_instructions;
> +      body.emit(f0010);
> +
> +      /* END IF */
> +
> +      /* IF CONDITION */
> +      ir_expression *const r0014 = bit_and(r000B, body.constant(4278190080u));
> +      ir_expression *const r0015 = equal(r0014, body.constant(0u));
> +      ir_if *f0013 = new(mem_ctx) ir_if(operand(r0015).val);
> +      exec_list *const f0013_parent_instructions = body.instructions;
> +
> +         /* THEN INSTRUCTIONS */
> +         body.instructions = &f0013->then_instructions;
> +
> +         body.emit(assign(r000D, add(r000D, body.constant(int(8))), 0x01));
> +
> +         body.emit(assign(r000B, lshift(r000B, body.constant(int(8))), 0x01));
> +
> +
> +      body.instructions = f0013_parent_instructions;
> +      body.emit(f0013);
> +
> +      /* END IF */
> +
> +      /* IF CONDITION */
> +      ir_expression *const r0017 = bit_and(r000B, body.constant(4026531840u));
> +      ir_expression *const r0018 = equal(r0017, body.constant(0u));
> +      ir_if *f0016 = new(mem_ctx) ir_if(operand(r0018).val);
> +      exec_list *const f0016_parent_instructions = body.instructions;
> +
> +         /* THEN INSTRUCTIONS */
> +         body.instructions = &f0016->then_instructions;
> +
> +         body.emit(assign(r000D, add(r000D, body.constant(int(4))), 0x01));
> +
> +         body.emit(assign(r000B, lshift(r000B, body.constant(int(4))), 0x01));
> +
> +
> +      body.instructions = f0016_parent_instructions;
> +      body.emit(f0016);
> +
> +      /* END IF */
> +
> +      /* IF CONDITION */
> +      ir_expression *const r001A = bit_and(r000B, body.constant(3221225472u));
> +      ir_expression *const r001B = equal(r001A, body.constant(0u));
> +      ir_if *f0019 = new(mem_ctx) ir_if(operand(r001B).val);
> +      exec_list *const f0019_parent_instructions = body.instructions;
> +
> +         /* THEN INSTRUCTIONS */
> +         body.instructions = &f0019->then_instructions;
> +
> +         body.emit(assign(r000D, add(r000D, body.constant(int(2))), 0x01));
> +
> +         body.emit(assign(r000B, lshift(r000B, body.constant(int(2))), 0x01));
> +
> +
> +      body.instructions = f0019_parent_instructions;
> +      body.emit(f0019);
> +
> +      /* END IF */
> +
> +      /* IF CONDITION */
> +      ir_expression *const r001D = bit_and(r000B, body.constant(2147483648u));
> +      ir_expression *const r001E = equal(r001D, body.constant(0u));
> +      ir_if *f001C = new(mem_ctx) ir_if(operand(r001E).val);
> +      exec_list *const f001C_parent_instructions = body.instructions;
> +
> +         /* THEN INSTRUCTIONS */
> +         body.instructions = &f001C->then_instructions;
> +
> +         body.emit(assign(r000D, add(r000D, body.constant(int(1))), 0x01));
> +
> +
> +      body.instructions = f001C_parent_instructions;
> +      body.emit(f001C);
> +
> +      /* END IF */
> +
> +      body.emit(assign(r000C, r000D, 0x01));
> +
> +
> +   body.instructions = f000E_parent_instructions;
> +   body.emit(f000E);
> +
> +   /* END IF */
> +
> +   body.emit(ret(r000C));
> +
> +   sig->replace_parameters(&sig_parameters);
> +   return sig;
> +}
> +ir_function_signature *
> +packFloat64(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 r001F = new(mem_ctx) ir_variable(glsl_type::uint_type, "zSign", ir_var_function_in);
> +   sig_parameters.push_tail(r001F);
> +   ir_variable *const r0020 = new(mem_ctx) ir_variable(glsl_type::int_type, "zExp", ir_var_function_in);
> +   sig_parameters.push_tail(r0020);
> +   ir_variable *const r0021 = new(mem_ctx) ir_variable(glsl_type::uint_type, "zFrac0", ir_var_function_in);
> +   sig_parameters.push_tail(r0021);
> +   ir_variable *const r0022 = new(mem_ctx) ir_variable(glsl_type::uint_type, "zFrac1", ir_var_function_in);
> +   sig_parameters.push_tail(r0022);
> +   ir_variable *const r0023 = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "z", ir_var_auto);
> +   body.emit(r0023);
> +   ir_expression *const r0024 = lshift(r001F, body.constant(int(31)));
> +   ir_expression *const r0025 = expr(ir_unop_i2u, r0020);
> +   ir_expression *const r0026 = lshift(r0025, body.constant(int(20)));
> +   ir_expression *const r0027 = add(r0024, r0026);
> +   body.emit(assign(r0023, add(r0027, r0021), 0x02));
> +
> +   body.emit(assign(r0023, r0022, 0x01));
> +
> +   body.emit(ret(r0023));
> +
> +   sig->replace_parameters(&sig_parameters);
> +   return sig;
> +}
> +ir_function_signature *
> +shift64Right(void *mem_ctx, builtin_available_predicate avail)
> +{
> +   ir_function_signature *const sig =
> +      new(mem_ctx) ir_function_signature(glsl_type::void_type, avail);
> +   ir_factory body(&sig->body, mem_ctx);
> +   sig->is_defined = true;
> +
> +   exec_list sig_parameters;
> +
> +   ir_variable *const r0028 = new(mem_ctx) ir_variable(glsl_type::uint_type, "a0", ir_var_function_in);
> +   sig_parameters.push_tail(r0028);
> +   ir_variable *const r0029 = new(mem_ctx) ir_variable(glsl_type::uint_type, "a1", ir_var_function_in);
> +   sig_parameters.push_tail(r0029);
> +   ir_variable *const r002A = new(mem_ctx) ir_variable(glsl_type::int_type, "count", ir_var_function_in);
> +   sig_parameters.push_tail(r002A);
> +   ir_variable *const r002B = new(mem_ctx) ir_variable(glsl_type::uint_type, "z0Ptr", ir_var_function_inout);
> +   sig_parameters.push_tail(r002B);
> +   ir_variable *const r002C = new(mem_ctx) ir_variable(glsl_type::uint_type, "z1Ptr", ir_var_function_inout);
> +   sig_parameters.push_tail(r002C);
> +   ir_variable *const r002D = new(mem_ctx) ir_variable(glsl_type::uint_type, "z1", ir_var_auto);
> +   body.emit(r002D);
> +   ir_variable *const r002E = new(mem_ctx) ir_variable(glsl_type::uint_type, "z0", ir_var_auto);
> +   body.emit(r002E);
> +   ir_variable *const r002F = body.make_temp(glsl_type::int_type, "assignment_tmp");
> +   ir_expression *const r0030 = neg(r002A);
> +   body.emit(assign(r002F, bit_and(r0030, body.constant(int(31))), 0x01));
> +
> +   /* IF CONDITION */
> +   ir_expression *const r0032 = equal(r002A, body.constant(int(0)));
> +   ir_if *f0031 = new(mem_ctx) ir_if(operand(r0032).val);
> +   exec_list *const f0031_parent_instructions = body.instructions;
> +
> +      /* THEN INSTRUCTIONS */
> +      body.instructions = &f0031->then_instructions;
> +
> +      body.emit(assign(r002D, r0029, 0x01));
> +
> +      body.emit(assign(r002E, r0028, 0x01));
> +
> +
> +      /* ELSE INSTRUCTIONS */
> +      body.instructions = &f0031->else_instructions;
> +
> +      /* IF CONDITION */
> +      ir_expression *const r0034 = less(r002A, body.constant(int(32)));
> +      ir_if *f0033 = new(mem_ctx) ir_if(operand(r0034).val);
> +      exec_list *const f0033_parent_instructions = body.instructions;
> +
> +         /* THEN INSTRUCTIONS */
> +         body.instructions = &f0033->then_instructions;
> +
> +         ir_expression *const r0035 = lshift(r0028, r002F);
> +         ir_expression *const r0036 = rshift(r0029, r002A);
> +         body.emit(assign(r002D, bit_or(r0035, r0036), 0x01));
> +
> +         body.emit(assign(r002E, rshift(r0028, r002A), 0x01));
> +
> +
> +         /* ELSE INSTRUCTIONS */
> +         body.instructions = &f0033->else_instructions;
> +
> +         ir_variable *const r0037 = body.make_temp(glsl_type::uint_type, "conditional_tmp");
> +         /* IF CONDITION */
> +         ir_expression *const r0039 = less(r002A, body.constant(int(64)));
> +         ir_if *f0038 = new(mem_ctx) ir_if(operand(r0039).val);
> +         exec_list *const f0038_parent_instructions = body.instructions;
> +
> +            /* THEN INSTRUCTIONS */
> +            body.instructions = &f0038->then_instructions;
> +
> +            ir_expression *const r003A = bit_and(r002A, body.constant(int(31)));
> +            body.emit(assign(r0037, rshift(r0028, r003A), 0x01));
> +
> +
> +            /* ELSE INSTRUCTIONS */
> +            body.instructions = &f0038->else_instructions;
> +
> +            body.emit(assign(r0037, body.constant(0u), 0x01));
> +
> +
> +         body.instructions = f0038_parent_instructions;
> +         body.emit(f0038);
> +
> +         /* END IF */
> +
> +         body.emit(assign(r002D, r0037, 0x01));
> +
> +         body.emit(assign(r002E, body.constant(0u), 0x01));
> +
> +
> +      body.instructions = f0033_parent_instructions;
> +      body.emit(f0033);
> +
> +      /* END IF */
> +
> +
> +   body.instructions = f0031_parent_instructions;
> +   body.emit(f0031);
> +
> +   /* END IF */
> +
> +   body.emit(assign(r002C, r002D, 0x01));
> +
> +   body.emit(assign(r002B, r002E, 0x01));
> +
> +   sig->replace_parameters(&sig_parameters);
> +   return sig;
> +}
> +ir_function_signature *
> +uint_to_fp64(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 r003B = new(mem_ctx) ir_variable(glsl_type::uint_type, "a", ir_var_function_in);
> +   sig_parameters.push_tail(r003B);
> +   ir_variable *const r003C = body.make_temp(glsl_type::uvec2_type, "return_value");
> +   ir_variable *const r003D = new(mem_ctx) ir_variable(glsl_type::uint_type, "aLow", ir_var_auto);
> +   body.emit(r003D);
> +   ir_variable *const r003E = new(mem_ctx) ir_variable(glsl_type::uint_type, "aHigh", ir_var_auto);
> +   body.emit(r003E);
> +   /* IF CONDITION */
> +   ir_expression *const r0040 = equal(r003B, body.constant(0u));
> +   ir_if *f003F = new(mem_ctx) ir_if(operand(r0040).val);
> +   exec_list *const f003F_parent_instructions = body.instructions;
> +
> +      /* THEN INSTRUCTIONS */
> +      body.instructions = &f003F->then_instructions;
> +
> +      body.emit(assign(r003C, ir_constant::zero(mem_ctx, glsl_type::uvec2_type), 0x03));
> +
> +
> +      /* ELSE INSTRUCTIONS */
> +      body.instructions = &f003F->else_instructions;
> +
> +      ir_variable *const r0041 = body.make_temp(glsl_type::uint_type, "a");
> +      body.emit(assign(r0041, r003B, 0x01));
> +
> +      ir_variable *const r0042 = body.make_temp(glsl_type::int_type, "return_value");
> +      ir_variable *const r0043 = new(mem_ctx) ir_variable(glsl_type::int_type, "shiftCount", ir_var_auto);
> +      body.emit(r0043);
> +      /* IF CONDITION */
> +      ir_expression *const r0045 = equal(r003B, body.constant(0u));
> +      ir_if *f0044 = new(mem_ctx) ir_if(operand(r0045).val);
> +      exec_list *const f0044_parent_instructions = body.instructions;
> +
> +         /* THEN INSTRUCTIONS */
> +         body.instructions = &f0044->then_instructions;
> +
> +         body.emit(assign(r0042, body.constant(int(32)), 0x01));
> +
> +
> +         /* ELSE INSTRUCTIONS */
> +         body.instructions = &f0044->else_instructions;
> +
> +         body.emit(assign(r0043, body.constant(int(0)), 0x01));
> +
> +         /* IF CONDITION */
> +         ir_expression *const r0047 = bit_and(r003B, body.constant(4294901760u));
> +         ir_expression *const r0048 = equal(r0047, body.constant(0u));
> +         ir_if *f0046 = new(mem_ctx) ir_if(operand(r0048).val);
> +         exec_list *const f0046_parent_instructions = body.instructions;
> +
> +            /* THEN INSTRUCTIONS */
> +            body.instructions = &f0046->then_instructions;
> +
> +            body.emit(assign(r0043, body.constant(int(16)), 0x01));
> +
> +            body.emit(assign(r0041, lshift(r003B, body.constant(int(16))), 0x01));
> +
> +
> +         body.instructions = f0046_parent_instructions;
> +         body.emit(f0046);
> +
> +         /* END IF */
> +
> +         /* IF CONDITION */
> +         ir_expression *const r004A = bit_and(r0041, body.constant(4278190080u));
> +         ir_expression *const r004B = equal(r004A, body.constant(0u));
> +         ir_if *f0049 = new(mem_ctx) ir_if(operand(r004B).val);
> +         exec_list *const f0049_parent_instructions = body.instructions;
> +
> +            /* THEN INSTRUCTIONS */
> +            body.instructions = &f0049->then_instructions;
> +
> +            body.emit(assign(r0043, add(r0043, body.constant(int(8))), 0x01));
> +
> +            body.emit(assign(r0041, lshift(r0041, body.constant(int(8))), 0x01));
> +
> +
> +         body.instructions = f0049_parent_instructions;
> +         body.emit(f0049);
> +
> +         /* END IF */
> +
> +         /* IF CONDITION */
> +         ir_expression *const r004D = bit_and(r0041, body.constant(4026531840u));
> +         ir_expression *const r004E = equal(r004D, body.constant(0u));
> +         ir_if *f004C = new(mem_ctx) ir_if(operand(r004E).val);
> +         exec_list *const f004C_parent_instructions = body.instructions;
> +
> +            /* THEN INSTRUCTIONS */
> +            body.instructions = &f004C->then_instructions;
> +
> +            body.emit(assign(r0043, add(r0043, body.constant(int(4))), 0x01));
> +
> +            body.emit(assign(r0041, lshift(r0041, body.constant(int(4))), 0x01));
> +
> +
> +         body.instructions = f004C_parent_instructions;
> +         body.emit(f004C);
> +
> +         /* END IF */
> +
> +         /* IF CONDITION */
> +         ir_expression *const r0050 = bit_and(r0041, body.constant(3221225472u));
> +         ir_expression *const r0051 = equal(r0050, body.constant(0u));
> +         ir_if *f004F = new(mem_ctx) ir_if(operand(r0051).val);
> +         exec_list *const f004F_parent_instructions = body.instructions;
> +
> +            /* THEN INSTRUCTIONS */
> +            body.instructions = &f004F->then_instructions;
> +
> +            body.emit(assign(r0043, add(r0043, body.constant(int(2))), 0x01));
> +
> +            body.emit(assign(r0041, lshift(r0041, body.constant(int(2))), 0x01));
> +
> +
> +         body.instructions = f004F_parent_instructions;
> +         body.emit(f004F);
> +
> +         /* END IF */
> +
> +         /* IF CONDITION */
> +         ir_expression *const r0053 = bit_and(r0041, body.constant(2147483648u));
> +         ir_expression *const r0054 = equal(r0053, body.constant(0u));
> +         ir_if *f0052 = new(mem_ctx) ir_if(operand(r0054).val);
> +         exec_list *const f0052_parent_instructions = body.instructions;
> +
> +            /* THEN INSTRUCTIONS */
> +            body.instructions = &f0052->then_instructions;
> +
> +            body.emit(assign(r0043, add(r0043, body.constant(int(1))), 0x01));
> +
> +
> +         body.instructions = f0052_parent_instructions;
> +         body.emit(f0052);
> +
> +         /* END IF */
> +
> +         body.emit(assign(r0042, r0043, 0x01));
> +
> +
> +      body.instructions = f0044_parent_instructions;
> +      body.emit(f0044);
> +
> +      /* END IF */
> +
> +      ir_variable *const r0055 = body.make_temp(glsl_type::int_type, "assignment_tmp");
> +      body.emit(assign(r0055, add(r0042, body.constant(int(21))), 0x01));
> +
> +      body.emit(assign(r003E, body.constant(0u), 0x01));
> +
> +      body.emit(assign(r003D, body.constant(0u), 0x01));
> +
> +      ir_variable *const r0056 = body.make_temp(glsl_type::int_type, "assignment_tmp");
> +      ir_expression *const r0057 = neg(r0055);
> +      body.emit(assign(r0056, bit_and(r0057, body.constant(int(31))), 0x01));
> +
> +      /* IF CONDITION */
> +      ir_expression *const r0059 = equal(r0055, body.constant(int(0)));
> +      ir_if *f0058 = new(mem_ctx) ir_if(operand(r0059).val);
> +      exec_list *const f0058_parent_instructions = body.instructions;
> +
> +         /* THEN INSTRUCTIONS */
> +         body.instructions = &f0058->then_instructions;
> +
> +         body.emit(assign(r003E, body.constant(0u), 0x01));
> +
> +         body.emit(assign(r003D, r003B, 0x01));
> +
> +
> +         /* ELSE INSTRUCTIONS */
> +         body.instructions = &f0058->else_instructions;
> +
> +         /* IF CONDITION */
> +         ir_expression *const r005B = less(r0055, body.constant(int(32)));
> +         ir_if *f005A = new(mem_ctx) ir_if(operand(r005B).val);
> +         exec_list *const f005A_parent_instructions = body.instructions;
> +
> +            /* THEN INSTRUCTIONS */
> +            body.instructions = &f005A->then_instructions;
> +
> +            body.emit(assign(r003E, rshift(r003B, r0056), 0x01));
> +
> +            body.emit(assign(r003D, lshift(r003B, r0055), 0x01));
> +
> +
> +            /* ELSE INSTRUCTIONS */
> +            body.instructions = &f005A->else_instructions;
> +
> +            ir_variable *const r005C = body.make_temp(glsl_type::uint_type, "conditional_tmp");
> +            /* IF CONDITION */
> +            ir_expression *const r005E = less(r0055, body.constant(int(64)));
> +            ir_if *f005D = new(mem_ctx) ir_if(operand(r005E).val);
> +            exec_list *const f005D_parent_instructions = body.instructions;
> +
> +               /* THEN INSTRUCTIONS */
> +               body.instructions = &f005D->then_instructions;
> +
> +               ir_expression *const r005F = add(r0055, body.constant(int(-32)));
> +               body.emit(assign(r005C, lshift(r003B, r005F), 0x01));
> +
> +
> +               /* ELSE INSTRUCTIONS */
> +               body.instructions = &f005D->else_instructions;
> +
> +               body.emit(assign(r005C, body.constant(0u), 0x01));
> +
> +
> +            body.instructions = f005D_parent_instructions;
> +            body.emit(f005D);
> +
> +            /* END IF */
> +
> +            body.emit(assign(r003E, r005C, 0x01));
> +
> +            body.emit(assign(r003D, body.constant(0u), 0x01));
> +
> +
> +         body.instructions = f005A_parent_instructions;
> +         body.emit(f005A);
> +
> +         /* END IF */
> +
> +
> +      body.instructions = f0058_parent_instructions;
> +      body.emit(f0058);
> +
> +      /* END IF */
> +
> +      ir_variable *const r0060 = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "z", ir_var_auto);
> +      body.emit(r0060);
> +      ir_expression *const r0061 = sub(body.constant(int(1074)), r0055);
> +      ir_expression *const r0062 = expr(ir_unop_i2u, r0061);
> +      ir_expression *const r0063 = lshift(r0062, body.constant(int(20)));
> +      body.emit(assign(r0060, add(r0063, r003E), 0x02));
> +
> +      body.emit(assign(r0060, r003D, 0x01));
> +
> +      body.emit(assign(r003C, r0060, 0x03));
> +
> +
> +   body.instructions = f003F_parent_instructions;
> +   body.emit(f003F);
> +
> +   /* END IF */
> +
> +   body.emit(ret(r003C));
> +
> +   sig->replace_parameters(&sig_parameters);
> +   return sig;
> +}
> +ir_function_signature *
> +int_to_fp64(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 r0064 = new(mem_ctx) ir_variable(glsl_type::int_type, "a", ir_var_function_in);
> +   sig_parameters.push_tail(r0064);
> +   ir_variable *const r0065 = body.make_temp(glsl_type::uvec2_type, "return_value");
> +   ir_variable *const r0066 = new(mem_ctx) ir_variable(glsl_type::uint_type, "zSign", ir_var_auto);
> +   body.emit(r0066);
> +   ir_variable *const r0067 = new(mem_ctx) ir_variable(glsl_type::uint_type, "zFrac1", ir_var_auto);
> +   body.emit(r0067);
> +   ir_variable *const r0068 = new(mem_ctx) ir_variable(glsl_type::uint_type, "zFrac0", ir_var_auto);
> +   body.emit(r0068);
> +   body.emit(assign(r0068, body.constant(0u), 0x01));
> +
> +   body.emit(assign(r0067, body.constant(0u), 0x01));
> +
> +   /* IF CONDITION */
> +   ir_expression *const r006A = equal(r0064, body.constant(int(0)));
> +   ir_if *f0069 = new(mem_ctx) ir_if(operand(r006A).val);
> +   exec_list *const f0069_parent_instructions = body.instructions;
> +
> +      /* THEN INSTRUCTIONS */
> +      body.instructions = &f0069->then_instructions;
> +
> +      ir_variable *const r006B = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "z", ir_var_auto);
> +      body.emit(r006B);
> +      body.emit(assign(r006B, body.constant(0u), 0x02));
> +
> +      body.emit(assign(r006B, body.constant(0u), 0x01));
> +
> +      body.emit(assign(r0065, r006B, 0x03));
> +
> +
> +      /* ELSE INSTRUCTIONS */
> +      body.instructions = &f0069->else_instructions;
> +
> +      ir_expression *const r006C = less(r0064, body.constant(int(0)));
> +      ir_expression *const r006D = expr(ir_unop_b2i, r006C);
> +      body.emit(assign(r0066, expr(ir_unop_i2u, r006D), 0x01));
> +
> +      ir_variable *const r006E = body.make_temp(glsl_type::uint_type, "conditional_tmp");
> +      /* IF CONDITION */
> +      ir_expression *const r0070 = less(r0064, body.constant(int(0)));
> +      ir_if *f006F = new(mem_ctx) ir_if(operand(r0070).val);
> +      exec_list *const f006F_parent_instructions = body.instructions;
> +
> +         /* THEN INSTRUCTIONS */
> +         body.instructions = &f006F->then_instructions;
> +
> +         ir_expression *const r0071 = neg(r0064);
> +         body.emit(assign(r006E, expr(ir_unop_i2u, r0071), 0x01));
> +
> +
> +         /* ELSE INSTRUCTIONS */
> +         body.instructions = &f006F->else_instructions;
> +
> +         body.emit(assign(r006E, expr(ir_unop_i2u, r0064), 0x01));
> +
> +
> +      body.instructions = f006F_parent_instructions;
> +      body.emit(f006F);
> +
> +      /* END IF */
> +
> +      ir_variable *const r0072 = body.make_temp(glsl_type::uint_type, "a");
> +      body.emit(assign(r0072, r006E, 0x01));
> +
> +      ir_variable *const r0073 = body.make_temp(glsl_type::int_type, "return_value");
> +      ir_variable *const r0074 = new(mem_ctx) ir_variable(glsl_type::int_type, "shiftCount", ir_var_auto);
> +      body.emit(r0074);
> +      /* IF CONDITION */
> +      ir_expression *const r0076 = equal(r006E, body.constant(0u));
> +      ir_if *f0075 = new(mem_ctx) ir_if(operand(r0076).val);
> +      exec_list *const f0075_parent_instructions = body.instructions;
> +
> +         /* THEN INSTRUCTIONS */
> +         body.instructions = &f0075->then_instructions;
> +
> +         body.emit(assign(r0073, body.constant(int(32)), 0x01));
> +
> +
> +         /* ELSE INSTRUCTIONS */
> +         body.instructions = &f0075->else_instructions;
> +
> +         body.emit(assign(r0074, body.constant(int(0)), 0x01));
> +
> +         /* IF CONDITION */
> +         ir_expression *const r0078 = bit_and(r006E, body.constant(4294901760u));
> +         ir_expression *const r0079 = equal(r0078, body.constant(0u));
> +         ir_if *f0077 = new(mem_ctx) ir_if(operand(r0079).val);
> +         exec_list *const f0077_parent_instructions = body.instructions;
> +
> +            /* THEN INSTRUCTIONS */
> +            body.instructions = &f0077->then_instructions;
> +
> +            body.emit(assign(r0074, body.constant(int(16)), 0x01));
> +
> +            body.emit(assign(r0072, lshift(r006E, body.constant(int(16))), 0x01));
> +
> +
> +         body.instructions = f0077_parent_instructions;
> +         body.emit(f0077);
> +
> +         /* END IF */
> +
> +         /* IF CONDITION */
> +         ir_expression *const r007B = bit_and(r0072, body.constant(4278190080u));
> +         ir_expression *const r007C = equal(r007B, body.constant(0u));
> +         ir_if *f007A = new(mem_ctx) ir_if(operand(r007C).val);
> +         exec_list *const f007A_parent_instructions = body.instructions;
> +
> +            /* THEN INSTRUCTIONS */
> +            body.instructions = &f007A->then_instructions;
> +
> +            body.emit(assign(r0074, add(r0074, body.constant(int(8))), 0x01));
> +
> +            body.emit(assign(r0072, lshift(r0072, body.constant(int(8))), 0x01));
> +
> +
> +         body.instructions = f007A_parent_instructions;
> +         body.emit(f007A);
> +
> +         /* END IF */
> +
> +         /* IF CONDITION */
> +         ir_expression *const r007E = bit_and(r0072, body.constant(4026531840u));
> +         ir_expression *const r007F = equal(r007E, body.constant(0u));
> +         ir_if *f007D = new(mem_ctx) ir_if(operand(r007F).val);
> +         exec_list *const f007D_parent_instructions = body.instructions;
> +
> +            /* THEN INSTRUCTIONS */
> +            body.instructions = &f007D->then_instructions;
> +
> +            body.emit(assign(r0074, add(r0074, body.constant(int(4))), 0x01));
> +
> +            body.emit(assign(r0072, lshift(r0072, body.constant(int(4))), 0x01));
> +
> +
> +         body.instructions = f007D_parent_instructions;
> +         body.emit(f007D);
> +
> +         /* END IF */
> +
> +         /* IF CONDITION */
> +         ir_expression *const r0081 = bit_and(r0072, body.constant(3221225472u));
> +         ir_expression *const r0082 = equal(r0081, body.constant(0u));
> +         ir_if *f0080 = new(mem_ctx) ir_if(operand(r0082).val);
> +         exec_list *const f0080_parent_instructions = body.instructions;
> +
> +            /* THEN INSTRUCTIONS */
> +            body.instructions = &f0080->then_instructions;
> +
> +            body.emit(assign(r0074, add(r0074, body.constant(int(2))), 0x01));
> +
> +            body.emit(assign(r0072, lshift(r0072, body.constant(int(2))), 0x01));
> +
> +
> +         body.instructions = f0080_parent_instructions;
> +         body.emit(f0080);
> +
> +         /* END IF */
> +
> +         /* IF CONDITION */
> +         ir_expression *const r0084 = bit_and(r0072, body.constant(2147483648u));
> +         ir_expression *const r0085 = equal(r0084, body.constant(0u));
> +         ir_if *f0083 = new(mem_ctx) ir_if(operand(r0085).val);
> +         exec_list *const f0083_parent_instructions = body.instructions;
> +
> +            /* THEN INSTRUCTIONS */
> +            body.instructions = &f0083->then_instructions;
> +
> +            body.emit(assign(r0074, add(r0074, body.constant(int(1))), 0x01));
> +
> +
> +         body.instructions = f0083_parent_instructions;
> +         body.emit(f0083);
> +
> +         /* END IF */
> +
> +         body.emit(assign(r0073, r0074, 0x01));
> +
> +
> +      body.instructions = f0075_parent_instructions;
> +      body.emit(f0075);
> +
> +      /* END IF */
> +
> +      ir_variable *const r0086 = body.make_temp(glsl_type::int_type, "assignment_tmp");
> +      body.emit(assign(r0086, add(r0073, body.constant(int(-11))), 0x01));
> +
> +      /* IF CONDITION */
> +      ir_expression *const r0088 = gequal(r0086, body.constant(int(0)));
> +      ir_if *f0087 = new(mem_ctx) ir_if(operand(r0088).val);
> +      exec_list *const f0087_parent_instructions = body.instructions;
> +
> +         /* THEN INSTRUCTIONS */
> +         body.instructions = &f0087->then_instructions;
> +
> +         body.emit(assign(r0068, lshift(r006E, r0086), 0x01));
> +
> +         body.emit(assign(r0067, body.constant(0u), 0x01));
> +
> +
> +         /* ELSE INSTRUCTIONS */
> +         body.instructions = &f0087->else_instructions;
> +
> +         ir_variable *const r0089 = body.make_temp(glsl_type::uint_type, "a1");
> +         body.emit(assign(r0089, body.constant(0u), 0x01));
> +
> +         ir_variable *const r008A = body.make_temp(glsl_type::int_type, "count");
> +         body.emit(assign(r008A, neg(r0086), 0x01));
> +
> +         ir_variable *const r008B = new(mem_ctx) ir_variable(glsl_type::uint_type, "z1", ir_var_auto);
> +         body.emit(r008B);
> +         ir_variable *const r008C = new(mem_ctx) ir_variable(glsl_type::uint_type, "z0", ir_var_auto);
> +         body.emit(r008C);
> +         ir_variable *const r008D = body.make_temp(glsl_type::int_type, "assignment_tmp");
> +         ir_expression *const r008E = neg(r008A);
> +         body.emit(assign(r008D, bit_and(r008E, body.constant(int(31))), 0x01));
> +
> +         /* IF CONDITION */
> +         ir_expression *const r0090 = equal(r008A, body.constant(int(0)));
> +         ir_if *f008F = new(mem_ctx) ir_if(operand(r0090).val);
> +         exec_list *const f008F_parent_instructions = body.instructions;
> +
> +            /* THEN INSTRUCTIONS */
> +            body.instructions = &f008F->then_instructions;
> +
> +            body.emit(assign(r008B, body.constant(0u), 0x01));
> +
> +            body.emit(assign(r008C, r006E, 0x01));
> +
> +
> +            /* ELSE INSTRUCTIONS */
> +            body.instructions = &f008F->else_instructions;
> +
> +            /* IF CONDITION */
> +            ir_expression *const r0092 = less(r008A, body.constant(int(32)));
> +            ir_if *f0091 = new(mem_ctx) ir_if(operand(r0092).val);
> +            exec_list *const f0091_parent_instructions = body.instructions;
> +
> +               /* THEN INSTRUCTIONS */
> +               body.instructions = &f0091->then_instructions;
> +
> +               ir_expression *const r0093 = lshift(r006E, r008D);
> +               body.emit(assign(r008B, bit_or(r0093, body.constant(0u)), 0x01));
> +
> +               body.emit(assign(r008C, rshift(r006E, r008A), 0x01));
> +
> +
> +               /* ELSE INSTRUCTIONS */
> +               body.instructions = &f0091->else_instructions;
> +
> +               ir_variable *const r0094 = body.make_temp(glsl_type::uint_type, "conditional_tmp");
> +               /* IF CONDITION */
> +               ir_expression *const r0096 = less(r008A, body.constant(int(64)));
> +               ir_if *f0095 = new(mem_ctx) ir_if(operand(r0096).val);
> +               exec_list *const f0095_parent_instructions = body.instructions;
> +
> +                  /* THEN INSTRUCTIONS */
> +                  body.instructions = &f0095->then_instructions;
> +
> +                  ir_expression *const r0097 = bit_and(r008A, body.constant(int(31)));
> +                  body.emit(assign(r0094, rshift(r006E, r0097), 0x01));
> +
> +
> +                  /* ELSE INSTRUCTIONS */
> +                  body.instructions = &f0095->else_instructions;
> +
> +                  body.emit(assign(r0094, body.constant(0u), 0x01));
> +
> +
> +               body.instructions = f0095_parent_instructions;
> +               body.emit(f0095);
> +
> +               /* END IF */
> +
> +               body.emit(assign(r008B, r0094, 0x01));
> +
> +               body.emit(assign(r008C, body.constant(0u), 0x01));
> +
> +
> +            body.instructions = f0091_parent_instructions;
> +            body.emit(f0091);
> +
> +            /* END IF */
> +
> +
> +         body.instructions = f008F_parent_instructions;
> +         body.emit(f008F);
> +
> +         /* END IF */
> +
> +         body.emit(assign(r0068, r008C, 0x01));
> +
> +         body.emit(assign(r0067, r008B, 0x01));
> +
> +
> +      body.instructions = f0087_parent_instructions;
> +      body.emit(f0087);
> +
> +      /* END IF */
> +
> +      ir_variable *const r0098 = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "z", ir_var_auto);
> +      body.emit(r0098);
> +      ir_expression *const r0099 = lshift(r0066, body.constant(int(31)));
> +      ir_expression *const r009A = sub(body.constant(int(1042)), r0086);
> +      ir_expression *const r009B = expr(ir_unop_i2u, r009A);
> +      ir_expression *const r009C = lshift(r009B, body.constant(int(20)));
> +      ir_expression *const r009D = add(r0099, r009C);
> +      body.emit(assign(r0098, add(r009D, r0068), 0x02));
> +
> +      body.emit(assign(r0098, r0067, 0x01));
> +
> +      body.emit(assign(r0065, r0098, 0x03));
> +
> +
> +   body.instructions = f0069_parent_instructions;
> +   body.emit(f0069);
> +
> +   /* END IF */
> +
> +   body.emit(ret(r0065));
> +
> +   sig->replace_parameters(&sig_parameters);
> +   return sig;
> +}
> diff --git a/src/compiler/glsl/builtin_functions.cpp b/src/compiler/glsl/builtin_functions.cpp
> index 530cdc0264..29e583ffeb 100644
> --- a/src/compiler/glsl/builtin_functions.cpp
> +++ b/src/compiler/glsl/builtin_functions.cpp
> @@ -3325,6 +3325,14 @@ builtin_builder::create_builtins()
>                  generate_ir::umul64(mem_ctx, integer_functions_supported),
>                  NULL);
>  
> +   add_function("__builtin_int_to_fp64",
> +		generate_ir::int_to_fp64(mem_ctx, integer_functions_supported),
> +		NULL);
> +
> +   add_function("__builtin_uint_to_fp64",
> +		generate_ir::uint_to_fp64(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 89ec9b7d5d..241fe53dd8 100644
> --- a/src/compiler/glsl/builtin_functions.h
> +++ b/src/compiler/glsl/builtin_functions.h
> @@ -67,6 +67,12 @@ sign64(void *mem_ctx, builtin_available_predicate avail);
>  ir_function_signature *
>  udivmod64(void *mem_ctx, builtin_available_predicate avail);
>  
> +ir_function_signature *
> +int_to_fp64(void *mem_ctx, builtin_available_predicate avail);
> +
> +ir_function_signature *
> +uint_to_fp64(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
> new file mode 100644
> index 0000000000..70f067fa61
> --- /dev/null
> +++ b/src/compiler/glsl/float64.glsl
> @@ -0,0 +1,126 @@
> +/* Compile with:
> + *
> + * glsl_compiler --version 130 --dump-builder float64.glsl > builtin_float64.h
> + *
> + */
> +
> +#version 130
> +#extension GL_ARB_shader_bit_encoding : enable
> +
> +/* Returns the number of leading 0 bits before the most-significant 1 bit of
> + * `a'.  If `a' is zero, 32 is returned.
> + */
> +int
> +countLeadingZeros32(uint a)
> +{
> +   if (a == 0u)
> +      return 32;
> +
> +   int shiftCount = 0;
> +   if ((a & 0xFFFF0000u) == 0u) {shiftCount += 16; a <<= 16;}
> +   if ((a & 0xFF000000u) == 0u) {shiftCount += 8; a <<= 8;}
> +   if ((a & 0xF0000000u) == 0u) {shiftCount += 4; a <<= 4;}
> +   if ((a & 0xC0000000u) == 0u) {shiftCount += 2; a <<= 2;}
> +   if ((a & 0x80000000u) == 0u) {shiftCount += 1;}
> +
> +   return shiftCount;
> +}
> +
> +/* Packs the sign `zSign', the exponent `zExp', and the significand formed by
> + * the concatenation of `zFrac0' and `zFrac1' into a double-precision floating-
> + * point value, returning the result.  After being shifted into the proper
> + * positions, the three fields `zSign', `zExp', and `zFrac0' are simply added
> + * together to form the most significant 32 bits of the result.  This means
> + * that any integer portion of `zFrac0' will be added into the exponent.  Since
> + * a properly normalized significand will have an integer portion equal to 1,
> + * the `zExp' input should be 1 less than the desired result exponent whenever
> + * `zFrac0' and `zFrac1' concatenated form a complete, normalized significand.
> + */
> +uvec2
> +packFloat64(uint zSign, int zExp, uint zFrac0, uint zFrac1)
> +{
> +   uvec2 z;
> +
> +   z.y = (zSign<<31) + (uint(zExp)<<20) + zFrac0;
> +   z.x = zFrac1;
> +   return z;
> +}
> +
> +/* Shifts the 64-bit value formed by concatenating `a0' and `a1' right by the
> + * number of bits given in `count'.  Any bits shifted off are lost.  The value
> + * of `count' can be arbitrarily large; in particular, if `count' is greater
> + * than 64, the result will be 0.  The result is broken into two 32-bit pieces
> + * which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
> + */
> +void
> +shift64Right(uint a0, uint a1,
> +             int count,
> +             inout uint z0Ptr,
> +             inout uint z1Ptr)
> +{
> +   uint z0;
> +   uint z1;
> +   int negCount = (-count) & 31;
> +
> +   if (count == 0) {
> +      z1 = a1;
> +      z0 = a0;
> +   } else if (count < 32) {
> +      z1 = (a0<<negCount) | (a1>>count);
> +      z0 = a0>>count;
> +   } else {
> +      z1 = (count < 64) ? (a0>>(count & 31)) : 0u;
> +      z0 = 0u;
> +   }
> +   z1Ptr = z1;
> +   z0Ptr = z0;
> +}
> +
> +uvec2
> +uint_to_fp64(uint a)
> +{
> +   if (a == 0u)
> +      return uvec2(0u, 0u);
> +
> +   int shiftDist = countLeadingZeros32(a) + 21;
> +
> +   uint aHigh = 0u;
> +   uint aLow = 0u;
> +   int negCount = (-shiftDist) & 31;
> +
> +   if (shiftDist == 0) {
> +      aHigh = 0u;
> +      aLow = a;
> +   } else if (shiftDist < 32) {
> +      aHigh = (a >> negCount);
> +      aLow = a << shiftDist;
> +   } else {
> +      aHigh = (shiftDist < 64) ? (a << shiftDist - 32) : 0u;
> +      aLow = 0u;
> +   }
> +
> +   return packFloat64(0u, 0x432 - shiftDist, aHigh, aLow);
> +}
> +
> +/* Returns the result of converting the 32-bit two's complement integer `a'
> + * to the double-precision floating-point format.  The conversion is performed
> + * according to the IEEE Standard for Floating-Point Arithmetic.
> + */
> +uvec2
> +int_to_fp64(int a)
> +{
> +   uint zFrac0 = 0u;
> +   uint zFrac1 = 0u;
> +   if (a==0)
> +      return packFloat64(0u, 0, 0u, 0u);
> +   uint zSign = uint(a < 0);
> +   uint absA = a < 0 ? uint(-a) : uint(a);
> +   int shiftCount = countLeadingZeros32(absA) - 11;
> +   if (0 <= shiftCount) {
> +      zFrac0 = absA << shiftCount;
> +      zFrac1 = 0u;
> +   } else {
> +      shift64Right(absA, 0u, -shiftCount, zFrac0, zFrac1);
> +   }
> +   return packFloat64(zSign, 0x412 - shiftCount, zFrac0, zFrac1);
> +}
> diff --git a/src/compiler/glsl/generate_ir.cpp b/src/compiler/glsl/generate_ir.cpp
> index 255b0484f2..983905a5cf 100644
> --- a/src/compiler/glsl/generate_ir.cpp
> +++ b/src/compiler/glsl/generate_ir.cpp
> @@ -29,5 +29,5 @@ using namespace ir_builder;
>  namespace generate_ir {
>  
>  #include "builtin_int64.h"
> -
> +#include "builtin_float64.h"
>  }
> 



More information about the mesa-dev mailing list