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