~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/intel/common/intel_decoder.c

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright © 2016 Intel Corporation
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
20
 
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
 
 * IN THE SOFTWARE.
22
 
 */
23
 
 
24
 
#include <stdio.h>
25
 
#include <stdbool.h>
26
 
#include <stdint.h>
27
 
#include <stdarg.h>
28
 
#include <string.h>
29
 
#include <expat.h>
30
 
#include <inttypes.h>
31
 
#include <zlib.h>
32
 
 
33
 
#include <util/macros.h>
34
 
#include <util/ralloc.h>
35
 
 
36
 
#include "intel_decoder.h"
37
 
 
38
 
#include "isl/isl.h"
39
 
#include "genxml/genX_xml.h"
40
 
 
41
 
#define XML_BUFFER_SIZE 4096
42
 
#define MAX_VALUE_ITEMS 128
43
 
 
44
 
struct location {
45
 
   const char *filename;
46
 
   int line_number;
47
 
};
48
 
 
49
 
struct parser_context {
50
 
   XML_Parser parser;
51
 
   int foo;
52
 
   struct location loc;
53
 
 
54
 
   struct intel_group *group;
55
 
   struct intel_enum *enoom;
56
 
 
57
 
   int n_values, n_allocated_values;
58
 
   struct intel_value **values;
59
 
 
60
 
   struct intel_field *last_field;
61
 
 
62
 
   struct intel_spec *spec;
63
 
};
64
 
 
65
 
const char *
66
 
intel_group_get_name(struct intel_group *group)
67
 
{
68
 
   return group->name;
69
 
}
70
 
 
71
 
uint32_t
72
 
intel_group_get_opcode(struct intel_group *group)
73
 
{
74
 
   return group->opcode;
75
 
}
76
 
 
77
 
struct intel_group *
78
 
intel_spec_find_struct(struct intel_spec *spec, const char *name)
79
 
{
80
 
   struct hash_entry *entry = _mesa_hash_table_search(spec->structs,
81
 
                                                      name);
82
 
   return entry ? entry->data : NULL;
83
 
}
84
 
 
85
 
struct intel_group *
86
 
intel_spec_find_register(struct intel_spec *spec, uint32_t offset)
87
 
{
88
 
   struct hash_entry *entry =
89
 
      _mesa_hash_table_search(spec->registers_by_offset,
90
 
                              (void *) (uintptr_t) offset);
91
 
   return entry ? entry->data : NULL;
92
 
}
93
 
 
94
 
struct intel_group *
95
 
intel_spec_find_register_by_name(struct intel_spec *spec, const char *name)
96
 
{
97
 
   struct hash_entry *entry =
98
 
      _mesa_hash_table_search(spec->registers_by_name, name);
99
 
   return entry ? entry->data : NULL;
100
 
}
101
 
 
102
 
struct intel_enum *
103
 
intel_spec_find_enum(struct intel_spec *spec, const char *name)
104
 
{
105
 
   struct hash_entry *entry = _mesa_hash_table_search(spec->enums,
106
 
                                                      name);
107
 
   return entry ? entry->data : NULL;
108
 
}
109
 
 
110
 
uint32_t
111
 
intel_spec_get_gen(struct intel_spec *spec)
112
 
{
113
 
   return spec->gen;
114
 
}
115
 
 
116
 
static void __attribute__((noreturn))
117
 
fail(struct location *loc, const char *msg, ...)
118
 
{
119
 
   va_list ap;
120
 
 
121
 
   va_start(ap, msg);
122
 
   fprintf(stderr, "%s:%d: error: ",
123
 
           loc->filename, loc->line_number);
124
 
   vfprintf(stderr, msg, ap);
125
 
   fprintf(stderr, "\n");
126
 
   va_end(ap);
127
 
   exit(EXIT_FAILURE);
128
 
}
129
 
 
130
 
static void
131
 
get_array_offset_count(const char **atts, uint32_t *offset, uint32_t *count,
132
 
                       uint32_t *size, bool *variable)
133
 
{
134
 
   for (int i = 0; atts[i]; i += 2) {
135
 
      char *p;
136
 
 
137
 
      if (strcmp(atts[i], "count") == 0) {
138
 
         *count = strtoul(atts[i + 1], &p, 0);
139
 
         if (*count == 0)
140
 
            *variable = true;
141
 
      } else if (strcmp(atts[i], "start") == 0) {
142
 
         *offset = strtoul(atts[i + 1], &p, 0);
143
 
      } else if (strcmp(atts[i], "size") == 0) {
144
 
         *size = strtoul(atts[i + 1], &p, 0);
145
 
      }
146
 
   }
147
 
   return;
148
 
}
149
 
 
150
 
static struct intel_group *
151
 
create_group(struct parser_context *ctx,
152
 
             const char *name,
153
 
             const char **atts,
154
 
             struct intel_group *parent,
155
 
             bool fixed_length)
156
 
{
157
 
   struct intel_group *group;
158
 
 
159
 
   group = rzalloc(ctx->spec, struct intel_group);
160
 
   if (name)
161
 
      group->name = ralloc_strdup(group, name);
162
 
 
163
 
   group->spec = ctx->spec;
164
 
   group->variable = false;
165
 
   group->fixed_length = fixed_length;
166
 
   group->dword_length_field = NULL;
167
 
   group->dw_length = 0;
168
 
   group->engine_mask = I915_ENGINE_CLASS_TO_MASK(I915_ENGINE_CLASS_RENDER) |
169
 
                        I915_ENGINE_CLASS_TO_MASK(I915_ENGINE_CLASS_VIDEO) |
170
 
                        I915_ENGINE_CLASS_TO_MASK(I915_ENGINE_CLASS_COPY);
171
 
   group->bias = 1;
172
 
 
173
 
   for (int i = 0; atts[i]; i += 2) {
174
 
      char *p;
175
 
      if (strcmp(atts[i], "length") == 0) {
176
 
         group->dw_length = strtoul(atts[i + 1], &p, 0);
177
 
      } else if (strcmp(atts[i], "bias") == 0) {
178
 
         group->bias = strtoul(atts[i + 1], &p, 0);
179
 
      } else if (strcmp(atts[i], "engine") == 0) {
180
 
         void *mem_ctx = ralloc_context(NULL);
181
 
         char *tmp = ralloc_strdup(mem_ctx, atts[i + 1]);
182
 
         char *save_ptr;
183
 
         char *tok = strtok_r(tmp, "|", &save_ptr);
184
 
 
185
 
         group->engine_mask = 0;
186
 
         while (tok != NULL) {
187
 
            if (strcmp(tok, "render") == 0) {
188
 
               group->engine_mask |= I915_ENGINE_CLASS_TO_MASK(I915_ENGINE_CLASS_RENDER);
189
 
            } else if (strcmp(tok, "video") == 0) {
190
 
               group->engine_mask |= I915_ENGINE_CLASS_TO_MASK(I915_ENGINE_CLASS_VIDEO);
191
 
            } else if (strcmp(tok, "blitter") == 0) {
192
 
               group->engine_mask |= I915_ENGINE_CLASS_TO_MASK(I915_ENGINE_CLASS_COPY);
193
 
            } else {
194
 
               fprintf(stderr, "unknown engine class defined for instruction \"%s\": %s\n", name, atts[i + 1]);
195
 
            }
196
 
 
197
 
            tok = strtok_r(NULL, "|", &save_ptr);
198
 
         }
199
 
 
200
 
         ralloc_free(mem_ctx);
201
 
      }
202
 
   }
203
 
 
204
 
   if (parent) {
205
 
      group->parent = parent;
206
 
      get_array_offset_count(atts,
207
 
                             &group->array_offset,
208
 
                             &group->array_count,
209
 
                             &group->array_item_size,
210
 
                             &group->variable);
211
 
   }
212
 
 
213
 
   return group;
214
 
}
215
 
 
216
 
static struct intel_enum *
217
 
create_enum(struct parser_context *ctx, const char *name, const char **atts)
218
 
{
219
 
   struct intel_enum *e;
220
 
 
221
 
   e = rzalloc(ctx->spec, struct intel_enum);
222
 
   if (name)
223
 
      e->name = ralloc_strdup(e, name);
224
 
 
225
 
   return e;
226
 
}
227
 
 
228
 
static void
229
 
get_register_offset(const char **atts, uint32_t *offset)
230
 
{
231
 
   for (int i = 0; atts[i]; i += 2) {
232
 
      char *p;
233
 
 
234
 
      if (strcmp(atts[i], "num") == 0)
235
 
         *offset = strtoul(atts[i + 1], &p, 0);
236
 
   }
237
 
   return;
238
 
}
239
 
 
240
 
static void
241
 
get_start_end_pos(int *start, int *end)
242
 
{
243
 
   /* start value has to be mod with 32 as we need the relative
244
 
    * start position in the first DWord. For the end position, add
245
 
    * the length of the field to the start position to get the
246
 
    * relative postion in the 64 bit address.
247
 
    */
248
 
   if (*end - *start > 32) {
249
 
      int len = *end - *start;
250
 
      *start = *start % 32;
251
 
      *end = *start + len;
252
 
   } else {
253
 
      *start = *start % 32;
254
 
      *end = *end % 32;
255
 
   }
256
 
 
257
 
   return;
258
 
}
259
 
 
260
 
static inline uint64_t
261
 
mask(int start, int end)
262
 
{
263
 
   uint64_t v;
264
 
 
265
 
   v = ~0ULL >> (63 - end + start);
266
 
 
267
 
   return v << start;
268
 
}
269
 
 
270
 
static inline uint64_t
271
 
field_value(uint64_t value, int start, int end)
272
 
{
273
 
   get_start_end_pos(&start, &end);
274
 
   return (value & mask(start, end)) >> (start);
275
 
}
276
 
 
277
 
static struct intel_type
278
 
string_to_type(struct parser_context *ctx, const char *s)
279
 
{
280
 
   int i, f;
281
 
   struct intel_group *g;
282
 
   struct intel_enum *e;
283
 
 
284
 
   if (strcmp(s, "int") == 0)
285
 
      return (struct intel_type) { .kind = INTEL_TYPE_INT };
286
 
   else if (strcmp(s, "uint") == 0)
287
 
      return (struct intel_type) { .kind = INTEL_TYPE_UINT };
288
 
   else if (strcmp(s, "bool") == 0)
289
 
      return (struct intel_type) { .kind = INTEL_TYPE_BOOL };
290
 
   else if (strcmp(s, "float") == 0)
291
 
      return (struct intel_type) { .kind = INTEL_TYPE_FLOAT };
292
 
   else if (strcmp(s, "address") == 0)
293
 
      return (struct intel_type) { .kind = INTEL_TYPE_ADDRESS };
294
 
   else if (strcmp(s, "offset") == 0)
295
 
      return (struct intel_type) { .kind = INTEL_TYPE_OFFSET };
296
 
   else if (sscanf(s, "u%d.%d", &i, &f) == 2)
297
 
      return (struct intel_type) { .kind = INTEL_TYPE_UFIXED, .i = i, .f = f };
298
 
   else if (sscanf(s, "s%d.%d", &i, &f) == 2)
299
 
      return (struct intel_type) { .kind = INTEL_TYPE_SFIXED, .i = i, .f = f };
300
 
   else if (g = intel_spec_find_struct(ctx->spec, s), g != NULL)
301
 
      return (struct intel_type) { .kind = INTEL_TYPE_STRUCT, .intel_struct = g };
302
 
   else if (e = intel_spec_find_enum(ctx->spec, s), e != NULL)
303
 
      return (struct intel_type) { .kind = INTEL_TYPE_ENUM, .intel_enum = e };
304
 
   else if (strcmp(s, "mbo") == 0)
305
 
      return (struct intel_type) { .kind = INTEL_TYPE_MBO };
306
 
   else if (strcmp(s, "mbz") == 0)
307
 
      return (struct intel_type) { .kind = INTEL_TYPE_MBZ };
308
 
   else
309
 
      fail(&ctx->loc, "invalid type: %s", s);
310
 
}
311
 
 
312
 
static struct intel_field *
313
 
create_field(struct parser_context *ctx, const char **atts)
314
 
{
315
 
   struct intel_field *field;
316
 
 
317
 
   field = rzalloc(ctx->group, struct intel_field);
318
 
   field->parent = ctx->group;
319
 
 
320
 
   for (int i = 0; atts[i]; i += 2) {
321
 
      char *p;
322
 
 
323
 
      if (strcmp(atts[i], "name") == 0) {
324
 
         field->name = ralloc_strdup(field, atts[i + 1]);
325
 
         if (strcmp(field->name, "DWord Length") == 0) {
326
 
            field->parent->dword_length_field = field;
327
 
         }
328
 
      } else if (strcmp(atts[i], "start") == 0) {
329
 
         field->start = strtoul(atts[i + 1], &p, 0);
330
 
      } else if (strcmp(atts[i], "end") == 0) {
331
 
         field->end = strtoul(atts[i + 1], &p, 0);
332
 
      } else if (strcmp(atts[i], "type") == 0) {
333
 
         field->type = string_to_type(ctx, atts[i + 1]);
334
 
      } else if (strcmp(atts[i], "default") == 0 &&
335
 
               field->start >= 16 && field->end <= 31) {
336
 
         field->has_default = true;
337
 
         field->default_value = strtoul(atts[i + 1], &p, 0);
338
 
      }
339
 
   }
340
 
 
341
 
   return field;
342
 
}
343
 
 
344
 
static struct intel_field *
345
 
create_array_field(struct parser_context *ctx, struct intel_group *array)
346
 
{
347
 
   struct intel_field *field;
348
 
 
349
 
   field = rzalloc(ctx->group, struct intel_field);
350
 
   field->parent = ctx->group;
351
 
 
352
 
   field->array = array;
353
 
   field->start = field->array->array_offset;
354
 
 
355
 
   return field;
356
 
}
357
 
 
358
 
static struct intel_value *
359
 
create_value(struct parser_context *ctx, const char **atts)
360
 
{
361
 
   struct intel_value *value = rzalloc(ctx->values, struct intel_value);
362
 
 
363
 
   for (int i = 0; atts[i]; i += 2) {
364
 
      if (strcmp(atts[i], "name") == 0)
365
 
         value->name = ralloc_strdup(value, atts[i + 1]);
366
 
      else if (strcmp(atts[i], "value") == 0)
367
 
         value->value = strtoul(atts[i + 1], NULL, 0);
368
 
   }
369
 
 
370
 
   return value;
371
 
}
372
 
 
373
 
static struct intel_field *
374
 
create_and_append_field(struct parser_context *ctx,
375
 
                        const char **atts,
376
 
                        struct intel_group *array)
377
 
{
378
 
   struct intel_field *field = array ?
379
 
      create_array_field(ctx, array) : create_field(ctx, atts);
380
 
   struct intel_field *prev = NULL, *list = ctx->group->fields;
381
 
 
382
 
   while (list && field->start > list->start) {
383
 
      prev = list;
384
 
      list = list->next;
385
 
   }
386
 
 
387
 
   field->next = list;
388
 
   if (prev == NULL)
389
 
      ctx->group->fields = field;
390
 
   else
391
 
      prev->next = field;
392
 
 
393
 
   return field;
394
 
}
395
 
 
396
 
static void
397
 
start_element(void *data, const char *element_name, const char **atts)
398
 
{
399
 
   struct parser_context *ctx = data;
400
 
   const char *name = NULL;
401
 
   const char *gen = NULL;
402
 
 
403
 
   ctx->loc.line_number = XML_GetCurrentLineNumber(ctx->parser);
404
 
 
405
 
   for (int i = 0; atts[i]; i += 2) {
406
 
      if (strcmp(atts[i], "name") == 0)
407
 
         name = atts[i + 1];
408
 
      else if (strcmp(atts[i], "gen") == 0)
409
 
         gen = atts[i + 1];
410
 
   }
411
 
 
412
 
   if (strcmp(element_name, "genxml") == 0) {
413
 
      if (name == NULL)
414
 
         fail(&ctx->loc, "no platform name given");
415
 
      if (gen == NULL)
416
 
         fail(&ctx->loc, "no gen given");
417
 
 
418
 
      int major, minor;
419
 
      int n = sscanf(gen, "%d.%d", &major, &minor);
420
 
      if (n == 0)
421
 
         fail(&ctx->loc, "invalid gen given: %s", gen);
422
 
      if (n == 1)
423
 
         minor = 0;
424
 
 
425
 
      ctx->spec->gen = intel_make_gen(major, minor);
426
 
   } else if (strcmp(element_name, "instruction") == 0) {
427
 
      ctx->group = create_group(ctx, name, atts, NULL, false);
428
 
   } else if (strcmp(element_name, "struct") == 0) {
429
 
      ctx->group = create_group(ctx, name, atts, NULL, true);
430
 
   } else if (strcmp(element_name, "register") == 0) {
431
 
      ctx->group = create_group(ctx, name, atts, NULL, true);
432
 
      get_register_offset(atts, &ctx->group->register_offset);
433
 
   } else if (strcmp(element_name, "group") == 0) {
434
 
      struct intel_group *group = create_group(ctx, "", atts, ctx->group, false);
435
 
      ctx->last_field = create_and_append_field(ctx, NULL, group);
436
 
      ctx->group = group;
437
 
   } else if (strcmp(element_name, "field") == 0) {
438
 
      ctx->last_field = create_and_append_field(ctx, atts, NULL);
439
 
   } else if (strcmp(element_name, "enum") == 0) {
440
 
      ctx->enoom = create_enum(ctx, name, atts);
441
 
   } else if (strcmp(element_name, "value") == 0) {
442
 
      if (ctx->n_values >= ctx->n_allocated_values) {
443
 
         ctx->n_allocated_values = MAX2(2, ctx->n_allocated_values * 2);
444
 
         ctx->values = reralloc_array_size(ctx->spec, ctx->values,
445
 
                                           sizeof(struct intel_value *),
446
 
                                           ctx->n_allocated_values);
447
 
      }
448
 
      assert(ctx->n_values < ctx->n_allocated_values);
449
 
      ctx->values[ctx->n_values++] = create_value(ctx, atts);
450
 
   }
451
 
 
452
 
}
453
 
 
454
 
static void
455
 
end_element(void *data, const char *name)
456
 
{
457
 
   struct parser_context *ctx = data;
458
 
   struct intel_spec *spec = ctx->spec;
459
 
 
460
 
   if (strcmp(name, "instruction") == 0 ||
461
 
       strcmp(name, "struct") == 0 ||
462
 
       strcmp(name, "register") == 0) {
463
 
      struct intel_group *group = ctx->group;
464
 
      struct intel_field *list = group->fields;
465
 
 
466
 
      ctx->group = ctx->group->parent;
467
 
 
468
 
      while (list && list->end <= 31) {
469
 
         if (list->start >= 16 && list->has_default) {
470
 
            group->opcode_mask |=
471
 
               mask(list->start % 32, list->end % 32);
472
 
            group->opcode |= list->default_value << list->start;
473
 
         }
474
 
         list = list->next;
475
 
      }
476
 
 
477
 
      if (strcmp(name, "instruction") == 0)
478
 
         _mesa_hash_table_insert(spec->commands, group->name, group);
479
 
      else if (strcmp(name, "struct") == 0)
480
 
         _mesa_hash_table_insert(spec->structs, group->name, group);
481
 
      else if (strcmp(name, "register") == 0) {
482
 
         _mesa_hash_table_insert(spec->registers_by_name, group->name, group);
483
 
         _mesa_hash_table_insert(spec->registers_by_offset,
484
 
                                 (void *) (uintptr_t) group->register_offset,
485
 
                                 group);
486
 
      }
487
 
   } else if (strcmp(name, "group") == 0) {
488
 
      ctx->group = ctx->group->parent;
489
 
   } else if (strcmp(name, "field") == 0) {
490
 
      struct intel_field *field = ctx->last_field;
491
 
      ctx->last_field = NULL;
492
 
      field->inline_enum.values = ctx->values;
493
 
      field->inline_enum.nvalues = ctx->n_values;
494
 
      ctx->values = ralloc_array(ctx->spec, struct intel_value*, ctx->n_allocated_values = 2);
495
 
      ctx->n_values = 0;
496
 
   } else if (strcmp(name, "enum") == 0) {
497
 
      struct intel_enum *e = ctx->enoom;
498
 
      e->values = ctx->values;
499
 
      e->nvalues = ctx->n_values;
500
 
      ctx->values = ralloc_array(ctx->spec, struct intel_value*, ctx->n_allocated_values = 2);
501
 
      ctx->n_values = 0;
502
 
      ctx->enoom = NULL;
503
 
      _mesa_hash_table_insert(spec->enums, e->name, e);
504
 
   }
505
 
}
506
 
 
507
 
static void
508
 
character_data(void *data, const XML_Char *s, int len)
509
 
{
510
 
}
511
 
 
512
 
static uint32_t zlib_inflate(const void *compressed_data,
513
 
                             uint32_t compressed_len,
514
 
                             void **out_ptr)
515
 
{
516
 
   struct z_stream_s zstream;
517
 
   void *out;
518
 
 
519
 
   memset(&zstream, 0, sizeof(zstream));
520
 
 
521
 
   zstream.next_in = (unsigned char *)compressed_data;
522
 
   zstream.avail_in = compressed_len;
523
 
 
524
 
   if (inflateInit(&zstream) != Z_OK)
525
 
      return 0;
526
 
 
527
 
   out = malloc(4096);
528
 
   zstream.next_out = out;
529
 
   zstream.avail_out = 4096;
530
 
 
531
 
   do {
532
 
      switch (inflate(&zstream, Z_SYNC_FLUSH)) {
533
 
      case Z_STREAM_END:
534
 
         goto end;
535
 
      case Z_OK:
536
 
         break;
537
 
      default:
538
 
         inflateEnd(&zstream);
539
 
         return 0;
540
 
      }
541
 
 
542
 
      if (zstream.avail_out)
543
 
         break;
544
 
 
545
 
      out = realloc(out, 2*zstream.total_out);
546
 
      if (out == NULL) {
547
 
         inflateEnd(&zstream);
548
 
         return 0;
549
 
      }
550
 
 
551
 
      zstream.next_out = (unsigned char *)out + zstream.total_out;
552
 
      zstream.avail_out = zstream.total_out;
553
 
   } while (1);
554
 
 end:
555
 
   inflateEnd(&zstream);
556
 
   *out_ptr = out;
557
 
   return zstream.total_out;
558
 
}
559
 
 
560
 
static uint32_t _hash_uint32(const void *key)
561
 
{
562
 
   return (uint32_t) (uintptr_t) key;
563
 
}
564
 
 
565
 
static struct intel_spec *
566
 
intel_spec_init(void)
567
 
{
568
 
   struct intel_spec *spec;
569
 
   spec = rzalloc(NULL, struct intel_spec);
570
 
   if (spec == NULL)
571
 
      return NULL;
572
 
 
573
 
   spec->commands =
574
 
      _mesa_hash_table_create(spec, _mesa_hash_string, _mesa_key_string_equal);
575
 
   spec->structs =
576
 
      _mesa_hash_table_create(spec, _mesa_hash_string, _mesa_key_string_equal);
577
 
   spec->registers_by_name =
578
 
      _mesa_hash_table_create(spec, _mesa_hash_string, _mesa_key_string_equal);
579
 
   spec->registers_by_offset =
580
 
      _mesa_hash_table_create(spec, _hash_uint32, _mesa_key_pointer_equal);
581
 
   spec->enums =
582
 
      _mesa_hash_table_create(spec, _mesa_hash_string, _mesa_key_string_equal);
583
 
   spec->access_cache =
584
 
      _mesa_hash_table_create(spec, _mesa_hash_string, _mesa_key_string_equal);
585
 
 
586
 
   return spec;
587
 
}
588
 
 
589
 
struct intel_spec *
590
 
intel_spec_load(const struct intel_device_info *devinfo)
591
 
{
592
 
   struct parser_context ctx;
593
 
   void *buf;
594
 
   uint8_t *text_data = NULL;
595
 
   uint32_t text_offset = 0, text_length = 0;
596
 
   ASSERTED uint32_t total_length;
597
 
   uint32_t ver_10 = devinfo->verx10;
598
 
 
599
 
   for (int i = 0; i < ARRAY_SIZE(genxml_files_table); i++) {
600
 
      if (genxml_files_table[i].ver_10 == ver_10) {
601
 
         text_offset = genxml_files_table[i].offset;
602
 
         text_length = genxml_files_table[i].length;
603
 
         break;
604
 
      }
605
 
   }
606
 
 
607
 
   if (text_length == 0) {
608
 
      fprintf(stderr, "unable to find gen (%u) data\n", ver_10);
609
 
      return NULL;
610
 
   }
611
 
 
612
 
   memset(&ctx, 0, sizeof ctx);
613
 
   ctx.parser = XML_ParserCreate(NULL);
614
 
   XML_SetUserData(ctx.parser, &ctx);
615
 
   if (ctx.parser == NULL) {
616
 
      fprintf(stderr, "failed to create parser\n");
617
 
      return NULL;
618
 
   }
619
 
 
620
 
   XML_SetElementHandler(ctx.parser, start_element, end_element);
621
 
   XML_SetCharacterDataHandler(ctx.parser, character_data);
622
 
 
623
 
   ctx.spec = intel_spec_init();
624
 
   if (ctx.spec == NULL) {
625
 
      fprintf(stderr, "Failed to create intel_spec\n");
626
 
      return NULL;
627
 
   }
628
 
 
629
 
   total_length = zlib_inflate(compress_genxmls,
630
 
                               sizeof(compress_genxmls),
631
 
                               (void **) &text_data);
632
 
   assert(text_offset + text_length <= total_length);
633
 
 
634
 
   buf = XML_GetBuffer(ctx.parser, text_length);
635
 
   memcpy(buf, &text_data[text_offset], text_length);
636
 
 
637
 
   if (XML_ParseBuffer(ctx.parser, text_length, true) == 0) {
638
 
      fprintf(stderr,
639
 
              "Error parsing XML at line %ld col %ld byte %ld/%u: %s\n",
640
 
              XML_GetCurrentLineNumber(ctx.parser),
641
 
              XML_GetCurrentColumnNumber(ctx.parser),
642
 
              XML_GetCurrentByteIndex(ctx.parser), text_length,
643
 
              XML_ErrorString(XML_GetErrorCode(ctx.parser)));
644
 
      XML_ParserFree(ctx.parser);
645
 
      free(text_data);
646
 
      return NULL;
647
 
   }
648
 
 
649
 
   XML_ParserFree(ctx.parser);
650
 
   free(text_data);
651
 
 
652
 
   return ctx.spec;
653
 
}
654
 
 
655
 
struct intel_spec *
656
 
intel_spec_load_filename(const char *filename)
657
 
{
658
 
   struct parser_context ctx;
659
 
   FILE *input;
660
 
   void *buf;
661
 
   size_t len;
662
 
 
663
 
   input = fopen(filename, "r");
664
 
   if (input == NULL) {
665
 
      fprintf(stderr, "failed to open xml description\n");
666
 
      return NULL;
667
 
   }
668
 
 
669
 
   memset(&ctx, 0, sizeof ctx);
670
 
   ctx.parser = XML_ParserCreate(NULL);
671
 
   XML_SetUserData(ctx.parser, &ctx);
672
 
   if (ctx.parser == NULL) {
673
 
      fprintf(stderr, "failed to create parser\n");
674
 
      fclose(input);
675
 
      return NULL;
676
 
   }
677
 
 
678
 
   XML_SetElementHandler(ctx.parser, start_element, end_element);
679
 
   XML_SetCharacterDataHandler(ctx.parser, character_data);
680
 
   ctx.loc.filename = filename;
681
 
 
682
 
   ctx.spec = intel_spec_init();
683
 
   if (ctx.spec == NULL) {
684
 
      fprintf(stderr, "Failed to create intel_spec\n");
685
 
      goto end;
686
 
   }
687
 
 
688
 
   do {
689
 
      buf = XML_GetBuffer(ctx.parser, XML_BUFFER_SIZE);
690
 
      len = fread(buf, 1, XML_BUFFER_SIZE, input);
691
 
      if (ferror(input)) {
692
 
         fprintf(stderr, "fread: %m\n");
693
 
         intel_spec_destroy(ctx.spec);
694
 
         ctx.spec = NULL;
695
 
         goto end;
696
 
      } else if (len == 0 && feof(input))
697
 
         goto end;
698
 
 
699
 
      if (XML_ParseBuffer(ctx.parser, len, len == 0) == 0) {
700
 
         fprintf(stderr,
701
 
                 "Error parsing XML at line %ld col %ld: %s\n",
702
 
                 XML_GetCurrentLineNumber(ctx.parser),
703
 
                 XML_GetCurrentColumnNumber(ctx.parser),
704
 
                 XML_ErrorString(XML_GetErrorCode(ctx.parser)));
705
 
         intel_spec_destroy(ctx.spec);
706
 
         ctx.spec = NULL;
707
 
         goto end;
708
 
      }
709
 
   } while (len > 0);
710
 
 
711
 
 end:
712
 
   XML_ParserFree(ctx.parser);
713
 
 
714
 
   fclose(input);
715
 
 
716
 
   /* free ctx.spec if genxml is empty */
717
 
   if (ctx.spec &&
718
 
       _mesa_hash_table_num_entries(ctx.spec->commands) == 0 &&
719
 
       _mesa_hash_table_num_entries(ctx.spec->structs) == 0) {
720
 
      fprintf(stderr,
721
 
              "Error parsing XML: empty spec.\n");
722
 
      intel_spec_destroy(ctx.spec);
723
 
      return NULL;
724
 
   }
725
 
 
726
 
   return ctx.spec;
727
 
}
728
 
 
729
 
struct intel_spec *
730
 
intel_spec_load_from_path(const struct intel_device_info *devinfo,
731
 
                          const char *path)
732
 
{
733
 
   size_t filename_len = strlen(path) + 20;
734
 
   char *filename = malloc(filename_len);
735
 
 
736
 
   ASSERTED size_t len = snprintf(filename, filename_len, "%s/gen%i.xml",
737
 
                  path, devinfo->ver);
738
 
   assert(len < filename_len);
739
 
 
740
 
   struct intel_spec *spec = intel_spec_load_filename(filename);
741
 
   free(filename);
742
 
 
743
 
   return spec;
744
 
}
745
 
 
746
 
void intel_spec_destroy(struct intel_spec *spec)
747
 
{
748
 
   ralloc_free(spec);
749
 
}
750
 
 
751
 
struct intel_group *
752
 
intel_spec_find_instruction(struct intel_spec *spec,
753
 
                            enum drm_i915_gem_engine_class engine,
754
 
                            const uint32_t *p)
755
 
{
756
 
   hash_table_foreach(spec->commands, entry) {
757
 
      struct intel_group *command = entry->data;
758
 
      uint32_t opcode = *p & command->opcode_mask;
759
 
      if ((command->engine_mask & I915_ENGINE_CLASS_TO_MASK(engine)) &&
760
 
           opcode == command->opcode)
761
 
         return command;
762
 
   }
763
 
 
764
 
   return NULL;
765
 
}
766
 
 
767
 
struct intel_field *
768
 
intel_group_find_field(struct intel_group *group, const char *name)
769
 
{
770
 
   char path[256];
771
 
   snprintf(path, sizeof(path), "%s/%s", group->name, name);
772
 
 
773
 
   struct intel_spec *spec = group->spec;
774
 
   struct hash_entry *entry = _mesa_hash_table_search(spec->access_cache,
775
 
                                                      path);
776
 
   if (entry)
777
 
      return entry->data;
778
 
 
779
 
   struct intel_field *field = group->fields;
780
 
   while (field) {
781
 
      if (strcmp(field->name, name) == 0) {
782
 
         _mesa_hash_table_insert(spec->access_cache,
783
 
                                 ralloc_strdup(spec, path),
784
 
                                 field);
785
 
         return field;
786
 
      }
787
 
      field = field->next;
788
 
   }
789
 
 
790
 
   return NULL;
791
 
}
792
 
 
793
 
int
794
 
intel_group_get_length(struct intel_group *group, const uint32_t *p)
795
 
{
796
 
   if (group) {
797
 
      if (group->fixed_length)
798
 
         return group->dw_length;
799
 
      else {
800
 
         struct intel_field *field = group->dword_length_field;
801
 
         if (field) {
802
 
            return field_value(p[0], field->start, field->end) + group->bias;
803
 
         }
804
 
      }
805
 
   }
806
 
 
807
 
   uint32_t h = p[0];
808
 
   uint32_t type = field_value(h, 29, 31);
809
 
 
810
 
   switch (type) {
811
 
   case 0: /* MI */ {
812
 
      uint32_t opcode = field_value(h, 23, 28);
813
 
      if (opcode < 16)
814
 
         return 1;
815
 
      else
816
 
         return field_value(h, 0, 7) + 2;
817
 
      break;
818
 
   }
819
 
 
820
 
   case 2: /* BLT */ {
821
 
      return field_value(h, 0, 7) + 2;
822
 
   }
823
 
 
824
 
   case 3: /* Render */ {
825
 
      uint32_t subtype = field_value(h, 27, 28);
826
 
      uint32_t opcode = field_value(h, 24, 26);
827
 
      uint16_t whole_opcode = field_value(h, 16, 31);
828
 
      switch (subtype) {
829
 
      case 0:
830
 
         if (whole_opcode == 0x6104 /* PIPELINE_SELECT_965 */)
831
 
            return 1;
832
 
         else if (opcode < 2)
833
 
            return field_value(h, 0, 7) + 2;
834
 
         else
835
 
            return -1;
836
 
      case 1:
837
 
         if (opcode < 2)
838
 
            return 1;
839
 
         else
840
 
            return -1;
841
 
      case 2: {
842
 
         if (opcode == 0)
843
 
            return field_value(h, 0, 7) + 2;
844
 
         else if (opcode < 3)
845
 
            return field_value(h, 0, 15) + 2;
846
 
         else
847
 
            return -1;
848
 
      }
849
 
      case 3:
850
 
         if (whole_opcode == 0x780b)
851
 
            return 1;
852
 
         else if (opcode < 4)
853
 
            return field_value(h, 0, 7) + 2;
854
 
         else
855
 
            return -1;
856
 
      }
857
 
   }
858
 
   }
859
 
 
860
 
   return -1;
861
 
}
862
 
 
863
 
static const char *
864
 
intel_get_enum_name(struct intel_enum *e, uint64_t value)
865
 
{
866
 
   for (int i = 0; i < e->nvalues; i++) {
867
 
      if (e->values[i]->value == value) {
868
 
         return e->values[i]->name;
869
 
      }
870
 
   }
871
 
   return NULL;
872
 
}
873
 
 
874
 
static bool
875
 
iter_more_fields(const struct intel_field_iterator *iter)
876
 
{
877
 
   return iter->field != NULL && iter->field->next != NULL;
878
 
}
879
 
 
880
 
static uint32_t
881
 
iter_array_offset_bits(const struct intel_field_iterator *iter)
882
 
{
883
 
   if (iter->level == 0)
884
 
      return 0;
885
 
 
886
 
   uint32_t offset = 0;
887
 
   const struct intel_group *group = iter->groups[1];
888
 
   for (int level = 1; level <= iter->level; level++, group = iter->groups[level]) {
889
 
      uint32_t array_idx = iter->array_iter[level];
890
 
      offset += group->array_offset + array_idx * group->array_item_size;
891
 
   }
892
 
 
893
 
   return offset;
894
 
}
895
 
 
896
 
/* Checks whether we have more items in the array to iterate, or more arrays to
897
 
 * iterate through.
898
 
 */
899
 
/* descend into a non-array field */
900
 
static void
901
 
iter_push_array(struct intel_field_iterator *iter)
902
 
{
903
 
   assert(iter->level >= 0);
904
 
 
905
 
   iter->group = iter->field->array;
906
 
   iter->level++;
907
 
   assert(iter->level < DECODE_MAX_ARRAY_DEPTH);
908
 
   iter->groups[iter->level] = iter->group;
909
 
   iter->array_iter[iter->level] = 0;
910
 
 
911
 
   assert(iter->group->fields != NULL); /* an empty <group> makes no sense */
912
 
   iter->field = iter->group->fields;
913
 
   iter->fields[iter->level] = iter->field;
914
 
}
915
 
 
916
 
static void
917
 
iter_pop_array(struct intel_field_iterator *iter)
918
 
{
919
 
   assert(iter->level > 0);
920
 
 
921
 
   iter->level--;
922
 
   iter->field = iter->fields[iter->level];
923
 
   iter->group = iter->groups[iter->level];
924
 
}
925
 
 
926
 
static void
927
 
iter_start_field(struct intel_field_iterator *iter, struct intel_field *field)
928
 
{
929
 
   iter->field = field;
930
 
   iter->fields[iter->level] = field;
931
 
 
932
 
   while (iter->field->array)
933
 
      iter_push_array(iter);
934
 
 
935
 
   int array_member_offset = iter_array_offset_bits(iter);
936
 
 
937
 
   iter->start_bit = array_member_offset + iter->field->start;
938
 
   iter->end_bit = array_member_offset + iter->field->end;
939
 
   iter->struct_desc = NULL;
940
 
}
941
 
 
942
 
static void
943
 
iter_advance_array(struct intel_field_iterator *iter)
944
 
{
945
 
   assert(iter->level > 0);
946
 
   int lvl = iter->level;
947
 
 
948
 
   if (iter->group->variable)
949
 
      iter->array_iter[lvl]++;
950
 
   else {
951
 
      if ((iter->array_iter[lvl] + 1) < iter->group->array_count) {
952
 
         iter->array_iter[lvl]++;
953
 
      }
954
 
   }
955
 
 
956
 
   iter_start_field(iter, iter->group->fields);
957
 
}
958
 
 
959
 
static bool
960
 
iter_more_array_elems(const struct intel_field_iterator *iter)
961
 
{
962
 
   int lvl = iter->level;
963
 
   assert(lvl >= 0);
964
 
 
965
 
   if (iter->group->variable) {
966
 
      int length = intel_group_get_length(iter->group, iter->p);
967
 
      assert(length >= 0 && "error the length is unknown!");
968
 
      return iter_array_offset_bits(iter) + iter->group->array_item_size <
969
 
         (length * 32);
970
 
   } else {
971
 
      return (iter->array_iter[lvl] + 1) < iter->group->array_count;
972
 
   }
973
 
}
974
 
 
975
 
static bool
976
 
iter_advance_field(struct intel_field_iterator *iter)
977
 
{
978
 
   /* Keep looping while we either have more fields to look at, or we are
979
 
    * inside a <group> and can go up a level.
980
 
    */
981
 
   while (iter_more_fields(iter) || iter->level > 0) {
982
 
      if (iter_more_fields(iter)) {
983
 
         iter_start_field(iter, iter->field->next);
984
 
         return true;
985
 
      }
986
 
 
987
 
      assert(iter->level >= 0);
988
 
 
989
 
      if (iter_more_array_elems(iter)) {
990
 
         iter_advance_array(iter);
991
 
         return true;
992
 
      }
993
 
 
994
 
      /* At this point, we reached the end of the <group> and were on the last
995
 
       * iteration. So it's time to go back to the parent and then advance the
996
 
       * field.
997
 
       */
998
 
      iter_pop_array(iter);
999
 
   }
1000
 
 
1001
 
   return false;
1002
 
}
1003
 
 
1004
 
static bool
1005
 
iter_decode_field_raw(struct intel_field_iterator *iter, uint64_t *qw)
1006
 
{
1007
 
   *qw = 0;
1008
 
 
1009
 
   int field_start = iter->p_bit + iter->start_bit;
1010
 
   int field_end = iter->p_bit + iter->end_bit;
1011
 
 
1012
 
   const uint32_t *p = iter->p + (iter->start_bit / 32);
1013
 
   if (iter->p_end && p >= iter->p_end)
1014
 
      return false;
1015
 
 
1016
 
   if ((field_end - field_start) > 32) {
1017
 
      if (!iter->p_end || (p + 1) < iter->p_end)
1018
 
         *qw = ((uint64_t) p[1]) << 32;
1019
 
      *qw |= p[0];
1020
 
   } else
1021
 
      *qw = p[0];
1022
 
 
1023
 
   *qw = field_value(*qw, field_start, field_end);
1024
 
 
1025
 
   /* Address & offset types have to be aligned to dwords, their start bit is
1026
 
    * a reminder of the alignment requirement.
1027
 
    */
1028
 
   if (iter->field->type.kind == INTEL_TYPE_ADDRESS ||
1029
 
       iter->field->type.kind == INTEL_TYPE_OFFSET)
1030
 
      *qw <<= field_start % 32;
1031
 
 
1032
 
   return true;
1033
 
}
1034
 
 
1035
 
static bool
1036
 
iter_decode_field(struct intel_field_iterator *iter)
1037
 
{
1038
 
   union {
1039
 
      uint64_t qw;
1040
 
      float f;
1041
 
   } v;
1042
 
 
1043
 
   if (iter->field->name)
1044
 
      snprintf(iter->name, sizeof(iter->name), "%s", iter->field->name);
1045
 
   else
1046
 
      memset(iter->name, 0, sizeof(iter->name));
1047
 
 
1048
 
   memset(&v, 0, sizeof(v));
1049
 
 
1050
 
   if (!iter_decode_field_raw(iter, &iter->raw_value))
1051
 
      return false;
1052
 
 
1053
 
   const char *enum_name = NULL;
1054
 
 
1055
 
   v.qw = iter->raw_value;
1056
 
   switch (iter->field->type.kind) {
1057
 
   case INTEL_TYPE_UNKNOWN:
1058
 
   case INTEL_TYPE_INT: {
1059
 
      snprintf(iter->value, sizeof(iter->value), "%"PRId64, v.qw);
1060
 
      enum_name = intel_get_enum_name(&iter->field->inline_enum, v.qw);
1061
 
      break;
1062
 
   }
1063
 
   case INTEL_TYPE_MBZ:
1064
 
   case INTEL_TYPE_UINT: {
1065
 
      snprintf(iter->value, sizeof(iter->value), "%"PRIu64, v.qw);
1066
 
      enum_name = intel_get_enum_name(&iter->field->inline_enum, v.qw);
1067
 
      break;
1068
 
   }
1069
 
   case INTEL_TYPE_BOOL: {
1070
 
      const char *true_string =
1071
 
         iter->print_colors ? "\e[0;35mtrue\e[0m" : "true";
1072
 
      snprintf(iter->value, sizeof(iter->value), "%s",
1073
 
               v.qw ? true_string : "false");
1074
 
      break;
1075
 
   }
1076
 
   case INTEL_TYPE_FLOAT:
1077
 
      snprintf(iter->value, sizeof(iter->value), "%f", v.f);
1078
 
      break;
1079
 
   case INTEL_TYPE_ADDRESS:
1080
 
   case INTEL_TYPE_OFFSET:
1081
 
      snprintf(iter->value, sizeof(iter->value), "0x%08"PRIx64, v.qw);
1082
 
      break;
1083
 
   case INTEL_TYPE_STRUCT:
1084
 
      snprintf(iter->value, sizeof(iter->value), "<struct %s>",
1085
 
               iter->field->type.intel_struct->name);
1086
 
      iter->struct_desc =
1087
 
         intel_spec_find_struct(iter->group->spec,
1088
 
                                iter->field->type.intel_struct->name);
1089
 
      break;
1090
 
   case INTEL_TYPE_UFIXED:
1091
 
      snprintf(iter->value, sizeof(iter->value), "%f",
1092
 
               (float) v.qw / (1 << iter->field->type.f));
1093
 
      break;
1094
 
   case INTEL_TYPE_SFIXED: {
1095
 
      /* Sign extend before converting */
1096
 
      int bits = iter->field->type.i + iter->field->type.f + 1;
1097
 
      int64_t v_sign_extend = ((int64_t)(v.qw << (64 - bits))) >> (64 - bits);
1098
 
      snprintf(iter->value, sizeof(iter->value), "%f",
1099
 
               (float) v_sign_extend / (1 << iter->field->type.f));
1100
 
      break;
1101
 
   }
1102
 
   case INTEL_TYPE_MBO:
1103
 
       break;
1104
 
   case INTEL_TYPE_ENUM: {
1105
 
      snprintf(iter->value, sizeof(iter->value), "%"PRId64, v.qw);
1106
 
      enum_name = intel_get_enum_name(iter->field->type.intel_enum, v.qw);
1107
 
      break;
1108
 
   }
1109
 
   }
1110
 
 
1111
 
   if (strlen(iter->group->name) == 0) {
1112
 
      int length = strlen(iter->name);
1113
 
      assert(iter->level >= 0);
1114
 
 
1115
 
      int level = 1;
1116
 
      char *buf = iter->name + length;
1117
 
      while (level <= iter->level) {
1118
 
         int printed = snprintf(buf, sizeof(iter->name) - length,
1119
 
                                "[%i]", iter->array_iter[level]);
1120
 
         level++;
1121
 
         length += printed;
1122
 
         buf += printed;
1123
 
      }
1124
 
   }
1125
 
 
1126
 
   if (enum_name) {
1127
 
      int length = strlen(iter->value);
1128
 
      snprintf(iter->value + length, sizeof(iter->value) - length,
1129
 
               " (%s)", enum_name);
1130
 
   } else if (strcmp(iter->name, "Surface Format") == 0 ||
1131
 
              strcmp(iter->name, "Source Element Format") == 0) {
1132
 
      if (isl_format_is_valid((enum isl_format)v.qw)) {
1133
 
         const char *fmt_name = isl_format_get_name((enum isl_format)v.qw);
1134
 
         int length = strlen(iter->value);
1135
 
         snprintf(iter->value + length, sizeof(iter->value) - length,
1136
 
                  " (%s)", fmt_name);
1137
 
      }
1138
 
   }
1139
 
 
1140
 
   return true;
1141
 
}
1142
 
 
1143
 
void
1144
 
intel_field_iterator_init(struct intel_field_iterator *iter,
1145
 
                          struct intel_group *group,
1146
 
                          const uint32_t *p, int p_bit,
1147
 
                          bool print_colors)
1148
 
{
1149
 
   memset(iter, 0, sizeof(*iter));
1150
 
 
1151
 
   iter->groups[iter->level] = group;
1152
 
   iter->group = group;
1153
 
   iter->p = p;
1154
 
   iter->p_bit = p_bit;
1155
 
 
1156
 
   int length = intel_group_get_length(iter->group, iter->p);
1157
 
   assert(length >= 0 && "error the length is unknown!");
1158
 
   iter->p_end = length >= 0 ? &p[length] : NULL;
1159
 
   iter->print_colors = print_colors;
1160
 
}
1161
 
 
1162
 
bool
1163
 
intel_field_iterator_next(struct intel_field_iterator *iter)
1164
 
{
1165
 
   /* Initial condition */
1166
 
   if (!iter->field) {
1167
 
      if (iter->group->fields)
1168
 
         iter_start_field(iter, iter->group->fields);
1169
 
 
1170
 
      bool result = iter_decode_field(iter);
1171
 
      if (!result && iter->p_end) {
1172
 
         /* We're dealing with a non empty struct of length=0 (BLEND_STATE on
1173
 
          * Gen 7.5)
1174
 
          */
1175
 
         assert(iter->group->dw_length == 0);
1176
 
      }
1177
 
 
1178
 
      return result;
1179
 
   }
1180
 
 
1181
 
   if (!iter_advance_field(iter))
1182
 
      return false;
1183
 
 
1184
 
   if (!iter_decode_field(iter))
1185
 
      return false;
1186
 
 
1187
 
   return true;
1188
 
}
1189
 
 
1190
 
static void
1191
 
print_dword_header(FILE *outfile,
1192
 
                   struct intel_field_iterator *iter,
1193
 
                   uint64_t offset, uint32_t dword)
1194
 
{
1195
 
   fprintf(outfile, "0x%08"PRIx64":  0x%08x : Dword %d\n",
1196
 
           offset + 4 * dword, iter->p[dword], dword);
1197
 
}
1198
 
 
1199
 
bool
1200
 
intel_field_is_header(struct intel_field *field)
1201
 
{
1202
 
   uint32_t bits;
1203
 
 
1204
 
   /* Instructions are identified by the first DWord. */
1205
 
   if (field->start >= 32 ||
1206
 
       field->end >= 32)
1207
 
      return false;
1208
 
 
1209
 
   bits = (1ULL << (field->end - field->start + 1)) - 1;
1210
 
   bits <<= field->start;
1211
 
 
1212
 
   return (field->parent->opcode_mask & bits) != 0;
1213
 
}
1214
 
 
1215
 
void
1216
 
intel_print_group(FILE *outfile, struct intel_group *group, uint64_t offset,
1217
 
                  const uint32_t *p, int p_bit, bool color)
1218
 
{
1219
 
   struct intel_field_iterator iter;
1220
 
   int last_dword = -1;
1221
 
 
1222
 
   intel_field_iterator_init(&iter, group, p, p_bit, color);
1223
 
   while (intel_field_iterator_next(&iter)) {
1224
 
      int iter_dword = iter.end_bit / 32;
1225
 
      if (last_dword != iter_dword) {
1226
 
         for (int i = last_dword + 1; i <= iter_dword; i++)
1227
 
            print_dword_header(outfile, &iter, offset, i);
1228
 
         last_dword = iter_dword;
1229
 
      }
1230
 
      if (!intel_field_is_header(iter.field)) {
1231
 
         fprintf(outfile, "    %s: %s\n", iter.name, iter.value);
1232
 
         if (iter.struct_desc) {
1233
 
            int struct_dword = iter.start_bit / 32;
1234
 
            uint64_t struct_offset = offset + 4 * struct_dword;
1235
 
            intel_print_group(outfile, iter.struct_desc, struct_offset,
1236
 
                              &p[struct_dword], iter.start_bit % 32, color);
1237
 
         }
1238
 
      }
1239
 
   }
1240
 
}