xref: /aosp_15_r20/external/mesa3d/src/panfrost/compiler/valhall/va_lower_isel.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright (C) 2021 Collabora Ltd.
3  *
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:
10  *
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
13  * Software.
14  *
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
21  * SOFTWARE.
22  */
23 
24 #include "bi_builder.h"
25 #include "va_compiler.h"
26 #include "valhall.h"
27 
28 static bi_instr *
lower(bi_builder * b,bi_instr * I)29 lower(bi_builder *b, bi_instr *I)
30 {
31    switch (I->op) {
32 
33    /* Integer addition has swizzles and addition with 0 is canonical swizzle */
34    case BI_OPCODE_SWZ_V2I16:
35       return bi_iadd_v2u16_to(b, I->dest[0], I->src[0], bi_zero(), false);
36 
37    case BI_OPCODE_SWZ_V4I8:
38       return bi_iadd_v4u8_to(b, I->dest[0], I->src[0], bi_zero(), false);
39 
40    case BI_OPCODE_ICMP_I32:
41       return bi_icmp_or_u32_to(b, I->dest[0], I->src[0], I->src[1], bi_zero(),
42                                I->cmpf, I->result_type);
43 
44    case BI_OPCODE_ICMP_V2I16:
45       return bi_icmp_or_v2u16_to(b, I->dest[0], I->src[0], I->src[1], bi_zero(),
46                                  I->cmpf, I->result_type);
47 
48    case BI_OPCODE_ICMP_V4I8:
49       return bi_icmp_or_v4u8_to(b, I->dest[0], I->src[0], I->src[1], bi_zero(),
50                                 I->cmpf, I->result_type);
51 
52    case BI_OPCODE_ICMP_U32:
53       return bi_icmp_or_u32_to(b, I->dest[0], I->src[0], I->src[1], bi_zero(),
54                                I->cmpf, I->result_type);
55 
56    case BI_OPCODE_ICMP_V2U16:
57       return bi_icmp_or_v2u16_to(b, I->dest[0], I->src[0], I->src[1], bi_zero(),
58                                  I->cmpf, I->result_type);
59 
60    case BI_OPCODE_ICMP_V4U8:
61       return bi_icmp_or_v4u8_to(b, I->dest[0], I->src[0], I->src[1], bi_zero(),
62                                 I->cmpf, I->result_type);
63 
64    case BI_OPCODE_ICMP_S32:
65       return bi_icmp_or_s32_to(b, I->dest[0], I->src[0], I->src[1], bi_zero(),
66                                I->cmpf, I->result_type);
67 
68    case BI_OPCODE_ICMP_V2S16:
69       return bi_icmp_or_v2s16_to(b, I->dest[0], I->src[0], I->src[1], bi_zero(),
70                                  I->cmpf, I->result_type);
71 
72    case BI_OPCODE_ICMP_V4S8:
73       return bi_icmp_or_v4s8_to(b, I->dest[0], I->src[0], I->src[1], bi_zero(),
74                                 I->cmpf, I->result_type);
75 
76    case BI_OPCODE_FCMP_F32:
77       return bi_fcmp_or_f32_to(b, I->dest[0], I->src[0], I->src[1], bi_zero(),
78                                I->cmpf, I->result_type);
79 
80    case BI_OPCODE_FCMP_V2F16:
81       return bi_fcmp_or_v2f16_to(b, I->dest[0], I->src[0], I->src[1], bi_zero(),
82                                  I->cmpf, I->result_type);
83 
84    /* Integer CSEL must have a signedness */
85    case BI_OPCODE_CSEL_I32:
86    case BI_OPCODE_CSEL_V2I16:
87       assert(I->cmpf == BI_CMPF_EQ || I->cmpf == BI_CMPF_NE);
88 
89       I->op = (I->op == BI_OPCODE_CSEL_I32) ? BI_OPCODE_CSEL_U32
90                                             : BI_OPCODE_CSEL_V2U16;
91       return NULL;
92 
93    /* Jump -> conditional branch with condition tied to true. */
94    case BI_OPCODE_JUMP:
95       if (I->branch_target) {
96          bi_instr *new_I = bi_branchz_i16(b, bi_zero(), I->src[0], BI_CMPF_EQ);
97          new_I->branch_target = I->branch_target;
98          return I;
99       } else {
100          return bi_branchzi(b, bi_zero(), I->src[0], BI_CMPF_EQ);
101       }
102 
103    case BI_OPCODE_AXCHG_I32:
104       I->op = BI_OPCODE_ATOM_RETURN_I32;
105       I->atom_opc = BI_ATOM_OPC_AXCHG;
106       I->sr_count = 1;
107       return NULL;
108 
109    case BI_OPCODE_ACMPXCHG_I32:
110       I->op = BI_OPCODE_ATOM_RETURN_I32;
111       I->atom_opc = BI_ATOM_OPC_ACMPXCHG;
112       /* Reads 2, this is special cased in bir.c */
113       I->sr_count = 1;
114       return NULL;
115 
116    case BI_OPCODE_ATOM_RETURN_I32:
117       if (bi_is_null(I->dest[0]))
118          I->op = BI_OPCODE_ATOM_I32;
119 
120       return NULL;
121 
122    case BI_OPCODE_MUX_I32:
123    case BI_OPCODE_MUX_V2I16:
124       if (bi_can_replace_with_csel(I))
125          return bi_csel_from_mux(b, I, true);
126 
127       return NULL;
128 
129    case BI_OPCODE_FADD_RSCALE_F32:
130       return bi_fma_rscale_f32_to(b, I->dest[0], I->src[0], bi_imm_f32(1.0),
131                                   I->src[1], I->src[2], I->special);
132 
133    default:
134       return NULL;
135    }
136 }
137 
138 void
va_lower_isel(bi_context * ctx)139 va_lower_isel(bi_context *ctx)
140 {
141    bi_foreach_instr_global_safe(ctx, I) {
142       bi_builder b = bi_init_builder(ctx, bi_before_instr(I));
143 
144       if (lower(&b, I))
145          bi_remove_instruction(I);
146    }
147 }
148