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 <inttypes.h> 25bf215546Sopenharmony_ci#include <stdbool.h> 26bf215546Sopenharmony_ci#include <stdint.h> 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci#include "rogue_dump.h" 29bf215546Sopenharmony_ci#include "rogue_shader.h" 30bf215546Sopenharmony_ci#include "rogue_util.h" 31bf215546Sopenharmony_ci#include "util/bitscan.h" 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_ci/** 34bf215546Sopenharmony_ci * \file rogue_dump.c 35bf215546Sopenharmony_ci * 36bf215546Sopenharmony_ci * \brief Contains functions to dump Rogue data structures into a textual 37bf215546Sopenharmony_ci * format. 38bf215546Sopenharmony_ci */ 39bf215546Sopenharmony_ci 40bf215546Sopenharmony_cistatic const char *const rogue_operand_string[ROGUE_OPERAND_TYPE_COUNT] = { 41bf215546Sopenharmony_ci [ROGUE_OPERAND_TYPE_REG_TEMP] = "r", 42bf215546Sopenharmony_ci [ROGUE_OPERAND_TYPE_REG_COEFF] = "cf", 43bf215546Sopenharmony_ci [ROGUE_OPERAND_TYPE_REG_CONST] = "c", 44bf215546Sopenharmony_ci [ROGUE_OPERAND_TYPE_REG_SHARED] = "sh", 45bf215546Sopenharmony_ci [ROGUE_OPERAND_TYPE_REG_PIXEL_OUT] = "po", 46bf215546Sopenharmony_ci [ROGUE_OPERAND_TYPE_REG_VERTEX_IN] = "vi", 47bf215546Sopenharmony_ci [ROGUE_OPERAND_TYPE_REG_INTERNAL] = "i", 48bf215546Sopenharmony_ci [ROGUE_OPERAND_TYPE_IMMEDIATE] = "#", 49bf215546Sopenharmony_ci [ROGUE_OPERAND_TYPE_DRC] = "drc", 50bf215546Sopenharmony_ci [ROGUE_OPERAND_TYPE_VREG] = "V", 51bf215546Sopenharmony_ci}; 52bf215546Sopenharmony_ci 53bf215546Sopenharmony_cistatic const char *const rogue_opcode_string[ROGUE_OP_COUNT] = { 54bf215546Sopenharmony_ci [ROGUE_OP_NOP] = "nop", 55bf215546Sopenharmony_ci [ROGUE_OP_END_FRAG] = "end.frag", 56bf215546Sopenharmony_ci [ROGUE_OP_END_VERT] = "end.vert", 57bf215546Sopenharmony_ci [ROGUE_OP_WDF] = "wdf", 58bf215546Sopenharmony_ci [ROGUE_OP_PIX_ITER_W] = "pixiter.w", 59bf215546Sopenharmony_ci [ROGUE_OP_MAX] = "max", 60bf215546Sopenharmony_ci [ROGUE_OP_MIN] = "min", 61bf215546Sopenharmony_ci [ROGUE_OP_PACK_U8888] = "pack.u8888", 62bf215546Sopenharmony_ci [ROGUE_OP_MOV] = "mov", 63bf215546Sopenharmony_ci [ROGUE_OP_MOV_IMM] = "mov.imm", 64bf215546Sopenharmony_ci [ROGUE_OP_FMA] = "fma", 65bf215546Sopenharmony_ci [ROGUE_OP_MUL] = "mul", 66bf215546Sopenharmony_ci [ROGUE_OP_VTXOUT] = "vtxout", 67bf215546Sopenharmony_ci}; 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_cistatic const char *const rogue_instr_flag_string[ROGUE_INSTR_FLAG_COUNT] = { 70bf215546Sopenharmony_ci [ROGUE_INSTR_FLAG_SAT] = "sat", 71bf215546Sopenharmony_ci [ROGUE_INSTR_FLAG_LP] = "lp", 72bf215546Sopenharmony_ci [ROGUE_INSTR_FLAG_OLCHK] = "olchk", 73bf215546Sopenharmony_ci}; 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_cistatic const char rogue_vector_string[4] = { 76bf215546Sopenharmony_ci 'x', 77bf215546Sopenharmony_ci 'y', 78bf215546Sopenharmony_ci 'z', 79bf215546Sopenharmony_ci 'w', 80bf215546Sopenharmony_ci}; 81bf215546Sopenharmony_ci 82bf215546Sopenharmony_ci/** 83bf215546Sopenharmony_ci * \brief Dumps an operand as text to a file pointer. 84bf215546Sopenharmony_ci * 85bf215546Sopenharmony_ci * \param[in] operand The operand. 86bf215546Sopenharmony_ci * \param[in] fp The file pointer. 87bf215546Sopenharmony_ci * \return true if successful, otherwise false. 88bf215546Sopenharmony_ci */ 89bf215546Sopenharmony_cibool rogue_dump_operand(const struct rogue_operand *operand, FILE *fp) 90bf215546Sopenharmony_ci{ 91bf215546Sopenharmony_ci ASSERT_OPERAND_RANGE(operand->type); 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_ci fprintf(fp, "%s", rogue_operand_string[operand->type]); 94bf215546Sopenharmony_ci 95bf215546Sopenharmony_ci if (operand->type == ROGUE_OPERAND_TYPE_IMMEDIATE) 96bf215546Sopenharmony_ci fprintf(fp, "%" PRIu64, operand->immediate.value); 97bf215546Sopenharmony_ci else if (operand->type == ROGUE_OPERAND_TYPE_DRC) 98bf215546Sopenharmony_ci fprintf(fp, "%zu", operand->drc.number); 99bf215546Sopenharmony_ci else if (rogue_check_bitset(rogue_onehot(operand->type), ROGUE_MASK_ANY_REG)) 100bf215546Sopenharmony_ci fprintf(fp, "%zu", operand->reg.number); 101bf215546Sopenharmony_ci else if (operand->type == ROGUE_OPERAND_TYPE_VREG) { 102bf215546Sopenharmony_ci fprintf(fp, "%zu", operand->vreg.number); 103bf215546Sopenharmony_ci if (operand->vreg.is_vector) 104bf215546Sopenharmony_ci fprintf(fp, ".%c", rogue_vector_string[operand->vreg.component]); 105bf215546Sopenharmony_ci } 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_ci return true; 108bf215546Sopenharmony_ci} 109bf215546Sopenharmony_ci 110bf215546Sopenharmony_ci/** 111bf215546Sopenharmony_ci * \brief Dumps an instruction as text to a file pointer. 112bf215546Sopenharmony_ci * 113bf215546Sopenharmony_ci * \param[in] instr The instruction. 114bf215546Sopenharmony_ci * \param[in] fp The file pointer. 115bf215546Sopenharmony_ci * \return true if successful, otherwise false. 116bf215546Sopenharmony_ci */ 117bf215546Sopenharmony_cibool rogue_dump_instr(const struct rogue_instr *instr, FILE *fp) 118bf215546Sopenharmony_ci{ 119bf215546Sopenharmony_ci uint64_t flags = 0U; 120bf215546Sopenharmony_ci 121bf215546Sopenharmony_ci ASSERT_OPCODE_RANGE(instr->opcode); 122bf215546Sopenharmony_ci 123bf215546Sopenharmony_ci flags = instr->flags; 124bf215546Sopenharmony_ci 125bf215546Sopenharmony_ci fprintf(fp, "%s", rogue_opcode_string[instr->opcode]); 126bf215546Sopenharmony_ci 127bf215546Sopenharmony_ci /* Iterate over each flag bit and print its string form. */ 128bf215546Sopenharmony_ci while (flags) { 129bf215546Sopenharmony_ci uint64_t flag = u_bit_scan64(&flags); 130bf215546Sopenharmony_ci ASSERT_INSTR_FLAG_RANGE(flag); 131bf215546Sopenharmony_ci fprintf(fp, ".%s", rogue_instr_flag_string[flag]); 132bf215546Sopenharmony_ci } 133bf215546Sopenharmony_ci 134bf215546Sopenharmony_ci if (instr->num_operands) 135bf215546Sopenharmony_ci fprintf(fp, " "); 136bf215546Sopenharmony_ci 137bf215546Sopenharmony_ci /* Dump each operand. */ 138bf215546Sopenharmony_ci for (size_t u = 0U; u < instr->num_operands; ++u) { 139bf215546Sopenharmony_ci CHECKF(rogue_dump_operand(&instr->operands[u], fp), 140bf215546Sopenharmony_ci "Failed to dump operand."); 141bf215546Sopenharmony_ci if (u < (instr->num_operands - 1)) 142bf215546Sopenharmony_ci fprintf(fp, ", "); 143bf215546Sopenharmony_ci } 144bf215546Sopenharmony_ci 145bf215546Sopenharmony_ci fprintf(fp, ";"); 146bf215546Sopenharmony_ci 147bf215546Sopenharmony_ci return true; 148bf215546Sopenharmony_ci} 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_ci/** 151bf215546Sopenharmony_ci * \brief Dumps a shader as text to a file pointer. 152bf215546Sopenharmony_ci * 153bf215546Sopenharmony_ci * \param[in] shader The shader. 154bf215546Sopenharmony_ci * \param[in] fp The file pointer. 155bf215546Sopenharmony_ci * \return true if successful, otherwise false. 156bf215546Sopenharmony_ci */ 157bf215546Sopenharmony_cibool rogue_dump_shader(const struct rogue_shader *shader, FILE *fp) 158bf215546Sopenharmony_ci{ 159bf215546Sopenharmony_ci /* Dump the shader stage. */ 160bf215546Sopenharmony_ci fprintf(fp, "# %s shader\n", _mesa_shader_stage_to_string(shader->stage)); 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_ci /* Dump each instruction. */ 163bf215546Sopenharmony_ci foreach_instr (instr, &shader->instr_list) { 164bf215546Sopenharmony_ci CHECKF(rogue_dump_instr(instr, fp), "Failed to dump instruction."); 165bf215546Sopenharmony_ci fprintf(fp, "\n"); 166bf215546Sopenharmony_ci } 167bf215546Sopenharmony_ci fprintf(fp, "\n"); 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_ci return true; 170bf215546Sopenharmony_ci} 171