1 /*
2 * Copyright © 2020 Google, Inc.
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 /* This file should not be built directly. Instead, it is included in the C
25 * file generated by isaspec/decode.py and built along with it.
26 */
27
28 #include <assert.h>
29 #include <inttypes.h>
30 #include <stdbool.h>
31 #include <stdint.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35
36 #include "util/bitset.h"
37 #include "util/compiler.h"
38 #include "util/half_float.h"
39 #include "util/hash_table.h"
40 #include "util/ralloc.h"
41 #include "util/u_debug.h"
42 #include "util/u_math.h"
43
44 #include "isa.h"
45
46 /**
47 * The set of leaf node bitsets in the bitset hiearchy which defines all
48 * the possible instructions.
49 *
50 * TODO maybe we want to pass this in as parameter so this same decoder
51 * can work with multiple different instruction sets.
52 */
53 extern const struct isa_bitset *__instruction[];
54
55 struct decode_state;
56
57 /**
58 * Decode scope. When parsing a field that is itself a bitset, we push a
59 * new scope to the stack. A nested bitset is allowed to resolve fields
60 * from an enclosing scope (needed, for example, to decode src register
61 * bitsets, where half/fullness is determined by fields outset if bitset
62 * in the instruction containing the bitset.
63 *
64 * But the field being resolved could be a derived field, or different
65 * depending on an override at a higher level of the stack, requiring
66 * expression evaluation which could in turn reference variables which
67 * triggers a recursive field lookup. But those lookups should not start
68 * from the top of the stack, but instead the current stack level. This
69 * prevents a field from accidentally resolving to different values
70 * depending on the starting point of the lookup. (Not only causing
71 * confusion, but this is behavior we don't want to depend on if we
72 * wanted to optimize things by caching field lookup results.)
73 */
74 struct decode_scope {
75 /**
76 * Enclosing scope
77 */
78 struct decode_scope *parent;
79
80 /**
81 * Current bitset value being decoded
82 */
83 bitmask_t val;
84
85 /**
86 * Current bitset.
87 */
88 const struct isa_bitset *bitset;
89
90 /**
91 * Field name remapping.
92 */
93 const struct isa_field_params *params;
94
95 /**
96 * Pointer back to decode state, for convenience.
97 */
98 struct decode_state *state;
99
100 /**
101 * Cache expression evaluation results. Expressions for overrides can
102 * be repeatedly evaluated for each field being resolved. And each
103 * field reference to a derived field (potentially from another expr)
104 * would require re-evaluation. But for a given scope, each evaluation
105 * of an expression gives the same result. So we can cache to speed
106 * things up.
107 *
108 * TODO we could maybe be clever and assign a unique idx to each expr
109 * and use a direct lookup table? Would be a bit more clever if it was
110 * smart enough to allow unrelated expressions that are never involved
111 * in a given scope to have overlapping cache lookup idx's.
112 */
113 struct hash_table *cache;
114 };
115
116 /**
117 * Current decode state
118 */
119 struct decode_state {
120 const struct isa_decode_options *options;
121
122 struct isa_print_state print;
123
124 /**
125 * Current instruction being decoded:
126 */
127 unsigned n;
128
129 /**
130 * Number of instructions being decoded
131 */
132 unsigned num_instr;
133
134 /**
135 * Bitset of instructions that are branch targets (if options->branch_labels
136 * is enabled)
137 */
138 BITSET_WORD *branch_targets;
139
140 /**
141 * Bitset of instructions that are call targets.
142 */
143 BITSET_WORD *call_targets;
144
145 /**
146 * Bitset of instructions that are entrypoints.
147 */
148 BITSET_WORD *entrypoints;
149
150 /**
151 * We allow a limited amount of expression evaluation recursion, but
152 * not recursive evaluation of any given expression, to prevent infinite
153 * recursion.
154 */
155 int expr_sp;
156 isa_expr_t expr_stack[8];
157
158 /**
159 * Current topmost/innermost level of scope used for decoding fields,
160 * including derived fields which may in turn rely on decoding other
161 * fields, potentially from a lower/out level in the stack.
162 */
163 struct decode_scope *scope;
164
165 /* Next entrypoint to be decoded. */
166 struct isa_entrypoint *next_entrypoint;
167
168 /* Sentinel value after the last entrypoint in the array. */
169 struct isa_entrypoint *end_entrypoint;
170
171 /**
172 * A small fixed upper limit on # of decode errors to capture per-
173 * instruction seems reasonable.
174 */
175 unsigned num_errors;
176 char *errors[4];
177 };
178
179 void
isa_print(struct isa_print_state * state,const char * fmt,...)180 isa_print(struct isa_print_state *state, const char *fmt, ...)
181 {
182 char *buffer;
183 va_list args;
184 int ret;
185
186 va_start(args, fmt);
187 ret = vasprintf(&buffer, fmt, args);
188 va_end(args);
189
190 if (ret != -1) {
191 const size_t len = strlen(buffer);
192
193 for (size_t i = 0; i < len; i++) {
194 const char c = buffer[i];
195
196 fputc(c, state->out);
197 state->line_column++;
198
199 if (c == '\n') {
200 state->line_column = 0;
201 }
202 }
203
204 free(buffer);
205
206 return;
207 }
208 }
209
210 static void display(struct decode_scope *scope);
211 static void decode_error(struct decode_state *state, const char *fmt, ...) _util_printf_format(2,3);
212
213 static void
decode_error(struct decode_state * state,const char * fmt,...)214 decode_error(struct decode_state *state, const char *fmt, ...)
215 {
216 if (!state->options->show_errors) {
217 return;
218 }
219
220 if (state->num_errors == ARRAY_SIZE(state->errors)) {
221 /* too many errors, bail */
222 return;
223 }
224
225 va_list ap;
226 va_start(ap, fmt);
227 vasprintf(&state->errors[state->num_errors++], fmt, ap);
228 va_end(ap);
229 }
230
231 static unsigned
flush_errors(struct decode_state * state)232 flush_errors(struct decode_state *state)
233 {
234 unsigned num_errors = state->num_errors;
235 if (num_errors > 0)
236 isa_print(&state->print, "\t; ");
237 for (unsigned i = 0; i < num_errors; i++) {
238 isa_print(&state->print, "%s%s", (i > 0) ? ", " : "", state->errors[i]);
239 free(state->errors[i]);
240 }
241 state->num_errors = 0;
242 return num_errors;
243 }
244
245
246 static bool
push_expr(struct decode_state * state,isa_expr_t expr)247 push_expr(struct decode_state *state, isa_expr_t expr)
248 {
249 for (int i = state->expr_sp - 1; i > 0; i--) {
250 if (state->expr_stack[i] == expr) {
251 return false;
252 }
253 }
254 state->expr_stack[state->expr_sp++] = expr;
255 return true;
256 }
257
258 static void
pop_expr(struct decode_state * state)259 pop_expr(struct decode_state *state)
260 {
261 assert(state->expr_sp > 0);
262 state->expr_sp--;
263 }
264
265 static struct decode_scope *
push_scope(struct decode_state * state,const struct isa_bitset * bitset,bitmask_t val)266 push_scope(struct decode_state *state, const struct isa_bitset *bitset, bitmask_t val)
267 {
268 struct decode_scope *scope = rzalloc_size(state, sizeof(*scope));
269
270 BITSET_COPY(scope->val.bitset, val.bitset);
271 scope->bitset = bitset;
272 scope->parent = state->scope;
273 scope->state = state;
274
275 state->scope = scope;
276
277 return scope;
278 }
279
280 static void
pop_scope(struct decode_scope * scope)281 pop_scope(struct decode_scope *scope)
282 {
283 assert(scope->state->scope == scope); /* must be top of stack */
284
285 scope->state->scope = scope->parent;
286 ralloc_free(scope);
287 }
288
289 /**
290 * Evaluate an expression, returning it's resulting value
291 */
292 static uint64_t
evaluate_expr(struct decode_scope * scope,isa_expr_t expr)293 evaluate_expr(struct decode_scope *scope, isa_expr_t expr)
294 {
295 if (scope->cache) {
296 struct hash_entry *entry = _mesa_hash_table_search(scope->cache, expr);
297 if (entry) {
298 return *(uint64_t *)entry->data;
299 }
300 } else {
301 scope->cache = _mesa_pointer_hash_table_create(scope);
302 }
303
304 if (!push_expr(scope->state, expr))
305 return 0;
306
307 uint64_t ret = expr(scope);
308
309 pop_expr(scope->state);
310
311 uint64_t *retp = ralloc_size(scope->cache, sizeof(*retp));
312 *retp = ret;
313 _mesa_hash_table_insert(scope->cache, expr, retp);
314
315 return ret;
316 }
317
318 /**
319 * Find the bitset in NULL terminated bitset hiearchy root table which
320 * matches against 'val'
321 */
322 static const struct isa_bitset *
find_bitset(struct decode_state * state,const struct isa_bitset ** bitsets,bitmask_t val)323 find_bitset(struct decode_state *state, const struct isa_bitset **bitsets,
324 bitmask_t val)
325 {
326 const struct isa_bitset *match = NULL;
327 for (int n = 0; bitsets[n]; n++) {
328 if (state->options->gpu_id > bitsets[n]->gen.max)
329 continue;
330 if (state->options->gpu_id < bitsets[n]->gen.min)
331 continue;
332
333 // m = (val & bitsets[n]->mask) & ~bitsets[n]->dontcare;
334 bitmask_t m = { 0 };
335 bitmask_t not_dontcare;
336
337 BITSET_AND(m.bitset, val.bitset, bitsets[n]->mask.bitset);
338
339 BITSET_COPY(not_dontcare.bitset, bitsets[n]->dontcare.bitset);
340 BITSET_NOT(not_dontcare.bitset);
341
342 BITSET_AND(m.bitset, m.bitset, not_dontcare.bitset);
343
344 if (!BITSET_EQUAL(m.bitset, bitsets[n]->match.bitset)) {
345 continue;
346 }
347
348 /* We should only have exactly one match
349 *
350 * TODO more complete/formal way to validate that any given
351 * bit pattern will only have a single match?
352 */
353 if (match) {
354 decode_error(state, "bitset conflict: %s vs %s", match->name,
355 bitsets[n]->name);
356 return NULL;
357 }
358
359 match = bitsets[n];
360 }
361
362 if (match) {
363 bitmask_t m = { 0 };
364 BITSET_AND(m.bitset, match->dontcare.bitset, val.bitset);
365
366 if (BITSET_COUNT(m.bitset)) {
367 decode_error(state, "dontcare bits in %s: %"BITSET_FORMAT,
368 match->name, BITSET_VALUE(m.bitset));
369 }
370 }
371
372 return match;
373 }
374
375 static const struct isa_field *
find_field(struct decode_scope * scope,const struct isa_bitset * bitset,const char * name,size_t name_len)376 find_field(struct decode_scope *scope, const struct isa_bitset *bitset,
377 const char *name, size_t name_len)
378 {
379 for (unsigned i = 0; i < bitset->num_cases; i++) {
380 const struct isa_case *c = bitset->cases[i];
381
382 if (c->expr) {
383 struct decode_state *state = scope->state;
384
385 /* When resolving a field for evaluating an expression,
386 * temporarily assume the expression evaluates to true.
387 * This allows <override/>'s to speculatively refer to
388 * fields defined within the override:
389 */
390 isa_expr_t cur_expr = NULL;
391 if (state->expr_sp > 0)
392 cur_expr = state->expr_stack[state->expr_sp - 1];
393 if ((cur_expr != c->expr) && !evaluate_expr(scope, c->expr))
394 continue;
395 }
396
397 for (unsigned i = 0; i < c->num_fields; i++) {
398 if (!strncmp(name, c->fields[i].name, name_len) &&
399 (c->fields[i].name[name_len] == '\0')) {
400 return &c->fields[i];
401 }
402 }
403 }
404
405 if (bitset->parent) {
406 const struct isa_field *f = find_field(scope, bitset->parent, name, name_len);
407 if (f) {
408 return f;
409 }
410 }
411
412 return NULL;
413 }
414
415 static bitmask_t
extract_field(struct decode_scope * scope,const struct isa_field * field)416 extract_field(struct decode_scope *scope, const struct isa_field *field)
417 {
418 bitmask_t val, mask;
419
420 BITSET_COPY(val.bitset, scope->val.bitset);
421 BITSET_ZERO(mask.bitset);
422
423 BITSET_SET_RANGE(mask.bitset, field->low, field->high);
424 BITSET_AND(val.bitset, val.bitset, mask.bitset);
425 BITSET_SHR(val.bitset, field->low);
426
427 return val;
428 }
429
430 /**
431 * Find the display template for a given bitset, recursively searching
432 * parents in the bitset hierarchy.
433 */
434 static const char *
find_display(struct decode_scope * scope,const struct isa_bitset * bitset)435 find_display(struct decode_scope *scope, const struct isa_bitset *bitset)
436 {
437 for (unsigned i = 0; i < bitset->num_cases; i++) {
438 const struct isa_case *c = bitset->cases[i];
439 if (c->expr && !evaluate_expr(scope, c->expr))
440 continue;
441 /* since this is the chosen case, it seems like a good place
442 * to check asserted bits:
443 */
444 for (unsigned j = 0; j < c->num_fields; j++) {
445 if (c->fields[j].type == TYPE_ASSERT) {
446 const struct isa_field *f = &c->fields[j];
447 bitmask_t val;
448
449 val = extract_field(scope, f);
450 if (!BITSET_EQUAL(val.bitset, f->val.bitset)) {
451 decode_error(scope->state, "WARNING: unexpected "
452 "bits[%u:%u] in %s: %"BITSET_FORMAT" vs %"BITSET_FORMAT,
453 f->low, f->high, bitset->name,
454 BITSET_VALUE(val.bitset), BITSET_VALUE(f->val.bitset));
455 }
456 }
457 }
458 if (!c->display)
459 continue;
460 return c->display;
461 }
462
463 /**
464 * If we didn't find something check up the bitset hierarchy.
465 */
466 if (bitset->parent) {
467 return find_display(scope, bitset->parent);
468 }
469
470 return NULL;
471 }
472
473 /**
474 * Decode a field that is itself another bitset type
475 */
476 static void
display_bitset_field(struct decode_scope * scope,const struct isa_field * field,bitmask_t val)477 display_bitset_field(struct decode_scope *scope, const struct isa_field *field, bitmask_t val)
478 {
479 const struct isa_bitset *b = find_bitset(scope->state, field->bitsets, val);
480 if (!b) {
481 decode_error(scope->state, "no match: FIELD: '%s.%s': %"BITSET_FORMAT,
482 scope->bitset->name, field->name, BITSET_VALUE(val.bitset));
483 return;
484 }
485
486 struct decode_scope *nested_scope =
487 push_scope(scope->state, b, val);
488 nested_scope->params = field->params;
489 display(nested_scope);
490 pop_scope(nested_scope);
491 }
492
493 static void
display_enum_field(struct decode_scope * scope,const struct isa_field * field,bitmask_t val)494 display_enum_field(struct decode_scope *scope, const struct isa_field *field, bitmask_t val)
495 {
496 const struct isa_enum *e = field->enums;
497 const uint64_t ui = bitmask_to_uint64_t(val);
498
499 for (unsigned i = 0; i < e->num_values; i++) {
500 if (e->values[i].val == ui) {
501 isa_print(&scope->state->print, "%s", e->values[i].display);
502 return;
503 }
504 }
505
506 isa_print(&scope->state->print, "%u", (unsigned)ui);
507 }
508
509 static const struct isa_field *
resolve_field(struct decode_scope * scope,const char * field_name,size_t field_name_len,bitmask_t * valp)510 resolve_field(struct decode_scope *scope, const char *field_name, size_t field_name_len, bitmask_t *valp)
511 {
512 if (!scope) {
513 /* We've reached the bottom of the stack! */
514 return NULL;
515 }
516
517 const struct isa_field *field =
518 find_field(scope, scope->bitset, field_name, field_name_len);
519
520 if (!field && scope->params) {
521 for (unsigned i = 0; i < scope->params->num_params; i++) {
522 if (!strncmp(field_name, scope->params->params[i].as, field_name_len) &&
523 (scope->params->params[i].as[field_name_len] == '\0')) {
524 const char *param_name = scope->params->params[i].name;
525 return resolve_field(scope->parent, param_name, strlen(param_name), valp);
526 }
527 }
528 }
529
530 if (!field) {
531 return NULL;
532 }
533
534 /* extract out raw field value: */
535 if (field->expr) {
536 uint64_t val = evaluate_expr(scope, field->expr);
537
538 *valp = uint64_t_to_bitmask(val);
539 } else {
540 *valp = extract_field(scope, field);
541 }
542
543 return field;
544 }
545
546 /* This is also used from generated expr functions */
547 uint64_t
isa_decode_field(struct decode_scope * scope,const char * field_name)548 isa_decode_field(struct decode_scope *scope, const char *field_name)
549 {
550 bitmask_t val;
551 const struct isa_field *field = resolve_field(scope, field_name, strlen(field_name), &val);
552 if (!field) {
553 decode_error(scope->state, "no field '%s'", field_name);
554 return 0;
555 }
556
557 return bitmask_to_uint64_t(val);
558 }
559
560 uint32_t
isa_get_gpu_id(struct decode_scope * scope)561 isa_get_gpu_id(struct decode_scope *scope)
562 {
563 return scope->state->options->gpu_id;
564 }
565
566 static void
display_field(struct decode_scope * scope,const char * field_name)567 display_field(struct decode_scope *scope, const char *field_name)
568 {
569 const struct isa_decode_options *options = scope->state->options;
570 struct decode_state *state = scope->state;
571 struct isa_print_state *print = &state->print;
572 size_t field_name_len = strlen(field_name);
573 int num_align = 0;
574
575 /* alignment handling */
576 const char *align = strstr(field_name, ":align=");
577
578 if (align) {
579 const char *value = strstr(align, "=") + 1;
580
581 field_name_len = align - field_name;
582 num_align = atoi(value);
583 }
584
585 /* Special case ':algin=' should only do alignment */
586 if (field_name == align) {
587 while (scope->state->print.line_column < num_align)
588 isa_print(print, " ");
589
590 return;
591 }
592
593 /* Special case 'NAME' maps to instruction/bitset name: */
594 if (!strncmp("NAME", field_name, field_name_len)) {
595 if (options->field_cb) {
596 options->field_cb(options->cbdata, field_name, &(struct isa_decode_value){
597 .str = scope->bitset->name,
598 });
599 }
600
601 while (scope->state->print.line_column < num_align)
602 isa_print(print, " ");
603
604 isa_print(print, "%s", scope->bitset->name);
605
606 return;
607 }
608
609 bitmask_t v;
610 const struct isa_field *field = resolve_field(scope, field_name, field_name_len, &v);
611 if (!field) {
612 decode_error(scope->state, "no field '%.*s'", (int)field_name_len, field_name);
613 return;
614 }
615
616 uint64_t val = bitmask_to_uint64_t(v);
617
618 if (options->field_cb) {
619 options->field_cb(options->cbdata, field_name, &(struct isa_decode_value){
620 .num = val,
621 });
622 }
623
624 unsigned width = 1 + field->high - field->low;
625
626 while (scope->state->print.line_column < num_align)
627 isa_print(print, " ");
628
629 switch (field->type) {
630 /* Basic types: */
631 case TYPE_BRANCH:
632 case TYPE_ABSBRANCH:
633 if (scope->state->options->branch_labels) {
634 int offset;
635 if (field->type == TYPE_BRANCH) {
636 offset = util_sign_extend(val, width) + scope->state->n;
637 } else {
638 offset = val;
639 }
640 if (offset < scope->state->num_instr) {
641 if (field->call) {
642 isa_print(print, "fxn%d", offset);
643 BITSET_SET(scope->state->call_targets, offset);
644 } else {
645 isa_print(print, "l%d", offset);
646 BITSET_SET(scope->state->branch_targets, offset);
647 }
648 break;
649 }
650 }
651 FALLTHROUGH;
652 case TYPE_INT:
653 isa_print(print, "%"PRId64, util_sign_extend(val, width));
654 break;
655 case TYPE_UINT:
656 isa_print(print, "%"PRIu64, val);
657 break;
658 case TYPE_HEX:
659 // TODO format # of digits based on field width?
660 isa_print(print, "%"PRIx64, val);
661 break;
662 case TYPE_OFFSET:
663 if (val != 0) {
664 isa_print(print, "%+"PRId64, util_sign_extend(val, width));
665 }
666 break;
667 case TYPE_UOFFSET:
668 if (val != 0) {
669 isa_print(print, "+%"PRIu64, val);
670 }
671 break;
672 case TYPE_FLOAT:
673 if (width == 16) {
674 isa_print(print, "%f", _mesa_half_to_float(val));
675 } else {
676 assert(width == 32);
677 isa_print(print, "%f", uif(val));
678 }
679 break;
680 case TYPE_BOOL:
681 if (field->display) {
682 if (val) {
683 isa_print(print, "%s", field->display);
684 }
685 } else {
686 isa_print(print, "%u", (unsigned)val);
687 }
688 break;
689 case TYPE_BOOL_INV: {
690 if (field->display) {
691 if (!val) {
692 isa_print(print, "%s", field->display);
693 }
694 } else {
695 isa_print(print, "%u", (unsigned)!val);
696 }
697 break;
698 }
699 case TYPE_ENUM:
700 display_enum_field(scope, field, v);
701 break;
702 case TYPE_CUSTOM:
703 /* The user has to provide a field_print_cb, but this can
704 * still be NULL during the branch offset pre-pass.
705 */
706 if (state->options->field_print_cb) {
707 state->options->field_print_cb(print, field_name, val);
708 }
709 break;
710
711 case TYPE_ASSERT:
712 /* assert fields are not for display */
713 assert(0);
714 break;
715
716 /* For fields that are decoded with another bitset hierarchy: */
717 case TYPE_BITSET:
718 display_bitset_field(scope, field, v);
719 break;
720 default:
721 decode_error(scope->state, "Bad field type: %d (%s)",
722 field->type, field->name);
723 }
724 }
725
726 static void
display(struct decode_scope * scope)727 display(struct decode_scope *scope)
728 {
729 const struct isa_bitset *bitset = scope->bitset;
730 const char *display = find_display(scope, bitset);
731
732 if (!display) {
733 decode_error(scope->state, "%s: no display template", bitset->name);
734 return;
735 }
736
737 const char *p = display;
738
739 while (*p != '\0') {
740 if (*p == '{') {
741 const char *e = ++p;
742 while (*e != '}') {
743 e++;
744 }
745
746 char *field_name = strndup(p, e-p);
747 display_field(scope, field_name);
748 free(field_name);
749
750 p = e;
751 } else {
752 fputc(*p, scope->state->print.out);
753 scope->state->print.line_column++;
754 }
755 p++;
756 }
757 }
758
759 static void
disasm(struct decode_state * state,void * bin,int sz)760 disasm(struct decode_state *state, void *bin, int sz)
761 {
762 BITSET_WORD *instrs = bin;
763 unsigned errors = 0; /* number of consecutive unmatched instructions */
764
765 assert(sz % BITMASK_WORDS == 0);
766
767 for (state->n = 0; state->n < state->num_instr; state->n++) {
768 bitmask_t instr = { 0 };
769
770 next_instruction(&instr, &instrs[state->n * BITMASK_WORDS]);
771 state->print.line_column = 0;
772
773 if (state->options->max_errors && (errors > state->options->max_errors)) {
774 break;
775 }
776
777 if (state->options->branch_labels) {
778 bool entrypoint = state->next_entrypoint !=
779 state->end_entrypoint &&
780 state->next_entrypoint->offset == state->n;
781
782 /* Print an extra empty line before functions and
783 * entrypoints to more clearly separate them.
784 */
785 if ((BITSET_TEST(state->call_targets, state->n) || entrypoint) &&
786 state->n != 0) {
787 if (state->options->pre_instr_cb) {
788 state->options->pre_instr_cb(state->options->cbdata,
789 state->n, instr.bitset);
790 }
791 isa_print(&state->print, "\n");
792 }
793
794 while (state->next_entrypoint != state->end_entrypoint &&
795 state->next_entrypoint->offset == state->n) {
796 if (state->options->pre_instr_cb) {
797 state->options->pre_instr_cb(state->options->cbdata,
798 state->n, instr.bitset);
799 }
800 isa_print(&state->print, "%s:\n", state->next_entrypoint->name);
801 state->next_entrypoint++;
802 }
803
804 if (BITSET_TEST(state->call_targets, state->n)) {
805 if (state->options->pre_instr_cb) {
806 state->options->pre_instr_cb(state->options->cbdata,
807 state->n, instr.bitset);
808 }
809 isa_print(&state->print, "fxn%d:\n", state->n);
810 }
811
812 if (BITSET_TEST(state->branch_targets, state->n)) {
813 if (state->options->pre_instr_cb) {
814 state->options->pre_instr_cb(state->options->cbdata,
815 state->n, instr.bitset);
816 }
817 isa_print(&state->print, "l%d:\n", state->n);
818 }
819 }
820
821 if (state->options->pre_instr_cb) {
822 state->options->pre_instr_cb(state->options->cbdata, state->n, instr.bitset);
823 }
824
825 const struct isa_bitset *b = find_bitset(state, __instruction, instr);
826 if (!b) {
827 if (state->options->no_match_cb) {
828 state->options->no_match_cb(state->print.out, instr.bitset, BITMASK_WORDS);
829 } else {
830 isa_print(&state->print, "no match: %"BITSET_FORMAT"\n", BITSET_VALUE(instr.bitset));
831 }
832 errors++;
833 continue;
834 }
835
836 struct decode_scope *scope = push_scope(state, b, instr);
837
838 display(scope);
839 if (flush_errors(state)) {
840 errors++;
841 } else {
842 errors = 0;
843 }
844
845 if (state->options->post_instr_cb) {
846 state->options->post_instr_cb(state->options->cbdata, state->n, instr.bitset);
847 }
848
849 isa_print(&state->print, "\n");
850
851 pop_scope(scope);
852
853 if (state->options->stop) {
854 break;
855 }
856 }
857 }
858
859 static void
decode_bitset_cb(void * out,struct decode_scope * scope,const struct isa_bitset * b)860 decode_bitset_cb(void *out, struct decode_scope *scope, const struct isa_bitset *b)
861 {
862 while (b) {
863 b->decode(out, scope);
864 b = b->parent;
865 }
866 }
867
868 static void
decode_field(void * out,struct decode_scope * scope,const char * field_name)869 decode_field(void *out, struct decode_scope *scope, const char *field_name)
870 {
871 const struct isa_bitset *bitset = scope->bitset;
872 size_t field_name_len = strlen(field_name);
873
874 /* alignment handling */
875 const char *align = strstr(field_name, ":align=");
876
877 if (align) {
878 field_name_len = align - field_name;
879 }
880
881 if (field_name == align)
882 return;
883
884 if (!strncmp("NAME", field_name, field_name_len))
885 return;
886
887 bitmask_t v;
888 const struct isa_field *field = resolve_field(scope, field_name, field_name_len, &v);
889 if (!field) {
890 decode_error(scope->state, "no field '%.*s'", (int)field_name_len, field_name);
891 return;
892 }
893
894 uint64_t val = bitmask_to_uint64_t(v);
895
896 for (unsigned i = 0; i < bitset->num_decode_fields; i++) {
897 if (!strncmp(bitset->decode_fields[i].name, field_name, field_name_len)) {
898 bitset->decode_fields[i].decode(out, scope, val);
899 return;
900 }
901 }
902 }
903
904 static void
decode_bitset(void * out,struct decode_scope * scope)905 decode_bitset(void *out, struct decode_scope *scope)
906 {
907 const struct isa_bitset *bitset = scope->bitset;
908 decode_bitset_cb(out, scope, bitset);
909
910 const char *display = find_display(scope, bitset);
911
912 if (!display) {
913 decode_error(scope->state, "%s: no display template", bitset->name);
914 return;
915 }
916
917 const char *p = display;
918
919 while (*p != '\0') {
920 if (*p == '{') {
921 const char *e = ++p;
922 while (*e != '}') {
923 e++;
924 }
925
926 char *field_name = strndup(p, e-p);
927 decode_field(out, scope, field_name);
928 free(field_name);
929
930 p = e;
931 }
932 p++;
933 }
934 }
935
936 void
isa_decode_bitset(void * out,const struct isa_bitset ** bitsets,struct decode_scope * scope,bitmask_t val)937 isa_decode_bitset(void *out, const struct isa_bitset **bitsets, struct decode_scope *scope, bitmask_t val)
938 {
939 struct decode_state *state = scope->state;
940
941 const struct isa_bitset *b = find_bitset(state, bitsets, val);
942 if (!b)
943 return;
944
945 struct decode_scope *new_scope = push_scope(state, b, val);
946
947 decode_bitset(out, new_scope);
948
949 pop_scope(new_scope);
950 }
951
952 static bool
decode(void * out,struct decode_state * state,void * bin)953 decode(void *out, struct decode_state *state, void *bin)
954 {
955 bitmask_t instr = { 0 };
956 next_instruction(&instr, bin);
957
958 const struct isa_bitset *b = find_bitset(state, __instruction, instr);
959 if (!b)
960 return false;
961
962 struct decode_scope *scope = push_scope(state, b, instr);
963
964 decode_bitset(out, scope);
965
966 pop_scope(scope);
967 return true;
968 }
969
970 static int
cmp_entrypoints(const void * _a,const void * _b)971 cmp_entrypoints(const void *_a, const void *_b)
972 {
973 const struct isa_entrypoint *a = _a, *b = _b;
974
975 /* For stable output, if we have multiple entrypoints with the same
976 * offset, sort them by string name:
977 */
978 if (a->offset == b->offset)
979 return strcmp(a->name, b->name);
980
981 return (int)a->offset - (int)b->offset;
982 }
983
984 void
isa_disasm(void * bin,int sz,FILE * out,const struct isa_decode_options * options)985 isa_disasm(void *bin, int sz, FILE *out, const struct isa_decode_options *options)
986 {
987 const struct isa_decode_options default_options = {
988 .gpu_id = options ? options->gpu_id : 0,
989 .branch_labels = options ? options->branch_labels : false
990 };
991 struct decode_state *state;
992
993 if (!options)
994 options = &default_options;
995
996 state = rzalloc_size(NULL, sizeof(*state));
997 state->options = options;
998 state->num_instr = sz / (BITMASK_WORDS * sizeof(BITSET_WORD));
999
1000 if (state->options->branch_labels) {
1001 state->branch_targets = rzalloc_size(state,
1002 sizeof(BITSET_WORD) * BITSET_WORDS(state->num_instr));
1003 state->call_targets = rzalloc_size(state,
1004 sizeof(BITSET_WORD) * BITSET_WORDS(state->num_instr));
1005
1006 /* Do a pre-pass to find all the branch targets: */
1007 state->print.out = fopen("/dev/null", "w");
1008 state->options = &default_options; /* skip hooks for prepass */
1009 disasm(state, bin, sz);
1010 fclose(state->print.out);
1011 if (options) {
1012 state->options = options;
1013 }
1014
1015 /* Sort the entrypoints by offset and initialize entrypoint
1016 * state.
1017 */
1018 if (options->entrypoint_count) {
1019 struct isa_entrypoint *entrypoints =
1020 ralloc_array(state, struct isa_entrypoint,
1021 options->entrypoint_count);
1022 memcpy(entrypoints, options->entrypoints,
1023 options->entrypoint_count * sizeof(*entrypoints));
1024 qsort(entrypoints, options->entrypoint_count,
1025 sizeof(*entrypoints), cmp_entrypoints);
1026 state->next_entrypoint = entrypoints;
1027 state->end_entrypoint = entrypoints + options->entrypoint_count;
1028 }
1029 }
1030
1031 state->print.out = out;
1032
1033 disasm(state, bin, sz);
1034
1035 ralloc_free(state);
1036 }
1037
1038 bool
isa_decode(void * out,void * bin,const struct isa_decode_options * options)1039 isa_decode(void *out, void *bin, const struct isa_decode_options *options)
1040 {
1041 struct decode_state *state = rzalloc_size(NULL, sizeof(*state));
1042 state->options = options;
1043
1044 bool result = decode(out, state, bin);
1045
1046 if (flush_errors(state)) {
1047 return false;
1048 }
1049
1050 ralloc_free(state);
1051 return result;
1052 }
1053