~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/imagination/rogue/rogue_encode.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 © 2022 Imagination Technologies Ltd.
3
 
 *
4
 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
5
 
 * of this software and associated documentation files (the "Software"), to deal
6
 
 * in the Software without restriction, including without limitation the rights
7
 
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
 
 * copies of the Software, and to permit persons to whom the Software is
9
 
 * 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 THE
18
 
 * 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
 
#include <stdbool.h>
25
 
#include <stdint.h>
26
 
#include <stdio.h>
27
 
#include <stdlib.h>
28
 
#include <string.h>
29
 
 
30
 
#include "hwdef/rogue_hw_defs.h"
31
 
#include "rogue_encode.h"
32
 
#include "rogue_encoders.h"
33
 
#include "rogue_operand.h"
34
 
#include "rogue_shader.h"
35
 
#include "rogue_util.h"
36
 
#include "util/bitscan.h"
37
 
#include "util/macros.h"
38
 
 
39
 
static size_t rogue_encode_reg_bank(const struct rogue_operand *operand)
40
 
{
41
 
   switch (operand->type) {
42
 
   case ROGUE_OPERAND_TYPE_REG_INTERNAL:
43
 
   case ROGUE_OPERAND_TYPE_REG_PIXEL_OUT:
44
 
   case ROGUE_OPERAND_TYPE_REG_CONST:
45
 
      return 0;
46
 
   case ROGUE_OPERAND_TYPE_REG_TEMP:
47
 
      return 1;
48
 
   case ROGUE_OPERAND_TYPE_REG_VERTEX_IN:
49
 
      return 2;
50
 
   case ROGUE_OPERAND_TYPE_REG_COEFF:
51
 
      return 3;
52
 
   case ROGUE_OPERAND_TYPE_REG_SHARED:
53
 
      return 4;
54
 
   default:
55
 
      break;
56
 
   }
57
 
 
58
 
   unreachable("Unimplemented register bank.");
59
 
}
60
 
 
61
 
/**
62
 
 * \brief Field mapping type.
63
 
 */
64
 
enum rogue_map_type {
65
 
   ROGUE_MAP_TYPE_INSTR_FLAG = 0,
66
 
   ROGUE_MAP_TYPE_OPERAND_FLAG,
67
 
   ROGUE_MAP_TYPE_OPERAND,
68
 
 
69
 
   ROGUE_MAP_TYPE_COUNT,
70
 
};
71
 
 
72
 
/**
73
 
 * \brief Field mapping rule description.
74
 
 */
75
 
struct rogue_field_mapping {
76
 
   /* Type of mapping being performed. */
77
 
   enum rogue_map_type type;
78
 
 
79
 
   /* Index of the source operand/flag being mapped. */
80
 
   size_t index;
81
 
 
82
 
   /* List of ranges to perform mapping. */
83
 
   struct rogue_rangelist rangelist;
84
 
 
85
 
   /* Function used to encode the input into the value to be mapped. */
86
 
   field_encoder_t encoder_fn;
87
 
};
88
 
 
89
 
/**
90
 
 * \brief Instruction encoding rule description.
91
 
 */
92
 
struct rogue_instr_encoding {
93
 
   /* Number of bytes making up the base mask. */
94
 
   size_t num_bytes;
95
 
   /* Base mask bytes. */
96
 
   uint8_t *bytes;
97
 
 
98
 
   /* Number of field mappings for this instruction. */
99
 
   size_t num_mappings;
100
 
   /* Field mappings. */
101
 
   struct rogue_field_mapping *mappings;
102
 
};
103
 
 
104
 
static const
105
 
struct rogue_instr_encoding instr_encodings[ROGUE_OP_COUNT] = {
106
 
        [ROGUE_OP_NOP] = {
107
 
                .num_bytes = 8,
108
 
                .bytes = (uint8_t []) { 0x04, 0x80, 0x6e, 0x00, 0xf2, 0xff, 0xff, 0xff },
109
 
        },
110
 
 
111
 
        [ROGUE_OP_END_FRAG] = {
112
 
                .num_bytes = 8,
113
 
                .bytes = (uint8_t []) { 0x04, 0x80, 0xee, 0x00, 0xf2, 0xff, 0xff, 0xff },
114
 
        },
115
 
 
116
 
        [ROGUE_OP_END_VERT] = {
117
 
                .num_bytes = 8,
118
 
                .bytes = (uint8_t []) { 0x44, 0xa0, 0x80, 0x05, 0x00, 0x00, 0x00, 0xff },
119
 
        },
120
 
 
121
 
        [ROGUE_OP_WDF] = {
122
 
                .num_bytes = 8,
123
 
                .bytes = (uint8_t []) { 0x04, 0x80, 0x6a, 0xff, 0xf2, 0xff, 0xff, 0xff },
124
 
                .num_mappings = 1,
125
 
                .mappings = (struct rogue_field_mapping []) {
126
 
                        {
127
 
                                .type = ROGUE_MAP_TYPE_OPERAND,
128
 
                                .index = 0,
129
 
                                .rangelist = {
130
 
                                        .num_ranges = 1,
131
 
                                        .ranges = (struct rogue_bitrange []) {
132
 
                                                { .start = 47, .num = 1, },
133
 
                                        },
134
 
                                },
135
 
                                .encoder_fn = &rogue_encoder_drc,
136
 
                        },
137
 
                },
138
 
        },
139
 
 
140
 
        [ROGUE_OP_PIX_ITER_W] = {
141
 
                .num_bytes = 16,
142
 
                .bytes = (uint8_t []) { 0x48, 0x20, 0xb0, 0x01, 0x80, 0x40, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xff, 0xf1, 0xff },
143
 
                .num_mappings = 6,
144
 
                .mappings = (struct rogue_field_mapping []) {
145
 
                        /* Instruction flag mappings. */
146
 
                        {
147
 
                                .type = ROGUE_MAP_TYPE_INSTR_FLAG,
148
 
                                .index = ROGUE_INSTR_FLAG_SAT,
149
 
                                .rangelist = {
150
 
                                        .num_ranges = 1,
151
 
                                        .ranges = (struct rogue_bitrange []) {
152
 
                                                { .start = 100, .num = 1, },
153
 
                                        },
154
 
                                },
155
 
                                .encoder_fn = NULL,
156
 
                        },
157
 
                        /* Operand mappings. */
158
 
                        {
159
 
                                .type = ROGUE_MAP_TYPE_OPERAND,
160
 
                                .index = 0,
161
 
                                .rangelist = {
162
 
                                        .num_ranges = 5,
163
 
                                        .ranges = (struct rogue_bitrange []) {
164
 
                                                { .start = 43, .num = 2, }, /* SB3(2..1) */
165
 
                                                { .start = 54, .num = 1, }, /* SB3(0) */
166
 
                                                { .start = 34, .num = 3, }, /* S3(10..8) */
167
 
                                                { .start = 41, .num = 2, }, /* S3(7..6) */
168
 
                                                { .start = 53, .num = 6, }, /* S3(5..0) */
169
 
                                        },
170
 
                                },
171
 
                                .encoder_fn = &rogue_encoder_reg_3_11,
172
 
                        },
173
 
                        {
174
 
                                .type = ROGUE_MAP_TYPE_OPERAND,
175
 
                                .index = 1,
176
 
                                .rangelist = {
177
 
                                        .num_ranges = 1,
178
 
                                        .ranges = (struct rogue_bitrange []) {
179
 
                                                { .start = 59, .num = 1, },
180
 
                                        },
181
 
                                },
182
 
                                .encoder_fn = &rogue_encoder_drc,
183
 
                        },
184
 
                        {
185
 
                                .type = ROGUE_MAP_TYPE_OPERAND,
186
 
                                .index = 2,
187
 
                                .rangelist = {
188
 
                                        .num_ranges = 6,
189
 
                                        .ranges = (struct rogue_bitrange []) {
190
 
                                                { .start = 59, .num = 1, }, /* SB0(2) */
191
 
                                                { .start = 76, .num = 1, }, /* SB0(1) */
192
 
                                                { .start = 94, .num = 1, }, /* SB0(0) */
193
 
                                                { .start = 57, .num = 1, }, /* S0(7) */
194
 
                                                { .start = 74, .num = 1, }, /* S0(6) */
195
 
                                                { .start = 93, .num = 6, }, /* S0(5..0) */
196
 
                                        },
197
 
                                },
198
 
                                .encoder_fn = &rogue_encoder_reg_3_8,
199
 
                        },
200
 
                        {
201
 
                                .type = ROGUE_MAP_TYPE_OPERAND,
202
 
                                .index = 3,
203
 
                                .rangelist = {
204
 
                                        .num_ranges = 4,
205
 
                                        .ranges = (struct rogue_bitrange []) {
206
 
                                                { .start = 63, .num = 1, }, /* SB2(2) */
207
 
                                                { .start = 71, .num = 2, }, /* SB2(1..0) */
208
 
                                                { .start = 62, .num = 2, }, /* S2(7..6) */
209
 
                                                { .start = 69, .num = 6, }, /* S2(5..0) */
210
 
                                        },
211
 
                                },
212
 
                                .encoder_fn = &rogue_encoder_reg_3_8,
213
 
                        },
214
 
                        {
215
 
                                .type = ROGUE_MAP_TYPE_OPERAND,
216
 
                                .index = 4,
217
 
                                .rangelist = {
218
 
                                        .num_ranges = 1,
219
 
                                        .ranges = (struct rogue_bitrange []) {
220
 
                                                { .start = 99, .num = 4, },
221
 
                                        },
222
 
                                },
223
 
                                .encoder_fn = &rogue_encoder_ls_1_16,
224
 
                        },
225
 
                },
226
 
        },
227
 
 
228
 
        [ROGUE_OP_MAX] = {
229
 
                .num_bytes = 16,
230
 
                .bytes = (uint8_t []) { 0x68, 0x42, 0xd0, 0x3c, 0xfa, 0x10, 0x87, 0x80, 0xc0, 0x80, 0x10, 0x00, 0x32, 0x80, 0x00, 0xff },
231
 
                .num_mappings = 3,
232
 
                .mappings = (struct rogue_field_mapping []) {
233
 
                        /* Operand mappings. */
234
 
                        {
235
 
                                .type = ROGUE_MAP_TYPE_OPERAND,
236
 
                                .index = 0,
237
 
                                .rangelist = {
238
 
                                        .num_ranges = 5,
239
 
                                        .ranges = (struct rogue_bitrange []) {
240
 
                                                { .start = 11, .num = 2, }, /* DBn(2..1) */
241
 
                                                { .start = 22, .num = 1, }, /* DBn(0) */
242
 
                                                { .start = 14, .num = 3, }, /* Dn(10..8) */
243
 
                                                { .start = 9, .num = 2, }, /* Dn(7..6) */
244
 
                                                { .start = 21, .num = 6, }, /* Dn(5..0) */
245
 
                                        },
246
 
                                },
247
 
                                .encoder_fn = &rogue_encoder_reg_3_11,
248
 
                        },
249
 
                        {
250
 
                                .type = ROGUE_MAP_TYPE_OPERAND,
251
 
                                .index = 1,
252
 
                                .rangelist = {
253
 
                                        .num_ranges = 7,
254
 
                                        .ranges = (struct rogue_bitrange []) {
255
 
                                                { .start = 43, .num = 1, }, /* SB0(2) */
256
 
                                                { .start = 52, .num = 1, }, /* SB0(1) */
257
 
                                                { .start = 70, .num = 1, }, /* SB0(0) */
258
 
                                                { .start = 47, .num = 3, }, /* S0(10..8) */
259
 
                                                { .start = 41, .num = 1, }, /* S0(7) */
260
 
                                                { .start = 50, .num = 1, }, /* S0(6) */
261
 
                                                { .start = 69, .num = 6, }, /* S0(5..0) */
262
 
                                        },
263
 
                                },
264
 
                                .encoder_fn = &rogue_encoder_reg_3_11,
265
 
                        },
266
 
                        {
267
 
                                .type = ROGUE_MAP_TYPE_OPERAND,
268
 
                                .index = 2,
269
 
                                .rangelist = {
270
 
                                        .num_ranges = 5,
271
 
                                        .ranges = (struct rogue_bitrange []) {
272
 
                                                { .start = 51, .num = 1, }, /* SB1(1) */
273
 
                                                { .start = 61, .num = 1, }, /* SB1(0) */
274
 
                                                { .start = 40, .num = 1, }, /* S1(7) */
275
 
                                                { .start = 49, .num = 2, }, /* S1(6..5) */
276
 
                                                { .start = 60, .num = 5, }, /* S1(4..0) */
277
 
                                        },
278
 
                                },
279
 
                                .encoder_fn = &rogue_encoder_reg_2_8,
280
 
                        },
281
 
                },
282
 
        },
283
 
 
284
 
        [ROGUE_OP_MIN] = {
285
 
                .num_bytes = 16,
286
 
                .bytes = (uint8_t []) { 0x68, 0x42, 0xd0, 0x3c, 0xf0, 0x11, 0x87, 0x80, 0xc0, 0x80, 0x10, 0x00, 0x32, 0x80, 0x00, 0xff },
287
 
                .num_mappings = 3,
288
 
                .mappings = (struct rogue_field_mapping []) {
289
 
                        /* Operand mappings. */
290
 
                        {
291
 
                                .type = ROGUE_MAP_TYPE_OPERAND,
292
 
                                .index = 0,
293
 
                                .rangelist = {
294
 
                                        .num_ranges = 5,
295
 
                                        .ranges = (struct rogue_bitrange []) {
296
 
                                                { .start = 11, .num = 2, }, /* DBn(2..1) */
297
 
                                                { .start = 22, .num = 1, }, /* DBn(0) */
298
 
                                                { .start = 14, .num = 3, }, /* Dn(10..8) */
299
 
                                                { .start = 9, .num = 2, }, /* Dn(7..6) */
300
 
                                                { .start = 21, .num = 6, }, /* Dn(5..0) */
301
 
                                        },
302
 
                                },
303
 
                                .encoder_fn = &rogue_encoder_reg_3_11,
304
 
                        },
305
 
                        {
306
 
                                .type = ROGUE_MAP_TYPE_OPERAND,
307
 
                                .index = 1,
308
 
                                .rangelist = {
309
 
                                        .num_ranges = 7,
310
 
                                        .ranges = (struct rogue_bitrange []) {
311
 
                                                { .start = 43, .num = 1, }, /* SB0(2) */
312
 
                                                { .start = 52, .num = 1, }, /* SB0(1) */
313
 
                                                { .start = 70, .num = 1, }, /* SB0(0) */
314
 
                                                { .start = 47, .num = 3, }, /* S0(10..8) */
315
 
                                                { .start = 41, .num = 1, }, /* S0(7) */
316
 
                                                { .start = 50, .num = 1, }, /* S0(6) */
317
 
                                                { .start = 69, .num = 6, }, /* S0(5..0) */
318
 
                                        },
319
 
                                },
320
 
                                .encoder_fn = &rogue_encoder_reg_3_11,
321
 
                        },
322
 
                        {
323
 
                                .type = ROGUE_MAP_TYPE_OPERAND,
324
 
                                .index = 2,
325
 
                                .rangelist = {
326
 
                                        .num_ranges = 5,
327
 
                                        .ranges = (struct rogue_bitrange []) {
328
 
                                                { .start = 51, .num = 1, }, /* SB1(1) */
329
 
                                                { .start = 61, .num = 1, }, /* SB1(0) */
330
 
                                                { .start = 40, .num = 1, }, /* S1(7) */
331
 
                                                { .start = 49, .num = 2, }, /* S1(6..5) */
332
 
                                                { .start = 60, .num = 5, }, /* S1(4..0) */
333
 
                                        },
334
 
                                },
335
 
                                .encoder_fn = &rogue_encoder_reg_2_8,
336
 
                        },
337
 
                },
338
 
        },
339
 
 
340
 
        [ROGUE_OP_PACK_U8888] = {
341
 
                .num_bytes = 16,
342
 
                .bytes = (uint8_t []) { 0x58, 0x92, 0x06, 0x9c, 0x20, 0x80, 0x00, 0x00, 0x00, 0x2c, 0x80, 0x00, 0xf2, 0xff, 0xff, 0xff },
343
 
                .num_mappings = 2,
344
 
                .mappings = (struct rogue_field_mapping []) {
345
 
                        /* Operand mappings. */
346
 
                        {
347
 
                                .type = ROGUE_MAP_TYPE_OPERAND,
348
 
                                .index = 0,
349
 
                                .rangelist = {
350
 
                                        .num_ranges = 5,
351
 
                                        .ranges = (struct rogue_bitrange []) {
352
 
                                                { .start = 35, .num = 2, }, /* DBn(2..1) */
353
 
                                                { .start = 46, .num = 1, }, /* DBn(0) */
354
 
                                                { .start = 38, .num = 3, }, /* Dn(10..8) */
355
 
                                                { .start = 33, .num = 2, }, /* Dn(7..6) */
356
 
                                                { .start = 45, .num = 6, }, /* Dn(5..0) */
357
 
                                        },
358
 
                                },
359
 
                                .encoder_fn = &rogue_encoder_reg_3_11,
360
 
                        },
361
 
                        {
362
 
                                .type = ROGUE_MAP_TYPE_OPERAND,
363
 
                                .index = 1,
364
 
                                .rangelist = {
365
 
                                        .num_ranges = 5,
366
 
                                        .ranges = (struct rogue_bitrange []) {
367
 
                                                { .start = 75, .num = 2, }, /* SB0(2..1) */
368
 
                                                { .start = 86, .num = 1, }, /* SB0(0) */
369
 
                                                { .start = 66, .num = 3, }, /* S0(10..8) */
370
 
                                                { .start = 73, .num = 2, }, /* S0(7..6) */
371
 
                                                { .start = 85, .num = 6, }, /* S0(5..0) */
372
 
                                        },
373
 
                                },
374
 
                                .encoder_fn = &rogue_encoder_reg_3_11,
375
 
                        },
376
 
                },
377
 
        },
378
 
 
379
 
        [ROGUE_OP_MOV] = {
380
 
                .num_bytes = 16,
381
 
                .bytes = (uint8_t []) { 0x48, 0x42, 0xd0, 0x3f, 0x87, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xf2, 0xff, 0xff, 0xff },
382
 
                .num_mappings = 3,
383
 
                .mappings = (struct rogue_field_mapping []) {
384
 
                        /* Instruction flag mappings. */
385
 
                        {
386
 
                                .type = ROGUE_MAP_TYPE_INSTR_FLAG,
387
 
                                .index = ROGUE_INSTR_FLAG_OLCHK,
388
 
                                .rangelist = {
389
 
                                        .num_ranges = 1,
390
 
                                        .ranges = (struct rogue_bitrange []) {
391
 
                                                { .start = 115, .num = 1, },
392
 
                                        },
393
 
                                },
394
 
                                .encoder_fn = NULL,
395
 
                        },
396
 
                        /* Operand mappings. */
397
 
                        {
398
 
                                .type = ROGUE_MAP_TYPE_OPERAND,
399
 
                                .index = 0,
400
 
                                .rangelist = {
401
 
                                        .num_ranges = 5,
402
 
                                        .ranges = (struct rogue_bitrange []) {
403
 
                                                { .start = 35, .num = 2, }, /* DBn(2..1) */
404
 
                                                { .start = 46, .num = 1, }, /* DBn(0) */
405
 
                                                { .start = 38, .num = 3, }, /* Dn(10..8) */
406
 
                                                { .start = 33, .num = 2, }, /* Dn(7..6) */
407
 
                                                { .start = 45, .num = 6, }, /* Dn(5..0) */
408
 
                                        },
409
 
                                },
410
 
                                .encoder_fn = &rogue_encoder_reg_3_11,
411
 
                        },
412
 
                        {
413
 
                                .type = ROGUE_MAP_TYPE_OPERAND,
414
 
                                .index = 1,
415
 
                                .rangelist = {
416
 
                                        .num_ranges = 5,
417
 
                                        .ranges = (struct rogue_bitrange []) {
418
 
                                                { .start = 75, .num = 2, }, /* SB0(2..1) */
419
 
                                                { .start = 86, .num = 1, }, /* SB0(0) */
420
 
                                                { .start = 66, .num = 3, }, /* S0(10..8) */
421
 
                                                { .start = 73, .num = 2, }, /* S0(7..6) */
422
 
                                                { .start = 85, .num = 6, }, /* S0(5..0) */
423
 
                                        },
424
 
                                },
425
 
                                .encoder_fn = &rogue_encoder_reg_3_11,
426
 
                        },
427
 
                },
428
 
        },
429
 
 
430
 
        [ROGUE_OP_MOV_IMM] = {
431
 
                .num_bytes = 16,
432
 
                .bytes = (uint8_t []) { 0x88, 0x92, 0x40, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xf2, 0xff, 0xff, 0xff },
433
 
                .num_mappings = 2,
434
 
                .mappings = (struct rogue_field_mapping []) {
435
 
                        /* Operand mappings. */
436
 
                        {
437
 
                                .type = ROGUE_MAP_TYPE_OPERAND,
438
 
                                .index = 0,
439
 
                                .rangelist = {
440
 
                                        .num_ranges = 5,
441
 
                                        .ranges = (struct rogue_bitrange []) {
442
 
                                                { .start = 35, .num = 2, }, /* DBn(2..1) */
443
 
                                                { .start = 46, .num = 1, }, /* DBn(0) */
444
 
                                                { .start = 38, .num = 3, }, /* Dn(10..8) */
445
 
                                                { .start = 33, .num = 2, }, /* Dn(7..6) */
446
 
                                                { .start = 45, .num = 6, }, /* Dn(5..0) */
447
 
                                        },
448
 
                                },
449
 
                                .encoder_fn = &rogue_encoder_reg_3_11,
450
 
                        },
451
 
                        {
452
 
                                .type = ROGUE_MAP_TYPE_OPERAND,
453
 
                                .index = 1,
454
 
                                .rangelist = {
455
 
                                        .num_ranges = 4,
456
 
                                        .ranges = (struct rogue_bitrange []) {
457
 
                                                { .start = 71, .num = 8, }, /* imm(31:24) */
458
 
                                                { .start = 79, .num = 8, }, /* imm(23:16) */
459
 
                                                { .start = 87, .num = 8, }, /* imm(15:8) */
460
 
                                                { .start = 95, .num = 8, }, /* imm(7:0) */
461
 
                                        },
462
 
                                },
463
 
                                .encoder_fn = &rogue_encoder_imm,
464
 
                        },
465
 
                },
466
 
        },
467
 
 
468
 
        [ROGUE_OP_FMA] = {
469
 
                .num_bytes = 16,
470
 
                .bytes = (uint8_t []) { 0x28, 0x02, 0xd0, 0x00, 0x80, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xff, 0xf1, 0xff },
471
 
                .num_mappings = 6,
472
 
                .mappings = (struct rogue_field_mapping []) {
473
 
                        /* Instruction flag mappings. */
474
 
                        {
475
 
                                .type = ROGUE_MAP_TYPE_INSTR_FLAG,
476
 
                                .index = ROGUE_INSTR_FLAG_SAT,
477
 
                                .rangelist = {
478
 
                                        .num_ranges = 1,
479
 
                                        .ranges = (struct rogue_bitrange []) {
480
 
                                                { .start = 104, .num = 1, },
481
 
                                        },
482
 
                                },
483
 
                                .encoder_fn = NULL,
484
 
                        },
485
 
                        {
486
 
                                .type = ROGUE_MAP_TYPE_INSTR_FLAG,
487
 
                                .index = ROGUE_INSTR_FLAG_LP,
488
 
                                .rangelist = {
489
 
                                        .num_ranges = 1,
490
 
                                        .ranges = (struct rogue_bitrange []) {
491
 
                                                { .start = 100, .num = 1, },
492
 
                                        },
493
 
                                },
494
 
                                .encoder_fn = NULL,
495
 
                        },
496
 
                        /* Operand mappings. */
497
 
                        {
498
 
                                .type = ROGUE_MAP_TYPE_OPERAND,
499
 
                                .index = 0,
500
 
                                .rangelist = {
501
 
                                        .num_ranges = 5,
502
 
                                        .ranges = (struct rogue_bitrange []) {
503
 
                                                { .start = 27, .num = 2, }, /* DBn(2..1) */
504
 
                                                { .start = 38, .num = 1, }, /* DBn(0) */
505
 
                                                { .start = 30, .num = 3, }, /* Dn(10..8) */
506
 
                                                { .start = 25, .num = 2, }, /* Dn(7..6) */
507
 
                                                { .start = 37, .num = 6, }, /* Dn(5..0) */
508
 
                                        },
509
 
                                },
510
 
                                .encoder_fn = &rogue_encoder_reg_3_11,
511
 
                        },
512
 
                        {
513
 
                                .type = ROGUE_MAP_TYPE_OPERAND,
514
 
                                .index = 1,
515
 
                                .rangelist = {
516
 
                                        .num_ranges = 6,
517
 
                                        .ranges = (struct rogue_bitrange []) {
518
 
                                                { .start = 59, .num = 1, }, /* SB0(2) */
519
 
                                                { .start = 76, .num = 1, }, /* SB0(1) */
520
 
                                                { .start = 94, .num = 1, }, /* SB0(0) */
521
 
                                                { .start = 57, .num = 1, }, /* S0(7) */
522
 
                                                { .start = 74, .num = 1, }, /* S0(6) */
523
 
                                                { .start = 93, .num = 6, }, /* S0(5..0) */
524
 
                                        },
525
 
                                },
526
 
                                .encoder_fn = &rogue_encoder_reg_3_8,
527
 
                        },
528
 
                        {
529
 
                                .type = ROGUE_MAP_TYPE_OPERAND,
530
 
                                .index = 2,
531
 
                                .rangelist = {
532
 
                                        .num_ranges = 5,
533
 
                                        .ranges = (struct rogue_bitrange []) {
534
 
                                                { .start = 75, .num = 1, }, /* SB1(1) */
535
 
                                                { .start = 85, .num = 1, }, /* SB1(0) */
536
 
                                                { .start = 56, .num = 1, }, /* S1(7) */
537
 
                                                { .start = 73, .num = 2, }, /* S1(6..5) */
538
 
                                                { .start = 84, .num = 5, }, /* S1(4..0) */
539
 
                                        },
540
 
                                },
541
 
                                .encoder_fn = &rogue_encoder_reg_2_8,
542
 
                        },
543
 
                        {
544
 
                                .type = ROGUE_MAP_TYPE_OPERAND,
545
 
                                .index = 3,
546
 
                                .rangelist = {
547
 
                                        .num_ranges = 4,
548
 
                                        .ranges = (struct rogue_bitrange []) {
549
 
                                                { .start = 63, .num = 1, }, /* SB2(2) */
550
 
                                                { .start = 71, .num = 2, }, /* SB2(1..0) */
551
 
                                                { .start = 62, .num = 2, }, /* S2(7..6) */
552
 
                                                { .start = 69, .num = 6, }, /* S2(5..0) */
553
 
                                        },
554
 
                                },
555
 
                                .encoder_fn = &rogue_encoder_reg_3_8,
556
 
                        },
557
 
                },
558
 
        },
559
 
 
560
 
        [ROGUE_OP_MUL] = {
561
 
                .num_bytes = 16,
562
 
                .bytes = (uint8_t []) { 0x28, 0x02, 0x40, 0x80, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0xff, 0xf2, 0xff, 0xff, 0xff },
563
 
                .num_mappings = 5,
564
 
                .mappings = (struct rogue_field_mapping []) {
565
 
                        /* Instruction flag mappings. */
566
 
                        {
567
 
                                .type = ROGUE_MAP_TYPE_INSTR_FLAG,
568
 
                                .index = ROGUE_INSTR_FLAG_SAT,
569
 
                                .rangelist = {
570
 
                                        .num_ranges = 1,
571
 
                                        .ranges = (struct rogue_bitrange []) {
572
 
                                                { .start = 108, .num = 1, },
573
 
                                        },
574
 
                                },
575
 
                                .encoder_fn = NULL,
576
 
                        },
577
 
                        {
578
 
                                .type = ROGUE_MAP_TYPE_INSTR_FLAG,
579
 
                                .index = ROGUE_INSTR_FLAG_LP,
580
 
                                .rangelist = {
581
 
                                        .num_ranges = 1,
582
 
                                        .ranges = (struct rogue_bitrange []) {
583
 
                                                { .start = 109, .num = 1, },
584
 
                                        },
585
 
                                },
586
 
                                .encoder_fn = NULL,
587
 
                        },
588
 
                        /* Operand mappings. */
589
 
                        {
590
 
                                .type = ROGUE_MAP_TYPE_OPERAND,
591
 
                                .index = 0,
592
 
                                .rangelist = {
593
 
                                        .num_ranges = 5,
594
 
                                        .ranges = (struct rogue_bitrange []) {
595
 
                                                { .start = 43, .num = 2, }, /* DBn(2..1) */
596
 
                                                { .start = 54, .num = 1, }, /* DBn(0) */
597
 
                                                { .start = 46, .num = 3, }, /* Dn(10..8) */
598
 
                                                { .start = 41, .num = 2, }, /* Dn(7..6) */
599
 
                                                { .start = 53, .num = 6, }, /* Dn(5..0) */
600
 
                                        },
601
 
                                },
602
 
                                .encoder_fn = &rogue_encoder_reg_3_11,
603
 
                        },
604
 
                        {
605
 
                                .type = ROGUE_MAP_TYPE_OPERAND,
606
 
                                .index = 1,
607
 
                                .rangelist = {
608
 
                                        .num_ranges = 7,
609
 
                                        .ranges = (struct rogue_bitrange []) {
610
 
                                                { .start = 75, .num = 1, }, /* SB0(2) */
611
 
                                                { .start = 84, .num = 1, }, /* SB0(1) */
612
 
                                                { .start = 102, .num = 1, }, /* SB0(0) */
613
 
                                                { .start = 79, .num = 3, }, /* S0(10..8) */
614
 
                                                { .start = 73, .num = 1, }, /* S0(7) */
615
 
                                                { .start = 82, .num = 1, }, /* S0(6) */
616
 
                                                { .start = 101, .num = 6, }, /* S0(5..0) */
617
 
                                        },
618
 
                                },
619
 
                                .encoder_fn = &rogue_encoder_reg_3_11,
620
 
                        },
621
 
                        {
622
 
                                .type = ROGUE_MAP_TYPE_OPERAND,
623
 
                                .index = 2,
624
 
                                .rangelist = {
625
 
                                        .num_ranges = 5,
626
 
                                        .ranges = (struct rogue_bitrange []) {
627
 
                                                { .start = 83, .num = 1, }, /* SB1(1) */
628
 
                                                { .start = 93, .num = 1, }, /* SB1(0) */
629
 
                                                { .start = 72, .num = 1, }, /* S1(7) */
630
 
                                                { .start = 81, .num = 2, }, /* S1(6..5) */
631
 
                                                { .start = 92, .num = 5, }, /* S1(4..0) */
632
 
                                        },
633
 
                                },
634
 
                                .encoder_fn = &rogue_encoder_reg_2_8,
635
 
                        },
636
 
                },
637
 
        },
638
 
 
639
 
        [ROGUE_OP_VTXOUT] = {
640
 
                .num_bytes = 16,
641
 
                .bytes = (uint8_t []) { 0x48, 0x20, 0x08, 0x00, 0x80, 0x00, 0x00, 0x00, 0x30, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff },
642
 
                .num_mappings = 2,
643
 
                .mappings = (struct rogue_field_mapping []) {
644
 
                        /* Operand mappings. */
645
 
                        {
646
 
                                .type = ROGUE_MAP_TYPE_OPERAND,
647
 
                                .index = 0,
648
 
                                .rangelist = {
649
 
                                        .num_ranges = 1,
650
 
                                        .ranges = (struct rogue_bitrange []) {
651
 
                                                { .start = 103, .num = 8, }, /* Immediate address. */
652
 
                                        },
653
 
                                },
654
 
                                .encoder_fn = &rogue_encoder_imm,
655
 
                        },
656
 
                        {
657
 
                                .type = ROGUE_MAP_TYPE_OPERAND,
658
 
                                .index = 1,
659
 
                                .rangelist = {
660
 
                                        .num_ranges = 5,
661
 
                                        .ranges = (struct rogue_bitrange []) {
662
 
                                                { .start = 83, .num = 2, }, /* SB0(2..1) */
663
 
                                                { .start = 94, .num = 1, }, /* SB0(0) */
664
 
                                                { .start = 74, .num = 3, }, /* S0(10..8) */
665
 
                                                { .start = 81, .num = 2, }, /* S0(7..6) */
666
 
                                                { .start = 93, .num = 6, }, /* S0(5..0) */
667
 
                                        },
668
 
                                },
669
 
                                .encoder_fn = &rogue_encoder_reg_3_11,
670
 
                        },
671
 
                },
672
 
        },
673
 
};
674
 
 
675
 
/**
676
 
 * \brief Applies a boolean flag encoding onto an instruction mask.
677
 
 *
678
 
 * \param[in] set Whether to set/unset the flag.
679
 
 * \param[in] mapping The field mapping to apply.
680
 
 * \param[in] instr_size The size of the instruction mask in bytes.
681
 
 * \param[in] instr_bytes The instruction mask.
682
 
 * \return true if encoding was successful.
683
 
 */
684
 
static bool rogue_encode_flag(bool set,
685
 
                              const struct rogue_field_mapping *mapping,
686
 
                              size_t instr_size,
687
 
                              uint8_t instr_bytes[instr_size])
688
 
{
689
 
   return rogue_distribute_value((uint64_t)set,
690
 
                                 &mapping->rangelist,
691
 
                                 instr_size,
692
 
                                 instr_bytes);
693
 
}
694
 
 
695
 
/**
696
 
 * \brief Applies an operand encoding onto an instruction mask.
697
 
 *
698
 
 * \param[in] operand The operand to apply.
699
 
 * \param[in] mapping The field mapping to apply.
700
 
 * \param[in] instr_size The size of the instruction mask in bytes.
701
 
 * \param[in] instr_bytes The instruction mask.
702
 
 * \return true if encoding was successful.
703
 
 */
704
 
static bool rogue_encode_operand(const struct rogue_operand *operand,
705
 
                                 const struct rogue_field_mapping *mapping,
706
 
                                 size_t instr_size,
707
 
                                 uint8_t instr_bytes[instr_size])
708
 
{
709
 
   uint64_t value = 0U;
710
 
 
711
 
   switch (operand->type) {
712
 
   case ROGUE_OPERAND_TYPE_REG_PIXEL_OUT:
713
 
      CHECKF(
714
 
         mapping->encoder_fn(&value,
715
 
                             2,
716
 
                             rogue_encode_reg_bank(operand),
717
 
                             operand->reg.number + ROGUE_PIXEL_OUT_REG_OFFSET),
718
 
         "Failed to encode pixel output register operand.");
719
 
      break;
720
 
   case ROGUE_OPERAND_TYPE_REG_INTERNAL:
721
 
      CHECKF(
722
 
         mapping->encoder_fn(&value,
723
 
                             2,
724
 
                             rogue_encode_reg_bank(operand),
725
 
                             operand->reg.number + ROGUE_INTERNAL_REG_OFFSET),
726
 
         "Failed to encode internal register operand.");
727
 
      break;
728
 
   case ROGUE_OPERAND_TYPE_REG_TEMP:
729
 
   case ROGUE_OPERAND_TYPE_REG_COEFF:
730
 
   case ROGUE_OPERAND_TYPE_REG_CONST:
731
 
   case ROGUE_OPERAND_TYPE_REG_SHARED:
732
 
   case ROGUE_OPERAND_TYPE_REG_VERTEX_IN:
733
 
      CHECKF(mapping->encoder_fn(&value,
734
 
                                 2,
735
 
                                 rogue_encode_reg_bank(operand),
736
 
                                 operand->reg.number),
737
 
             "Failed to encode register operand.");
738
 
      break;
739
 
 
740
 
   case ROGUE_OPERAND_TYPE_IMMEDIATE:
741
 
      CHECKF(mapping->encoder_fn(&value, 1, operand->immediate.value),
742
 
             "Failed to encode immediate operand.");
743
 
      break;
744
 
 
745
 
   case ROGUE_OPERAND_TYPE_DRC:
746
 
      CHECKF(mapping->encoder_fn(&value, 1, (uint64_t)operand->drc.number),
747
 
             "Failed to encode DRC operand.");
748
 
      break;
749
 
 
750
 
   default:
751
 
      return false;
752
 
   }
753
 
 
754
 
   CHECKF(rogue_distribute_value(value,
755
 
                                 &mapping->rangelist,
756
 
                                 instr_size,
757
 
                                 instr_bytes),
758
 
          "Failed to distribute value.");
759
 
 
760
 
   return true;
761
 
}
762
 
 
763
 
/**
764
 
 * \brief Applies operand and flag encodings to the base instruction bytes, then
765
 
 * writes the result to file pointer "fp".
766
 
 *
767
 
 * \param[in] instr The instruction to be encoded.
768
 
 * \param[in] fp The file pointer.
769
 
 * \return true if encoding was successful.
770
 
 */
771
 
bool rogue_encode_instr(const struct rogue_instr *instr, FILE *fp)
772
 
{
773
 
   const struct rogue_instr_encoding *instr_encoding;
774
 
   size_t instr_size;
775
 
   uint8_t instr_bytes[ROGUE_MAX_INSTR_BYTES];
776
 
 
777
 
   ASSERT_OPCODE_RANGE(instr->opcode);
778
 
 
779
 
   instr_encoding = &instr_encodings[instr->opcode];
780
 
 
781
 
   /* Set up base instruction bytes. */
782
 
   instr_size = instr_encoding->num_bytes;
783
 
   assert(instr_size <= ARRAY_SIZE(instr_bytes));
784
 
   memcpy(instr_bytes, instr_encoding->bytes, instr_size);
785
 
 
786
 
   /* Encode the operands and flags. */
787
 
   for (size_t u = 0U; u < instr_encoding->num_mappings; ++u) {
788
 
      const struct rogue_field_mapping *mapping = &instr_encoding->mappings[u];
789
 
 
790
 
      switch (mapping->type) {
791
 
      case ROGUE_MAP_TYPE_INSTR_FLAG: {
792
 
         uint64_t flag = rogue_onehot(mapping->index);
793
 
         CHECKF(rogue_encode_flag(!!(instr->flags & flag),
794
 
                                  mapping,
795
 
                                  instr_size,
796
 
                                  instr_bytes),
797
 
                "Failed to encode instruction flag.");
798
 
         break;
799
 
      }
800
 
 
801
 
      case ROGUE_MAP_TYPE_OPERAND_FLAG:
802
 
         return false;
803
 
 
804
 
      case ROGUE_MAP_TYPE_OPERAND: {
805
 
         size_t operand_index = mapping->index;
806
 
         CHECKF(rogue_encode_operand(&instr->operands[operand_index],
807
 
                                     mapping,
808
 
                                     instr_size,
809
 
                                     instr_bytes),
810
 
                "Failed to encode instruction operand.");
811
 
         break;
812
 
      }
813
 
 
814
 
      default:
815
 
         return false;
816
 
      }
817
 
   }
818
 
 
819
 
   CHECKF(fwrite(instr_bytes, 1, instr_size, fp) == instr_size,
820
 
          "Failed to write encoded instruction bytes.");
821
 
   fflush(fp);
822
 
 
823
 
   return true;
824
 
}
825
 
 
826
 
/**
827
 
 * \brief Encodes each instruction in "shader", writing the output to "fp".
828
 
 *
829
 
 * \param[in] shader The shader to be encoded.
830
 
 * \param[in] fp The file pointer.
831
 
 * \return true if encoding was successful.
832
 
 */
833
 
bool rogue_encode_shader(const struct rogue_shader *shader, FILE *fp)
834
 
{
835
 
   long bytes_written;
836
 
 
837
 
   /* Encode each instruction. */
838
 
   foreach_instr (instr, &shader->instr_list)
839
 
      CHECKF(rogue_encode_instr(instr, fp), "Failed to encode instruction.");
840
 
 
841
 
   /* Pad end of shader if required. */
842
 
   bytes_written = ftell(fp);
843
 
   if (bytes_written <= 0)
844
 
      return false;
845
 
 
846
 
   /* FIXME: Figure out the define for alignment of 16. */
847
 
   for (size_t u = 0; u < (bytes_written % 16); ++u)
848
 
      fputc(0xff, fp);
849
 
 
850
 
   return true;
851
 
}