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_MUL
| UNITS_ADD
| OP_COMMUTES
},
38 [midgard_alu_op_fmax
] = {"fmax", UNITS_MUL
| UNITS_ADD
| 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_fround
] = {"fround", UNITS_ADD
},
50 [midgard_alu_op_froundeven
] = {"froundeven", UNITS_ADD
},
51 [midgard_alu_op_ftrunc
] = {"ftrunc", UNITS_ADD
},
52 [midgard_alu_op_ffloor
] = {"ffloor", UNITS_ADD
},
53 [midgard_alu_op_fceil
] = {"fceil", UNITS_ADD
},
54 [midgard_alu_op_ffma
] = {"ffma", UNIT_VLUT
},
56 /* Though they output a scalar, they need to run on a vector unit
57 * since they process vectors */
58 [midgard_alu_op_fdot3
] = {"fdot3", UNIT_VMUL
| OP_CHANNEL_COUNT(3) | OP_COMMUTES
},
59 [midgard_alu_op_fdot3r
] = {"fdot3r", UNIT_VMUL
| OP_CHANNEL_COUNT(3) | OP_COMMUTES
},
60 [midgard_alu_op_fdot4
] = {"fdot4", UNIT_VMUL
| OP_CHANNEL_COUNT(4) | OP_COMMUTES
},
62 /* Incredibly, iadd can run on vmul, etc */
63 [midgard_alu_op_iadd
] = {"iadd", UNITS_MOST
| OP_COMMUTES
},
64 [midgard_alu_op_iaddsat
] = {"iaddsat", UNITS_ADD
| OP_COMMUTES
},
65 [midgard_alu_op_uaddsat
] = {"uaddsat", UNITS_ADD
| OP_COMMUTES
},
66 [midgard_alu_op_iabsdiff
] = {"iabsdiff", UNITS_ADD
},
67 [midgard_alu_op_uabsdiff
] = {"uabsdiff", UNITS_ADD
},
68 [midgard_alu_op_ichoose
] = {"ichoose", UNITS_ADD
},
69 [midgard_alu_op_isub
] = {"isub", UNITS_MOST
},
70 [midgard_alu_op_isubsat
] = {"isubsat", UNITS_MOST
},
71 [midgard_alu_op_usubsat
] = {"usubsat", UNITS_MOST
},
72 [midgard_alu_op_imul
] = {"imul", UNITS_MUL
| OP_COMMUTES
},
73 [midgard_alu_op_imov
] = {"imov", UNITS_MOST
| QUIRK_FLIPPED_R24
},
75 /* For vector comparisons, use ball etc */
76 [midgard_alu_op_feq
] = {"feq", UNITS_MOST
| OP_COMMUTES
},
77 [midgard_alu_op_fne
] = {"fne", UNITS_MOST
| OP_COMMUTES
},
78 [midgard_alu_op_fle
] = {"fle", UNITS_MOST
},
79 [midgard_alu_op_flt
] = {"flt", UNITS_MOST
},
80 [midgard_alu_op_ieq
] = {"ieq", UNITS_MOST
| OP_COMMUTES
},
81 [midgard_alu_op_ine
] = {"ine", UNITS_MOST
| OP_COMMUTES
},
82 [midgard_alu_op_ilt
] = {"ilt", UNITS_MOST
},
83 [midgard_alu_op_ile
] = {"ile", UNITS_MOST
},
84 [midgard_alu_op_ult
] = {"ult", UNITS_MOST
},
85 [midgard_alu_op_ule
] = {"ule", UNITS_MOST
},
87 [midgard_alu_op_icsel
] = {"icsel", UNITS_ADD
},
88 [midgard_alu_op_icsel_v
] = {"icsel_v", UNITS_ADD
}, /* Acts as bitselect() */
89 [midgard_alu_op_fcsel_v
] = {"fcsel_v", UNITS_ADD
},
90 [midgard_alu_op_fcsel
] = {"fcsel", UNITS_ADD
| UNIT_SMUL
},
92 [midgard_alu_op_frcp
] = {"frcp", UNIT_VLUT
},
93 [midgard_alu_op_frsqrt
] = {"frsqrt", UNIT_VLUT
},
94 [midgard_alu_op_fsqrt
] = {"fsqrt", UNIT_VLUT
},
95 [midgard_alu_op_fpow_pt1
] = {"fpow_pt1", UNIT_VLUT
},
96 [midgard_alu_op_fpown_pt1
] = {"fpown_pt1", UNIT_VLUT
},
97 [midgard_alu_op_fpowr_pt1
] = {"fpowr_pt1", UNIT_VLUT
},
98 [midgard_alu_op_fexp2
] = {"fexp2", UNIT_VLUT
},
99 [midgard_alu_op_flog2
] = {"flog2", UNIT_VLUT
},
101 [midgard_alu_op_f2i
] = {"f2i", UNITS_ADD
| OP_TYPE_CONVERT
},
102 [midgard_alu_op_f2u
] = {"f2u", UNITS_ADD
| OP_TYPE_CONVERT
},
103 [midgard_alu_op_f2u8
] = {"f2u8", UNITS_ADD
| OP_TYPE_CONVERT
},
104 [midgard_alu_op_i2f
] = {"i2f", UNITS_ADD
| OP_TYPE_CONVERT
},
105 [midgard_alu_op_u2f
] = {"u2f", UNITS_ADD
| OP_TYPE_CONVERT
},
107 [midgard_alu_op_fsin
] = {"fsin", UNIT_VLUT
},
108 [midgard_alu_op_fcos
] = {"fcos", UNIT_VLUT
},
110 /* XXX: Test case where it's right on smul but not sadd */
111 [midgard_alu_op_iand
] = {"iand", UNITS_MOST
| OP_COMMUTES
},
112 [midgard_alu_op_iandnot
] = {"iandnot", UNITS_MOST
},
114 [midgard_alu_op_ior
] = {"ior", UNITS_MOST
| OP_COMMUTES
},
115 [midgard_alu_op_iornot
] = {"iornot", UNITS_MOST
| OP_COMMUTES
},
116 [midgard_alu_op_inor
] = {"inor", UNITS_MOST
| OP_COMMUTES
},
117 [midgard_alu_op_ixor
] = {"ixor", UNITS_MOST
| OP_COMMUTES
},
118 [midgard_alu_op_inxor
] = {"inxor", UNITS_MOST
| OP_COMMUTES
},
119 [midgard_alu_op_iclz
] = {"iclz", UNITS_ADD
},
120 [midgard_alu_op_ibitcount8
] = {"ibitcount8", UNITS_ADD
},
121 [midgard_alu_op_inand
] = {"inand", UNITS_MOST
},
122 [midgard_alu_op_ishl
] = {"ishl", UNITS_ADD
},
123 [midgard_alu_op_iasr
] = {"iasr", UNITS_ADD
},
124 [midgard_alu_op_ilsr
] = {"ilsr", UNITS_ADD
},
126 [midgard_alu_op_fball_eq
] = {"fball_eq", UNITS_VECTOR
| OP_COMMUTES
},
127 [midgard_alu_op_fbany_neq
] = {"fbany_neq", UNITS_VECTOR
| OP_COMMUTES
},
128 [midgard_alu_op_iball_eq
] = {"iball_eq", UNITS_VECTOR
| OP_COMMUTES
},
129 [midgard_alu_op_iball_neq
] = {"iball_neq", UNITS_VECTOR
| OP_COMMUTES
},
130 [midgard_alu_op_ibany_eq
] = {"ibany_eq", UNITS_VECTOR
| OP_COMMUTES
},
131 [midgard_alu_op_ibany_neq
] = {"ibany_neq", UNITS_VECTOR
| OP_COMMUTES
},
133 /* These instructions are not yet emitted by the compiler, so
134 * don't speculate about units yet */
135 [midgard_alu_op_ishladd
] = {"ishladd", 0},
137 [midgard_alu_op_uball_lt
] = {"uball_lt", 0},
138 [midgard_alu_op_uball_lte
] = {"uball_lte", 0},
139 [midgard_alu_op_iball_lt
] = {"iball_lt", 0},
140 [midgard_alu_op_iball_lte
] = {"iball_lte", 0},
141 [midgard_alu_op_ubany_lt
] = {"ubany_lt", 0},
142 [midgard_alu_op_ubany_lte
] = {"ubany_lte", 0},
143 [midgard_alu_op_ibany_lt
] = {"ibany_lt", 0},
144 [midgard_alu_op_ibany_lte
] = {"ibany_lte", 0},
146 [midgard_alu_op_freduce
] = {"freduce", 0},
147 [midgard_alu_op_bball_eq
] = {"bball_eq", 0 | OP_COMMUTES
},
148 [midgard_alu_op_bbany_neq
] = {"bball_eq", 0 | OP_COMMUTES
},
149 [midgard_alu_op_fatan2_pt1
] = {"fatan2_pt1", 0},
150 [midgard_alu_op_fatan_pt2
] = {"fatan_pt2", 0},
153 const char *load_store_opcode_names
[256] = {
154 [midgard_op_st_cubemap_coords
] = "st_cubemap_coords",
155 [midgard_op_ld_global_id
] = "ld_global_id",
157 [midgard_op_atomic_add
] = "atomic_add",
158 [midgard_op_atomic_and
] = "atomic_and",
159 [midgard_op_atomic_or
] = "atomic_or",
160 [midgard_op_atomic_xor
] = "atomic_xor",
161 [midgard_op_atomic_imin
] = "atomic_imin",
162 [midgard_op_atomic_umin
] = "atomic_umin",
163 [midgard_op_atomic_imax
] = "atomic_imax",
164 [midgard_op_atomic_umax
] = "atomic_umax",
165 [midgard_op_atomic_xchg
] = "atomic_xchg",
167 [midgard_op_ld_char
] = "ld_char",
168 [midgard_op_ld_char2
] = "ld_char2",
169 [midgard_op_ld_short
] = "ld_short",
170 [midgard_op_ld_char4
] = "ld_char4",
171 [midgard_op_ld_short4
] = "ld_short4",
172 [midgard_op_ld_int4
] = "ld_int4",
174 [midgard_op_ld_attr_32
] = "ld_attr_32",
175 [midgard_op_ld_attr_16
] = "ld_attr_16",
176 [midgard_op_ld_attr_32i
] = "ld_attr_32i",
178 [midgard_op_ld_vary_32
] = "ld_vary_32",
179 [midgard_op_ld_vary_16
] = "ld_vary_16",
180 [midgard_op_ld_vary_32i
] = "ld_vary_32i",
182 [midgard_op_ld_color_buffer_16
] = "ld_color_buffer_16",
184 [midgard_op_ld_uniform_16
] = "ld_uniform_16",
185 [midgard_op_ld_uniform_32
] = "ld_uniform_32",
186 [midgard_op_ld_color_buffer_8
] = "ld_color_buffer_8",
188 [midgard_op_st_char
] = "st_char",
189 [midgard_op_st_char2
] = "st_char2",
190 [midgard_op_st_char4
] = "st_char4",
191 [midgard_op_st_short4
] = "st_short4",
192 [midgard_op_st_int4
] = "st_int4",
194 [midgard_op_st_vary_32
] = "st_vary_32",
195 [midgard_op_st_vary_16
] = "st_vary_16",
196 [midgard_op_st_vary_32i
] = "st_vary_32i",
198 [midgard_op_st_image_f
] = "st_image_f",
199 [midgard_op_st_image_ui
] = "st_image_ui",
200 [midgard_op_st_image_i
] = "st_image_i",