Signed-off-by: Elie Tournier <elie.tourn...@collabora.com> --- src/compiler/glsl/builtin_float64.h | 589 ++++++++++++++++++++++++++++++++ src/compiler/glsl/builtin_functions.cpp | 4 + src/compiler/glsl/builtin_functions.h | 3 + src/compiler/glsl/float64.glsl | 133 ++++++++ 4 files changed, 729 insertions(+)
diff --git a/src/compiler/glsl/builtin_float64.h b/src/compiler/glsl/builtin_float64.h index b50ebc2dc2..dad5811289 100644 --- a/src/compiler/glsl/builtin_float64.h +++ b/src/compiler/glsl/builtin_float64.h @@ -23652,3 +23652,592 @@ fp32_to_fp64(void *mem_ctx, builtin_available_predicate avail) sig->replace_parameters(&sig_parameters); return sig; } +ir_function_signature * +packFloat32(void *mem_ctx, builtin_available_predicate avail) +{ + ir_function_signature *const sig = + new(mem_ctx) ir_function_signature(glsl_type::uint_type, avail); + ir_factory body(&sig->body, mem_ctx); + sig->is_defined = true; + + exec_list sig_parameters; + + ir_variable *const r13A7 = new(mem_ctx) ir_variable(glsl_type::uint_type, "zSign", ir_var_function_in); + sig_parameters.push_tail(r13A7); + ir_variable *const r13A8 = new(mem_ctx) ir_variable(glsl_type::uint_type, "zExp", ir_var_function_in); + sig_parameters.push_tail(r13A8); + ir_variable *const r13A9 = new(mem_ctx) ir_variable(glsl_type::uint_type, "zFrac", ir_var_function_in); + sig_parameters.push_tail(r13A9); + ir_expression *const r13AA = lshift(r13A7, body.constant(int(31))); + ir_expression *const r13AB = lshift(r13A8, body.constant(int(23))); + ir_expression *const r13AC = add(r13AA, r13AB); + ir_expression *const r13AD = add(r13AC, r13A9); + body.emit(ret(r13AD)); + + sig->replace_parameters(&sig_parameters); + return sig; +} +ir_function_signature * +shift32RightJamming(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 r13AE = new(mem_ctx) ir_variable(glsl_type::uint_type, "a", ir_var_function_in); + sig_parameters.push_tail(r13AE); + ir_variable *const r13AF = new(mem_ctx) ir_variable(glsl_type::int_type, "count", ir_var_function_in); + sig_parameters.push_tail(r13AF); + ir_variable *const r13B0 = new(mem_ctx) ir_variable(glsl_type::uint_type, "zPtr", ir_var_function_inout); + sig_parameters.push_tail(r13B0); + ir_variable *const r13B1 = new(mem_ctx) ir_variable(glsl_type::uint_type, "z", ir_var_auto); + body.emit(r13B1); + /* IF CONDITION */ + ir_expression *const r13B3 = equal(r13AF, body.constant(int(0))); + ir_if *f13B2 = new(mem_ctx) ir_if(operand(r13B3).val); + exec_list *const f13B2_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f13B2->then_instructions; + + body.emit(assign(r13B1, r13AE, 0x01)); + + + /* ELSE INSTRUCTIONS */ + body.instructions = &f13B2->else_instructions; + + /* IF CONDITION */ + ir_expression *const r13B5 = less(r13AF, body.constant(int(32))); + ir_if *f13B4 = new(mem_ctx) ir_if(operand(r13B5).val); + exec_list *const f13B4_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f13B4->then_instructions; + + ir_expression *const r13B6 = rshift(r13AE, r13AF); + ir_expression *const r13B7 = neg(r13AF); + ir_expression *const r13B8 = bit_and(r13B7, body.constant(int(31))); + ir_expression *const r13B9 = lshift(r13AE, r13B8); + ir_expression *const r13BA = nequal(r13B9, body.constant(0u)); + ir_expression *const r13BB = expr(ir_unop_b2i, r13BA); + ir_expression *const r13BC = expr(ir_unop_i2u, r13BB); + body.emit(assign(r13B1, bit_or(r13B6, r13BC), 0x01)); + + + /* ELSE INSTRUCTIONS */ + body.instructions = &f13B4->else_instructions; + + ir_expression *const r13BD = nequal(r13AE, body.constant(0u)); + ir_expression *const r13BE = expr(ir_unop_b2i, r13BD); + body.emit(assign(r13B1, expr(ir_unop_i2u, r13BE), 0x01)); + + + body.instructions = f13B4_parent_instructions; + body.emit(f13B4); + + /* END IF */ + + + body.instructions = f13B2_parent_instructions; + body.emit(f13B2); + + /* END IF */ + + body.emit(assign(r13B0, r13B1, 0x01)); + + sig->replace_parameters(&sig_parameters); + return sig; +} +ir_function_signature * +roundAndPackFloat32(void *mem_ctx, builtin_available_predicate avail) +{ + ir_function_signature *const sig = + new(mem_ctx) ir_function_signature(glsl_type::uint_type, avail); + ir_factory body(&sig->body, mem_ctx); + sig->is_defined = true; + + exec_list sig_parameters; + + ir_variable *const r13BF = new(mem_ctx) ir_variable(glsl_type::uint_type, "zSign", ir_var_function_in); + sig_parameters.push_tail(r13BF); + ir_variable *const r13C0 = new(mem_ctx) ir_variable(glsl_type::uint_type, "zExp", ir_var_function_in); + sig_parameters.push_tail(r13C0); + ir_variable *const r13C1 = new(mem_ctx) ir_variable(glsl_type::uint_type, "zFrac", ir_var_function_in); + sig_parameters.push_tail(r13C1); + ir_variable *const r13C2 = body.make_temp(glsl_type::bool_type, "execute_flag"); + body.emit(assign(r13C2, body.constant(true), 0x01)); + + ir_variable *const r13C3 = body.make_temp(glsl_type::uint_type, "return_value"); + ir_variable *const r13C4 = new(mem_ctx) ir_variable(glsl_type::uint_type, "roundBits", ir_var_auto); + body.emit(r13C4); + body.emit(assign(r13C4, bit_and(r13C1, body.constant(127u)), 0x01)); + + /* IF CONDITION */ + ir_expression *const r13C6 = lequal(body.constant(253u), r13C0); + ir_if *f13C5 = new(mem_ctx) ir_if(operand(r13C6).val); + exec_list *const f13C5_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f13C5->then_instructions; + + /* IF CONDITION */ + ir_expression *const r13C8 = less(body.constant(253u), r13C0); + ir_expression *const r13C9 = equal(r13C0, body.constant(253u)); + ir_expression *const r13CA = less(r13C1, body.constant(4294967232u)); + ir_expression *const r13CB = logic_and(r13C9, r13CA); + ir_expression *const r13CC = logic_or(r13C8, r13CB); + ir_if *f13C7 = new(mem_ctx) ir_if(operand(r13CC).val); + exec_list *const f13C7_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f13C7->then_instructions; + + ir_expression *const r13CD = lshift(r13BF, body.constant(int(31))); + body.emit(assign(r13C3, add(r13CD, body.constant(2139095040u)), 0x01)); + + body.emit(assign(r13C2, body.constant(false), 0x01)); + + + /* ELSE INSTRUCTIONS */ + body.instructions = &f13C7->else_instructions; + + /* IF CONDITION */ + ir_expression *const r13CF = less(r13C0, body.constant(0u)); + ir_if *f13CE = new(mem_ctx) ir_if(operand(r13CF).val); + exec_list *const f13CE_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f13CE->then_instructions; + + ir_variable *const r13D0 = body.make_temp(glsl_type::int_type, "count"); + ir_expression *const r13D1 = expr(ir_unop_u2i, r13C0); + body.emit(assign(r13D0, neg(r13D1), 0x01)); + + ir_variable *const r13D2 = new(mem_ctx) ir_variable(glsl_type::uint_type, "z", ir_var_auto); + body.emit(r13D2); + /* IF CONDITION */ + ir_expression *const r13D4 = equal(r13D0, body.constant(int(0))); + ir_if *f13D3 = new(mem_ctx) ir_if(operand(r13D4).val); + exec_list *const f13D3_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f13D3->then_instructions; + + body.emit(assign(r13D2, r13C1, 0x01)); + + + /* ELSE INSTRUCTIONS */ + body.instructions = &f13D3->else_instructions; + + /* IF CONDITION */ + ir_expression *const r13D6 = less(r13D0, body.constant(int(32))); + ir_if *f13D5 = new(mem_ctx) ir_if(operand(r13D6).val); + exec_list *const f13D5_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f13D5->then_instructions; + + ir_expression *const r13D7 = rshift(r13C1, r13D0); + ir_expression *const r13D8 = neg(r13D0); + ir_expression *const r13D9 = bit_and(r13D8, body.constant(int(31))); + ir_expression *const r13DA = lshift(r13C1, r13D9); + ir_expression *const r13DB = nequal(r13DA, body.constant(0u)); + ir_expression *const r13DC = expr(ir_unop_b2i, r13DB); + ir_expression *const r13DD = expr(ir_unop_i2u, r13DC); + body.emit(assign(r13D2, bit_or(r13D7, r13DD), 0x01)); + + + /* ELSE INSTRUCTIONS */ + body.instructions = &f13D5->else_instructions; + + ir_expression *const r13DE = nequal(r13C1, body.constant(0u)); + ir_expression *const r13DF = expr(ir_unop_b2i, r13DE); + body.emit(assign(r13D2, expr(ir_unop_i2u, r13DF), 0x01)); + + + body.instructions = f13D5_parent_instructions; + body.emit(f13D5); + + /* END IF */ + + + body.instructions = f13D3_parent_instructions; + body.emit(f13D3); + + /* END IF */ + + body.emit(assign(r13C1, r13D2, 0x01)); + + body.emit(assign(r13C0, body.constant(0u), 0x01)); + + body.emit(assign(r13C4, bit_and(r13D2, body.constant(127u)), 0x01)); + + + body.instructions = f13CE_parent_instructions; + body.emit(f13CE); + + /* END IF */ + + + body.instructions = f13C7_parent_instructions; + body.emit(f13C7); + + /* END IF */ + + + body.instructions = f13C5_parent_instructions; + body.emit(f13C5); + + /* END IF */ + + /* IF CONDITION */ + ir_if *f13E0 = new(mem_ctx) ir_if(operand(r13C2).val); + exec_list *const f13E0_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f13E0->then_instructions; + + ir_expression *const r13E1 = add(r13C1, body.constant(64u)); + body.emit(assign(r13C1, rshift(r13E1, body.constant(int(7))), 0x01)); + + ir_expression *const r13E2 = bit_xor(r13C4, body.constant(64u)); + ir_expression *const r13E3 = equal(r13E2, body.constant(0u)); + ir_expression *const r13E4 = expr(ir_unop_b2i, r13E3); + ir_expression *const r13E5 = expr(ir_unop_i2u, r13E4); + ir_expression *const r13E6 = bit_and(r13E5, body.constant(1u)); + ir_expression *const r13E7 = expr(ir_unop_bit_not, r13E6); + body.emit(assign(r13C1, bit_and(r13C1, r13E7), 0x01)); + + /* IF CONDITION */ + ir_expression *const r13E9 = equal(r13C1, body.constant(0u)); + ir_if *f13E8 = new(mem_ctx) ir_if(operand(r13E9).val); + exec_list *const f13E8_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f13E8->then_instructions; + + body.emit(assign(r13C0, body.constant(0u), 0x01)); + + + body.instructions = f13E8_parent_instructions; + body.emit(f13E8); + + /* END IF */ + + ir_expression *const r13EA = lshift(r13BF, body.constant(int(31))); + ir_expression *const r13EB = lshift(r13C0, body.constant(int(23))); + ir_expression *const r13EC = add(r13EA, r13EB); + body.emit(assign(r13C3, add(r13EC, r13C1), 0x01)); + + body.emit(assign(r13C2, body.constant(false), 0x01)); + + + body.instructions = f13E0_parent_instructions; + body.emit(f13E0); + + /* END IF */ + + body.emit(ret(r13C3)); + + sig->replace_parameters(&sig_parameters); + return sig; +} +ir_function_signature * +fp64_to_fp32(void *mem_ctx, builtin_available_predicate avail) +{ + ir_function_signature *const sig = + new(mem_ctx) ir_function_signature(glsl_type::uint_type, avail); + ir_factory body(&sig->body, mem_ctx); + sig->is_defined = true; + + exec_list sig_parameters; + + ir_variable *const r13ED = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "a", ir_var_function_in); + sig_parameters.push_tail(r13ED); + ir_variable *const r13EE = body.make_temp(glsl_type::uint_type, "return_value"); + ir_variable *const r13EF = new(mem_ctx) ir_variable(glsl_type::uint_type, "zFrac", ir_var_auto); + body.emit(r13EF); + body.emit(assign(r13EF, body.constant(0u), 0x01)); + + ir_variable *const r13F0 = body.make_temp(glsl_type::uvec2_type, "vec_ctor"); + body.emit(assign(r13F0, bit_and(swizzle_x(r13ED), body.constant(1048575u)), 0x01)); + + body.emit(assign(r13F0, swizzle_y(r13ED), 0x02)); + + ir_variable *const r13F1 = body.make_temp(glsl_type::uint_type, "extractFloat64Exp_retval"); + ir_expression *const r13F2 = rshift(swizzle_x(r13ED), body.constant(int(20))); + body.emit(assign(r13F1, bit_and(r13F2, body.constant(2047u)), 0x01)); + + ir_variable *const r13F3 = body.make_temp(glsl_type::uint_type, "extractFloat64Sign_retval"); + body.emit(assign(r13F3, rshift(swizzle_x(r13ED), body.constant(int(31))), 0x01)); + + /* IF CONDITION */ + ir_expression *const r13F5 = equal(r13F1, body.constant(2047u)); + ir_if *f13F4 = new(mem_ctx) ir_if(operand(r13F5).val); + exec_list *const f13F4_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f13F4->then_instructions; + + /* IF CONDITION */ + ir_expression *const r13F7 = bit_or(swizzle_x(r13F0), swizzle_y(r13ED)); + ir_expression *const r13F8 = nequal(r13F7, body.constant(0u)); + ir_if *f13F6 = new(mem_ctx) ir_if(operand(r13F8).val); + exec_list *const f13F6_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f13F6->then_instructions; + + ir_expression *const r13F9 = lshift(r13F3, body.constant(int(31))); + ir_expression *const r13FA = bit_or(r13F9, body.constant(2143289344u)); + ir_expression *const r13FB = bit_and(swizzle_x(r13F0), body.constant(1048575u)); + ir_expression *const r13FC = lshift(r13FB, body.constant(int(3))); + ir_expression *const r13FD = bit_or(r13FA, r13FC); + ir_expression *const r13FE = rshift(swizzle_y(r13ED), body.constant(int(29))); + body.emit(assign(r13EE, bit_or(r13FD, r13FE), 0x01)); + + + /* ELSE INSTRUCTIONS */ + body.instructions = &f13F6->else_instructions; + + ir_expression *const r13FF = lshift(r13F3, body.constant(int(31))); + body.emit(assign(r13EE, add(r13FF, body.constant(2139095040u)), 0x01)); + + + body.instructions = f13F6_parent_instructions; + body.emit(f13F6); + + /* END IF */ + + + /* ELSE INSTRUCTIONS */ + body.instructions = &f13F4->else_instructions; + + ir_variable *const r1400 = new(mem_ctx) ir_variable(glsl_type::uint_type, "z1", ir_var_auto); + body.emit(r1400); + ir_variable *const r1401 = new(mem_ctx) ir_variable(glsl_type::uint_type, "z0", ir_var_auto); + body.emit(r1401); + ir_expression *const r1402 = lshift(swizzle_x(r13F0), body.constant(int(10))); + ir_expression *const r1403 = rshift(swizzle_y(r13ED), body.constant(int(22))); + ir_expression *const r1404 = bit_or(r1402, r1403); + ir_expression *const r1405 = lshift(swizzle_y(r13ED), body.constant(int(10))); + ir_expression *const r1406 = nequal(r1405, body.constant(0u)); + ir_expression *const r1407 = expr(ir_unop_b2i, r1406); + ir_expression *const r1408 = expr(ir_unop_i2u, r1407); + body.emit(assign(r1400, bit_or(r1404, r1408), 0x01)); + + body.emit(assign(r1401, rshift(swizzle_x(r13F0), body.constant(int(22))), 0x01)); + + body.emit(assign(r13EF, r1400, 0x01)); + + /* IF CONDITION */ + ir_expression *const r140A = nequal(r13F1, body.constant(0u)); + ir_if *f1409 = new(mem_ctx) ir_if(operand(r140A).val); + exec_list *const f1409_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f1409->then_instructions; + + body.emit(assign(r13EF, bit_or(r1400, body.constant(1073741824u)), 0x01)); + + + body.instructions = f1409_parent_instructions; + body.emit(f1409); + + /* END IF */ + + ir_variable *const r140B = body.make_temp(glsl_type::uint_type, "zExp"); + body.emit(assign(r140B, add(r13F1, body.constant(4294966399u)), 0x01)); + + ir_variable *const r140C = body.make_temp(glsl_type::uint_type, "zFrac"); + body.emit(assign(r140C, r13EF, 0x01)); + + ir_variable *const r140D = body.make_temp(glsl_type::bool_type, "execute_flag"); + body.emit(assign(r140D, body.constant(true), 0x01)); + + ir_variable *const r140E = body.make_temp(glsl_type::uint_type, "return_value"); + ir_variable *const r140F = new(mem_ctx) ir_variable(glsl_type::uint_type, "roundBits", ir_var_auto); + body.emit(r140F); + body.emit(assign(r140F, bit_and(r13EF, body.constant(127u)), 0x01)); + + /* IF CONDITION */ + ir_expression *const r1411 = lequal(body.constant(253u), r140B); + ir_if *f1410 = new(mem_ctx) ir_if(operand(r1411).val); + exec_list *const f1410_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f1410->then_instructions; + + /* IF CONDITION */ + ir_expression *const r1413 = less(body.constant(253u), r140B); + ir_expression *const r1414 = equal(r140B, body.constant(253u)); + ir_expression *const r1415 = less(r13EF, body.constant(4294967232u)); + ir_expression *const r1416 = logic_and(r1414, r1415); + ir_expression *const r1417 = logic_or(r1413, r1416); + ir_if *f1412 = new(mem_ctx) ir_if(operand(r1417).val); + exec_list *const f1412_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f1412->then_instructions; + + ir_expression *const r1418 = lshift(r13F3, body.constant(int(31))); + body.emit(assign(r140E, add(r1418, body.constant(2139095040u)), 0x01)); + + body.emit(assign(r140D, body.constant(false), 0x01)); + + + /* ELSE INSTRUCTIONS */ + body.instructions = &f1412->else_instructions; + + /* IF CONDITION */ + ir_expression *const r141A = less(r140B, body.constant(0u)); + ir_if *f1419 = new(mem_ctx) ir_if(operand(r141A).val); + exec_list *const f1419_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f1419->then_instructions; + + ir_variable *const r141B = body.make_temp(glsl_type::int_type, "count"); + ir_expression *const r141C = expr(ir_unop_u2i, r140B); + body.emit(assign(r141B, neg(r141C), 0x01)); + + ir_variable *const r141D = new(mem_ctx) ir_variable(glsl_type::uint_type, "z", ir_var_auto); + body.emit(r141D); + /* IF CONDITION */ + ir_expression *const r141F = equal(r141B, body.constant(int(0))); + ir_if *f141E = new(mem_ctx) ir_if(operand(r141F).val); + exec_list *const f141E_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f141E->then_instructions; + + body.emit(assign(r141D, r13EF, 0x01)); + + + /* ELSE INSTRUCTIONS */ + body.instructions = &f141E->else_instructions; + + /* IF CONDITION */ + ir_expression *const r1421 = less(r141B, body.constant(int(32))); + ir_if *f1420 = new(mem_ctx) ir_if(operand(r1421).val); + exec_list *const f1420_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f1420->then_instructions; + + ir_expression *const r1422 = rshift(r13EF, r141B); + ir_expression *const r1423 = neg(r141B); + ir_expression *const r1424 = bit_and(r1423, body.constant(int(31))); + ir_expression *const r1425 = lshift(r13EF, r1424); + ir_expression *const r1426 = nequal(r1425, body.constant(0u)); + ir_expression *const r1427 = expr(ir_unop_b2i, r1426); + ir_expression *const r1428 = expr(ir_unop_i2u, r1427); + body.emit(assign(r141D, bit_or(r1422, r1428), 0x01)); + + + /* ELSE INSTRUCTIONS */ + body.instructions = &f1420->else_instructions; + + ir_expression *const r1429 = nequal(r13EF, body.constant(0u)); + ir_expression *const r142A = expr(ir_unop_b2i, r1429); + body.emit(assign(r141D, expr(ir_unop_i2u, r142A), 0x01)); + + + body.instructions = f1420_parent_instructions; + body.emit(f1420); + + /* END IF */ + + + body.instructions = f141E_parent_instructions; + body.emit(f141E); + + /* END IF */ + + body.emit(assign(r140C, r141D, 0x01)); + + body.emit(assign(r140B, body.constant(0u), 0x01)); + + body.emit(assign(r140F, bit_and(r141D, body.constant(127u)), 0x01)); + + + body.instructions = f1419_parent_instructions; + body.emit(f1419); + + /* END IF */ + + + body.instructions = f1412_parent_instructions; + body.emit(f1412); + + /* END IF */ + + + body.instructions = f1410_parent_instructions; + body.emit(f1410); + + /* END IF */ + + /* IF CONDITION */ + ir_if *f142B = new(mem_ctx) ir_if(operand(r140D).val); + exec_list *const f142B_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f142B->then_instructions; + + ir_expression *const r142C = add(r140C, body.constant(64u)); + body.emit(assign(r140C, rshift(r142C, body.constant(int(7))), 0x01)); + + ir_expression *const r142D = bit_xor(r140F, body.constant(64u)); + ir_expression *const r142E = equal(r142D, body.constant(0u)); + ir_expression *const r142F = expr(ir_unop_b2i, r142E); + ir_expression *const r1430 = expr(ir_unop_i2u, r142F); + ir_expression *const r1431 = bit_and(r1430, body.constant(1u)); + ir_expression *const r1432 = expr(ir_unop_bit_not, r1431); + body.emit(assign(r140C, bit_and(r140C, r1432), 0x01)); + + /* IF CONDITION */ + ir_expression *const r1434 = equal(r140C, body.constant(0u)); + ir_if *f1433 = new(mem_ctx) ir_if(operand(r1434).val); + exec_list *const f1433_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f1433->then_instructions; + + body.emit(assign(r140B, body.constant(0u), 0x01)); + + + body.instructions = f1433_parent_instructions; + body.emit(f1433); + + /* END IF */ + + ir_expression *const r1435 = lshift(r13F3, body.constant(int(31))); + ir_expression *const r1436 = lshift(r140B, body.constant(int(23))); + ir_expression *const r1437 = add(r1435, r1436); + body.emit(assign(r140E, add(r1437, r140C), 0x01)); + + body.emit(assign(r140D, body.constant(false), 0x01)); + + + body.instructions = f142B_parent_instructions; + body.emit(f142B); + + /* END IF */ + + body.emit(assign(r13EE, r140E, 0x01)); + + + body.instructions = f13F4_parent_instructions; + body.emit(f13F4); + + /* END IF */ + + body.emit(ret(r13EE)); + + sig->replace_parameters(&sig_parameters); + return sig; +} diff --git a/src/compiler/glsl/builtin_functions.cpp b/src/compiler/glsl/builtin_functions.cpp index 17192b63f2..a88ceeb955 100644 --- a/src/compiler/glsl/builtin_functions.cpp +++ b/src/compiler/glsl/builtin_functions.cpp @@ -3165,6 +3165,10 @@ builtin_builder::create_builtins() generate_ir::fp32_to_fp64(mem_ctx, integer_functions_supported), NULL); + add_function("__builtin_fp64_to_fp32", + generate_ir::fp64_to_fp32(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 a228f17596..3845c5e79f 100644 --- a/src/compiler/glsl/builtin_functions.h +++ b/src/compiler/glsl/builtin_functions.h @@ -90,6 +90,9 @@ fdiv64(void *mem_ctx, builtin_available_predicate avail); ir_function_signature * fp32_to_fp64(void *mem_ctx, builtin_available_predicate avail); +ir_function_signature * +fp64_to_fp32(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 ee9224c293..3f790dec83 100644 --- a/src/compiler/glsl/float64.glsl +++ b/src/compiler/glsl/float64.glsl @@ -1243,3 +1243,136 @@ fp32_to_fp64( uint a ) return packFloat64( aSign, aExp + 0x380u, aFrac>>3, aFrac<<29 ); } + +/* Packs the sign `zSign', exponent `zExp', and significand `zFrac' into a + * single-precision floating-point value, returning the result. After being + * shifted into the proper positions, the three fields are simply added + * together to form the result. This means that any integer portion of `zSig' + * 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 `zFrac' is a complete, normalized + * significand. + */ +uint +packFloat32( uint zSign, uint zExp, uint zFrac ) +{ + return ( zSign<<31 ) + ( zExp<<23 ) + zFrac; +} + +/* Shifts `a' right by the number of bits given in `count'. If any nonzero + * bits are shifted off, they are "jammed" into the least significant bit of + * the result by setting the least significant bit to 1. The value of `count' + * can be arbitrarily large; in particular, if `count' is greater than 32, the + * result will be either 0 or 1, depending on whether `a' is zero or nonzero. + * The result is stored in the location pointed to by `zPtr'. + */ +void +shift32RightJamming( uint a, int count, inout uint zPtr ) +{ + uint z; + + if( count == 0 ) { + z = a; + } else if( count < 32 ) { + z = ( a>>count ) | uint ( ( a<<( ( - count ) & 31 ) ) != 0u ); + } else { + z = uint ( a != 0u ); + } + zPtr = z; +} + +/* Takes an abstract floating-point value having sign `zSign', exponent `zExp', + * and significand `zFrac', and returns the proper single-precision floating- + * point value corresponding to the abstract input. Ordinarily, the abstract + * value is simply rounded and packed into the single-precision format, with + * the inexact exception raised if the abstract input cannot be represented + * exactly. However, if the abstract value is too large, the overflow and + * inexact exceptions are raised and an infinity or maximal finite value is + * returned. If the abstract value is too small, the input value is rounded to + * a subnormal number, and the underflow and inexact exceptions are raised if + * the abstract input cannot be represented exactly as a subnormal single- + * precision floating-point number. + * The input significand `zFrac' has its binary point between bits 30 + * and 29, which is 7 bits to the left of the usual location. This shifted + * significand must be normalized or smaller. If `zFrac' is not normalized, + * `zExp' must be 0; in that case, the result returned is a subnormal number, + * and it must not require rounding. In the usual case that `zFrac' is + * normalized, `zExp' must be 1 less than the "true" floating-point exponent. + * The handling of underflow and overflow follows the IEEE Standard for + * Floating-Point Arithmetic. + */ +uint +roundAndPackFloat32( uint zSign, uint zExp, uint zFrac ) +{ + uint roundNearestEven; + uint roundIncrement; + uint roundBits; + + roundNearestEven = uint ( FLOAT_ROUNDING_MODE == FLOAT_ROUND_NEAREST_EVEN ); + roundIncrement = 0x40u; + if ( roundNearestEven == 0u ) { + if ( FLOAT_ROUNDING_MODE == FLOAT_ROUND_TO_ZERO ) { + roundIncrement = 0u; + } else { + roundIncrement = 0x7Fu; + if ( zSign != 0u ) { + if ( FLOAT_ROUNDING_MODE == FLOAT_ROUND_UP ) { + roundIncrement = 0u; + } + } else { + if ( FLOAT_ROUNDING_MODE == FLOAT_ROUND_DOWN ) { + roundIncrement = 0u; + } + } + } + } + roundBits = zFrac & 0x7Fu; + if ( 0xFDu <= zExp ) { + if ( ( 0xFDu < zExp ) || + ( ( zExp == 0xFDu ) && ( ( zFrac + roundIncrement ) < 0u ) ) ) { + return packFloat32( + zSign, 0xFFu, 0u ) - uint ( roundIncrement == 0u ); + } + if ( zExp < 0u ) { + shift32RightJamming( zFrac, - int (zExp), zFrac ); + zExp = 0u; + roundBits = zFrac & 0x7Fu; + } + } + zFrac = ( zFrac + roundIncrement )>>7; + zFrac &= ~ ( uint ( ( roundBits ^ 0x40u ) == 0u ) & roundNearestEven ); + if ( zFrac == 0u ) { + zExp = 0u; + } + return packFloat32( zSign, zExp, zFrac ); +} + +/* Returns the result of converting the double-precision floating-point value + * `a' to the single-precision floating-point format. The conversion is + * performed according to the IEEE Standard for Floating-Point Arithmetic. + */ +uint +fp64_to_fp32( uvec2 a ) +{ + uint aSign; + uint aExp; + uint zFrac = 0u; + uint allZero = 0u; + uvec2 aFrac; + + aFrac = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( aExp == 0x7FFu ) { + if ( ( aFrac.x | aFrac.y ) != 0u ) { + return ( aSign<<31 ) | 0x7FC00000u | + ( ( aFrac.x & 0x000FFFFFu )<<3 ) | ( aFrac.y>>29 ); + } + return packFloat32( aSign, 0xFFu, 0u ); + } + shift64RightJamming( aFrac, 22, allZero, zFrac ); + if ( aExp != 0u ) { + zFrac |= 0x40000000u; + } + return roundAndPackFloat32( aSign, aExp - 0x381u, zFrac ); +} -- 2.11.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev