summaryrefslogtreecommitdiffstats
path: root/src/compiler/glsl
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/glsl')
-rw-r--r--src/compiler/glsl/builtin_functions.cpp8
-rw-r--r--src/compiler/glsl/builtin_functions.h6
-rw-r--r--src/compiler/glsl/builtin_int64.h474
-rw-r--r--src/compiler/glsl/glcpp/glcpp-parse.y2
-rw-r--r--src/compiler/glsl/int64.glsl18
5 files changed, 508 insertions, 0 deletions
diff --git a/src/compiler/glsl/builtin_functions.cpp b/src/compiler/glsl/builtin_functions.cpp
index 6d9ff4b504c..4a6c5afd65c 100644
--- a/src/compiler/glsl/builtin_functions.cpp
+++ b/src/compiler/glsl/builtin_functions.cpp
@@ -3103,6 +3103,10 @@ builtin_builder::create_builtins()
generate_ir::idiv64(mem_ctx, integer_functions_supported),
NULL);
+ add_function("__builtin_imod64",
+ generate_ir::imod64(mem_ctx, integer_functions_supported),
+ NULL);
+
add_function("__builtin_sign64",
generate_ir::sign64(mem_ctx, integer_functions_supported),
NULL);
@@ -3111,6 +3115,10 @@ builtin_builder::create_builtins()
generate_ir::udiv64(mem_ctx, integer_functions_supported),
NULL);
+ add_function("__builtin_umod64",
+ generate_ir::umod64(mem_ctx, integer_functions_supported),
+ NULL);
+
add_function("__builtin_umul64",
generate_ir::umul64(mem_ctx, integer_functions_supported),
NULL);
diff --git a/src/compiler/glsl/builtin_functions.h b/src/compiler/glsl/builtin_functions.h
index ac1a8ccd1eb..7ae211b48aa 100644
--- a/src/compiler/glsl/builtin_functions.h
+++ b/src/compiler/glsl/builtin_functions.h
@@ -52,6 +52,12 @@ ir_function_signature *
idiv64(void *mem_ctx, builtin_available_predicate avail);
ir_function_signature *
+umod64(void *mem_ctx, builtin_available_predicate avail);
+
+ir_function_signature *
+imod64(void *mem_ctx, builtin_available_predicate avail);
+
+ir_function_signature *
umul64(void *mem_ctx, builtin_available_predicate avail);
ir_function_signature *
diff --git a/src/compiler/glsl/builtin_int64.h b/src/compiler/glsl/builtin_int64.h
index 5eaa4a8eac9..c3577afdee8 100644
--- a/src/compiler/glsl/builtin_int64.h
+++ b/src/compiler/glsl/builtin_int64.h
@@ -726,3 +726,477 @@ idiv64(void *mem_ctx, builtin_available_predicate avail)
sig->replace_parameters(&sig_parameters);
return sig;
}
+ir_function_signature *
+umod64(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 r0096 = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "n", ir_var_function_in);
+ sig_parameters.push_tail(r0096);
+ ir_variable *const r0097 = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "d", ir_var_function_in);
+ sig_parameters.push_tail(r0097);
+ ir_variable *const r0098 = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "n", ir_var_auto);
+ body.emit(r0098);
+ body.emit(assign(r0098, r0096, 0x03));
+
+ ir_variable *const r0099 = new(mem_ctx) ir_variable(glsl_type::int_type, "i", ir_var_auto);
+ body.emit(r0099);
+ ir_variable *const r009A = new(mem_ctx) ir_variable(glsl_type::uint64_t_type, "n64", ir_var_auto);
+ body.emit(r009A);
+ ir_variable *const r009B = new(mem_ctx) ir_variable(glsl_type::int_type, "log2_denom", ir_var_auto);
+ body.emit(r009B);
+ ir_variable *const r009C = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "quot", ir_var_auto);
+ body.emit(r009C);
+ body.emit(assign(r009C, ir_constant::zero(mem_ctx, glsl_type::uvec2_type), 0x03));
+
+ ir_expression *const r009D = expr(ir_unop_find_msb, swizzle_y(r0097));
+ body.emit(assign(r009B, add(r009D, body.constant(int(32))), 0x01));
+
+ /* IF CONDITION */
+ ir_expression *const r009F = equal(swizzle_y(r0097), body.constant(0u));
+ ir_expression *const r00A0 = gequal(swizzle_y(r0096), swizzle_x(r0097));
+ ir_expression *const r00A1 = logic_and(r009F, r00A0);
+ ir_if *f009E = new(mem_ctx) ir_if(operand(r00A1).val);
+ exec_list *const f009E_parent_instructions = body.instructions;
+
+ /* THEN INSTRUCTIONS */
+ body.instructions = &f009E->then_instructions;
+
+ ir_variable *const r00A2 = new(mem_ctx) ir_variable(glsl_type::int_type, "i", ir_var_auto);
+ body.emit(r00A2);
+ ir_variable *const r00A3 = body.make_temp(glsl_type::int_type, "findMSB_retval");
+ body.emit(assign(r00A3, expr(ir_unop_find_msb, swizzle_x(r0097)), 0x01));
+
+ body.emit(assign(r009B, r00A3, 0x01));
+
+ body.emit(assign(r00A2, body.constant(int(31)), 0x01));
+
+ /* LOOP BEGIN */
+ ir_loop *f00A4 = new(mem_ctx) ir_loop();
+ exec_list *const f00A4_parent_instructions = body.instructions;
+
+ body.instructions = &f00A4->body_instructions;
+
+ /* IF CONDITION */
+ ir_expression *const r00A6 = less(r00A2, body.constant(int(1)));
+ ir_if *f00A5 = new(mem_ctx) ir_if(operand(r00A6).val);
+ exec_list *const f00A5_parent_instructions = body.instructions;
+
+ /* THEN INSTRUCTIONS */
+ body.instructions = &f00A5->then_instructions;
+
+ body.emit(new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_break));
+
+
+ body.instructions = f00A5_parent_instructions;
+ body.emit(f00A5);
+
+ /* END IF */
+
+ /* IF CONDITION */
+ ir_expression *const r00A8 = sub(body.constant(int(31)), r00A2);
+ ir_expression *const r00A9 = lequal(r00A3, r00A8);
+ ir_expression *const r00AA = lshift(swizzle_x(r0097), r00A2);
+ ir_expression *const r00AB = lequal(r00AA, swizzle_y(r0098));
+ ir_expression *const r00AC = logic_and(r00A9, r00AB);
+ ir_if *f00A7 = new(mem_ctx) ir_if(operand(r00AC).val);
+ exec_list *const f00A7_parent_instructions = body.instructions;
+
+ /* THEN INSTRUCTIONS */
+ body.instructions = &f00A7->then_instructions;
+
+ ir_expression *const r00AD = lshift(swizzle_x(r0097), r00A2);
+ body.emit(assign(r0098, sub(swizzle_y(r0098), r00AD), 0x02));
+
+ ir_expression *const r00AE = lshift(body.constant(1u), r00A2);
+ body.emit(assign(r009C, bit_or(swizzle_y(r009C), r00AE), 0x02));
+
+
+ body.instructions = f00A7_parent_instructions;
+ body.emit(f00A7);
+
+ /* END IF */
+
+ body.emit(assign(r00A2, add(r00A2, body.constant(int(-1))), 0x01));
+
+ /* LOOP END */
+
+ body.instructions = f00A4_parent_instructions;
+ body.emit(f00A4);
+
+ /* IF CONDITION */
+ ir_expression *const r00B0 = lequal(swizzle_x(r0097), swizzle_y(r0098));
+ ir_if *f00AF = new(mem_ctx) ir_if(operand(r00B0).val);
+ exec_list *const f00AF_parent_instructions = body.instructions;
+
+ /* THEN INSTRUCTIONS */
+ body.instructions = &f00AF->then_instructions;
+
+ body.emit(assign(r0098, sub(swizzle_y(r0098), swizzle_x(r0097)), 0x02));
+
+ body.emit(assign(r009C, bit_or(swizzle_y(r009C), body.constant(1u)), 0x02));
+
+
+ body.instructions = f00AF_parent_instructions;
+ body.emit(f00AF);
+
+ /* END IF */
+
+
+ body.instructions = f009E_parent_instructions;
+ body.emit(f009E);
+
+ /* END IF */
+
+ ir_variable *const r00B1 = body.make_temp(glsl_type::uint64_t_type, "packUint2x32_retval");
+ body.emit(assign(r00B1, expr(ir_unop_pack_uint_2x32, r0097), 0x01));
+
+ body.emit(assign(r009A, expr(ir_unop_pack_uint_2x32, r0098), 0x01));
+
+ body.emit(assign(r0099, body.constant(int(31)), 0x01));
+
+ /* LOOP BEGIN */
+ ir_loop *f00B2 = new(mem_ctx) ir_loop();
+ exec_list *const f00B2_parent_instructions = body.instructions;
+
+ body.instructions = &f00B2->body_instructions;
+
+ /* IF CONDITION */
+ ir_expression *const r00B4 = less(r0099, body.constant(int(1)));
+ ir_if *f00B3 = new(mem_ctx) ir_if(operand(r00B4).val);
+ exec_list *const f00B3_parent_instructions = body.instructions;
+
+ /* THEN INSTRUCTIONS */
+ body.instructions = &f00B3->then_instructions;
+
+ body.emit(new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_break));
+
+
+ body.instructions = f00B3_parent_instructions;
+ body.emit(f00B3);
+
+ /* END IF */
+
+ /* IF CONDITION */
+ ir_expression *const r00B6 = sub(body.constant(int(63)), r0099);
+ ir_expression *const r00B7 = lequal(r009B, r00B6);
+ ir_expression *const r00B8 = lshift(r00B1, r0099);
+ ir_expression *const r00B9 = lequal(r00B8, r009A);
+ ir_expression *const r00BA = logic_and(r00B7, r00B9);
+ ir_if *f00B5 = new(mem_ctx) ir_if(operand(r00BA).val);
+ exec_list *const f00B5_parent_instructions = body.instructions;
+
+ /* THEN INSTRUCTIONS */
+ body.instructions = &f00B5->then_instructions;
+
+ ir_expression *const r00BB = lshift(r00B1, r0099);
+ body.emit(assign(r009A, sub(r009A, r00BB), 0x01));
+
+ ir_expression *const r00BC = lshift(body.constant(1u), r0099);
+ body.emit(assign(r009C, bit_or(swizzle_x(r009C), r00BC), 0x01));
+
+
+ body.instructions = f00B5_parent_instructions;
+ body.emit(f00B5);
+
+ /* END IF */
+
+ body.emit(assign(r0099, add(r0099, body.constant(int(-1))), 0x01));
+
+ /* LOOP END */
+
+ body.instructions = f00B2_parent_instructions;
+ body.emit(f00B2);
+
+ /* IF CONDITION */
+ ir_expression *const r00BE = lequal(r00B1, r009A);
+ ir_if *f00BD = new(mem_ctx) ir_if(operand(r00BE).val);
+ exec_list *const f00BD_parent_instructions = body.instructions;
+
+ /* THEN INSTRUCTIONS */
+ body.instructions = &f00BD->then_instructions;
+
+ body.emit(assign(r009A, sub(r009A, r00B1), 0x01));
+
+ body.emit(assign(r009C, bit_or(swizzle_x(r009C), body.constant(1u)), 0x01));
+
+
+ body.instructions = f00BD_parent_instructions;
+ body.emit(f00BD);
+
+ /* END IF */
+
+ ir_variable *const r00BF = body.make_temp(glsl_type::uvec4_type, "vec_ctor");
+ body.emit(assign(r00BF, r009C, 0x03));
+
+ body.emit(assign(r00BF, expr(ir_unop_unpack_uint_2x32, r009A), 0x0c));
+
+ ir_swizzle *const r00C0 = swizzle(r00BF, MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W, SWIZZLE_X, SWIZZLE_X), 2);
+ body.emit(ret(r00C0));
+
+ sig->replace_parameters(&sig_parameters);
+ return sig;
+}
+ir_function_signature *
+imod64(void *mem_ctx, builtin_available_predicate avail)
+{
+ ir_function_signature *const sig =
+ new(mem_ctx) ir_function_signature(glsl_type::ivec2_type, avail);
+ ir_factory body(&sig->body, mem_ctx);
+ sig->is_defined = true;
+
+ exec_list sig_parameters;
+
+ ir_variable *const r00C1 = new(mem_ctx) ir_variable(glsl_type::ivec2_type, "_n", ir_var_function_in);
+ sig_parameters.push_tail(r00C1);
+ ir_variable *const r00C2 = new(mem_ctx) ir_variable(glsl_type::ivec2_type, "_d", ir_var_function_in);
+ sig_parameters.push_tail(r00C2);
+ ir_variable *const r00C3 = new(mem_ctx) ir_variable(glsl_type::bool_type, "negate", ir_var_auto);
+ body.emit(r00C3);
+ ir_expression *const r00C4 = less(swizzle_y(r00C1), body.constant(int(0)));
+ ir_expression *const r00C5 = less(swizzle_y(r00C2), body.constant(int(0)));
+ body.emit(assign(r00C3, nequal(r00C4, r00C5), 0x01));
+
+ ir_variable *const r00C6 = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "n", ir_var_auto);
+ body.emit(r00C6);
+ ir_expression *const r00C7 = expr(ir_unop_pack_int_2x32, r00C1);
+ ir_expression *const r00C8 = expr(ir_unop_abs, r00C7);
+ ir_expression *const r00C9 = expr(ir_unop_i642u64, r00C8);
+ body.emit(assign(r00C6, expr(ir_unop_unpack_uint_2x32, r00C9), 0x03));
+
+ ir_variable *const r00CA = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "d", ir_var_auto);
+ body.emit(r00CA);
+ ir_expression *const r00CB = expr(ir_unop_pack_int_2x32, r00C2);
+ ir_expression *const r00CC = expr(ir_unop_abs, r00CB);
+ ir_expression *const r00CD = expr(ir_unop_i642u64, r00CC);
+ body.emit(assign(r00CA, expr(ir_unop_unpack_uint_2x32, r00CD), 0x03));
+
+ ir_variable *const r00CE = new(mem_ctx) ir_variable(glsl_type::int_type, "i", ir_var_auto);
+ body.emit(r00CE);
+ ir_variable *const r00CF = new(mem_ctx) ir_variable(glsl_type::uint64_t_type, "n64", ir_var_auto);
+ body.emit(r00CF);
+ ir_variable *const r00D0 = new(mem_ctx) ir_variable(glsl_type::int_type, "log2_denom", ir_var_auto);
+ body.emit(r00D0);
+ ir_variable *const r00D1 = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "quot", ir_var_auto);
+ body.emit(r00D1);
+ body.emit(assign(r00D1, ir_constant::zero(mem_ctx, glsl_type::uvec2_type), 0x03));
+
+ ir_expression *const r00D2 = expr(ir_unop_find_msb, swizzle_y(r00CA));
+ body.emit(assign(r00D0, add(r00D2, body.constant(int(32))), 0x01));
+
+ /* IF CONDITION */
+ ir_expression *const r00D4 = equal(swizzle_y(r00CA), body.constant(0u));
+ ir_expression *const r00D5 = gequal(swizzle_y(r00C6), swizzle_x(r00CA));
+ ir_expression *const r00D6 = logic_and(r00D4, r00D5);
+ ir_if *f00D3 = new(mem_ctx) ir_if(operand(r00D6).val);
+ exec_list *const f00D3_parent_instructions = body.instructions;
+
+ /* THEN INSTRUCTIONS */
+ body.instructions = &f00D3->then_instructions;
+
+ ir_variable *const r00D7 = new(mem_ctx) ir_variable(glsl_type::int_type, "i", ir_var_auto);
+ body.emit(r00D7);
+ ir_variable *const r00D8 = body.make_temp(glsl_type::int_type, "findMSB_retval");
+ body.emit(assign(r00D8, expr(ir_unop_find_msb, swizzle_x(r00CA)), 0x01));
+
+ body.emit(assign(r00D0, r00D8, 0x01));
+
+ body.emit(assign(r00D7, body.constant(int(31)), 0x01));
+
+ /* LOOP BEGIN */
+ ir_loop *f00D9 = new(mem_ctx) ir_loop();
+ exec_list *const f00D9_parent_instructions = body.instructions;
+
+ body.instructions = &f00D9->body_instructions;
+
+ /* IF CONDITION */
+ ir_expression *const r00DB = less(r00D7, body.constant(int(1)));
+ ir_if *f00DA = new(mem_ctx) ir_if(operand(r00DB).val);
+ exec_list *const f00DA_parent_instructions = body.instructions;
+
+ /* THEN INSTRUCTIONS */
+ body.instructions = &f00DA->then_instructions;
+
+ body.emit(new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_break));
+
+
+ body.instructions = f00DA_parent_instructions;
+ body.emit(f00DA);
+
+ /* END IF */
+
+ /* IF CONDITION */
+ ir_expression *const r00DD = sub(body.constant(int(31)), r00D7);
+ ir_expression *const r00DE = lequal(r00D8, r00DD);
+ ir_expression *const r00DF = lshift(swizzle_x(r00CA), r00D7);
+ ir_expression *const r00E0 = lequal(r00DF, swizzle_y(r00C6));
+ ir_expression *const r00E1 = logic_and(r00DE, r00E0);
+ ir_if *f00DC = new(mem_ctx) ir_if(operand(r00E1).val);
+ exec_list *const f00DC_parent_instructions = body.instructions;
+
+ /* THEN INSTRUCTIONS */
+ body.instructions = &f00DC->then_instructions;
+
+ ir_expression *const r00E2 = lshift(swizzle_x(r00CA), r00D7);
+ body.emit(assign(r00C6, sub(swizzle_y(r00C6), r00E2), 0x02));
+
+ ir_expression *const r00E3 = lshift(body.constant(1u), r00D7);
+ body.emit(assign(r00D1, bit_or(swizzle_y(r00D1), r00E3), 0x02));
+
+
+ body.instructions = f00DC_parent_instructions;
+ body.emit(f00DC);
+
+ /* END IF */
+
+ body.emit(assign(r00D7, add(r00D7, body.constant(int(-1))), 0x01));
+
+ /* LOOP END */
+
+ body.instructions = f00D9_parent_instructions;
+ body.emit(f00D9);
+
+ /* IF CONDITION */
+ ir_expression *const r00E5 = lequal(swizzle_x(r00CA), swizzle_y(r00C6));
+ ir_if *f00E4 = new(mem_ctx) ir_if(operand(r00E5).val);
+ exec_list *const f00E4_parent_instructions = body.instructions;
+
+ /* THEN INSTRUCTIONS */
+ body.instructions = &f00E4->then_instructions;
+
+ body.emit(assign(r00C6, sub(swizzle_y(r00C6), swizzle_x(r00CA)), 0x02));
+
+ body.emit(assign(r00D1, bit_or(swizzle_y(r00D1), body.constant(1u)), 0x02));
+
+
+ body.instructions = f00E4_parent_instructions;
+ body.emit(f00E4);
+
+ /* END IF */
+
+
+ body.instructions = f00D3_parent_instructions;
+ body.emit(f00D3);
+
+ /* END IF */
+
+ ir_variable *const r00E6 = body.make_temp(glsl_type::uint64_t_type, "packUint2x32_retval");
+ body.emit(assign(r00E6, expr(ir_unop_pack_uint_2x32, r00CA), 0x01));
+
+ body.emit(assign(r00CF, expr(ir_unop_pack_uint_2x32, r00C6), 0x01));
+
+ body.emit(assign(r00CE, body.constant(int(31)), 0x01));
+
+ /* LOOP BEGIN */
+ ir_loop *f00E7 = new(mem_ctx) ir_loop();
+ exec_list *const f00E7_parent_instructions = body.instructions;
+
+ body.instructions = &f00E7->body_instructions;
+
+ /* IF CONDITION */
+ ir_expression *const r00E9 = less(r00CE, body.constant(int(1)));
+ ir_if *f00E8 = new(mem_ctx) ir_if(operand(r00E9).val);
+ exec_list *const f00E8_parent_instructions = body.instructions;
+
+ /* THEN INSTRUCTIONS */
+ body.instructions = &f00E8->then_instructions;
+
+ body.emit(new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_break));
+
+
+ body.instructions = f00E8_parent_instructions;
+ body.emit(f00E8);
+
+ /* END IF */
+
+ /* IF CONDITION */
+ ir_expression *const r00EB = sub(body.constant(int(63)), r00CE);
+ ir_expression *const r00EC = lequal(r00D0, r00EB);
+ ir_expression *const r00ED = lshift(r00E6, r00CE);
+ ir_expression *const r00EE = lequal(r00ED, r00CF);
+ ir_expression *const r00EF = logic_and(r00EC, r00EE);
+ ir_if *f00EA = new(mem_ctx) ir_if(operand(r00EF).val);
+ exec_list *const f00EA_parent_instructions = body.instructions;
+
+ /* THEN INSTRUCTIONS */
+ body.instructions = &f00EA->then_instructions;
+
+ ir_expression *const r00F0 = lshift(r00E6, r00CE);
+ body.emit(assign(r00CF, sub(r00CF, r00F0), 0x01));
+
+ ir_expression *const r00F1 = lshift(body.constant(1u), r00CE);
+ body.emit(assign(r00D1, bit_or(swizzle_x(r00D1), r00F1), 0x01));
+
+
+ body.instructions = f00EA_parent_instructions;
+ body.emit(f00EA);
+
+ /* END IF */
+
+ body.emit(assign(r00CE, add(r00CE, body.constant(int(-1))), 0x01));
+
+ /* LOOP END */
+
+ body.instructions = f00E7_parent_instructions;
+ body.emit(f00E7);
+
+ /* IF CONDITION */
+ ir_expression *const r00F3 = lequal(r00E6, r00CF);
+ ir_if *f00F2 = new(mem_ctx) ir_if(operand(r00F3).val);
+ exec_list *const f00F2_parent_instructions = body.instructions;
+
+ /* THEN INSTRUCTIONS */
+ body.instructions = &f00F2->then_instructions;
+
+ body.emit(assign(r00CF, sub(r00CF, r00E6), 0x01));
+
+ body.emit(assign(r00D1, bit_or(swizzle_x(r00D1), body.constant(1u)), 0x01));
+
+
+ body.instructions = f00F2_parent_instructions;
+ body.emit(f00F2);
+
+ /* END IF */
+
+ ir_variable *const r00F4 = body.make_temp(glsl_type::uvec4_type, "vec_ctor");
+ body.emit(assign(r00F4, r00D1, 0x03));
+
+ body.emit(assign(r00F4, expr(ir_unop_unpack_uint_2x32, r00CF), 0x0c));
+
+ ir_variable *const r00F5 = body.make_temp(glsl_type::ivec2_type, "conditional_tmp");
+ /* IF CONDITION */
+ ir_if *f00F6 = new(mem_ctx) ir_if(operand(r00C3).val);
+ exec_list *const f00F6_parent_instructions = body.instructions;
+
+ /* THEN INSTRUCTIONS */
+ body.instructions = &f00F6->then_instructions;
+
+ ir_swizzle *const r00F7 = swizzle(r00F4, MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_Y, SWIZZLE_X, SWIZZLE_X), 2);
+ ir_expression *const r00F8 = expr(ir_unop_pack_uint_2x32, r00F7);
+ ir_expression *const r00F9 = expr(ir_unop_u642i64, r00F8);
+ ir_expression *const r00FA = neg(r00F9);
+ body.emit(assign(r00F5, expr(ir_unop_unpack_int_2x32, r00FA), 0x03));
+
+
+ /* ELSE INSTRUCTIONS */
+ body.instructions = &f00F6->else_instructions;
+
+ ir_swizzle *const r00FB = swizzle(r00F4, MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_Y, SWIZZLE_X, SWIZZLE_X), 2);
+ body.emit(assign(r00F5, expr(ir_unop_u2i, r00FB), 0x03));
+
+
+ body.instructions = f00F6_parent_instructions;
+ body.emit(f00F6);
+
+ /* END IF */
+
+ body.emit(ret(r00F5));
+
+ sig->replace_parameters(&sig_parameters);
+ return sig;
+}
diff --git a/src/compiler/glsl/glcpp/glcpp-parse.y b/src/compiler/glsl/glcpp/glcpp-parse.y
index d801cf8a9d7..e113253061f 100644
--- a/src/compiler/glsl/glcpp/glcpp-parse.y
+++ b/src/compiler/glsl/glcpp/glcpp-parse.y
@@ -2346,7 +2346,9 @@ _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t versio
add_builtin_define(parser, "__have_builtin_builtin_sign64", 1);
add_builtin_define(parser, "__have_builtin_builtin_umul64", 1);
add_builtin_define(parser, "__have_builtin_builtin_udiv64", 1);
+ add_builtin_define(parser, "__have_builtin_builtin_umod64", 1);
add_builtin_define(parser, "__have_builtin_builtin_idiv64", 1);
+ add_builtin_define(parser, "__have_builtin_builtin_imod64", 1);
}
}
diff --git a/src/compiler/glsl/int64.glsl b/src/compiler/glsl/int64.glsl
index 84e80ee349b..b1036e379c9 100644
--- a/src/compiler/glsl/int64.glsl
+++ b/src/compiler/glsl/int64.glsl
@@ -101,3 +101,21 @@ idiv64(ivec2 _n, ivec2 _d)
return negate ? unpackInt2x32(-int64_t(packUint2x32(quot))) : ivec2(quot);
}
+
+uvec2
+umod64(uvec2 n, uvec2 d)
+{
+ return udivmod64(n, d).zw;
+}
+
+ivec2
+imod64(ivec2 _n, ivec2 _d)
+{
+ const bool negate = (_n.y < 0) != (_d.y < 0);
+ uvec2 n = unpackUint2x32(uint64_t(abs(packInt2x32(_n))));
+ uvec2 d = unpackUint2x32(uint64_t(abs(packInt2x32(_d))));
+
+ uvec2 rem = udivmod64(n, d).zy;
+
+ return negate ? unpackInt2x32(-int64_t(packUint2x32(rem))) : ivec2(rem);
+}