1 /* Copyright (c) 2018-2019 Alyssa Rosenzweig (alyssa@rosenzweig.io)
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to deal
5 * in the Software without restriction, including without limitation the rights
6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 * copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions:
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 /* Include the definitions of the macros and such */
26 #define MIDGARD_OPS_TABLE
28 #undef MIDGARD_OPS_TABLE
30 /* Table of mapping opcodes to accompanying properties. This is used for both
31 * the disassembler and the compiler. It is placed in a .c file like this to
32 * avoid duplications in the binary */
34 struct mir_op_props alu_opcode_props
[256] = {
35 [midgard_alu_op_fadd
] = {"fadd", UNITS_ADD
| OP_COMMUTES
},
36 [midgard_alu_op_fmul
] = {"fmul", UNITS_MUL
| UNIT_VLUT
| OP_COMMUTES
},
37 [midgard_alu_op_fmin
] = {"fmin", UNITS_MOST
| OP_COMMUTES
},
38 [midgard_alu_op_fmax
] = {"fmax", UNITS_MOST
| OP_COMMUTES
},
39 [midgard_alu_op_imin
] = {"imin", UNITS_MOST
| OP_COMMUTES
},
40 [midgard_alu_op_imax
] = {"imax", UNITS_MOST
| OP_COMMUTES
},
41 [midgard_alu_op_umin
] = {"umin", UNITS_MOST
| OP_COMMUTES
},
42 [midgard_alu_op_umax
] = {"umax", UNITS_MOST
| OP_COMMUTES
},
43 [midgard_alu_op_ihadd
] = {"ihadd", UNITS_ADD
| OP_COMMUTES
},
44 [midgard_alu_op_uhadd
] = {"uhadd", UNITS_ADD
| OP_COMMUTES
},
45 [midgard_alu_op_irhadd
] = {"irhadd", UNITS_ADD
| OP_COMMUTES
},
46 [midgard_alu_op_urhadd
] = {"urhadd", UNITS_ADD
| OP_COMMUTES
},
48 [midgard_alu_op_fmov
] = {"fmov", UNITS_ALL
| QUIRK_FLIPPED_R24
},
49 [midgard_alu_op_fmov_rtz
] = {"fmov_rtz", UNITS_ALL
| QUIRK_FLIPPED_R24
},
50 [midgard_alu_op_fmov_rtn
] = {"fmov_rtn", UNITS_ALL
| QUIRK_FLIPPED_R24
},
51 [midgard_alu_op_fmov_rtp
] = {"fmov_rtp", UNITS_ALL
| QUIRK_FLIPPED_R24
},
52 [midgard_alu_op_fround
] = {"fround", UNITS_ADD
},
53 [midgard_alu_op_froundeven
] = {"froundeven", UNITS_ADD
},
54 [midgard_alu_op_ftrunc
] = {"ftrunc", UNITS_ADD
},
55 [midgard_alu_op_ffloor
] = {"ffloor", UNITS_ADD
},
56 [midgard_alu_op_fceil
] = {"fceil", UNITS_ADD
},
58 /* Multiplies the X/Y components of the first arg and adds the second
59 * arg. Like other LUTs, it must be scalarized. */
60 [midgard_alu_op_ffma
] = {"ffma", UNIT_VLUT
},
62 /* Though they output a scalar, they need to run on a vector unit
63 * since they process vectors */
64 [midgard_alu_op_fdot3
] = {"fdot3", UNIT_VMUL
| OP_CHANNEL_COUNT(3) | OP_COMMUTES
},
65 [midgard_alu_op_fdot3r
] = {"fdot3r", UNIT_VMUL
| OP_CHANNEL_COUNT(3) | OP_COMMUTES
},
66 [midgard_alu_op_fdot4
] = {"fdot4", UNIT_VMUL
| OP_CHANNEL_COUNT(4) | OP_COMMUTES
},
68 /* Incredibly, iadd can run on vmul, etc */
69 [midgard_alu_op_iadd
] = {"iadd", UNITS_MOST
| OP_COMMUTES
},
70 [midgard_alu_op_ishladd
] = {"ishladd", UNITS_MUL
},
71 [midgard_alu_op_iaddsat
] = {"iaddsat", UNITS_ADD
| OP_COMMUTES
},
72 [midgard_alu_op_uaddsat
] = {"uaddsat", UNITS_ADD
| OP_COMMUTES
},
73 [midgard_alu_op_iabsdiff
] = {"iabsdiff", UNITS_ADD
},
74 [midgard_alu_op_uabsdiff
] = {"uabsdiff", UNITS_ADD
},
75 [midgard_alu_op_ichoose
] = {"ichoose", UNITS_ADD
},
76 [midgard_alu_op_isub
] = {"isub", UNITS_MOST
},
77 [midgard_alu_op_isubsat
] = {"isubsat", UNITS_MOST
},
78 [midgard_alu_op_usubsat
] = {"usubsat", UNITS_MOST
},
79 [midgard_alu_op_imul
] = {"imul", UNITS_MUL
| OP_COMMUTES
},
80 [midgard_alu_op_imov
] = {"imov", UNITS_ALL
| QUIRK_FLIPPED_R24
},
82 /* For vector comparisons, use ball etc */
83 [midgard_alu_op_feq
] = {"feq", UNITS_MOST
| OP_TYPE_CONVERT
| OP_COMMUTES
},
84 [midgard_alu_op_fne
] = {"fne", UNITS_MOST
| OP_TYPE_CONVERT
| OP_COMMUTES
},
85 [midgard_alu_op_fle
] = {"fle", UNITS_MOST
| OP_TYPE_CONVERT
},
86 [midgard_alu_op_flt
] = {"flt", UNITS_MOST
| OP_TYPE_CONVERT
},
87 [midgard_alu_op_ieq
] = {"ieq", UNITS_MOST
| OP_COMMUTES
},
88 [midgard_alu_op_ine
] = {"ine", UNITS_MOST
| OP_COMMUTES
},
89 [midgard_alu_op_ilt
] = {"ilt", UNITS_MOST
},
90 [midgard_alu_op_ile
] = {"ile", UNITS_MOST
},
91 [midgard_alu_op_ult
] = {"ult", UNITS_MOST
},
92 [midgard_alu_op_ule
] = {"ule", UNITS_MOST
},
94 /* csel must run in the second pipeline stage (r31 written in first) */
95 [midgard_alu_op_icsel
] = {"icsel", UNIT_VADD
| UNIT_SMUL
},
96 [midgard_alu_op_icsel_v
] = {"icsel_v", UNIT_VADD
| UNIT_SMUL
}, /* Acts as bitselect() */
97 [midgard_alu_op_fcsel_v
] = {"fcsel_v", UNIT_VADD
| UNIT_SMUL
},
98 [midgard_alu_op_fcsel
] = {"fcsel", UNIT_VADD
| UNIT_SMUL
},
100 [midgard_alu_op_frcp
] = {"frcp", UNIT_VLUT
},
101 [midgard_alu_op_frsqrt
] = {"frsqrt", UNIT_VLUT
},
102 [midgard_alu_op_fsqrt
] = {"fsqrt", UNIT_VLUT
},
103 [midgard_alu_op_fpow_pt1
] = {"fpow_pt1", UNIT_VLUT
},
104 [midgard_alu_op_fpown_pt1
] = {"fpown_pt1", UNIT_VLUT
},
105 [midgard_alu_op_fpowr_pt1
] = {"fpowr_pt1", UNIT_VLUT
},
106 [midgard_alu_op_fexp2
] = {"fexp2", UNIT_VLUT
},
107 [midgard_alu_op_flog2
] = {"flog2", UNIT_VLUT
},
109 [midgard_alu_op_f2i_rte
] = {"f2i_rte", UNITS_ADD
| OP_TYPE_CONVERT
},
110 [midgard_alu_op_f2i_rtz
] = {"f2i_rtz", UNITS_ADD
| OP_TYPE_CONVERT
},
111 [midgard_alu_op_f2i_rtn
] = {"f2i_rtn", UNITS_ADD
| OP_TYPE_CONVERT
},
112 [midgard_alu_op_f2i_rtp
] = {"f2i_rtp", UNITS_ADD
| OP_TYPE_CONVERT
},
113 [midgard_alu_op_f2u_rte
] = {"f2i_rte", UNITS_ADD
| OP_TYPE_CONVERT
},
114 [midgard_alu_op_f2u_rtz
] = {"f2i_rtz", UNITS_ADD
| OP_TYPE_CONVERT
},
115 [midgard_alu_op_f2u_rtn
] = {"f2i_rtn", UNITS_ADD
| OP_TYPE_CONVERT
},
116 [midgard_alu_op_f2u_rtp
] = {"f2i_rtp", UNITS_ADD
| OP_TYPE_CONVERT
},
117 [midgard_alu_op_i2f_rte
] = {"i2f", UNITS_ADD
| OP_TYPE_CONVERT
},
118 [midgard_alu_op_i2f_rtz
] = {"i2f_rtz", UNITS_ADD
| OP_TYPE_CONVERT
},
119 [midgard_alu_op_i2f_rtn
] = {"i2f_rtn", UNITS_ADD
| OP_TYPE_CONVERT
},
120 [midgard_alu_op_i2f_rtp
] = {"i2f_rtp", UNITS_ADD
| OP_TYPE_CONVERT
},
121 [midgard_alu_op_u2f_rte
] = {"u2f", UNITS_ADD
| OP_TYPE_CONVERT
},
122 [midgard_alu_op_u2f_rtz
] = {"u2f_rtz", UNITS_ADD
| OP_TYPE_CONVERT
},
123 [midgard_alu_op_u2f_rtn
] = {"u2f_rtn", UNITS_ADD
| OP_TYPE_CONVERT
},
124 [midgard_alu_op_u2f_rtp
] = {"u2f_rtp", UNITS_ADD
| OP_TYPE_CONVERT
},
126 [midgard_alu_op_fsin
] = {"fsin", UNIT_VLUT
},
127 [midgard_alu_op_fcos
] = {"fcos", UNIT_VLUT
},
129 [midgard_alu_op_iand
] = {"iand", UNITS_MOST
| OP_COMMUTES
},
130 [midgard_alu_op_iandnot
] = {"iandnot", UNITS_MOST
},
132 [midgard_alu_op_ior
] = {"ior", UNITS_MOST
| OP_COMMUTES
},
133 [midgard_alu_op_iornot
] = {"iornot", UNITS_MOST
| OP_COMMUTES
},
134 [midgard_alu_op_inor
] = {"inor", UNITS_MOST
| OP_COMMUTES
},
135 [midgard_alu_op_ixor
] = {"ixor", UNITS_MOST
| OP_COMMUTES
},
136 [midgard_alu_op_inxor
] = {"inxor", UNITS_MOST
| OP_COMMUTES
},
137 [midgard_alu_op_iclz
] = {"iclz", UNITS_ADD
},
138 [midgard_alu_op_ibitcount8
] = {"ibitcount8", UNITS_ADD
},
139 [midgard_alu_op_inand
] = {"inand", UNITS_MOST
},
140 [midgard_alu_op_ishl
] = {"ishl", UNITS_ADD
},
141 [midgard_alu_op_iasr
] = {"iasr", UNITS_ADD
},
142 [midgard_alu_op_ilsr
] = {"ilsr", UNITS_ADD
},
144 [midgard_alu_op_fball_eq
] = {"fball_eq", UNITS_VECTOR
| OP_CHANNEL_COUNT(4) | OP_COMMUTES
| OP_TYPE_CONVERT
},
145 [midgard_alu_op_fball_neq
] = {"fball_neq", UNITS_VECTOR
| OP_CHANNEL_COUNT(4) | OP_COMMUTES
| OP_TYPE_CONVERT
},
146 [midgard_alu_op_fball_lt
] = {"fball_lt", UNITS_VECTOR
| OP_CHANNEL_COUNT(4) | OP_COMMUTES
| OP_TYPE_CONVERT
},
147 [midgard_alu_op_fball_lte
] = {"fball_lte", UNITS_VECTOR
| OP_CHANNEL_COUNT(4) | OP_COMMUTES
| OP_TYPE_CONVERT
},
149 [midgard_alu_op_fbany_eq
] = {"fbany_eq", UNITS_VECTOR
| OP_CHANNEL_COUNT(4) | OP_COMMUTES
| OP_TYPE_CONVERT
},
150 [midgard_alu_op_fbany_neq
] = {"fbany_neq", UNITS_VECTOR
| OP_CHANNEL_COUNT(4) | OP_COMMUTES
| OP_TYPE_CONVERT
},
151 [midgard_alu_op_fbany_lt
] = {"fbany_lt", UNITS_VECTOR
| OP_CHANNEL_COUNT(4) | OP_COMMUTES
| OP_TYPE_CONVERT
},
152 [midgard_alu_op_fbany_lte
] = {"fbany_lte", UNITS_VECTOR
| OP_CHANNEL_COUNT(4) | OP_COMMUTES
| OP_TYPE_CONVERT
},
154 [midgard_alu_op_iball_eq
] = {"iball_eq", UNITS_VECTOR
| OP_CHANNEL_COUNT(4) | OP_COMMUTES
},
155 [midgard_alu_op_iball_neq
] = {"iball_neq", UNITS_VECTOR
| OP_CHANNEL_COUNT(4) | OP_COMMUTES
},
156 [midgard_alu_op_iball_lt
] = {"iball_lt", UNITS_VECTOR
| OP_CHANNEL_COUNT(4) | OP_COMMUTES
},
157 [midgard_alu_op_iball_lte
] = {"iball_lte", UNITS_VECTOR
| OP_CHANNEL_COUNT(4) | OP_COMMUTES
},
158 [midgard_alu_op_uball_lt
] = {"uball_lt", UNITS_VECTOR
| OP_CHANNEL_COUNT(4) | OP_COMMUTES
},
159 [midgard_alu_op_uball_lte
] = {"uball_lte", UNITS_VECTOR
| OP_CHANNEL_COUNT(4) | OP_COMMUTES
},
161 [midgard_alu_op_ibany_eq
] = {"ibany_eq", UNITS_VECTOR
| OP_CHANNEL_COUNT(4) | OP_COMMUTES
},
162 [midgard_alu_op_ibany_neq
] = {"ibany_neq", UNITS_VECTOR
| OP_CHANNEL_COUNT(4) | OP_COMMUTES
},
163 [midgard_alu_op_ibany_lt
] = {"ibany_lt", UNITS_VECTOR
| OP_CHANNEL_COUNT(4) | OP_COMMUTES
},
164 [midgard_alu_op_ibany_lte
] = {"ibany_lte", UNITS_VECTOR
| OP_CHANNEL_COUNT(4) | OP_COMMUTES
},
165 [midgard_alu_op_ubany_lt
] = {"ubany_lt", UNITS_VECTOR
| OP_CHANNEL_COUNT(4) | OP_COMMUTES
},
166 [midgard_alu_op_ubany_lte
] = {"ubany_lte", UNITS_VECTOR
| OP_CHANNEL_COUNT(4) | OP_COMMUTES
},
168 [midgard_alu_op_fatan2_pt1
] = {"fatan2_pt1", UNIT_VLUT
},
169 [midgard_alu_op_fatan_pt2
] = {"fatan_pt2", UNIT_VLUT
},
171 /* Haven't seen in a while */
172 [midgard_alu_op_freduce
] = {"freduce", 0},
175 /* Define shorthands */
177 #define M8 midgard_reg_mode_8
178 #define M16 midgard_reg_mode_16
179 #define M32 midgard_reg_mode_32
180 #define M64 midgard_reg_mode_64
182 struct mir_ldst_op_props load_store_opcode_props
[256] = {
183 [midgard_op_ld_cubemap_coords
] = {"ld_cubemap_coords", M32
},
184 [midgard_op_ld_compute_id
] = {"ld_compute_id", M32
},
185 [midgard_op_ldst_perspective_division_z
] = {"ldst_perspective_division_z", M32
},
186 [midgard_op_ldst_perspective_division_w
] = {"ldst_perspective_division_w", M32
},
188 [midgard_op_atomic_add
] = {"atomic_add", M32
| LDST_SIDE_FX
},
189 [midgard_op_atomic_and
] = {"atomic_and", M32
| LDST_SIDE_FX
},
190 [midgard_op_atomic_or
] = {"atomic_or", M32
| LDST_SIDE_FX
},
191 [midgard_op_atomic_xor
] = {"atomic_xor", M32
| LDST_SIDE_FX
},
192 [midgard_op_atomic_imin
] = {"atomic_imin", M32
| LDST_SIDE_FX
},
193 [midgard_op_atomic_umin
] = {"atomic_umin", M32
| LDST_SIDE_FX
},
194 [midgard_op_atomic_imax
] = {"atomic_imax", M32
| LDST_SIDE_FX
},
195 [midgard_op_atomic_umax
] = {"atomic_umax", M32
| LDST_SIDE_FX
},
196 [midgard_op_atomic_xchg
] = {"atomic_xchg", M32
| LDST_SIDE_FX
},
198 [midgard_op_atomic_add64
] = {"atomic_add64", M64
| LDST_SIDE_FX
},
199 [midgard_op_atomic_and64
] = {"atomic_and64", M64
| LDST_SIDE_FX
},
200 [midgard_op_atomic_or64
] = {"atomic_or64", M64
| LDST_SIDE_FX
},
201 [midgard_op_atomic_xor64
] = {"atomic_xor64", M64
| LDST_SIDE_FX
},
202 [midgard_op_atomic_imin64
] = {"atomic_imin64", M64
| LDST_SIDE_FX
},
203 [midgard_op_atomic_umin64
] = {"atomic_umin64", M64
| LDST_SIDE_FX
},
204 [midgard_op_atomic_imax64
] = {"atomic_imax64", M64
| LDST_SIDE_FX
},
205 [midgard_op_atomic_umax64
] = {"atomic_umax64", M64
| LDST_SIDE_FX
},
206 [midgard_op_atomic_xchg64
] = {"atomic_xchg64", M64
| LDST_SIDE_FX
},
208 [midgard_op_ld_char
] = {"ld_char", M32
},
209 [midgard_op_ld_char2
] = {"ld_char2", M16
},
210 [midgard_op_ld_short
] = {"ld_short", M32
},
211 [midgard_op_ld_char4
] = {"ld_char4", M32
},
212 [midgard_op_ld_short4
] = {"ld_short4", M32
},
213 [midgard_op_ld_int4
] = {"ld_int4", M32
},
215 [midgard_op_ld_attr_32
] = {"ld_attr_32", M32
},
216 [midgard_op_ld_attr_32i
] = {"ld_attr_32i", M32
},
217 [midgard_op_ld_attr_32u
] = {"ld_attr_32u", M32
},
218 [midgard_op_ld_attr_16
] = {"ld_attr_16", M32
},
220 [midgard_op_ld_vary_32
] = {"ld_vary_32", M32
},
221 [midgard_op_ld_vary_16
] = {"ld_vary_16", M32
},
222 [midgard_op_ld_vary_32i
] = {"ld_vary_32i", M32
},
223 [midgard_op_ld_vary_32u
] = {"ld_vary_32u", M32
},
225 [midgard_op_ld_color_buffer_8
] = {"ld_color_buffer_8", M8
| LDST_SPECIAL_MASK
},
226 [midgard_op_ld_color_buffer_16
] = {"ld_color_buffer_16", 0},
228 [midgard_op_ld_ubo_char
] = {"ld_ubo_char", M32
},
229 [midgard_op_ld_ubo_char2
] = {"ld_ubo_char2", M16
},
230 [midgard_op_ld_ubo_char4
] = {"ld_ubo_char4", M32
},
231 [midgard_op_ld_ubo_short4
] = {"ld_ubo_short4", M32
},
232 [midgard_op_ld_ubo_int4
] = {"ld_ubo_int4", M32
},
234 [midgard_op_st_char
] = {"st_char", M32
| LDST_STORE
},
235 [midgard_op_st_char2
] = {"st_char2", M16
| LDST_STORE
},
236 [midgard_op_st_char4
] = {"st_char4", M32
| LDST_STORE
},
237 [midgard_op_st_short4
] = {"st_short4", M32
| LDST_STORE
},
238 [midgard_op_st_int4
] = {"st_int4", M32
| LDST_STORE
},
240 [midgard_op_st_vary_32
] = {"st_vary_32", M32
| LDST_STORE
},
241 [midgard_op_st_vary_32i
] = {"st_vary_32i", M32
| LDST_STORE
},
242 [midgard_op_st_vary_32u
] = {"st_vary_32u", M32
| LDST_STORE
},
243 [midgard_op_st_vary_16
] = {"st_vary_16", M16
| LDST_STORE
},
245 [midgard_op_st_image_f
] = {"st_image_f", M32
| LDST_STORE
},
246 [midgard_op_st_image_ui
] = {"st_image_ui", M32
| LDST_STORE
},
247 [midgard_op_st_image_i
] = {"st_image_i", M32
| LDST_STORE
},