2 * Copyright (C) 2019 Collabora, Ltd.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * Authors (Collabora):
24 * Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
28 #include "midgard_ops.h"
31 /* Could a 32-bit value represent exactly a 32-bit floating point? */
34 mir_constant_float(uint32_t u
)
38 memcpy(&f
, &u
, sizeof(u
));
40 /* TODO: What exactly is the condition? */
41 return !(isnan(f
) || isinf(f
));
44 /* Promotes imov with a constant to fmov where the constant is exactly
45 * representible as a float */
48 midgard_opt_promote_fmov(compiler_context
*ctx
, midgard_block
*block
)
50 bool progress
= false;
52 mir_foreach_instr_in_block(block
, ins
) {
53 if (ins
->type
!= TAG_ALU_4
) continue;
54 if (ins
->alu
.op
!= midgard_alu_op_imov
) continue;
55 if (ins
->has_inline_constant
) continue;
56 if (!ins
->has_constants
) continue;
57 if (mir_nontrivial_source2_mod_simple(ins
)) continue;
58 if (mir_nontrivial_outmod(ins
)) continue;
59 if (ins
->alu
.reg_mode
!= midgard_reg_mode_32
) continue;
61 /* We found an imov with a constant. Check the constants */
64 for (unsigned i
= 0; i
< ARRAY_SIZE(ins
->constants
.u32
); ++i
)
65 ok
&= mir_constant_float(ins
->constants
.u32
[i
]);
71 ins
->alu
.op
= midgard_alu_op_fmov
;
74 /* Clear the int mod */
75 midgard_vector_alu_src u
= vector_alu_from_unsigned(ins
->alu
.src2
);
77 ins
->alu
.src2
= vector_alu_srco_unsigned(u
);