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