[Mesa-dev] [PATCH 12/47] glsl: Add "built-in" functions to do int_to_fp64(int)
Elie Tournier
tournier.elie at gmail.com
Wed Aug 23 11:07:42 UTC 2017
Signed-off-by: Elie Tournier <elie.tournier at collabora.com>
---
src/compiler/glsl/builtin_float64.h | 334 ++++++++++++++++++++++++++++++++
src/compiler/glsl/builtin_functions.cpp | 4 +
src/compiler/glsl/builtin_functions.h | 3 +
src/compiler/glsl/float64.glsl | 23 +++
src/compiler/glsl/glcpp/glcpp-parse.y | 1 +
5 files changed, 365 insertions(+)
diff --git a/src/compiler/glsl/builtin_float64.h b/src/compiler/glsl/builtin_float64.h
index c5640c459a..644407a185 100644
--- a/src/compiler/glsl/builtin_float64.h
+++ b/src/compiler/glsl/builtin_float64.h
@@ -12837,3 +12837,337 @@ fp64_to_int(void *mem_ctx, builtin_available_predicate avail)
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 r0ABE = new(mem_ctx) ir_variable(glsl_type::int_type, "a", ir_var_function_in);
+ sig_parameters.push_tail(r0ABE);
+ ir_variable *const r0ABF = body.make_temp(glsl_type::uvec2_type, "return_value");
+ ir_variable *const r0AC0 = new(mem_ctx) ir_variable(glsl_type::uint_type, "zSign", ir_var_auto);
+ body.emit(r0AC0);
+ ir_variable *const r0AC1 = new(mem_ctx) ir_variable(glsl_type::uint_type, "zFrac1", ir_var_auto);
+ body.emit(r0AC1);
+ ir_variable *const r0AC2 = new(mem_ctx) ir_variable(glsl_type::uint_type, "zFrac0", ir_var_auto);
+ body.emit(r0AC2);
+ body.emit(assign(r0AC2, body.constant(0u), 0x01));
+
+ body.emit(assign(r0AC1, body.constant(0u), 0x01));
+
+ /* IF CONDITION */
+ ir_expression *const r0AC4 = equal(r0ABE, body.constant(int(0)));
+ ir_if *f0AC3 = new(mem_ctx) ir_if(operand(r0AC4).val);
+ exec_list *const f0AC3_parent_instructions = body.instructions;
+
+ /* THEN INSTRUCTIONS */
+ body.instructions = &f0AC3->then_instructions;
+
+ ir_variable *const r0AC5 = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "z", ir_var_auto);
+ body.emit(r0AC5);
+ body.emit(assign(r0AC5, body.constant(0u), 0x02));
+
+ body.emit(assign(r0AC5, body.constant(0u), 0x01));
+
+ body.emit(assign(r0ABF, r0AC5, 0x03));
+
+
+ /* ELSE INSTRUCTIONS */
+ body.instructions = &f0AC3->else_instructions;
+
+ ir_expression *const r0AC6 = less(r0ABE, body.constant(int(0)));
+ ir_expression *const r0AC7 = expr(ir_unop_b2i, r0AC6);
+ body.emit(assign(r0AC0, expr(ir_unop_i2u, r0AC7), 0x01));
+
+ ir_variable *const r0AC8 = body.make_temp(glsl_type::uint_type, "conditional_tmp");
+ /* IF CONDITION */
+ ir_expression *const r0ACA = less(r0ABE, body.constant(int(0)));
+ ir_if *f0AC9 = new(mem_ctx) ir_if(operand(r0ACA).val);
+ exec_list *const f0AC9_parent_instructions = body.instructions;
+
+ /* THEN INSTRUCTIONS */
+ body.instructions = &f0AC9->then_instructions;
+
+ ir_expression *const r0ACB = neg(r0ABE);
+ body.emit(assign(r0AC8, expr(ir_unop_i2u, r0ACB), 0x01));
+
+
+ /* ELSE INSTRUCTIONS */
+ body.instructions = &f0AC9->else_instructions;
+
+ body.emit(assign(r0AC8, expr(ir_unop_i2u, r0ABE), 0x01));
+
+
+ body.instructions = f0AC9_parent_instructions;
+ body.emit(f0AC9);
+
+ /* END IF */
+
+ ir_variable *const r0ACC = body.make_temp(glsl_type::uint_type, "a");
+ body.emit(assign(r0ACC, r0AC8, 0x01));
+
+ ir_variable *const r0ACD = body.make_temp(glsl_type::int_type, "return_value");
+ ir_variable *const r0ACE = new(mem_ctx) ir_variable(glsl_type::int_type, "shiftCount", ir_var_auto);
+ body.emit(r0ACE);
+ /* IF CONDITION */
+ ir_expression *const r0AD0 = equal(r0AC8, body.constant(0u));
+ ir_if *f0ACF = new(mem_ctx) ir_if(operand(r0AD0).val);
+ exec_list *const f0ACF_parent_instructions = body.instructions;
+
+ /* THEN INSTRUCTIONS */
+ body.instructions = &f0ACF->then_instructions;
+
+ body.emit(assign(r0ACD, body.constant(int(32)), 0x01));
+
+
+ /* ELSE INSTRUCTIONS */
+ body.instructions = &f0ACF->else_instructions;
+
+ body.emit(assign(r0ACE, body.constant(int(0)), 0x01));
+
+ /* IF CONDITION */
+ ir_expression *const r0AD2 = bit_and(r0AC8, body.constant(4294901760u));
+ ir_expression *const r0AD3 = equal(r0AD2, body.constant(0u));
+ ir_if *f0AD1 = new(mem_ctx) ir_if(operand(r0AD3).val);
+ exec_list *const f0AD1_parent_instructions = body.instructions;
+
+ /* THEN INSTRUCTIONS */
+ body.instructions = &f0AD1->then_instructions;
+
+ body.emit(assign(r0ACE, body.constant(int(16)), 0x01));
+
+ body.emit(assign(r0ACC, lshift(r0AC8, body.constant(int(16))), 0x01));
+
+
+ body.instructions = f0AD1_parent_instructions;
+ body.emit(f0AD1);
+
+ /* END IF */
+
+ /* IF CONDITION */
+ ir_expression *const r0AD5 = bit_and(r0ACC, body.constant(4278190080u));
+ ir_expression *const r0AD6 = equal(r0AD5, body.constant(0u));
+ ir_if *f0AD4 = new(mem_ctx) ir_if(operand(r0AD6).val);
+ exec_list *const f0AD4_parent_instructions = body.instructions;
+
+ /* THEN INSTRUCTIONS */
+ body.instructions = &f0AD4->then_instructions;
+
+ body.emit(assign(r0ACE, add(r0ACE, body.constant(int(8))), 0x01));
+
+ body.emit(assign(r0ACC, lshift(r0ACC, body.constant(int(8))), 0x01));
+
+
+ body.instructions = f0AD4_parent_instructions;
+ body.emit(f0AD4);
+
+ /* END IF */
+
+ /* IF CONDITION */
+ ir_expression *const r0AD8 = bit_and(r0ACC, body.constant(4026531840u));
+ ir_expression *const r0AD9 = equal(r0AD8, body.constant(0u));
+ ir_if *f0AD7 = new(mem_ctx) ir_if(operand(r0AD9).val);
+ exec_list *const f0AD7_parent_instructions = body.instructions;
+
+ /* THEN INSTRUCTIONS */
+ body.instructions = &f0AD7->then_instructions;
+
+ body.emit(assign(r0ACE, add(r0ACE, body.constant(int(4))), 0x01));
+
+ body.emit(assign(r0ACC, lshift(r0ACC, body.constant(int(4))), 0x01));
+
+
+ body.instructions = f0AD7_parent_instructions;
+ body.emit(f0AD7);
+
+ /* END IF */
+
+ /* IF CONDITION */
+ ir_expression *const r0ADB = bit_and(r0ACC, body.constant(3221225472u));
+ ir_expression *const r0ADC = equal(r0ADB, body.constant(0u));
+ ir_if *f0ADA = new(mem_ctx) ir_if(operand(r0ADC).val);
+ exec_list *const f0ADA_parent_instructions = body.instructions;
+
+ /* THEN INSTRUCTIONS */
+ body.instructions = &f0ADA->then_instructions;
+
+ body.emit(assign(r0ACE, add(r0ACE, body.constant(int(2))), 0x01));
+
+ body.emit(assign(r0ACC, lshift(r0ACC, body.constant(int(2))), 0x01));
+
+
+ body.instructions = f0ADA_parent_instructions;
+ body.emit(f0ADA);
+
+ /* END IF */
+
+ /* IF CONDITION */
+ ir_expression *const r0ADE = bit_and(r0ACC, body.constant(2147483648u));
+ ir_expression *const r0ADF = equal(r0ADE, body.constant(0u));
+ ir_if *f0ADD = new(mem_ctx) ir_if(operand(r0ADF).val);
+ exec_list *const f0ADD_parent_instructions = body.instructions;
+
+ /* THEN INSTRUCTIONS */
+ body.instructions = &f0ADD->then_instructions;
+
+ body.emit(assign(r0ACE, add(r0ACE, body.constant(int(1))), 0x01));
+
+
+ body.instructions = f0ADD_parent_instructions;
+ body.emit(f0ADD);
+
+ /* END IF */
+
+ body.emit(assign(r0ACD, r0ACE, 0x01));
+
+
+ body.instructions = f0ACF_parent_instructions;
+ body.emit(f0ACF);
+
+ /* END IF */
+
+ ir_variable *const r0AE0 = body.make_temp(glsl_type::int_type, "assignment_tmp");
+ body.emit(assign(r0AE0, add(r0ACD, body.constant(int(-11))), 0x01));
+
+ /* IF CONDITION */
+ ir_expression *const r0AE2 = lequal(body.constant(int(0)), r0AE0);
+ ir_if *f0AE1 = new(mem_ctx) ir_if(operand(r0AE2).val);
+ exec_list *const f0AE1_parent_instructions = body.instructions;
+
+ /* THEN INSTRUCTIONS */
+ body.instructions = &f0AE1->then_instructions;
+
+ body.emit(assign(r0AC2, lshift(r0AC8, r0AE0), 0x01));
+
+ body.emit(assign(r0AC1, body.constant(0u), 0x01));
+
+
+ /* ELSE INSTRUCTIONS */
+ body.instructions = &f0AE1->else_instructions;
+
+ ir_variable *const r0AE3 = body.make_temp(glsl_type::uint_type, "a1");
+ body.emit(assign(r0AE3, body.constant(0u), 0x01));
+
+ ir_variable *const r0AE4 = body.make_temp(glsl_type::int_type, "count");
+ body.emit(assign(r0AE4, neg(r0AE0), 0x01));
+
+ ir_variable *const r0AE5 = new(mem_ctx) ir_variable(glsl_type::uint_type, "z1", ir_var_auto);
+ body.emit(r0AE5);
+ ir_variable *const r0AE6 = new(mem_ctx) ir_variable(glsl_type::uint_type, "z0", ir_var_auto);
+ body.emit(r0AE6);
+ ir_variable *const r0AE7 = body.make_temp(glsl_type::int_type, "assignment_tmp");
+ ir_expression *const r0AE8 = neg(r0AE4);
+ body.emit(assign(r0AE7, bit_and(r0AE8, body.constant(int(31))), 0x01));
+
+ /* IF CONDITION */
+ ir_expression *const r0AEA = equal(r0AE4, body.constant(int(0)));
+ ir_if *f0AE9 = new(mem_ctx) ir_if(operand(r0AEA).val);
+ exec_list *const f0AE9_parent_instructions = body.instructions;
+
+ /* THEN INSTRUCTIONS */
+ body.instructions = &f0AE9->then_instructions;
+
+ body.emit(assign(r0AE5, body.constant(0u), 0x01));
+
+ body.emit(assign(r0AE6, r0AC8, 0x01));
+
+
+ /* ELSE INSTRUCTIONS */
+ body.instructions = &f0AE9->else_instructions;
+
+ /* IF CONDITION */
+ ir_expression *const r0AEC = less(r0AE4, body.constant(int(32)));
+ ir_if *f0AEB = new(mem_ctx) ir_if(operand(r0AEC).val);
+ exec_list *const f0AEB_parent_instructions = body.instructions;
+
+ /* THEN INSTRUCTIONS */
+ body.instructions = &f0AEB->then_instructions;
+
+ ir_expression *const r0AED = lshift(r0AC8, r0AE7);
+ body.emit(assign(r0AE5, bit_or(r0AED, body.constant(0u)), 0x01));
+
+ body.emit(assign(r0AE6, rshift(r0AC8, r0AE4), 0x01));
+
+
+ /* ELSE INSTRUCTIONS */
+ body.instructions = &f0AEB->else_instructions;
+
+ ir_variable *const r0AEE = body.make_temp(glsl_type::uint_type, "conditional_tmp");
+ /* IF CONDITION */
+ ir_expression *const r0AF0 = less(r0AE4, body.constant(int(64)));
+ ir_if *f0AEF = new(mem_ctx) ir_if(operand(r0AF0).val);
+ exec_list *const f0AEF_parent_instructions = body.instructions;
+
+ /* THEN INSTRUCTIONS */
+ body.instructions = &f0AEF->then_instructions;
+
+ ir_expression *const r0AF1 = bit_and(r0AE4, body.constant(int(31)));
+ body.emit(assign(r0AEE, rshift(r0AC8, r0AF1), 0x01));
+
+
+ /* ELSE INSTRUCTIONS */
+ body.instructions = &f0AEF->else_instructions;
+
+ body.emit(assign(r0AEE, body.constant(0u), 0x01));
+
+
+ body.instructions = f0AEF_parent_instructions;
+ body.emit(f0AEF);
+
+ /* END IF */
+
+ body.emit(assign(r0AE5, r0AEE, 0x01));
+
+ body.emit(assign(r0AE6, body.constant(0u), 0x01));
+
+
+ body.instructions = f0AEB_parent_instructions;
+ body.emit(f0AEB);
+
+ /* END IF */
+
+
+ body.instructions = f0AE9_parent_instructions;
+ body.emit(f0AE9);
+
+ /* END IF */
+
+ body.emit(assign(r0AC2, r0AE6, 0x01));
+
+ body.emit(assign(r0AC1, r0AE5, 0x01));
+
+
+ body.instructions = f0AE1_parent_instructions;
+ body.emit(f0AE1);
+
+ /* END IF */
+
+ ir_variable *const r0AF2 = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "z", ir_var_auto);
+ body.emit(r0AF2);
+ ir_expression *const r0AF3 = lshift(r0AC0, body.constant(int(31)));
+ ir_expression *const r0AF4 = sub(body.constant(int(1042)), r0AE0);
+ ir_expression *const r0AF5 = expr(ir_unop_i2u, r0AF4);
+ ir_expression *const r0AF6 = lshift(r0AF5, body.constant(int(20)));
+ ir_expression *const r0AF7 = add(r0AF3, r0AF6);
+ body.emit(assign(r0AF2, add(r0AF7, r0AC2), 0x02));
+
+ body.emit(assign(r0AF2, r0AC1, 0x01));
+
+ body.emit(assign(r0ABF, r0AF2, 0x03));
+
+
+ body.instructions = f0AC3_parent_instructions;
+ body.emit(f0AC3);
+
+ /* END IF */
+
+ body.emit(ret(r0ABF));
+
+ sig->replace_parameters(&sig_parameters);
+ return sig;
+}
diff --git a/src/compiler/glsl/builtin_functions.cpp b/src/compiler/glsl/builtin_functions.cpp
index 53491d8c38..67d2eec1ce 100644
--- a/src/compiler/glsl/builtin_functions.cpp
+++ b/src/compiler/glsl/builtin_functions.cpp
@@ -3368,6 +3368,10 @@ builtin_builder::create_builtins()
generate_ir::fp64_to_int(mem_ctx, integer_functions_supported),
NULL);
+ add_function("__builtin_int_to_fp64",
+ generate_ir::int_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 3adb2d230f..2ef249bdc6 100644
--- a/src/compiler/glsl/builtin_functions.h
+++ b/src/compiler/glsl/builtin_functions.h
@@ -100,6 +100,9 @@ uint_to_fp64(void *mem_ctx, builtin_available_predicate avail);
ir_function_signature *
fp64_to_int(void *mem_ctx, builtin_available_predicate avail);
+ir_function_signature *
+int_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
index a9cffd4f9b..e9269630dc 100644
--- a/src/compiler/glsl/float64.glsl
+++ b/src/compiler/glsl/float64.glsl
@@ -976,3 +976,26 @@ fp64_to_int(uvec2 a)
return z;
}
+
+/* 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/glcpp/glcpp-parse.y b/src/compiler/glsl/glcpp/glcpp-parse.y
index ff501b69e1..474df8695b 100644
--- a/src/compiler/glsl/glcpp/glcpp-parse.y
+++ b/src/compiler/glsl/glcpp/glcpp-parse.y
@@ -2460,6 +2460,7 @@ _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t versio
add_builtin_define(parser, "__have_builtin_builtin_fp64_to_uint", 1);
add_builtin_define(parser, "__have_builtin_builtin_uint_to_fp64", 1);
add_builtin_define(parser, "__have_builtin_builtin_fp64_to_int", 1);
+ add_builtin_define(parser, "__have_builtin_builtin_int_to_fp64", 1);
}
}
--
2.14.1
More information about the mesa-dev
mailing list