File spirv/asm/asm.c changed (mode: 100644) (index 757b510..141c14c) |
3 |
3 |
#include <stdlib.h> |
#include <stdlib.h> |
4 |
4 |
#include <stdbool.h> |
#include <stdbool.h> |
5 |
5 |
#include <string.h> |
#include <string.h> |
|
6 |
|
/* see LICENSE sylvain.bertrand@legeek.net */ |
6 |
7 |
/* |
/* |
7 |
8 |
* FAT WARNING: DO NOT TRY TO GENERALIZE/FACTOR THE CODE TOO EARLY |
* FAT WARNING: DO NOT TRY TO GENERALIZE/FACTOR THE CODE TOO EARLY |
8 |
9 |
* AND EXCESSIVE GENERALIZATION/FACTORIZATION IS NOT WELCOME |
* AND EXCESSIVE GENERALIZATION/FACTORIZATION IS NOT WELCOME |
|
... |
... |
static u8 id_get(u32 *id, u8 *s, u8 *e, u8 **err_str) |
267 |
268 |
|
|
268 |
269 |
|
|
269 |
270 |
if (*s != '%') { /* an id start with '%' */ |
if (*s != '%') { /* an id start with '%' */ |
270 |
|
*err_str = "missing '%' at the beginning af the id"; |
|
|
271 |
|
*err_str = "missing '%' at the beginning of the id"; |
271 |
272 |
return ERR; |
return ERR; |
272 |
273 |
} |
} |
273 |
274 |
|
|
|
... |
... |
static u32 opd_id(u8 *op, u8 *name, u8 *desc) |
336 |
337 |
u8 *opd_e; |
u8 *opd_e; |
337 |
338 |
u8 *err_str; |
u8 *err_str; |
338 |
339 |
u32 id; |
u32 id; |
339 |
|
|
|
340 |
|
opd_val_reach(op, name); |
|
|
340 |
|
|
|
341 |
|
if (name != 0) |
|
342 |
|
opd_val_reach(op, name); |
341 |
343 |
|
|
342 |
344 |
opd_s = b; |
opd_s = b; |
343 |
345 |
ws_or_eol_reach(); |
ws_or_eol_reach(); |
|
... |
... |
static void op_type_pointer(void) |
1277 |
1279 |
|
|
1278 |
1280 |
} |
} |
1279 |
1281 |
|
|
|
1282 |
|
/* a spirv "variable" is a pointer to some allocated storage */ |
1280 |
1283 |
static void op_variable(void) |
static void op_variable(void) |
1281 |
1284 |
{ |
{ |
1282 |
1285 |
u8 r; |
u8 r; |
1283 |
|
bool have_pointer_type; |
|
1284 |
|
u32 pointer_type; |
|
1285 |
|
bool have_id; |
|
1286 |
|
u32 id; |
|
|
1286 |
|
bool have_type; |
|
1287 |
|
u32 type; |
|
1288 |
|
bool have_pointer_id; |
|
1289 |
|
u32 pointer_id; |
1287 |
1290 |
bool have_storage_class; |
bool have_storage_class; |
1288 |
1291 |
u32 storage_class; |
u32 storage_class; |
1289 |
1292 |
u8 *err_str; |
u8 *err_str; |
|
... |
... |
static void op_variable(void) |
1293 |
1296 |
|
|
1294 |
1297 |
u32 word; |
u32 word; |
1295 |
1298 |
|
|
1296 |
|
have_pointer_type = false; |
|
1297 |
|
have_id = false; |
|
|
1299 |
|
have_type = false; |
|
1300 |
|
have_pointer_id = false; |
1298 |
1301 |
have_storage_class = false; |
have_storage_class = false; |
1299 |
1302 |
initializers_n = 0; |
initializers_n = 0; |
1300 |
1303 |
|
|
|
... |
... |
static void op_variable(void) |
1312 |
1315 |
ws_or_eol_or_eq_reach(); |
ws_or_eol_or_eq_reach(); |
1313 |
1316 |
opd_e = b; |
opd_e = b; |
1314 |
1317 |
|
|
1315 |
|
if (str_slice_cmp("pointer_type", opd_s, opd_e)) { |
|
1316 |
|
pointer_type = opd_id("variable", "pointer_type", |
|
1317 |
|
"pointer type id"); |
|
1318 |
|
have_pointer_type = true; |
|
1319 |
|
} else if (str_slice_cmp("id", opd_s, opd_e)) { |
|
1320 |
|
id = opd_id("variable", "id", "id"); |
|
|
1318 |
|
if (str_slice_cmp("type", opd_s, opd_e)) { |
|
1319 |
|
type = opd_id("variable", "type", "type id"); |
|
1320 |
|
have_type = true; |
|
1321 |
|
} else if (str_slice_cmp("pointer_id", opd_s, opd_e)) { |
|
1322 |
|
pointer_id = opd_id("variable", "pointer_id", "pointer id"); |
1321 |
1323 |
|
|
1322 |
|
r = id_use(id, &err_str); |
|
|
1324 |
|
r = id_use(pointer_id, &err_str); |
1323 |
1325 |
if (r != OK) { |
if (r != OK) { |
1324 |
|
err("ERROR:%u:variable:something is wrong with the id:%s\n", line_num, err_str); |
|
|
1326 |
|
err("ERROR:%u:variable:something is wrong with the pointer id:%s\n", line_num, err_str); |
1325 |
1327 |
exit(1); |
exit(1); |
1326 |
1328 |
} |
} |
1327 |
|
have_id = true; |
|
|
1329 |
|
have_pointer_id = true; |
1328 |
1330 |
} else if (str_slice_cmp("storage_class", opd_s, opd_e)) { |
} else if (str_slice_cmp("storage_class", opd_s, opd_e)) { |
1329 |
1331 |
storage_class = opd_storage_class("variable"); |
storage_class = opd_storage_class("variable"); |
1330 |
1332 |
have_storage_class = true; |
have_storage_class = true; |
|
... |
... |
static void op_variable(void) |
1333 |
1335 |
exit(1); |
exit(1); |
1334 |
1336 |
} |
} |
1335 |
1337 |
|
|
1336 |
|
if (have_pointer_type && have_id && have_storage_class) |
|
|
1338 |
|
if (have_type && have_pointer_id && have_storage_class) |
1337 |
1339 |
break; |
break; |
1338 |
1340 |
} |
} |
1339 |
1341 |
|
|
|
... |
... |
static void op_variable(void) |
1351 |
1353 |
word |= (4 + initializers_n) << 16; |
word |= (4 + initializers_n) << 16; |
1352 |
1354 |
emit(word); |
emit(word); |
1353 |
1355 |
|
|
1354 |
|
emit(pointer_type); |
|
1355 |
|
emit(id); |
|
|
1356 |
|
emit(type); |
|
1357 |
|
emit(pointer_id); |
1356 |
1358 |
emit(storage_class); |
emit(storage_class); |
1357 |
1359 |
|
|
1358 |
1360 |
word = 0; |
word = 0; |
|
... |
... |
static void op_variable(void) |
1364 |
1366 |
} |
} |
1365 |
1367 |
} |
} |
1366 |
1368 |
|
|
|
1369 |
|
static void decoration_location_opds_consume(u8 *op, u32 *opds, u32 *opds_n) |
|
1370 |
|
{ |
|
1371 |
|
u8 r; |
|
1372 |
|
u8 *opd_s; |
|
1373 |
|
u8 *opd_e; |
|
1374 |
|
u8 *err_str; |
|
1375 |
|
|
|
1376 |
|
r = ws_skip(); |
|
1377 |
|
if (r == EOL) { |
|
1378 |
|
err("ERROR:%u:%s:location decoration is missing its value\n", line_num, op); |
|
1379 |
|
exit(1); |
|
1380 |
|
} |
|
1381 |
|
|
|
1382 |
|
opd_s = b; |
|
1383 |
|
ws_or_eol_reach(); |
|
1384 |
|
opd_e = b; |
|
1385 |
|
|
|
1386 |
|
r = u32_decode(opds + *opds_n, opd_s, opd_e, &err_str); |
|
1387 |
|
if (r != OK) { |
|
1388 |
|
err("ERROR:%u:%s:unable to decade location decoration value:%s\n", line_num, op, err_str); |
|
1389 |
|
exit(1); |
|
1390 |
|
} |
|
1391 |
|
++(*opds_n); |
|
1392 |
|
} |
|
1393 |
|
|
1367 |
1394 |
static void decoration_builtin_opds_consume(u8 *op, u32 *opds, u32 *opds_n) |
static void decoration_builtin_opds_consume(u8 *op, u32 *opds, u32 *opds_n) |
1368 |
1395 |
{ |
{ |
1369 |
1396 |
u8 r; |
u8 r; |
|
... |
... |
static void decoration_opds_consume(u8 * op, u32 decoration, u32 *opds, |
1521 |
1548 |
case 11: |
case 11: |
1522 |
1549 |
decoration_builtin_opds_consume(op, opds, opds_n); |
decoration_builtin_opds_consume(op, opds, opds_n); |
1523 |
1550 |
break; |
break; |
|
1551 |
|
case 30: |
|
1552 |
|
decoration_location_opds_consume(op, opds, opds_n); |
|
1553 |
|
break; |
1524 |
1554 |
} |
} |
1525 |
1555 |
} |
} |
1526 |
1556 |
|
|
|
... |
... |
static u32 opd_decoration(u8 *op) |
1559 |
1589 |
return 10; |
return 10; |
1560 |
1590 |
else if (str_slice_cmp("builtin", opd_s, opd_e)) |
else if (str_slice_cmp("builtin", opd_s, opd_e)) |
1561 |
1591 |
return 11; |
return 11; |
|
1592 |
|
else if (str_slice_cmp("location", opd_s, opd_e)) |
|
1593 |
|
return 30; |
1562 |
1594 |
/* TODO: more */ |
/* TODO: more */ |
1563 |
1595 |
|
|
1564 |
1596 |
err("ERROR:%u:%s:decoration operand:unknown value \"%.*s\"\n", line_num, op, opd_e - opd_s, opd_s); |
err("ERROR:%u:%s:decoration operand:unknown value \"%.*s\"\n", line_num, op, opd_e - opd_s, opd_s); |
|
... |
... |
static void op_label(void) |
1967 |
1999 |
emit(id); |
emit(id); |
1968 |
2000 |
} |
} |
1969 |
2001 |
|
|
|
2002 |
|
/* XXX: may factor it with op_binop_x */ |
|
2003 |
|
static void op_iequal(void) |
|
2004 |
|
{ |
|
2005 |
|
u8 r; |
|
2006 |
|
bool have_type; |
|
2007 |
|
u32 type; |
|
2008 |
|
bool have_id; |
|
2009 |
|
u32 id; |
|
2010 |
|
bool have_opd0; |
|
2011 |
|
u32 opd0; |
|
2012 |
|
bool have_opd1; |
|
2013 |
|
u32 opd1; |
|
2014 |
|
u8 *err_str; |
|
2015 |
|
|
|
2016 |
|
u32 word; |
|
2017 |
|
|
|
2018 |
|
have_type = false; |
|
2019 |
|
have_id = false; |
|
2020 |
|
loop { |
|
2021 |
|
u8 *opd_s; |
|
2022 |
|
u8 *opd_e; |
|
2023 |
|
|
|
2024 |
|
r = ws_skip(); |
|
2025 |
|
if (r == EOL) { |
|
2026 |
|
err("ERROR:%u:iequal:missing operands\n", line_num); |
|
2027 |
|
exit(1); |
|
2028 |
|
} |
|
2029 |
|
|
|
2030 |
|
opd_s = b; |
|
2031 |
|
ws_or_eol_or_eq_reach(); |
|
2032 |
|
opd_e = b; |
|
2033 |
|
|
|
2034 |
|
if (str_slice_cmp("type", opd_s, opd_e)) { |
|
2035 |
|
type = opd_id("iequal", "type", "result type id"); |
|
2036 |
|
have_type = true; |
|
2037 |
|
} else if (str_slice_cmp("id", opd_s, opd_e)) { |
|
2038 |
|
id = opd_id("type", "id", "id"); |
|
2039 |
|
|
|
2040 |
|
r = id_use(id, &err_str); |
|
2041 |
|
if (r != OK) { |
|
2042 |
|
err("ERROR:%u:iequal:something is wrong with the id:%s\n", line_num, err_str); |
|
2043 |
|
exit(1); |
|
2044 |
|
} |
|
2045 |
|
have_id = true; |
|
2046 |
|
} else { |
|
2047 |
|
err("ERROR:%u:iequal:unknown operand \"%.*s\"\n", line_num, opd_e - opd_s, opd_s); |
|
2048 |
|
exit(1); |
|
2049 |
|
} |
|
2050 |
|
|
|
2051 |
|
if (have_type && have_id) |
|
2052 |
|
break; |
|
2053 |
|
} |
|
2054 |
|
|
|
2055 |
|
/* now the operation operands */ |
|
2056 |
|
have_opd0 = false; |
|
2057 |
|
have_opd1 = false; |
|
2058 |
|
loop { |
|
2059 |
|
r = ws_skip(); |
|
2060 |
|
if (r == EOL) { |
|
2061 |
|
err("ERROR:%u:iequal:missing comparison operands\n", line_num); |
|
2062 |
|
exit(1); |
|
2063 |
|
} |
|
2064 |
|
|
|
2065 |
|
if (!have_opd0) { |
|
2066 |
|
opd0 = opd_id("iequal", 0, "comparison first operand"); |
|
2067 |
|
have_opd0 = true; |
|
2068 |
|
} else if (!have_opd1) { |
|
2069 |
|
opd1 = opd_id("iequal", 0, "comparison second operand"); |
|
2070 |
|
have_opd1 = true; |
|
2071 |
|
} |
|
2072 |
|
|
|
2073 |
|
if (have_opd0 && have_opd1) |
|
2074 |
|
break; |
|
2075 |
|
} |
|
2076 |
|
|
|
2077 |
|
word = 170; |
|
2078 |
|
word |= 5 << 16; |
|
2079 |
|
emit(word); |
|
2080 |
|
|
|
2081 |
|
emit(type); |
|
2082 |
|
emit(id); |
|
2083 |
|
emit(opd0); |
|
2084 |
|
emit(opd1); |
|
2085 |
|
} |
|
2086 |
|
|
|
2087 |
|
static u32 opd_selection_control(u8 *op) |
|
2088 |
|
{ |
|
2089 |
|
u8 *opd_s; |
|
2090 |
|
u8 *opd_e; |
|
2091 |
|
|
|
2092 |
|
opd_val_reach(op, "selection_control"); |
|
2093 |
|
|
|
2094 |
|
opd_s = b; |
|
2095 |
|
ws_or_eol_reach(); |
|
2096 |
|
opd_e = b; |
|
2097 |
|
|
|
2098 |
|
if (str_slice_cmp("none", opd_s, opd_e)) |
|
2099 |
|
return 0; |
|
2100 |
|
else if (str_slice_cmp("flatten", opd_s, opd_e)) |
|
2101 |
|
return 1; |
|
2102 |
|
else if (str_slice_cmp("dont_flatten", opd_s, opd_e)) |
|
2103 |
|
return 2; |
|
2104 |
|
err("ERROR:%u:%s:selection_control operand:unknown value \"%.*s\"\n", line_num, op, opd_e - opd_s, opd_s); |
|
2105 |
|
exit(1); |
|
2106 |
|
} |
|
2107 |
|
|
|
2108 |
|
static void op_selection_merge(void) |
|
2109 |
|
{ |
|
2110 |
|
u8 r; |
|
2111 |
|
bool have_block; |
|
2112 |
|
u32 block; |
|
2113 |
|
bool have_selection_control; |
|
2114 |
|
u32 selection_control; |
|
2115 |
|
u8 *err_str; |
|
2116 |
|
|
|
2117 |
|
u32 word; |
|
2118 |
|
|
|
2119 |
|
have_block = false; |
|
2120 |
|
have_selection_control = false; |
|
2121 |
|
loop { |
|
2122 |
|
u8 *opd_s; |
|
2123 |
|
u8 *opd_e; |
|
2124 |
|
|
|
2125 |
|
r = ws_skip(); |
|
2126 |
|
if (r == EOL) { |
|
2127 |
|
err("ERROR:%u:selection_merge:missing operands\n", line_num); |
|
2128 |
|
exit(1); |
|
2129 |
|
} |
|
2130 |
|
|
|
2131 |
|
opd_s = b; |
|
2132 |
|
ws_or_eol_or_eq_reach(); |
|
2133 |
|
opd_e = b; |
|
2134 |
|
|
|
2135 |
|
if (str_slice_cmp("block", opd_s, opd_e)) { |
|
2136 |
|
block = opd_id("selection_merge", "block", "block label id"); |
|
2137 |
|
have_block = true; |
|
2138 |
|
} else if (str_slice_cmp("selection_control", opd_s, opd_e)) { |
|
2139 |
|
selection_control = opd_selection_control("selection_merge"); |
|
2140 |
|
have_selection_control = true; |
|
2141 |
|
} else { |
|
2142 |
|
err("ERROR:%u:selection_merge:unknown operand \"%.*s\"\n", line_num, opd_e - opd_s, opd_s); |
|
2143 |
|
exit(1); |
|
2144 |
|
} |
|
2145 |
|
|
|
2146 |
|
if (have_block && have_selection_control) |
|
2147 |
|
break; |
|
2148 |
|
} |
|
2149 |
|
|
|
2150 |
|
word = 247; |
|
2151 |
|
word |= 3 << 16; |
|
2152 |
|
emit(word); |
|
2153 |
|
|
|
2154 |
|
emit(block); |
|
2155 |
|
emit(selection_control); |
|
2156 |
|
} |
|
2157 |
|
|
|
2158 |
|
/* expect b to point on the first valid char */ |
|
2159 |
|
static u8 targets_collect(u32 *opds, u32 *opds_n, u8 **err_str) |
|
2160 |
|
{ |
|
2161 |
|
static u8 err_str_buf[BUFSIZ]; |
|
2162 |
|
|
|
2163 |
|
*err_str = err_str_buf; |
|
2164 |
|
loop { |
|
2165 |
|
u8 r; |
|
2166 |
|
u8 *u32_s; |
|
2167 |
|
u8 *u32_e; |
|
2168 |
|
u8 *id_s; |
|
2169 |
|
u8 *id_e; |
|
2170 |
|
u8 *err_str_next; |
|
2171 |
|
|
|
2172 |
|
if ((*opds_n + 2) > VAR_OPDS_N_MAX) { |
|
2173 |
|
snprintf(err_str_buf, BUFSIZ, "target[%u]:no room for target in operand storage", *opds_n / 2); |
|
2174 |
|
return ERR; |
|
2175 |
|
} |
|
2176 |
|
|
|
2177 |
|
u32_s = b; |
|
2178 |
|
ws_or_eol_reach(); |
|
2179 |
|
u32_e = b; |
|
2180 |
|
|
|
2181 |
|
r = u32_decode(opds + *opds_n, u32_s, u32_e, &err_str_next); |
|
2182 |
|
if (r != OK) { |
|
2183 |
|
snprintf(err_str_buf, BUFSIZ, "target[%u]:literal number:%s", *opds_n / 2, err_str_next); |
|
2184 |
|
return r; |
|
2185 |
|
} |
|
2186 |
|
|
|
2187 |
|
r = ws_skip(); |
|
2188 |
|
if (r == EOL) { |
|
2189 |
|
snprintf(err_str_buf, BUFSIZ, "target[%u]:missing label id", *opds_n / 2); |
|
2190 |
|
return ERR; |
|
2191 |
|
} |
|
2192 |
|
|
|
2193 |
|
id_s = b; |
|
2194 |
|
ws_or_eol_reach(); |
|
2195 |
|
id_e = b; |
|
2196 |
|
|
|
2197 |
|
r = id_get(opds + *opds_n + 1, id_s, id_e, &err_str_next); |
|
2198 |
|
if (r != OK) { |
|
2199 |
|
snprintf(err_str_buf, BUFSIZ, "target[%u]:label id:%s", *opds_n / 2, err_str_next); |
|
2200 |
|
return r; |
|
2201 |
|
} |
|
2202 |
|
|
|
2203 |
|
(*opds_n) += 2; |
|
2204 |
|
|
|
2205 |
|
r = ws_skip(); |
|
2206 |
|
if (r == EOL) |
|
2207 |
|
return OK; |
|
2208 |
|
} |
|
2209 |
|
} |
|
2210 |
|
|
|
2211 |
|
static void op_switch(void) |
|
2212 |
|
{ |
|
2213 |
|
u8 r; |
|
2214 |
|
bool have_selector; |
|
2215 |
|
u32 selector; |
|
2216 |
|
bool have_default_id; |
|
2217 |
|
u32 default_id; |
|
2218 |
|
u8 *err_str; |
|
2219 |
|
|
|
2220 |
|
u32 targets_opds[VAR_OPDS_N_MAX]; |
|
2221 |
|
u32 targets_opds_n; |
|
2222 |
|
|
|
2223 |
|
u32 word; |
|
2224 |
|
|
|
2225 |
|
have_selector = false; |
|
2226 |
|
have_default_id = false; |
|
2227 |
|
targets_opds_n = 0; |
|
2228 |
|
loop { |
|
2229 |
|
u8 *opd_s; |
|
2230 |
|
u8 *opd_e; |
|
2231 |
|
|
|
2232 |
|
r = ws_skip(); |
|
2233 |
|
if (r == EOL) { |
|
2234 |
|
err("ERROR:%u:switch:missing operands\n", line_num); |
|
2235 |
|
exit(1); |
|
2236 |
|
} |
|
2237 |
|
|
|
2238 |
|
opd_s = b; |
|
2239 |
|
ws_or_eol_or_eq_reach(); |
|
2240 |
|
opd_e = b; |
|
2241 |
|
|
|
2242 |
|
if (str_slice_cmp("selector", opd_s, opd_e)) { |
|
2243 |
|
selector = opd_id("switch", "selector", "selector id"); |
|
2244 |
|
have_selector = true; |
|
2245 |
|
} else if (str_slice_cmp("default", opd_s, opd_e)) { |
|
2246 |
|
default_id = opd_id("switch", "default", "default id"); |
|
2247 |
|
have_default_id = true; |
|
2248 |
|
} else { |
|
2249 |
|
err("ERROR:%u:switch:unknown operand \"%.*s\"\n", line_num, opd_e - opd_s, opd_s); |
|
2250 |
|
exit(1); |
|
2251 |
|
} |
|
2252 |
|
|
|
2253 |
|
if (have_selector && have_default_id) |
|
2254 |
|
break; |
|
2255 |
|
} |
|
2256 |
|
|
|
2257 |
|
r = ws_skip(); |
|
2258 |
|
if (r == OK) { |
|
2259 |
|
/* have targets */ |
|
2260 |
|
targets_collect(targets_opds, &targets_opds_n, &err_str); |
|
2261 |
|
if (r != OK) { |
|
2262 |
|
err("ERROR:%u:switch:collecting targets:%s\n", line_num, err_str); |
|
2263 |
|
exit(1); |
|
2264 |
|
} |
|
2265 |
|
} |
|
2266 |
|
|
|
2267 |
|
word = 251; |
|
2268 |
|
word |= (3 + targets_opds_n) << 16; |
|
2269 |
|
emit(word); |
|
2270 |
|
|
|
2271 |
|
emit(selector); |
|
2272 |
|
emit(default_id); |
|
2273 |
|
|
|
2274 |
|
word = 0; |
|
2275 |
|
loop { |
|
2276 |
|
if (word == targets_opds_n) |
|
2277 |
|
break; |
|
2278 |
|
emit(targets_opds[word]); |
|
2279 |
|
++word; |
|
2280 |
|
} |
|
2281 |
|
} |
|
2282 |
|
|
|
2283 |
|
static void memory_opds_alignment_get(u8 *op, u32 *alignment) |
|
2284 |
|
{ |
|
2285 |
|
u8 r; |
|
2286 |
|
u8 *s; |
|
2287 |
|
u8 *e; |
|
2288 |
|
u8 *err_str; |
|
2289 |
|
|
|
2290 |
|
r = ws_skip(); |
|
2291 |
|
if (r != OK) { |
|
2292 |
|
err("ERROR:%u:%s:memory operands:missing alignment literal value\n", line_num, op); |
|
2293 |
|
exit(1); |
|
2294 |
|
} |
|
2295 |
|
|
|
2296 |
|
s = b; |
|
2297 |
|
ws_or_eol_reach(); |
|
2298 |
|
e = b; |
|
2299 |
|
|
|
2300 |
|
r = u32_decode(alignment, s, e, &err_str); |
|
2301 |
|
if (r != OK) { |
|
2302 |
|
err("ERROR:%u:%s:memory operands:unable to decode alignment literal value:%s\n", line_num, op, err_str); |
|
2303 |
|
exit(1); |
|
2304 |
|
} |
|
2305 |
|
|
|
2306 |
|
} |
|
2307 |
|
|
|
2308 |
|
static void memory_opds_x_scope_get(u8 *op, u8 *opd, u32 *scope) |
|
2309 |
|
{ |
|
2310 |
|
u8 r; |
|
2311 |
|
u8 *s; |
|
2312 |
|
u8 *e; |
|
2313 |
|
|
|
2314 |
|
r = ws_skip(); |
|
2315 |
|
if (r != OK) { |
|
2316 |
|
err("ERROR:%u:%s:memory operands:missing %s scope\n", line_num, op, opd); |
|
2317 |
|
exit(1); |
|
2318 |
|
} |
|
2319 |
|
|
|
2320 |
|
s = b; |
|
2321 |
|
ws_or_eol_reach(); |
|
2322 |
|
e = b; |
|
2323 |
|
|
|
2324 |
|
/* XXX: will probably be factor out */ |
|
2325 |
|
if (str_slice_cmp("cross_device", s, e)) |
|
2326 |
|
*scope = 0; |
|
2327 |
|
else if (str_slice_cmp("device", s, e)) |
|
2328 |
|
*scope = 1; |
|
2329 |
|
else if (str_slice_cmp("workgroup", s, e)) |
|
2330 |
|
*scope = 2; |
|
2331 |
|
else if (str_slice_cmp("subgroup", s, e)) |
|
2332 |
|
*scope = 3; |
|
2333 |
|
else if (str_slice_cmp("invocation", s, e)) |
|
2334 |
|
*scope = 4; |
|
2335 |
|
else if (str_slice_cmp("queue_family", s, e)) |
|
2336 |
|
*scope = 5; |
|
2337 |
|
else { |
|
2338 |
|
err("ERROR:%u:%s:memory operands:unable to decode %s scope\n", line_num, op, opd); |
|
2339 |
|
exit(1); |
|
2340 |
|
} |
|
2341 |
|
} |
|
2342 |
|
|
|
2343 |
|
/* flag0|flag1|flag2... opds_flag_X opds_flag_Y... with X < Y*/ |
|
2344 |
|
static void memory_opds_collect(u8 *op, u32 *memory_opds, u32 *memory_opds_n) |
|
2345 |
|
{ |
|
2346 |
|
u8 *opd_s; |
|
2347 |
|
u8 *opd_e; |
|
2348 |
|
u32 additional_opd_idx; |
|
2349 |
|
|
|
2350 |
|
memory_opds[0] = 0x0; |
|
2351 |
|
|
|
2352 |
|
loop { |
|
2353 |
|
opd_s = b; |
|
2354 |
|
ws_or_eol_or_bar_reach(); |
|
2355 |
|
opd_e = b; |
|
2356 |
|
|
|
2357 |
|
if (str_slice_cmp("none", opd_s, opd_e)) { |
|
2358 |
|
memory_opds[0] = 0x0; |
|
2359 |
|
ws_or_eol_reach(); /* consume it all, useless */ |
|
2360 |
|
break; |
|
2361 |
|
} else if (str_slice_cmp("volatile", opd_s, opd_e)) |
|
2362 |
|
memory_opds[0] |= 0x1; |
|
2363 |
|
else if (str_slice_cmp("aligned", opd_s, opd_e)) |
|
2364 |
|
memory_opds[0] |= 0x2; |
|
2365 |
|
else if (str_slice_cmp("non_temporal", opd_s, opd_e)) |
|
2366 |
|
memory_opds[0] |= 0x4; |
|
2367 |
|
else if (str_slice_cmp("make_pointer_available", opd_s, opd_e)) |
|
2368 |
|
memory_opds[0] |= 0x8; |
|
2369 |
|
else if (str_slice_cmp("make_pointer_visible", opd_s, opd_e)) |
|
2370 |
|
memory_opds[0] |= 0x10; |
|
2371 |
|
else if (str_slice_cmp("non_private_pointer", opd_s, opd_e)) |
|
2372 |
|
memory_opds[0] |= 0x20; |
|
2373 |
|
else { |
|
2374 |
|
err("ERROR:%u:%s:memory operands:unknown operand \"%.*s\"\n", line_num, op, opd_e - opd_s, opd_s); |
|
2375 |
|
exit(1); |
|
2376 |
|
} |
|
2377 |
|
if (b == eol || *b != '|') |
|
2378 |
|
break; |
|
2379 |
|
++b; |
|
2380 |
|
} |
|
2381 |
|
|
|
2382 |
|
*memory_opds_n = 1; |
|
2383 |
|
additional_opd_idx = 1; /* skip the flags word */ |
|
2384 |
|
|
|
2385 |
|
if ((memory_opds[0] & 0x2) != 0) { |
|
2386 |
|
memory_opds_alignment_get(op, memory_opds + additional_opd_idx); |
|
2387 |
|
++(*memory_opds_n); |
|
2388 |
|
++additional_opd_idx; |
|
2389 |
|
} |
|
2390 |
|
if ((memory_opds[0] & 0x8) != 0) { |
|
2391 |
|
memory_opds_x_scope_get(op, "make_pointer_available", |
|
2392 |
|
memory_opds + additional_opd_idx); |
|
2393 |
|
++(*memory_opds_n); |
|
2394 |
|
++additional_opd_idx; |
|
2395 |
|
} |
|
2396 |
|
if ((memory_opds[0] & 0x10) != 0) { |
|
2397 |
|
memory_opds_x_scope_get(op, "make_pointer_visible", |
|
2398 |
|
memory_opds + additional_opd_idx); |
|
2399 |
|
++(*memory_opds_n); |
|
2400 |
|
++additional_opd_idx; |
|
2401 |
|
} |
|
2402 |
|
} |
|
2403 |
|
|
|
2404 |
|
static void op_store(void) |
|
2405 |
|
{ |
|
2406 |
|
u8 r; |
|
2407 |
|
bool have_pointer; |
|
2408 |
|
u32 pointer; |
|
2409 |
|
bool have_object; |
|
2410 |
|
u32 object; |
|
2411 |
|
u8 *err_str; |
|
2412 |
|
|
|
2413 |
|
u32 memory_opds[VAR_OPDS_N_MAX]; |
|
2414 |
|
u32 memory_opds_n; |
|
2415 |
|
|
|
2416 |
|
u32 word; |
|
2417 |
|
|
|
2418 |
|
have_pointer = false; |
|
2419 |
|
have_object = false; |
|
2420 |
|
memory_opds_n = 0; |
|
2421 |
|
|
|
2422 |
|
loop { |
|
2423 |
|
u8 *opd_s; |
|
2424 |
|
u8 *opd_e; |
|
2425 |
|
|
|
2426 |
|
r = ws_skip(); |
|
2427 |
|
if (r == EOL) { |
|
2428 |
|
err("ERROR:%u:type_function:missing operands\n", line_num); |
|
2429 |
|
exit(1); |
|
2430 |
|
} |
|
2431 |
|
|
|
2432 |
|
opd_s = b; |
|
2433 |
|
ws_or_eol_or_eq_reach(); |
|
2434 |
|
opd_e = b; |
|
2435 |
|
|
|
2436 |
|
if (str_slice_cmp("pointer", opd_s, opd_e)) { |
|
2437 |
|
pointer = opd_id("store", "pointer", "pointer id"); |
|
2438 |
|
have_pointer = true; |
|
2439 |
|
} else if (str_slice_cmp("object", opd_s, opd_e)) { |
|
2440 |
|
object = opd_id("store", "object", "object id"); |
|
2441 |
|
have_object = true; |
|
2442 |
|
} else { |
|
2443 |
|
err("ERROR:%u:store:unknown operand \"%.*s\"\n", line_num, opd_e - opd_s, opd_s); |
|
2444 |
|
exit(1); |
|
2445 |
|
} |
|
2446 |
|
|
|
2447 |
|
if (have_pointer && have_object) |
|
2448 |
|
break; |
|
2449 |
|
} |
|
2450 |
|
|
|
2451 |
|
r = ws_skip(); |
|
2452 |
|
if (r == OK) /* have memory opd(s) */ |
|
2453 |
|
memory_opds_collect("store", memory_opds, &memory_opds_n); |
|
2454 |
|
|
|
2455 |
|
word = 62; |
|
2456 |
|
word |= (3 + memory_opds_n) << 16; |
|
2457 |
|
emit(word); |
|
2458 |
|
|
|
2459 |
|
emit(pointer); |
|
2460 |
|
emit(object); |
|
2461 |
|
|
|
2462 |
|
word = 0; |
|
2463 |
|
loop { |
|
2464 |
|
if (word == memory_opds_n) |
|
2465 |
|
break; |
|
2466 |
|
emit(memory_opds[word]); |
|
2467 |
|
++word; |
|
2468 |
|
} |
|
2469 |
|
} |
|
2470 |
|
|
1970 |
2471 |
static void op_dispatch(void) |
static void op_dispatch(void) |
1971 |
2472 |
{ |
{ |
1972 |
2473 |
u8 *op_s; |
u8 *op_s; |
|
... |
... |
static void op_dispatch(void) |
2012 |
2513 |
op_function_end(); |
op_function_end(); |
2013 |
2514 |
else if (str_slice_cmp("label", op_s, op_e)) |
else if (str_slice_cmp("label", op_s, op_e)) |
2014 |
2515 |
op_label(); |
op_label(); |
|
2516 |
|
else if (str_slice_cmp("iequal", op_s, op_e)) |
|
2517 |
|
op_iequal(); |
|
2518 |
|
else if (str_slice_cmp("selection_merge", op_s, op_e)) |
|
2519 |
|
op_selection_merge(); |
|
2520 |
|
else if (str_slice_cmp("switch", op_s, op_e)) |
|
2521 |
|
op_switch(); |
|
2522 |
|
else if (str_slice_cmp("store", op_s, op_e)) |
|
2523 |
|
op_store(); |
2015 |
2524 |
/* TODO: MORE */ |
/* TODO: MORE */ |
2016 |
2525 |
else { |
else { |
2017 |
2526 |
err("ERROR:%u:unknown instruction \"%.*s\"\n", line_num, op_e - op_s, op_s); |
err("ERROR:%u:unknown instruction \"%.*s\"\n", line_num, op_e - op_s, op_s); |
File spirv/dis/dis.c changed (mode: 100644) (index aab4bfc..5e28deb) |
4 |
4 |
#include <stdint.h> |
#include <stdint.h> |
5 |
5 |
#include <stdlib.h> |
#include <stdlib.h> |
6 |
6 |
#include <string.h> |
#include <string.h> |
|
7 |
|
/* see LICENSE sylvain.bertrand@legeek.net */ |
|
8 |
|
/* |
|
9 |
|
* FAT WARNING: DO NOT TRY TO GENERALIZE/FACTOR THE CODE TOO EARLY |
|
10 |
|
* AND EXCESSIVE GENERALIZATION/FACTORIZATION IS NOT WELCOME |
|
11 |
|
*/ |
7 |
12 |
/* |
/* |
8 |
13 |
* ABBREVIATIONS: |
* ABBREVIATIONS: |
9 |
14 |
* blk(s) : BLocK(S) |
* blk(s) : BLocK(S) |
|
... |
... |
constant { |
117 |
122 |
spirv_op_logicalor = 166, |
spirv_op_logicalor = 166, |
118 |
123 |
spirv_op_logicaland = 167, |
spirv_op_logicaland = 167, |
119 |
124 |
spirv_op_select = 169, |
spirv_op_select = 169, |
|
125 |
|
spirv_op_iequal = 170, |
120 |
126 |
spirv_op_fordequal = 180, |
spirv_op_fordequal = 180, |
121 |
127 |
spirv_op_fordnotequal = 182, |
spirv_op_fordnotequal = 182, |
122 |
128 |
spirv_op_fordlessthan = 184, |
spirv_op_fordlessthan = 184, |
|
... |
... |
constant { |
128 |
134 |
spirv_op_label = 248, |
spirv_op_label = 248, |
129 |
135 |
spirv_op_branch = 249, |
spirv_op_branch = 249, |
130 |
136 |
spirv_op_branchconditional = 250, |
spirv_op_branchconditional = 250, |
|
137 |
|
spirv_op_switch = 251, |
131 |
138 |
spirv_op_return = 253, |
spirv_op_return = 253, |
132 |
139 |
spirv_op_returnvalue = 254, |
spirv_op_returnvalue = 254, |
133 |
140 |
spirv_op_typepipestorage = 322, |
spirv_op_typepipestorage = 322, |
|
... |
... |
u8 *ops_name[0xffff + 1] = { |
219 |
226 |
[spirv_op_logicalor] = "logical_or", |
[spirv_op_logicalor] = "logical_or", |
220 |
227 |
[spirv_op_logicaland] = "logical_and", |
[spirv_op_logicaland] = "logical_and", |
221 |
228 |
[spirv_op_select] = "select", |
[spirv_op_select] = "select", |
|
229 |
|
[spirv_op_iequal] = "iequal", |
222 |
230 |
[spirv_op_fordequal] = "ford_equal", |
[spirv_op_fordequal] = "ford_equal", |
223 |
231 |
[spirv_op_fordnotequal] = "ford_not_equal", |
[spirv_op_fordnotequal] = "ford_not_equal", |
224 |
232 |
[spirv_op_fordlessthan] = "ford_less_than", |
[spirv_op_fordlessthan] = "ford_less_than", |
|
... |
... |
u8 *ops_name[0xffff + 1] = { |
230 |
238 |
[spirv_op_label] = "label", |
[spirv_op_label] = "label", |
231 |
239 |
[spirv_op_branch] = "branch", |
[spirv_op_branch] = "branch", |
232 |
240 |
[spirv_op_branchconditional] = "branch_conditional", |
[spirv_op_branchconditional] = "branch_conditional", |
|
241 |
|
[spirv_op_switch] = "switch", |
233 |
242 |
[spirv_op_return] = "return", |
[spirv_op_return] = "return", |
234 |
243 |
[spirv_op_returnvalue] = "return_value", |
[spirv_op_returnvalue] = "return_value", |
235 |
244 |
[spirv_op_typepipestorage] = "type_pipe_storage", |
[spirv_op_typepipestorage] = "type_pipe_storage", |
|
... |
... |
static u8 *img_fmt_to_str(u32 w) |
1391 |
1400 |
{ |
{ |
1392 |
1401 |
switch (w) { |
switch (w) { |
1393 |
1402 |
case 0: |
case 0: |
1394 |
|
return "unkown"; |
|
|
1403 |
|
return "unknown_valid"; |
1395 |
1404 |
case 1: |
case 1: |
1396 |
1405 |
return "rgba32f"; |
return "rgba32f"; |
1397 |
1406 |
case 2: |
case 2: |
|
... |
... |
static u8 *img_fmt_to_str(u32 w) |
1471 |
1480 |
case 39: |
case 39: |
1472 |
1481 |
return "r8ui"; |
return "r8ui"; |
1473 |
1482 |
default: |
default: |
1474 |
|
return "unknown_image_format_code"; |
|
|
1483 |
|
return "unknown_invalid_image_format_code"; |
1475 |
1484 |
} |
} |
1476 |
1485 |
} |
} |
1477 |
1486 |
|
|
|
... |
... |
static u8 *access_qualifier_to_str(u32 w) |
1491 |
1500 |
|
|
1492 |
1501 |
static void op_typeimage_out(void) |
static void op_typeimage_out(void) |
1493 |
1502 |
{ |
{ |
1494 |
|
out_ind_id("%s id=%%%U sampled_type=%%%u dim=%s depth=%s arrayed=%s multisample=%s sampled=%s image_format=%s", 0, op_name, opds[0], opds[1], dim_to_str(opds[2]), depth_to_str(opds[3]), arrayed_to_str(opds[4]), multisample_to_str(opds[5]), sampled_to_str(opds[6]), img_fmt_to_str(opds[7])); |
|
|
1503 |
|
out_ind_id("%s id=%%%u sampled_type=%%%u dim=%s depth=%s arrayed=%s multisample=%s sampled=%s image_format=%s", 0, op_name, opds[0], opds[1], dim_to_str(opds[2]), depth_to_str(opds[3]), arrayed_to_str(opds[4]), multisample_to_str(opds[5]), sampled_to_str(opds[6]), img_fmt_to_str(opds[7])); |
1495 |
1504 |
if (op_ws_n > 9) /* have access qualifier */ |
if (op_ws_n > 9) /* have access qualifier */ |
1496 |
1505 |
out(" access_qualifier=%s\n", access_qualifier_to_str(opds[8])); |
out(" access_qualifier=%s\n", access_qualifier_to_str(opds[8])); |
1497 |
1506 |
else |
else |
|
... |
... |
static void op_specconstantop_out(void) |
1716 |
1725 |
|
|
1717 |
1726 |
static void op_variable_out(void) |
static void op_variable_out(void) |
1718 |
1727 |
{ |
{ |
1719 |
|
out_ind_id("%s id=%%%u pointer_type=%%%u storage_class=%s", 1, op_name, opds[1], opds[0], storage_class_to_str(opds[2])); |
|
|
1728 |
|
out_ind_id("%s pointer_id=%%%u type=%%%u storage_class=%s", 1, op_name, opds[1], opds[0], storage_class_to_str(opds[2])); |
1720 |
1729 |
|
|
1721 |
1730 |
if (op_ws_n > 4) { |
if (op_ws_n > 4) { |
1722 |
1731 |
out(" initializer=%%%u", opds[3]); |
out(" initializer=%%%u", opds[3]); |
|
... |
... |
static void layout_nonfuncdecls_out(void) |
1739 |
1748 |
break; |
break; |
1740 |
1749 |
/* types start -----------------------------------------------*/ |
/* types start -----------------------------------------------*/ |
1741 |
1750 |
case spirv_op_typevoid: |
case spirv_op_typevoid: |
1742 |
|
out_ind_id("%s id=%%%u\n", 0, op_name, opds[0]); |
|
|
1751 |
|
out_ind_id("%s %%%u\n", 0, op_name, opds[0]); |
1743 |
1752 |
break; |
break; |
1744 |
1753 |
case spirv_op_typebool: |
case spirv_op_typebool: |
1745 |
|
out_ind_id("%s id=%%%u\n", 0, op_name, opds[0]); |
|
|
1754 |
|
out_ind_id("%s %%%u\n", 0, op_name, opds[0]); |
1746 |
1755 |
break; |
break; |
1747 |
1756 |
case spirv_op_typeint: |
case spirv_op_typeint: |
1748 |
1757 |
out_ind_id("%s id=%%%u width=%u signedness=%s\n", 0, op_name, opds[0], opds[1], signedness_to_str(opds[2])); |
out_ind_id("%s id=%%%u width=%u signedness=%s\n", 0, op_name, opds[0], opds[1], signedness_to_str(opds[2])); |
|
... |
... |
static void layout_nonfuncdecls_out(void) |
1845 |
1854 |
op_specconstantop_out(); |
op_specconstantop_out(); |
1846 |
1855 |
break; |
break; |
1847 |
1856 |
/* constants end ---------------------------------------------*/ |
/* constants end ---------------------------------------------*/ |
|
1857 |
|
/* carefull, a spirv "variable" is a pointer */ |
1848 |
1858 |
case spirv_op_variable: |
case spirv_op_variable: |
1849 |
1859 |
op_variable_out(); |
op_variable_out(); |
1850 |
1860 |
break; |
break; |
|
... |
... |
static u8 *scope_to_str(u32 w) |
1917 |
1927 |
} |
} |
1918 |
1928 |
} |
} |
1919 |
1929 |
|
|
1920 |
|
#define flag_no_opd(val, str) \ |
|
|
1930 |
|
#define flag(val, str) \ |
1921 |
1931 |
if ((opds[i] & val) != 0) { \ |
if ((opds[i] & val) != 0) { \ |
1922 |
1932 |
if (!first) \ |
if (!first) \ |
1923 |
1933 |
out("|"); \ |
out("|"); \ |
1924 |
1934 |
out(str); \ |
out(str); \ |
1925 |
1935 |
first = false; \ |
first = false; \ |
1926 |
1936 |
} |
} |
1927 |
|
#define TMP_SZ 128 |
|
1928 |
|
/* return the idx of the next mem opd */ |
|
1929 |
|
static u16 mem_opd_out(u16 i) |
|
|
1937 |
|
static void mem_opds_out(u16 i) |
1930 |
1938 |
{ |
{ |
1931 |
|
u8 tmp[TMP_SZ]; |
|
1932 |
|
u16 additional_opds; |
|
1933 |
1939 |
bool first; |
bool first; |
|
1940 |
|
u16 additional_opds; |
1934 |
1941 |
|
|
1935 |
|
additional_opds = i + 1; |
|
|
1942 |
|
/*--------------------------------------------------------------------*/ |
|
1943 |
|
|
|
1944 |
|
if (opds[i] == 0) |
|
1945 |
|
return; |
|
1946 |
|
|
|
1947 |
|
out(" "); |
|
1948 |
|
out_cmts("/*memory_operands=*/"); |
1936 |
1949 |
|
|
1937 |
|
if (opds[i] == 0) { |
|
1938 |
|
out("none"); |
|
1939 |
|
return i + 1; |
|
1940 |
|
} |
|
1941 |
1950 |
|
|
1942 |
1951 |
first = true; |
first = true; |
1943 |
1952 |
|
|
1944 |
1953 |
/* order matters */ |
/* order matters */ |
1945 |
|
flag_no_opd(0x00000001, "volatile") |
|
|
1954 |
|
flag(0x00000001, "volatile") |
|
1955 |
|
flag(0x00000002, "aligned") |
|
1956 |
|
flag(0x00000004, "non_temporal") |
|
1957 |
|
flag(0x00000008, "make_pointer_available"); |
|
1958 |
|
flag(0x00000010, "make_pointer_visible"); |
|
1959 |
|
flag(0x00000020, "non_private_pointer") |
|
1960 |
|
flag(0xffffffe0, "unknown_memory_operand_flag(s)-->consider the following instruction operands as corrupted") |
|
1961 |
|
|
|
1962 |
|
/*--------------------------------------------------------------------*/ |
|
1963 |
|
|
|
1964 |
|
additional_opds = i + 1; |
1946 |
1965 |
|
|
1947 |
1966 |
if ((opds[i] & 0x00000002) != 0) { |
if ((opds[i] & 0x00000002) != 0) { |
1948 |
|
if (!first) |
|
1949 |
|
out("|"); |
|
1950 |
|
out("aligned"); |
|
1951 |
|
first = false; |
|
1952 |
|
snprintf(tmp, TMP_SZ, "(%u)", opds[additional_opds]); |
|
1953 |
|
out(tmp); |
|
|
1967 |
|
if (additional_opds > opds_last) { |
|
1968 |
|
out("\n"); |
|
1969 |
|
out_ind("error:memory operands:missing alignment\n"); |
|
1970 |
|
exit(1); |
|
1971 |
|
} |
|
1972 |
|
if (cmts) |
|
1973 |
|
out(" /*alignment=*/0x%x", opds[additional_opds]); |
|
1974 |
|
else |
|
1975 |
|
out(" 0x%x", opds[additional_opds]); |
1954 |
1976 |
++additional_opds; |
++additional_opds; |
1955 |
1977 |
} |
} |
1956 |
|
|
|
1957 |
|
flag_no_opd(0x00000004, "non_temporal") |
|
1958 |
|
|
|
1959 |
1978 |
if ((opds[i] & 0x00000008) != 0) { |
if ((opds[i] & 0x00000008) != 0) { |
1960 |
|
if (!first) |
|
1961 |
|
out("|"); |
|
1962 |
|
out("make_pointer_available"); |
|
1963 |
|
first = false; |
|
1964 |
|
snprintf(tmp, TMP_SZ, "(%s)", scope_to_str(opds[additional_opds])); |
|
1965 |
|
out(tmp); |
|
|
1979 |
|
if (additional_opds > opds_last) { |
|
1980 |
|
out("\n"); |
|
1981 |
|
out_ind("error:memory operands:missing make_pointer_available scope\n"); |
|
1982 |
|
exit(1); |
|
1983 |
|
} |
|
1984 |
|
if (cmts) |
|
1985 |
|
out(" /*make_pointer_available scope=*/%s", scope_to_str(opds[additional_opds])); |
|
1986 |
|
else |
|
1987 |
|
out(" %s", scope_to_str(opds[additional_opds])); |
1966 |
1988 |
++additional_opds; |
++additional_opds; |
1967 |
1989 |
} |
} |
1968 |
|
|
|
1969 |
1990 |
if ((opds[i] & 0x00000010) != 0) { |
if ((opds[i] & 0x00000010) != 0) { |
1970 |
|
if (!first) |
|
1971 |
|
out("|"); |
|
1972 |
|
out("make_pointer_visible"); |
|
1973 |
|
first = false; |
|
1974 |
|
snprintf(tmp, TMP_SZ, "(%s)", scope_to_str(opds[additional_opds])); |
|
1975 |
|
out(tmp); |
|
|
1991 |
|
if (additional_opds > opds_last) { |
|
1992 |
|
out("\n"); |
|
1993 |
|
out_ind("error:memory operands:missing make_pointer_visible scope\n"); |
|
1994 |
|
exit(1); |
|
1995 |
|
} |
|
1996 |
|
if (cmts) |
|
1997 |
|
out(" /*make_pointer_visible scope=*/%s", scope_to_str(opds[additional_opds])); |
|
1998 |
|
else |
|
1999 |
|
out(" %s", scope_to_str(opds[additional_opds])); |
1976 |
2000 |
++additional_opds; |
++additional_opds; |
1977 |
2001 |
} |
} |
1978 |
|
|
|
1979 |
|
flag_no_opd(0x00000010, "non_private_pointer") |
|
1980 |
|
|
|
1981 |
|
flag_no_opd(0xffffffe0, "unknown_memory_operand_flag(s)-->consider the following instruction operands as corrupted") |
|
1982 |
|
|
|
1983 |
|
return additional_opds; |
|
1984 |
2002 |
} |
} |
1985 |
2003 |
#undef flag_no_opd |
#undef flag_no_opd |
1986 |
|
#undef TMP_SZ |
|
1987 |
|
|
|
1988 |
|
/* will output the mem opds till the end of the instruction */ |
|
1989 |
|
static void mem_opds_out(u16 i) |
|
1990 |
|
{ |
|
1991 |
|
u16 mem_opd_idx; |
|
1992 |
|
|
|
1993 |
|
mem_opd_idx = 0; |
|
1994 |
|
out(" "); |
|
1995 |
|
out_cmts("/*memory_operands[%u]=*/", mem_opd_idx); |
|
1996 |
|
|
|
1997 |
|
loop { |
|
1998 |
|
i = mem_opd_out(i); |
|
1999 |
|
++mem_opd_idx; |
|
2000 |
|
|
|
2001 |
|
if (i > opds_last) |
|
2002 |
|
break; |
|
2003 |
|
} |
|
2004 |
|
} |
|
2005 |
2004 |
|
|
2006 |
2005 |
static void op_load_out(void) |
static void op_load_out(void) |
2007 |
2006 |
{ |
{ |
|
... |
... |
static void op_load_out(void) |
2011 |
2010 |
out("\n"); |
out("\n"); |
2012 |
2011 |
} |
} |
2013 |
2012 |
|
|
2014 |
|
static void op_vectorshuffle_out_depth(void) |
|
|
2013 |
|
static void op_vectorshuffle_out(void) |
2015 |
2014 |
{ |
{ |
2016 |
2015 |
u16 i; |
u16 i; |
2017 |
2016 |
|
|
|
... |
... |
static void op_vectorshuffle_out_depth(void) |
2034 |
2033 |
out("\n"); |
out("\n"); |
2035 |
2034 |
} |
} |
2036 |
2035 |
|
|
2037 |
|
static void op_compositeextract_out_depth(void) |
|
|
2036 |
|
static void op_compositeextract_out(void) |
2038 |
2037 |
{ |
{ |
2039 |
2038 |
u16 i; |
u16 i; |
2040 |
2039 |
|
|
|
... |
... |
static void op_compositeextract_out_depth(void) |
2053 |
2052 |
out("\n"); |
out("\n"); |
2054 |
2053 |
} |
} |
2055 |
2054 |
|
|
2056 |
|
static void op_compositeconstruct_out_depth(void) |
|
|
2055 |
|
static void op_compositeconstruct_out(void) |
2057 |
2056 |
{ |
{ |
2058 |
2057 |
u16 i; |
u16 i; |
2059 |
2058 |
|
|
|
... |
... |
static void op_compositeconstruct_out_depth(void) |
2072 |
2071 |
out("\n"); |
out("\n"); |
2073 |
2072 |
} |
} |
2074 |
2073 |
|
|
2075 |
|
static void op_store_out_depth(void) |
|
|
2074 |
|
static void op_store_out(void) |
2076 |
2075 |
{ |
{ |
2077 |
2076 |
out_ind("%s pointer=%%%u object=%%%u", op_name, opds[0], opds[1]); |
out_ind("%s pointer=%%%u object=%%%u", op_name, opds[0], opds[1]); |
2078 |
2077 |
if (op_ws_n > 3) |
if (op_ws_n > 3) |
|
... |
... |
static void op_store_out_depth(void) |
2080 |
2079 |
out("\n"); |
out("\n"); |
2081 |
2080 |
} |
} |
2082 |
2081 |
|
|
2083 |
|
static void op_imagesampleimplicitlod_out_depth(void) |
|
|
2082 |
|
static void op_imagesampleimplicitlod_out(void) |
2084 |
2083 |
{ |
{ |
2085 |
2084 |
u16 i; |
u16 i; |
2086 |
2085 |
|
|
|
... |
... |
static void op_imagesampleexplicitlod_out(void) |
2128 |
2127 |
out("\n"); |
out("\n"); |
2129 |
2128 |
} |
} |
2130 |
2129 |
|
|
2131 |
|
static void op_functioncall_out_depth(void) |
|
|
2130 |
|
static void op_functioncall_out(void) |
2132 |
2131 |
{ |
{ |
2133 |
2132 |
u16 i; |
u16 i; |
2134 |
2133 |
|
|
|
... |
... |
static void op_functioncall_out_depth(void) |
2147 |
2146 |
out("\n"); |
out("\n"); |
2148 |
2147 |
} |
} |
2149 |
2148 |
|
|
2150 |
|
static void op_branchconditional_out_depth(void) |
|
|
2149 |
|
static void op_branchconditional_out(void) |
2151 |
2150 |
{ |
{ |
2152 |
2151 |
u16 i; |
u16 i; |
2153 |
2152 |
|
|
|
... |
... |
static void op_extinst_out(void) |
2199 |
2198 |
out("\n"); |
out("\n"); |
2200 |
2199 |
} |
} |
2201 |
2200 |
|
|
2202 |
|
static void op_accesschain_out_depth(void) |
|
|
2201 |
|
static void op_accesschain_out(void) |
2203 |
2202 |
{ |
{ |
2204 |
2203 |
u16 i; |
u16 i; |
2205 |
2204 |
|
|
|
... |
... |
static void op_accesschain_out_depth(void) |
2218 |
2217 |
out("\n"); |
out("\n"); |
2219 |
2218 |
} |
} |
2220 |
2219 |
|
|
2221 |
|
static void op_compositeinsert_out_depth(void) |
|
|
2220 |
|
static void op_compositeinsert_out(void) |
2222 |
2221 |
{ |
{ |
2223 |
2222 |
u16 i; |
u16 i; |
2224 |
2223 |
|
|
|
... |
... |
static void op_compositeinsert_out_depth(void) |
2237 |
2236 |
out("\n"); |
out("\n"); |
2238 |
2237 |
} |
} |
2239 |
2238 |
|
|
2240 |
|
static void op_phi_out_depth(void) |
|
|
2239 |
|
static void op_phi_out(void) |
2241 |
2240 |
{ |
{ |
2242 |
2241 |
u16 i; |
u16 i; |
2243 |
2242 |
|
|
|
... |
... |
static void op_phi_out_depth(void) |
2248 |
2247 |
if (i > opds_last) |
if (i > opds_last) |
2249 |
2248 |
break; |
break; |
2250 |
2249 |
if (cmts) |
if (cmts) |
2251 |
|
out( "/*variables[%u]=*/%%%u /*parents[%u]=*/%%%u", (i - 2) / 2, opds[i], (i - 2) / 2, opds[i + 1]); |
|
|
2250 |
|
out(" /*variables[%u]=*/%%%u /*parents[%u]=*/%%%u", (i - 2) / 2, opds[i], (i - 2) / 2, opds[i + 1]); |
2252 |
2251 |
else |
else |
2253 |
|
out( "%%%u %%%u", opds[i], opds[i + 1]); |
|
|
2252 |
|
out(" %%%u %%%u", opds[i], opds[i + 1]); |
|
2253 |
|
i += 2; |
|
2254 |
|
} |
|
2255 |
|
out("\n"); |
|
2256 |
|
} |
|
2257 |
|
|
|
2258 |
|
static void op_switch_out(void) |
|
2259 |
|
{ |
|
2260 |
|
u16 i; |
|
2261 |
|
|
|
2262 |
|
out_ind("%s selector=%%%u default=%%%u", op_name, opds[0], opds[1]); |
|
2263 |
|
|
|
2264 |
|
i = 2; |
|
2265 |
|
loop { |
|
2266 |
|
if (i > opds_last) |
|
2267 |
|
break; |
|
2268 |
|
if (cmts) |
|
2269 |
|
out(" /*target[%u].literal=*/0x%08x /*target[%u].label_id=*/%%%u", (i - 2) / 2, opds[i], (i - 2) / 2, opds[i + 1]); |
|
2270 |
|
else |
|
2271 |
|
out(" 0x%08x %%%u", opds[i], opds[i + 1]); |
2254 |
2272 |
i += 2; |
i += 2; |
2255 |
2273 |
} |
} |
2256 |
2274 |
out("\n"); |
out("\n"); |
|
... |
... |
static void layout_funcs_out(void) |
2278 |
2296 |
out_ind("%s %%%u line=%u column=%u\n", op_name, opds[0], opds[1], opds[2]); |
out_ind("%s %%%u line=%u column=%u\n", op_name, opds[0], opds[1], opds[2]); |
2279 |
2297 |
break; |
break; |
2280 |
2298 |
case spirv_op_function: |
case spirv_op_function: |
2281 |
|
out_ind_id("%s id=%%%u return_type=%%%u function_control=%s function_type=%%%u\n", 1, op_name, opds[1], opds[0], function_control_to_str(opds[2]), opds[3]); |
|
|
2299 |
|
out_ind_id("%s id=%%%u return_type=%%%u control=%s type=%%%u\n", 1, op_name, opds[1], opds[0], function_control_to_str(opds[2]), opds[3]); |
2282 |
2300 |
func_has_blk = false; |
func_has_blk = false; |
2283 |
2301 |
++depth; /* start of a blk */ |
++depth; /* start of a blk */ |
2284 |
2302 |
break; |
break; |
|
... |
... |
static void layout_funcs_out(void) |
2303 |
2321 |
op_load_out(); |
op_load_out(); |
2304 |
2322 |
break; |
break; |
2305 |
2323 |
case spirv_op_vectorshuffle: |
case spirv_op_vectorshuffle: |
2306 |
|
op_vectorshuffle_out_depth(); |
|
|
2324 |
|
op_vectorshuffle_out(); |
2307 |
2325 |
break; |
break; |
2308 |
2326 |
case spirv_op_compositeextract: |
case spirv_op_compositeextract: |
2309 |
|
op_compositeextract_out_depth(); |
|
|
2327 |
|
op_compositeextract_out(); |
2310 |
2328 |
break; |
break; |
2311 |
2329 |
case spirv_op_compositeconstruct: |
case spirv_op_compositeconstruct: |
2312 |
|
op_compositeconstruct_out_depth(); |
|
|
2330 |
|
op_compositeconstruct_out(); |
2313 |
2331 |
break; |
break; |
2314 |
2332 |
case spirv_op_store: |
case spirv_op_store: |
2315 |
|
op_store_out_depth(); |
|
|
2333 |
|
op_store_out(); |
2316 |
2334 |
break; |
break; |
2317 |
2335 |
case spirv_op_return: |
case spirv_op_return: |
2318 |
2336 |
out_ind("%s\n", op_name); |
out_ind("%s\n", op_name); |
2319 |
2337 |
--depth; /* end of blk */ |
--depth; /* end of blk */ |
2320 |
2338 |
break; |
break; |
2321 |
2339 |
case spirv_op_imagesampleimplicitlod: |
case spirv_op_imagesampleimplicitlod: |
2322 |
|
op_imagesampleimplicitlod_out_depth(); |
|
|
2340 |
|
op_imagesampleimplicitlod_out(); |
2323 |
2341 |
break; |
break; |
2324 |
2342 |
case spirv_op_fmul: |
case spirv_op_fmul: |
2325 |
2343 |
if (cmts) |
if (cmts) |
|
... |
... |
static void layout_funcs_out(void) |
2331 |
2349 |
op_variable_out(); |
op_variable_out(); |
2332 |
2350 |
break; |
break; |
2333 |
2351 |
case spirv_op_functioncall: |
case spirv_op_functioncall: |
2334 |
|
op_functioncall_out_depth(); |
|
|
2352 |
|
op_functioncall_out(); |
2335 |
2353 |
break; |
break; |
2336 |
2354 |
case spirv_op_fordlessthanequal: |
case spirv_op_fordlessthanequal: |
2337 |
2355 |
if (cmts) |
if (cmts) |
|
... |
... |
static void layout_funcs_out(void) |
2340 |
2358 |
out_ind_id("%s id=%%%u type=%%%u %%%u %%%u\n", 1, op_name, opds[1], opds[0], opds[2], opds[3]); |
out_ind_id("%s id=%%%u type=%%%u %%%u %%%u\n", 1, op_name, opds[1], opds[0], opds[2], opds[3]); |
2341 |
2359 |
break; |
break; |
2342 |
2360 |
case spirv_op_selectionmerge: |
case spirv_op_selectionmerge: |
2343 |
|
out_ind("%s merge_block=%%%u section_control=%s\n", op_name, opds[0], selection_control_to_str(opds[1])); |
|
|
2361 |
|
out_ind("%s block=%%%u selection_control=%s\n", op_name, opds[0], selection_control_to_str(opds[1])); |
2344 |
2362 |
break; |
break; |
2345 |
2363 |
case spirv_op_branchconditional: |
case spirv_op_branchconditional: |
2346 |
|
op_branchconditional_out_depth(); |
|
|
2364 |
|
op_branchconditional_out(); |
2347 |
2365 |
depth--; /* end of blk */ |
depth--; /* end of blk */ |
2348 |
2366 |
break; |
break; |
2349 |
2367 |
case spirv_op_fdiv: |
case spirv_op_fdiv: |
|
... |
... |
static void layout_funcs_out(void) |
2370 |
2388 |
out_ind("%s value=%%%u\n", op_name, opds[0]); |
out_ind("%s value=%%%u\n", op_name, opds[0]); |
2371 |
2389 |
break; |
break; |
2372 |
2390 |
case spirv_op_accesschain: |
case spirv_op_accesschain: |
2373 |
|
op_accesschain_out_depth(); |
|
|
2391 |
|
op_accesschain_out(); |
2374 |
2392 |
break; |
break; |
2375 |
2393 |
case spirv_op_compositeinsert: |
case spirv_op_compositeinsert: |
2376 |
|
op_compositeinsert_out_depth(); |
|
|
2394 |
|
op_compositeinsert_out(); |
2377 |
2395 |
break; |
break; |
2378 |
2396 |
case spirv_op_sampledimage: |
case spirv_op_sampledimage: |
2379 |
2397 |
out_ind_id("%s id=%%%u type=%%%u image=%%%u sampler=%%%u\n", 1, op_name, opds[1], opds[0], opds[2], opds[3]); |
out_ind_id("%s id=%%%u type=%%%u image=%%%u sampler=%%%u\n", 1, op_name, opds[1], opds[0], opds[2], opds[3]); |
|
... |
... |
static void layout_funcs_out(void) |
2403 |
2421 |
out_ind_id("%s id=%%%u type=%%%u %%%u %%%u\n", 1, op_name, opds[1], opds[0], opds[2], opds[3]); |
out_ind_id("%s id=%%%u type=%%%u %%%u %%%u\n", 1, op_name, opds[1], opds[0], opds[2], opds[3]); |
2404 |
2422 |
break; |
break; |
2405 |
2423 |
case spirv_op_phi: |
case spirv_op_phi: |
2406 |
|
op_phi_out_depth(); |
|
|
2424 |
|
op_phi_out(); |
2407 |
2425 |
break; |
break; |
2408 |
2426 |
case spirv_op_fordgreaterthan: |
case spirv_op_fordgreaterthan: |
2409 |
2427 |
if (cmts) |
if (cmts) |
|
... |
... |
static void layout_funcs_out(void) |
2459 |
2477 |
else |
else |
2460 |
2478 |
out_ind_id("%s id=%%%u type=%%%u %%%u %%%u\n", 1, op_name, opds[1], opds[0], opds[2], opds[3]); |
out_ind_id("%s id=%%%u type=%%%u %%%u %%%u\n", 1, op_name, opds[1], opds[0], opds[2], opds[3]); |
2461 |
2479 |
break; |
break; |
|
2480 |
|
case spirv_op_iequal: |
|
2481 |
|
if (cmts) |
|
2482 |
|
out_ind_id("%s id=%%%u type=%%%u /*operands[0]=*/%%%u /*operands[1]=*/%%%u\n", 1, op_name, opds[1], opds[0], opds[2], opds[3]); |
|
2483 |
|
else |
|
2484 |
|
out_ind_id("%s id=%%%u type=%%%u %%%u %%%u\n", 1, op_name, opds[1], opds[0], opds[2], opds[3]); |
|
2485 |
|
break; |
|
2486 |
|
case spirv_op_switch: |
|
2487 |
|
op_switch_out(); |
|
2488 |
|
break; |
2462 |
2489 |
/* TODO: MORE! */ |
/* TODO: MORE! */ |
2463 |
2490 |
default: |
default: |
2464 |
2491 |
section_breaking_op_num = op_num; |
section_breaking_op_num = op_num; |