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 <assert.h> 25bf215546Sopenharmony_ci#include <stdint.h> 26bf215546Sopenharmony_ci#include <stdio.h> 27bf215546Sopenharmony_ci#include <stdlib.h> 28bf215546Sopenharmony_ci#include <stdbool.h> 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci#include "pvr_rogue_pds_defs.h" 31bf215546Sopenharmony_ci#include "pvr_rogue_pds_encode.h" 32bf215546Sopenharmony_ci#include "pvr_rogue_pds_disasm.h" 33bf215546Sopenharmony_ci#include "util/macros.h" 34bf215546Sopenharmony_ci 35bf215546Sopenharmony_cistatic void pvr_error_check(PVR_ERR_CALLBACK err_callback, 36bf215546Sopenharmony_ci struct pvr_dissassembler_error error) 37bf215546Sopenharmony_ci{ 38bf215546Sopenharmony_ci if (err_callback) 39bf215546Sopenharmony_ci err_callback(error); 40bf215546Sopenharmony_ci else 41bf215546Sopenharmony_ci fprintf(stderr, "ERROR: %s\n", error.text); 42bf215546Sopenharmony_ci} 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_ci#define X(a) #a, 45bf215546Sopenharmony_cistatic const char *const instructions[] = { PVR_INSTRUCTIONS }; 46bf215546Sopenharmony_ci#undef X 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_cistatic void error_reg_range(uint32_t raw, 49bf215546Sopenharmony_ci void *context, 50bf215546Sopenharmony_ci PVR_ERR_CALLBACK err_callback, 51bf215546Sopenharmony_ci uint32_t parameter, 52bf215546Sopenharmony_ci struct pvr_dissassembler_error error) 53bf215546Sopenharmony_ci{ 54bf215546Sopenharmony_ci char param[32]; 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ci error.type = PVR_PDS_ERR_PARAM_RANGE; 57bf215546Sopenharmony_ci error.instruction = error.instruction; 58bf215546Sopenharmony_ci error.parameter = parameter; 59bf215546Sopenharmony_ci error.raw = raw; 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_ci if (parameter == 0) 62bf215546Sopenharmony_ci snprintf(param, sizeof(param), "dst"); 63bf215546Sopenharmony_ci else 64bf215546Sopenharmony_ci snprintf(param, sizeof(param), "src%u", parameter - 1); 65bf215546Sopenharmony_ci 66bf215546Sopenharmony_ci error.text = malloc(PVR_PDS_MAX_INST_STR_LEN); 67bf215546Sopenharmony_ci assert(error.text); 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_ci snprintf(error.text, 70bf215546Sopenharmony_ci PVR_PDS_MAX_INST_STR_LEN, 71bf215546Sopenharmony_ci "Register out of range, instruction: %s, operand: %s, value: %u", 72bf215546Sopenharmony_ci instructions[error.instruction], 73bf215546Sopenharmony_ci param, 74bf215546Sopenharmony_ci raw); 75bf215546Sopenharmony_ci pvr_error_check(err_callback, error); 76bf215546Sopenharmony_ci} 77bf215546Sopenharmony_ci 78bf215546Sopenharmony_cistatic struct pvr_operand * 79bf215546Sopenharmony_cipvr_pds_disassemble_regs32(void *context, 80bf215546Sopenharmony_ci PVR_ERR_CALLBACK err_callback, 81bf215546Sopenharmony_ci struct pvr_dissassembler_error error, 82bf215546Sopenharmony_ci uint32_t instruction, 83bf215546Sopenharmony_ci uint32_t parameter) 84bf215546Sopenharmony_ci{ 85bf215546Sopenharmony_ci struct pvr_operand *op = calloc(1, sizeof(*op)); 86bf215546Sopenharmony_ci assert(op); 87bf215546Sopenharmony_ci 88bf215546Sopenharmony_ci op->type = UNRESOLVED; 89bf215546Sopenharmony_ci instruction &= PVR_ROGUE_PDSINST_REGS32_MASK; 90bf215546Sopenharmony_ci switch (pvr_pds_inst_decode_field_range_regs32(instruction)) { 91bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_REGS32_CONST32: 92bf215546Sopenharmony_ci op->type = CONST32; 93bf215546Sopenharmony_ci op->address = instruction - PVR_ROGUE_PDSINST_REGS32_CONST32_LOWER; 94bf215546Sopenharmony_ci op->absolute_address = op->address; 95bf215546Sopenharmony_ci break; 96bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_REGS32_TEMP32: 97bf215546Sopenharmony_ci op->type = TEMP32; 98bf215546Sopenharmony_ci op->address = instruction - PVR_ROGUE_PDSINST_REGS32_TEMP32_LOWER; 99bf215546Sopenharmony_ci op->absolute_address = op->address; 100bf215546Sopenharmony_ci break; 101bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_REGS32_PTEMP32: 102bf215546Sopenharmony_ci op->type = PTEMP32; 103bf215546Sopenharmony_ci op->address = instruction - PVR_ROGUE_PDSINST_REGS32_PTEMP32_LOWER; 104bf215546Sopenharmony_ci op->absolute_address = op->address; 105bf215546Sopenharmony_ci break; 106bf215546Sopenharmony_ci default: 107bf215546Sopenharmony_ci error_reg_range(instruction, context, err_callback, parameter, error); 108bf215546Sopenharmony_ci } 109bf215546Sopenharmony_ci return op; 110bf215546Sopenharmony_ci} 111bf215546Sopenharmony_cistatic struct pvr_operand * 112bf215546Sopenharmony_cipvr_pds_disassemble_regs32tp(void *context, 113bf215546Sopenharmony_ci PVR_ERR_CALLBACK err_callback, 114bf215546Sopenharmony_ci struct pvr_dissassembler_error error, 115bf215546Sopenharmony_ci uint32_t instruction, 116bf215546Sopenharmony_ci uint32_t parameter) 117bf215546Sopenharmony_ci{ 118bf215546Sopenharmony_ci struct pvr_operand *op = calloc(1, sizeof(*op)); 119bf215546Sopenharmony_ci assert(op); 120bf215546Sopenharmony_ci 121bf215546Sopenharmony_ci op->type = UNRESOLVED; 122bf215546Sopenharmony_ci instruction &= PVR_ROGUE_PDSINST_REGS32TP_MASK; 123bf215546Sopenharmony_ci switch (pvr_pds_inst_decode_field_range_regs32tp(instruction)) { 124bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_REGS32TP_TEMP32: 125bf215546Sopenharmony_ci op->type = TEMP32; 126bf215546Sopenharmony_ci op->address = instruction - PVR_ROGUE_PDSINST_REGS32TP_TEMP32_LOWER; 127bf215546Sopenharmony_ci op->absolute_address = op->address; 128bf215546Sopenharmony_ci break; 129bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_REGS32TP_PTEMP32: 130bf215546Sopenharmony_ci op->type = PTEMP32; 131bf215546Sopenharmony_ci op->address = instruction - PVR_ROGUE_PDSINST_REGS32TP_PTEMP32_LOWER; 132bf215546Sopenharmony_ci op->absolute_address = op->address; 133bf215546Sopenharmony_ci break; 134bf215546Sopenharmony_ci default: 135bf215546Sopenharmony_ci error_reg_range(instruction, context, err_callback, parameter, error); 136bf215546Sopenharmony_ci } 137bf215546Sopenharmony_ci return op; 138bf215546Sopenharmony_ci} 139bf215546Sopenharmony_cistatic struct pvr_operand * 140bf215546Sopenharmony_cipvr_pds_disassemble_regs32t(void *context, 141bf215546Sopenharmony_ci PVR_ERR_CALLBACK err_callback, 142bf215546Sopenharmony_ci struct pvr_dissassembler_error error, 143bf215546Sopenharmony_ci uint32_t instruction, 144bf215546Sopenharmony_ci uint32_t parameter) 145bf215546Sopenharmony_ci{ 146bf215546Sopenharmony_ci struct pvr_operand *op = calloc(1, sizeof(*op)); 147bf215546Sopenharmony_ci assert(op); 148bf215546Sopenharmony_ci 149bf215546Sopenharmony_ci op->type = UNRESOLVED; 150bf215546Sopenharmony_ci instruction &= PVR_ROGUE_PDSINST_REGS32T_MASK; 151bf215546Sopenharmony_ci switch (pvr_pds_inst_decode_field_range_regs32t(instruction)) { 152bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_REGS32T_TEMP32: 153bf215546Sopenharmony_ci op->type = TEMP32; 154bf215546Sopenharmony_ci op->address = instruction - PVR_ROGUE_PDSINST_REGS32T_TEMP32_LOWER; 155bf215546Sopenharmony_ci op->absolute_address = op->address; 156bf215546Sopenharmony_ci break; 157bf215546Sopenharmony_ci default: 158bf215546Sopenharmony_ci error_reg_range(instruction, context, err_callback, parameter, error); 159bf215546Sopenharmony_ci } 160bf215546Sopenharmony_ci return op; 161bf215546Sopenharmony_ci} 162bf215546Sopenharmony_ci 163bf215546Sopenharmony_cistatic struct pvr_operand * 164bf215546Sopenharmony_cipvr_pds_disassemble_regs64(void *context, 165bf215546Sopenharmony_ci PVR_ERR_CALLBACK err_callback, 166bf215546Sopenharmony_ci struct pvr_dissassembler_error error, 167bf215546Sopenharmony_ci uint32_t instruction, 168bf215546Sopenharmony_ci uint32_t parameter) 169bf215546Sopenharmony_ci{ 170bf215546Sopenharmony_ci struct pvr_operand *op = calloc(1, sizeof(*op)); 171bf215546Sopenharmony_ci assert(op); 172bf215546Sopenharmony_ci 173bf215546Sopenharmony_ci op->type = UNRESOLVED; 174bf215546Sopenharmony_ci instruction &= PVR_ROGUE_PDSINST_REGS64_MASK; 175bf215546Sopenharmony_ci switch (pvr_pds_inst_decode_field_range_regs64(instruction)) { 176bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_REGS64_CONST64: 177bf215546Sopenharmony_ci op->type = CONST64; 178bf215546Sopenharmony_ci op->address = instruction - PVR_ROGUE_PDSINST_REGS64_CONST64_LOWER; 179bf215546Sopenharmony_ci op->absolute_address = op->address * 2; 180bf215546Sopenharmony_ci break; 181bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_REGS64_TEMP64: 182bf215546Sopenharmony_ci op->type = TEMP64; 183bf215546Sopenharmony_ci op->address = instruction - PVR_ROGUE_PDSINST_REGS64_TEMP64_LOWER; 184bf215546Sopenharmony_ci op->absolute_address = op->address * 2; 185bf215546Sopenharmony_ci break; 186bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_REGS64_PTEMP64: 187bf215546Sopenharmony_ci op->type = PTEMP64; 188bf215546Sopenharmony_ci op->address = instruction - PVR_ROGUE_PDSINST_REGS64_PTEMP64_LOWER; 189bf215546Sopenharmony_ci op->absolute_address = op->address * 2; 190bf215546Sopenharmony_ci break; 191bf215546Sopenharmony_ci default: 192bf215546Sopenharmony_ci error_reg_range(instruction, context, err_callback, parameter, error); 193bf215546Sopenharmony_ci } 194bf215546Sopenharmony_ci 195bf215546Sopenharmony_ci return op; 196bf215546Sopenharmony_ci} 197bf215546Sopenharmony_cistatic struct pvr_operand * 198bf215546Sopenharmony_cipvr_pds_disassemble_regs64t(void *context, 199bf215546Sopenharmony_ci PVR_ERR_CALLBACK err_callback, 200bf215546Sopenharmony_ci struct pvr_dissassembler_error error, 201bf215546Sopenharmony_ci uint32_t instruction, 202bf215546Sopenharmony_ci uint32_t parameter) 203bf215546Sopenharmony_ci{ 204bf215546Sopenharmony_ci struct pvr_operand *op = calloc(1, sizeof(*op)); 205bf215546Sopenharmony_ci assert(op); 206bf215546Sopenharmony_ci 207bf215546Sopenharmony_ci op->type = UNRESOLVED; 208bf215546Sopenharmony_ci instruction &= PVR_ROGUE_PDSINST_REGS64T_MASK; 209bf215546Sopenharmony_ci switch (pvr_pds_inst_decode_field_range_regs64tp(instruction)) { 210bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_REGS64T_TEMP64: 211bf215546Sopenharmony_ci op->type = TEMP64; 212bf215546Sopenharmony_ci op->address = instruction - PVR_ROGUE_PDSINST_REGS64T_TEMP64_LOWER; 213bf215546Sopenharmony_ci op->absolute_address = op->address * 2; 214bf215546Sopenharmony_ci break; 215bf215546Sopenharmony_ci default: 216bf215546Sopenharmony_ci error_reg_range(instruction, context, err_callback, parameter, error); 217bf215546Sopenharmony_ci } 218bf215546Sopenharmony_ci return op; 219bf215546Sopenharmony_ci} 220bf215546Sopenharmony_ci 221bf215546Sopenharmony_cistatic struct pvr_operand * 222bf215546Sopenharmony_cipvr_pds_disassemble_regs64C(void *context, 223bf215546Sopenharmony_ci PVR_ERR_CALLBACK err_callback, 224bf215546Sopenharmony_ci struct pvr_dissassembler_error error, 225bf215546Sopenharmony_ci uint32_t instruction, 226bf215546Sopenharmony_ci uint32_t parameter) 227bf215546Sopenharmony_ci{ 228bf215546Sopenharmony_ci struct pvr_operand *op = calloc(1, sizeof(*op)); 229bf215546Sopenharmony_ci assert(op); 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_ci op->type = UNRESOLVED; 232bf215546Sopenharmony_ci instruction &= PVR_ROGUE_PDSINST_REGS64C_MASK; 233bf215546Sopenharmony_ci switch (pvr_rogue_pds_inst_decode_field_range_regs64c(instruction)) { 234bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_REGS64C_CONST64: 235bf215546Sopenharmony_ci op->type = CONST64; 236bf215546Sopenharmony_ci op->address = instruction - PVR_ROGUE_PDSINST_REGS64C_CONST64_LOWER; 237bf215546Sopenharmony_ci op->absolute_address = op->address * 2; 238bf215546Sopenharmony_ci break; 239bf215546Sopenharmony_ci default: 240bf215546Sopenharmony_ci error_reg_range(instruction, context, err_callback, parameter, error); 241bf215546Sopenharmony_ci } 242bf215546Sopenharmony_ci return op; 243bf215546Sopenharmony_ci} 244bf215546Sopenharmony_ci 245bf215546Sopenharmony_cistatic struct pvr_operand * 246bf215546Sopenharmony_cipvr_pds_disassemble_regs64tp(void *context, 247bf215546Sopenharmony_ci PVR_ERR_CALLBACK err_callback, 248bf215546Sopenharmony_ci struct pvr_dissassembler_error error, 249bf215546Sopenharmony_ci uint32_t instruction, 250bf215546Sopenharmony_ci uint32_t parameter) 251bf215546Sopenharmony_ci{ 252bf215546Sopenharmony_ci struct pvr_operand *op = calloc(1, sizeof(*op)); 253bf215546Sopenharmony_ci assert(op); 254bf215546Sopenharmony_ci 255bf215546Sopenharmony_ci op->type = UNRESOLVED; 256bf215546Sopenharmony_ci instruction &= PVR_ROGUE_PDSINST_REGS64TP_MASK; 257bf215546Sopenharmony_ci switch (pvr_pds_inst_decode_field_range_regs64tp(instruction)) { 258bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_REGS64TP_TEMP64: 259bf215546Sopenharmony_ci op->type = TEMP64; 260bf215546Sopenharmony_ci op->address = instruction - PVR_ROGUE_PDSINST_REGS64TP_TEMP64_LOWER; 261bf215546Sopenharmony_ci op->absolute_address = op->address * 2; 262bf215546Sopenharmony_ci break; 263bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_REGS64TP_PTEMP64: 264bf215546Sopenharmony_ci op->type = PTEMP64; 265bf215546Sopenharmony_ci op->address = instruction - PVR_ROGUE_PDSINST_REGS64TP_PTEMP64_LOWER; 266bf215546Sopenharmony_ci op->absolute_address = op->address * 2; 267bf215546Sopenharmony_ci break; 268bf215546Sopenharmony_ci default: 269bf215546Sopenharmony_ci error_reg_range(instruction, context, err_callback, parameter, error); 270bf215546Sopenharmony_ci } 271bf215546Sopenharmony_ci return op; 272bf215546Sopenharmony_ci} 273bf215546Sopenharmony_ci 274bf215546Sopenharmony_ci#define PVR_TYPE_OPCODE BITFIELD_BIT(31U) 275bf215546Sopenharmony_ci#define PVR_TYPE_OPCODE_SP BITFIELD_BIT(27U) 276bf215546Sopenharmony_ci#define PVR_TYPE_OPCODEB BITFIELD_BIT(30U) 277bf215546Sopenharmony_ci 278bf215546Sopenharmony_ci#define PVR_TYPE_OPCODE_SHIFT 28U 279bf215546Sopenharmony_ci#define PVR_TYPE_OPCODE_SP_SHIFT 23U 280bf215546Sopenharmony_ci#define PVR_TYPE_OPCODEB_SHIFT 29U 281bf215546Sopenharmony_ci 282bf215546Sopenharmony_cistatic struct pvr_instruction * 283bf215546Sopenharmony_cipvr_pds_disassemble_instruction_add64(void *context, 284bf215546Sopenharmony_ci PVR_ERR_CALLBACK err_callback, 285bf215546Sopenharmony_ci struct pvr_dissassembler_error error, 286bf215546Sopenharmony_ci uint32_t instruction) 287bf215546Sopenharmony_ci{ 288bf215546Sopenharmony_ci struct pvr_add *add = malloc(sizeof(*add)); 289bf215546Sopenharmony_ci assert(add); 290bf215546Sopenharmony_ci 291bf215546Sopenharmony_ci add->instruction.type = INS_ADD64; 292bf215546Sopenharmony_ci add->instruction.next = NULL; 293bf215546Sopenharmony_ci 294bf215546Sopenharmony_ci add->cc = instruction & PVR_ROGUE_PDSINST_ADD64_CC_ENABLE; 295bf215546Sopenharmony_ci add->alum = instruction & PVR_ROGUE_PDSINST_ADD64_ALUM_SIGNED; 296bf215546Sopenharmony_ci add->sna = instruction & PVR_ROGUE_PDSINST_ADD64_SNA_SUB; 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_ci add->src0 = pvr_pds_disassemble_regs64(context, 299bf215546Sopenharmony_ci err_callback, 300bf215546Sopenharmony_ci error, 301bf215546Sopenharmony_ci instruction >> 302bf215546Sopenharmony_ci PVR_ROGUE_PDSINST_ADD64_SRC0_SHIFT, 303bf215546Sopenharmony_ci 1); 304bf215546Sopenharmony_ci add->src0->instruction = &add->instruction; 305bf215546Sopenharmony_ci add->src1 = pvr_pds_disassemble_regs64(context, 306bf215546Sopenharmony_ci err_callback, 307bf215546Sopenharmony_ci error, 308bf215546Sopenharmony_ci instruction >> 309bf215546Sopenharmony_ci PVR_ROGUE_PDSINST_ADD64_SRC1_SHIFT, 310bf215546Sopenharmony_ci 2); 311bf215546Sopenharmony_ci add->src1->instruction = &add->instruction; 312bf215546Sopenharmony_ci add->dst = pvr_pds_disassemble_regs64tp(context, 313bf215546Sopenharmony_ci err_callback, 314bf215546Sopenharmony_ci error, 315bf215546Sopenharmony_ci instruction >> 316bf215546Sopenharmony_ci PVR_ROGUE_PDSINST_ADD64_DST_SHIFT, 317bf215546Sopenharmony_ci 0); 318bf215546Sopenharmony_ci add->dst->instruction = &add->instruction; 319bf215546Sopenharmony_ci 320bf215546Sopenharmony_ci return &add->instruction; 321bf215546Sopenharmony_ci} 322bf215546Sopenharmony_ci 323bf215546Sopenharmony_cistatic struct pvr_instruction * 324bf215546Sopenharmony_cipvr_pds_disassemble_instruction_add32(void *context, 325bf215546Sopenharmony_ci PVR_ERR_CALLBACK err_callback, 326bf215546Sopenharmony_ci struct pvr_dissassembler_error error, 327bf215546Sopenharmony_ci uint32_t instruction) 328bf215546Sopenharmony_ci{ 329bf215546Sopenharmony_ci struct pvr_add *add = malloc(sizeof(*add)); 330bf215546Sopenharmony_ci assert(add); 331bf215546Sopenharmony_ci 332bf215546Sopenharmony_ci add->instruction.type = INS_ADD32; 333bf215546Sopenharmony_ci add->instruction.next = NULL; 334bf215546Sopenharmony_ci 335bf215546Sopenharmony_ci add->cc = instruction & PVR_ROGUE_PDSINST_ADD32_CC_ENABLE; 336bf215546Sopenharmony_ci add->alum = instruction & PVR_ROGUE_PDSINST_ADD32_ALUM_SIGNED; 337bf215546Sopenharmony_ci add->sna = instruction & PVR_ROGUE_PDSINST_ADD32_SNA_SUB; 338bf215546Sopenharmony_ci 339bf215546Sopenharmony_ci add->src0 = pvr_pds_disassemble_regs32(context, 340bf215546Sopenharmony_ci err_callback, 341bf215546Sopenharmony_ci error, 342bf215546Sopenharmony_ci instruction >> 343bf215546Sopenharmony_ci PVR_ROGUE_PDSINST_ADD32_SRC0_SHIFT, 344bf215546Sopenharmony_ci 1); 345bf215546Sopenharmony_ci add->src0->instruction = &add->instruction; 346bf215546Sopenharmony_ci add->src1 = pvr_pds_disassemble_regs32(context, 347bf215546Sopenharmony_ci err_callback, 348bf215546Sopenharmony_ci error, 349bf215546Sopenharmony_ci instruction >> 350bf215546Sopenharmony_ci PVR_ROGUE_PDSINST_ADD32_SRC1_SHIFT, 351bf215546Sopenharmony_ci 2); 352bf215546Sopenharmony_ci add->src1->instruction = &add->instruction; 353bf215546Sopenharmony_ci add->dst = pvr_pds_disassemble_regs32tp(context, 354bf215546Sopenharmony_ci err_callback, 355bf215546Sopenharmony_ci error, 356bf215546Sopenharmony_ci instruction >> 357bf215546Sopenharmony_ci PVR_ROGUE_PDSINST_ADD32_DST_SHIFT, 358bf215546Sopenharmony_ci 0); 359bf215546Sopenharmony_ci add->dst->instruction = &add->instruction; 360bf215546Sopenharmony_ci 361bf215546Sopenharmony_ci return &add->instruction; 362bf215546Sopenharmony_ci} 363bf215546Sopenharmony_ci 364bf215546Sopenharmony_cistatic struct pvr_instruction * 365bf215546Sopenharmony_cipvr_pds_disassemble_instruction_stm(void *context, 366bf215546Sopenharmony_ci PVR_ERR_CALLBACK err_callback, 367bf215546Sopenharmony_ci struct pvr_dissassembler_error error, 368bf215546Sopenharmony_ci uint32_t instruction) 369bf215546Sopenharmony_ci{ 370bf215546Sopenharmony_ci struct pvr_stm *stm = malloc(sizeof(*stm)); 371bf215546Sopenharmony_ci assert(stm); 372bf215546Sopenharmony_ci 373bf215546Sopenharmony_ci stm->instruction.next = NULL; 374bf215546Sopenharmony_ci stm->instruction.type = INS_STM; 375bf215546Sopenharmony_ci 376bf215546Sopenharmony_ci stm->cc = instruction & (1 << PVR_ROGUE_PDSINST_STM_CCS_CCS_CC_SHIFT); 377bf215546Sopenharmony_ci stm->ccs_global = instruction & 378bf215546Sopenharmony_ci (1 << PVR_ROGUE_PDSINST_STM_CCS_CCS_GLOBAL_SHIFT); 379bf215546Sopenharmony_ci stm->ccs_so = instruction & (1 << PVR_ROGUE_PDSINST_STM_CCS_CCS_SO_SHIFT); 380bf215546Sopenharmony_ci stm->tst = instruction & (1 << PVR_ROGUE_PDSINST_STM_SO_TST_SHIFT); 381bf215546Sopenharmony_ci 382bf215546Sopenharmony_ci stm->stream_out = (instruction >> PVR_ROGUE_PDSINST_STM_SO_SHIFT) & 383bf215546Sopenharmony_ci PVR_ROGUE_PDSINST_SO_MASK; 384bf215546Sopenharmony_ci 385bf215546Sopenharmony_ci stm->src0 = pvr_pds_disassemble_regs64tp( 386bf215546Sopenharmony_ci context, 387bf215546Sopenharmony_ci err_callback, 388bf215546Sopenharmony_ci error, 389bf215546Sopenharmony_ci instruction >> PVR_ROGUE_PDSINST_STM_SO_SRC0_SHIFT, 390bf215546Sopenharmony_ci 1); 391bf215546Sopenharmony_ci stm->src0->instruction = &stm->instruction; 392bf215546Sopenharmony_ci 393bf215546Sopenharmony_ci stm->src1 = pvr_pds_disassemble_regs64tp( 394bf215546Sopenharmony_ci context, 395bf215546Sopenharmony_ci err_callback, 396bf215546Sopenharmony_ci error, 397bf215546Sopenharmony_ci instruction >> PVR_ROGUE_PDSINST_STM_SO_SRC1_SHIFT, 398bf215546Sopenharmony_ci 2); 399bf215546Sopenharmony_ci stm->src1->instruction = &stm->instruction; 400bf215546Sopenharmony_ci 401bf215546Sopenharmony_ci stm->src2 = pvr_pds_disassemble_regs32( 402bf215546Sopenharmony_ci context, 403bf215546Sopenharmony_ci err_callback, 404bf215546Sopenharmony_ci error, 405bf215546Sopenharmony_ci instruction >> PVR_ROGUE_PDSINST_STM_SO_SRC2_SHIFT, 406bf215546Sopenharmony_ci 3); 407bf215546Sopenharmony_ci stm->src2->instruction = &stm->instruction; 408bf215546Sopenharmony_ci 409bf215546Sopenharmony_ci stm->src3 = pvr_pds_disassemble_regs64tp( 410bf215546Sopenharmony_ci context, 411bf215546Sopenharmony_ci err_callback, 412bf215546Sopenharmony_ci error, 413bf215546Sopenharmony_ci instruction >> PVR_ROGUE_PDSINST_STM_SO_SRC3_SHIFT, 414bf215546Sopenharmony_ci 4); 415bf215546Sopenharmony_ci stm->src3->instruction = &stm->instruction; 416bf215546Sopenharmony_ci 417bf215546Sopenharmony_ci return &stm->instruction; 418bf215546Sopenharmony_ci} 419bf215546Sopenharmony_ci 420bf215546Sopenharmony_cistatic struct pvr_instruction * 421bf215546Sopenharmony_cipvr_pds_disassemble_instruction_sftlp32(void *context, 422bf215546Sopenharmony_ci PVR_ERR_CALLBACK err_callback, 423bf215546Sopenharmony_ci struct pvr_dissassembler_error error, 424bf215546Sopenharmony_ci uint32_t instruction) 425bf215546Sopenharmony_ci{ 426bf215546Sopenharmony_ci struct pvr_sftlp *ins = malloc(sizeof(*ins)); 427bf215546Sopenharmony_ci assert(ins); 428bf215546Sopenharmony_ci 429bf215546Sopenharmony_ci ins->instruction.next = NULL; 430bf215546Sopenharmony_ci ins->instruction.type = INS_SFTLP32; 431bf215546Sopenharmony_ci 432bf215546Sopenharmony_ci ins->cc = instruction & PVR_ROGUE_PDSINST_SFTLP32_CC_ENABLE; 433bf215546Sopenharmony_ci ins->IM = instruction & PVR_ROGUE_PDSINST_SFTLP32_IM_ENABLE; 434bf215546Sopenharmony_ci ins->lop = (instruction >> PVR_ROGUE_PDSINST_SFTLP32_LOP_SHIFT) & 435bf215546Sopenharmony_ci PVR_ROGUE_PDSINST_LOP_MASK; 436bf215546Sopenharmony_ci ins->src0 = pvr_pds_disassemble_regs32t( 437bf215546Sopenharmony_ci context, 438bf215546Sopenharmony_ci err_callback, 439bf215546Sopenharmony_ci error, 440bf215546Sopenharmony_ci instruction >> PVR_ROGUE_PDSINST_SFTLP32_SRC0_SHIFT, 441bf215546Sopenharmony_ci 1); 442bf215546Sopenharmony_ci ins->src0->instruction = &ins->instruction; 443bf215546Sopenharmony_ci ins->src1 = pvr_pds_disassemble_regs32( 444bf215546Sopenharmony_ci context, 445bf215546Sopenharmony_ci err_callback, 446bf215546Sopenharmony_ci error, 447bf215546Sopenharmony_ci instruction >> PVR_ROGUE_PDSINST_SFTLP32_SRC1_SHIFT, 448bf215546Sopenharmony_ci 2); 449bf215546Sopenharmony_ci ins->src1->instruction = &ins->instruction; 450bf215546Sopenharmony_ci ins->dst = pvr_pds_disassemble_regs32t( 451bf215546Sopenharmony_ci context, 452bf215546Sopenharmony_ci err_callback, 453bf215546Sopenharmony_ci error, 454bf215546Sopenharmony_ci instruction >> PVR_ROGUE_PDSINST_SFTLP32_DST_SHIFT, 455bf215546Sopenharmony_ci 0); 456bf215546Sopenharmony_ci ins->dst->instruction = &ins->instruction; 457bf215546Sopenharmony_ci 458bf215546Sopenharmony_ci if (ins->IM) { 459bf215546Sopenharmony_ci signed char cImmediate = 460bf215546Sopenharmony_ci ((instruction >> PVR_ROGUE_PDSINST_SFTLP32_SRC2_SHIFT) & 461bf215546Sopenharmony_ci PVR_ROGUE_PDSINST_REGS32_MASK) 462bf215546Sopenharmony_ci << 2; 463bf215546Sopenharmony_ci ins->src2 = calloc(1, sizeof(*ins->src2)); 464bf215546Sopenharmony_ci assert(ins->src2); 465bf215546Sopenharmony_ci 466bf215546Sopenharmony_ci ins->src2->literal = abs((cImmediate / 4)); 467bf215546Sopenharmony_ci ins->src2->negate = cImmediate < 0; 468bf215546Sopenharmony_ci ins->src2->instruction = &ins->instruction; 469bf215546Sopenharmony_ci } else { 470bf215546Sopenharmony_ci ins->src2 = pvr_pds_disassemble_regs32tp( 471bf215546Sopenharmony_ci context, 472bf215546Sopenharmony_ci err_callback, 473bf215546Sopenharmony_ci error, 474bf215546Sopenharmony_ci (instruction >> PVR_ROGUE_PDSINST_SFTLP32_SRC2_SHIFT), 475bf215546Sopenharmony_ci 3); 476bf215546Sopenharmony_ci ins->src2->instruction = &ins->instruction; 477bf215546Sopenharmony_ci } 478bf215546Sopenharmony_ci 479bf215546Sopenharmony_ci return &ins->instruction; 480bf215546Sopenharmony_ci} 481bf215546Sopenharmony_ci 482bf215546Sopenharmony_cistatic struct pvr_instruction * 483bf215546Sopenharmony_cipvr_pds_disassemble_instruction_sftlp64(void *context, 484bf215546Sopenharmony_ci PVR_ERR_CALLBACK err_callback, 485bf215546Sopenharmony_ci struct pvr_dissassembler_error error, 486bf215546Sopenharmony_ci uint32_t instruction) 487bf215546Sopenharmony_ci{ 488bf215546Sopenharmony_ci struct pvr_sftlp *ins = malloc(sizeof(*ins)); 489bf215546Sopenharmony_ci assert(ins); 490bf215546Sopenharmony_ci 491bf215546Sopenharmony_ci ins->instruction.next = NULL; 492bf215546Sopenharmony_ci ins->instruction.type = INS_SFTLP64; 493bf215546Sopenharmony_ci 494bf215546Sopenharmony_ci ins->cc = instruction & PVR_ROGUE_PDSINST_SFTLP64_CC_ENABLE; 495bf215546Sopenharmony_ci ins->IM = instruction & PVR_ROGUE_PDSINST_SFTLP64_IM_ENABLE; 496bf215546Sopenharmony_ci ins->lop = (instruction >> PVR_ROGUE_PDSINST_SFTLP64_LOP_SHIFT) & 497bf215546Sopenharmony_ci PVR_ROGUE_PDSINST_LOP_MASK; 498bf215546Sopenharmony_ci ins->src0 = pvr_pds_disassemble_regs64tp( 499bf215546Sopenharmony_ci context, 500bf215546Sopenharmony_ci err_callback, 501bf215546Sopenharmony_ci error, 502bf215546Sopenharmony_ci instruction >> PVR_ROGUE_PDSINST_SFTLP64_SRC0_SHIFT, 503bf215546Sopenharmony_ci 1); 504bf215546Sopenharmony_ci ins->src0->instruction = &ins->instruction; 505bf215546Sopenharmony_ci ins->src1 = pvr_pds_disassemble_regs64tp( 506bf215546Sopenharmony_ci context, 507bf215546Sopenharmony_ci err_callback, 508bf215546Sopenharmony_ci error, 509bf215546Sopenharmony_ci instruction >> PVR_ROGUE_PDSINST_SFTLP64_SRC1_SHIFT, 510bf215546Sopenharmony_ci 2); 511bf215546Sopenharmony_ci ins->src1->instruction = &ins->instruction; 512bf215546Sopenharmony_ci ins->dst = pvr_pds_disassemble_regs64tp( 513bf215546Sopenharmony_ci context, 514bf215546Sopenharmony_ci err_callback, 515bf215546Sopenharmony_ci error, 516bf215546Sopenharmony_ci instruction >> PVR_ROGUE_PDSINST_SFTLP64_DST_SHIFT, 517bf215546Sopenharmony_ci 0); 518bf215546Sopenharmony_ci ins->dst->instruction = &ins->instruction; 519bf215546Sopenharmony_ci 520bf215546Sopenharmony_ci if (ins->IM) { 521bf215546Sopenharmony_ci signed char cImmediate = 522bf215546Sopenharmony_ci (instruction >> PVR_ROGUE_PDSINST_SFTLP64_SRC2_SHIFT) & 523bf215546Sopenharmony_ci PVR_ROGUE_PDSINST_REGS32_MASK; 524bf215546Sopenharmony_ci ins->src2 = calloc(1, sizeof(*ins->src2)); 525bf215546Sopenharmony_ci assert(ins->src2); 526bf215546Sopenharmony_ci 527bf215546Sopenharmony_ci ins->src2->literal = (abs(cImmediate) > 63) ? 63 : abs(cImmediate); 528bf215546Sopenharmony_ci ins->src2->negate = (cImmediate < 0); 529bf215546Sopenharmony_ci ins->src2->instruction = &ins->instruction; 530bf215546Sopenharmony_ci } else { 531bf215546Sopenharmony_ci ins->src2 = pvr_pds_disassemble_regs32( 532bf215546Sopenharmony_ci context, 533bf215546Sopenharmony_ci err_callback, 534bf215546Sopenharmony_ci error, 535bf215546Sopenharmony_ci (instruction >> PVR_ROGUE_PDSINST_SFTLP64_SRC2_SHIFT), 536bf215546Sopenharmony_ci 3); 537bf215546Sopenharmony_ci ins->src2->instruction = &ins->instruction; 538bf215546Sopenharmony_ci } 539bf215546Sopenharmony_ci 540bf215546Sopenharmony_ci return &ins->instruction; 541bf215546Sopenharmony_ci} 542bf215546Sopenharmony_cistatic struct pvr_instruction * 543bf215546Sopenharmony_cipvr_pds_disassemble_instruction_cmp(void *context, 544bf215546Sopenharmony_ci PVR_ERR_CALLBACK err_callback, 545bf215546Sopenharmony_ci struct pvr_dissassembler_error error, 546bf215546Sopenharmony_ci uint32_t instruction) 547bf215546Sopenharmony_ci{ 548bf215546Sopenharmony_ci struct pvr_cmp *cmp = malloc(sizeof(*cmp)); 549bf215546Sopenharmony_ci assert(cmp); 550bf215546Sopenharmony_ci 551bf215546Sopenharmony_ci cmp->instruction.next = NULL; 552bf215546Sopenharmony_ci cmp->instruction.type = INS_CMP; 553bf215546Sopenharmony_ci cmp->cc = instruction & PVR_ROGUE_PDSINST_CMP_CC_ENABLE; 554bf215546Sopenharmony_ci cmp->IM = instruction & PVR_ROGUE_PDSINST_CMP_IM_ENABLE; 555bf215546Sopenharmony_ci cmp->cop = instruction >> PVR_ROGUE_PDSINST_CMP_COP_SHIFT & 556bf215546Sopenharmony_ci PVR_ROGUE_PDSINST_COP_MASK; 557bf215546Sopenharmony_ci cmp->src0 = pvr_pds_disassemble_regs64tp(context, 558bf215546Sopenharmony_ci err_callback, 559bf215546Sopenharmony_ci error, 560bf215546Sopenharmony_ci instruction >> 561bf215546Sopenharmony_ci PVR_ROGUE_PDSINST_CMP_SRC0_SHIFT, 562bf215546Sopenharmony_ci 1); 563bf215546Sopenharmony_ci cmp->src0->instruction = &cmp->instruction; 564bf215546Sopenharmony_ci 565bf215546Sopenharmony_ci if (cmp->IM) { 566bf215546Sopenharmony_ci uint32_t immediate = (instruction >> PVR_ROGUE_PDSINST_CMP_SRC1_SHIFT) & 567bf215546Sopenharmony_ci PVR_ROGUE_PDSINST_IMM16_MASK; 568bf215546Sopenharmony_ci cmp->src1 = calloc(1, sizeof(*cmp->src1)); 569bf215546Sopenharmony_ci assert(cmp->src1); 570bf215546Sopenharmony_ci 571bf215546Sopenharmony_ci cmp->src1->type = LITERAL_NUM; 572bf215546Sopenharmony_ci cmp->src1->literal = immediate; 573bf215546Sopenharmony_ci } else { 574bf215546Sopenharmony_ci cmp->src1 = pvr_pds_disassemble_regs64( 575bf215546Sopenharmony_ci context, 576bf215546Sopenharmony_ci err_callback, 577bf215546Sopenharmony_ci error, 578bf215546Sopenharmony_ci instruction >> PVR_ROGUE_PDSINST_CMP_SRC1_SHIFT, 579bf215546Sopenharmony_ci 2); 580bf215546Sopenharmony_ci } 581bf215546Sopenharmony_ci cmp->src1->instruction = &cmp->instruction; 582bf215546Sopenharmony_ci 583bf215546Sopenharmony_ci return &cmp->instruction; 584bf215546Sopenharmony_ci} 585bf215546Sopenharmony_ci 586bf215546Sopenharmony_cistatic struct pvr_instruction * 587bf215546Sopenharmony_cipvr_pds_disassemble_instruction_sp_ld_st(void *context, 588bf215546Sopenharmony_ci PVR_ERR_CALLBACK err_callback, 589bf215546Sopenharmony_ci struct pvr_dissassembler_error error, 590bf215546Sopenharmony_ci bool ld, 591bf215546Sopenharmony_ci uint32_t instruction, 592bf215546Sopenharmony_ci bool cc) 593bf215546Sopenharmony_ci{ 594bf215546Sopenharmony_ci struct pvr_ldst *ins = malloc(sizeof(*ins)); 595bf215546Sopenharmony_ci assert(ins); 596bf215546Sopenharmony_ci 597bf215546Sopenharmony_ci ins->instruction.next = NULL; 598bf215546Sopenharmony_ci ins->instruction.type = ld ? INS_LD : INS_ST; 599bf215546Sopenharmony_ci 600bf215546Sopenharmony_ci ins->cc = cc; 601bf215546Sopenharmony_ci ins->src0 = 602bf215546Sopenharmony_ci pvr_pds_disassemble_regs64(context, 603bf215546Sopenharmony_ci err_callback, 604bf215546Sopenharmony_ci error, 605bf215546Sopenharmony_ci instruction >> PVR_ROGUE_PDSINST_LD_SRC0_SHIFT, 606bf215546Sopenharmony_ci 1); 607bf215546Sopenharmony_ci ins->src0->instruction = &ins->instruction; 608bf215546Sopenharmony_ci ins->st = !ld; 609bf215546Sopenharmony_ci 610bf215546Sopenharmony_ci return &ins->instruction; 611bf215546Sopenharmony_ci} 612bf215546Sopenharmony_ci 613bf215546Sopenharmony_cistatic struct pvr_instruction * 614bf215546Sopenharmony_cipvr_pds_disassemble_instruction_sp_stmc(uint32_t instruction, bool cc) 615bf215546Sopenharmony_ci{ 616bf215546Sopenharmony_ci struct pvr_stmc *stmc = malloc(sizeof(*stmc)); 617bf215546Sopenharmony_ci assert(stmc); 618bf215546Sopenharmony_ci 619bf215546Sopenharmony_ci stmc->instruction.next = NULL; 620bf215546Sopenharmony_ci stmc->instruction.type = INS_STMC; 621bf215546Sopenharmony_ci 622bf215546Sopenharmony_ci stmc->cc = cc; 623bf215546Sopenharmony_ci stmc->src0 = calloc(1, sizeof(*stmc->src0)); 624bf215546Sopenharmony_ci assert(stmc->src0); 625bf215546Sopenharmony_ci 626bf215546Sopenharmony_ci stmc->src0->type = LITERAL_NUM; 627bf215546Sopenharmony_ci stmc->src0->literal = (instruction >> PVR_ROGUE_PDSINST_STMC_SOMASK_SHIFT) & 628bf215546Sopenharmony_ci PVR_ROGUE_PDSINST_SOMASK_MASK; 629bf215546Sopenharmony_ci stmc->src0->instruction = &stmc->instruction; 630bf215546Sopenharmony_ci 631bf215546Sopenharmony_ci return &stmc->instruction; 632bf215546Sopenharmony_ci} 633bf215546Sopenharmony_ci 634bf215546Sopenharmony_cistatic struct pvr_instruction * 635bf215546Sopenharmony_cipvr_pds_disassemble_instruction_sp_limm(void *context, 636bf215546Sopenharmony_ci PVR_ERR_CALLBACK err_callback, 637bf215546Sopenharmony_ci struct pvr_dissassembler_error error, 638bf215546Sopenharmony_ci uint32_t instruction, 639bf215546Sopenharmony_ci bool cc) 640bf215546Sopenharmony_ci{ 641bf215546Sopenharmony_ci struct pvr_limm *limm = malloc(sizeof(*limm)); 642bf215546Sopenharmony_ci assert(limm); 643bf215546Sopenharmony_ci limm->instruction.next = NULL; 644bf215546Sopenharmony_ci limm->instruction.type = INS_LIMM; 645bf215546Sopenharmony_ci 646bf215546Sopenharmony_ci limm->cc = cc; 647bf215546Sopenharmony_ci limm->GR = (instruction & PVR_ROGUE_PDSINST_LIMM_GR_ENABLE) != 0; 648bf215546Sopenharmony_ci limm->src0 = calloc(1, sizeof(*limm->src0)); 649bf215546Sopenharmony_ci assert(limm->src0); 650bf215546Sopenharmony_ci 651bf215546Sopenharmony_ci limm->src0->type = LITERAL_NUM; 652bf215546Sopenharmony_ci limm->src0->literal = (instruction >> PVR_ROGUE_PDSINST_LIMM_SRC0_SHIFT) & 653bf215546Sopenharmony_ci PVR_ROGUE_PDSINST_IMM16_MASK; 654bf215546Sopenharmony_ci limm->src0->instruction = &limm->instruction; 655bf215546Sopenharmony_ci limm->dst = pvr_pds_disassemble_regs32t(context, 656bf215546Sopenharmony_ci err_callback, 657bf215546Sopenharmony_ci error, 658bf215546Sopenharmony_ci instruction >> 659bf215546Sopenharmony_ci PVR_ROGUE_PDSINST_LIMM_SRC1_SHIFT, 660bf215546Sopenharmony_ci 0); 661bf215546Sopenharmony_ci limm->dst->instruction = &limm->instruction; 662bf215546Sopenharmony_ci 663bf215546Sopenharmony_ci return &limm->instruction; 664bf215546Sopenharmony_ci} 665bf215546Sopenharmony_ci 666bf215546Sopenharmony_cistatic struct pvr_instruction * 667bf215546Sopenharmony_cipvr_pds_disassemble_simple(enum pvr_instruction_type type, bool cc) 668bf215546Sopenharmony_ci{ 669bf215546Sopenharmony_ci struct pvr_simple *ins = malloc(sizeof(*ins)); 670bf215546Sopenharmony_ci assert(ins); 671bf215546Sopenharmony_ci 672bf215546Sopenharmony_ci ins->instruction.next = NULL; 673bf215546Sopenharmony_ci ins->instruction.type = type; 674bf215546Sopenharmony_ci ins->cc = cc; 675bf215546Sopenharmony_ci 676bf215546Sopenharmony_ci return &ins->instruction; 677bf215546Sopenharmony_ci} 678bf215546Sopenharmony_ci 679bf215546Sopenharmony_cistatic struct pvr_instruction * 680bf215546Sopenharmony_cipvr_pds_disassemble_instruction_bra(uint32_t instruction) 681bf215546Sopenharmony_ci{ 682bf215546Sopenharmony_ci uint32_t branch_addr; 683bf215546Sopenharmony_ci struct pvr_bra *bra = (struct pvr_bra *)malloc(sizeof(*bra)); 684bf215546Sopenharmony_ci assert(bra); 685bf215546Sopenharmony_ci 686bf215546Sopenharmony_ci bra->instruction.type = INS_BRA; 687bf215546Sopenharmony_ci bra->instruction.next = NULL; 688bf215546Sopenharmony_ci 689bf215546Sopenharmony_ci branch_addr = (instruction >> PVR_ROGUE_PDSINST_BRA_ADDR_SHIFT) & 690bf215546Sopenharmony_ci PVR_ROGUE_PDSINST_BRAADDR_MASK; 691bf215546Sopenharmony_ci bra->address = (branch_addr & 0x40000U) ? ((int)branch_addr) - 0x80000 692bf215546Sopenharmony_ci : (int)branch_addr; 693bf215546Sopenharmony_ci 694bf215546Sopenharmony_ci bra->srcc = malloc(sizeof(*bra->srcc)); 695bf215546Sopenharmony_ci assert(bra->srcc); 696bf215546Sopenharmony_ci 697bf215546Sopenharmony_ci bra->srcc->predicate = (instruction >> PVR_ROGUE_PDSINST_BRA_SRCC_SHIFT) & 698bf215546Sopenharmony_ci PVR_ROGUE_PDSINST_PREDICATE_MASK; 699bf215546Sopenharmony_ci bra->srcc->negate = instruction & PVR_ROGUE_PDSINST_BRA_NEG_ENABLE; 700bf215546Sopenharmony_ci 701bf215546Sopenharmony_ci bra->setc = malloc(sizeof(*bra->setc)); 702bf215546Sopenharmony_ci assert(bra->setc); 703bf215546Sopenharmony_ci 704bf215546Sopenharmony_ci bra->setc->predicate = (instruction >> PVR_ROGUE_PDSINST_BRA_SETC_SHIFT) & 705bf215546Sopenharmony_ci PVR_ROGUE_PDSINST_PREDICATE_MASK; 706bf215546Sopenharmony_ci 707bf215546Sopenharmony_ci bra->target = NULL; 708bf215546Sopenharmony_ci 709bf215546Sopenharmony_ci return &bra->instruction; 710bf215546Sopenharmony_ci} 711bf215546Sopenharmony_ci 712bf215546Sopenharmony_cistatic struct pvr_instruction * 713bf215546Sopenharmony_cipvr_pds_disassemble_instruction_sp(void *context, 714bf215546Sopenharmony_ci PVR_ERR_CALLBACK err_callback, 715bf215546Sopenharmony_ci struct pvr_dissassembler_error error, 716bf215546Sopenharmony_ci uint32_t instruction) 717bf215546Sopenharmony_ci{ 718bf215546Sopenharmony_ci uint32_t op = (instruction >> PVR_TYPE_OPCODE_SP_SHIFT) & 719bf215546Sopenharmony_ci PVR_ROGUE_PDSINST_OPCODESP_MASK; 720bf215546Sopenharmony_ci bool cc = instruction & PVR_TYPE_OPCODE_SP; 721bf215546Sopenharmony_ci 722bf215546Sopenharmony_ci switch (op) { 723bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_OPCODESP_LD: 724bf215546Sopenharmony_ci error.instruction = INS_LD; 725bf215546Sopenharmony_ci return pvr_pds_disassemble_instruction_sp_ld_st( 726bf215546Sopenharmony_ci context, 727bf215546Sopenharmony_ci err_callback, 728bf215546Sopenharmony_ci error, 729bf215546Sopenharmony_ci true, 730bf215546Sopenharmony_ci instruction, 731bf215546Sopenharmony_ci instruction & (1 << PVR_ROGUE_PDSINST_LD_CC_SHIFT)); 732bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_OPCODESP_ST: 733bf215546Sopenharmony_ci error.instruction = INS_ST; 734bf215546Sopenharmony_ci return pvr_pds_disassemble_instruction_sp_ld_st( 735bf215546Sopenharmony_ci context, 736bf215546Sopenharmony_ci err_callback, 737bf215546Sopenharmony_ci error, 738bf215546Sopenharmony_ci false, 739bf215546Sopenharmony_ci instruction, 740bf215546Sopenharmony_ci instruction & (1 << PVR_ROGUE_PDSINST_ST_CC_SHIFT)); 741bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_OPCODESP_STMC: 742bf215546Sopenharmony_ci error.instruction = INS_STMC; 743bf215546Sopenharmony_ci return pvr_pds_disassemble_instruction_sp_stmc(instruction, cc); 744bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_OPCODESP_LIMM: 745bf215546Sopenharmony_ci error.instruction = INS_LIMM; 746bf215546Sopenharmony_ci return pvr_pds_disassemble_instruction_sp_limm(context, 747bf215546Sopenharmony_ci err_callback, 748bf215546Sopenharmony_ci error, 749bf215546Sopenharmony_ci instruction, 750bf215546Sopenharmony_ci cc); 751bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_OPCODESP_WDF: 752bf215546Sopenharmony_ci error.instruction = INS_WDF; 753bf215546Sopenharmony_ci return pvr_pds_disassemble_simple(INS_WDF, cc); 754bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_OPCODESP_LOCK: 755bf215546Sopenharmony_ci error.instruction = INS_LOCK; 756bf215546Sopenharmony_ci return pvr_pds_disassemble_simple(INS_LOCK, cc); 757bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_OPCODESP_RELEASE: 758bf215546Sopenharmony_ci error.instruction = INS_RELEASE; 759bf215546Sopenharmony_ci return pvr_pds_disassemble_simple(INS_RELEASE, cc); 760bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_OPCODESP_HALT: 761bf215546Sopenharmony_ci error.instruction = INS_HALT; 762bf215546Sopenharmony_ci return pvr_pds_disassemble_simple(INS_HALT, cc); 763bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_OPCODESP_NOP: 764bf215546Sopenharmony_ci error.instruction = INS_NOP; 765bf215546Sopenharmony_ci return pvr_pds_disassemble_simple(INS_NOP, cc); 766bf215546Sopenharmony_ci default: 767bf215546Sopenharmony_ci error.type = PVR_PDS_ERR_SP_UNKNOWN; 768bf215546Sopenharmony_ci error.text = "opcode unknown for special instruction"; 769bf215546Sopenharmony_ci pvr_error_check(err_callback, error); 770bf215546Sopenharmony_ci return NULL; 771bf215546Sopenharmony_ci } 772bf215546Sopenharmony_ci} 773bf215546Sopenharmony_ci 774bf215546Sopenharmony_cistatic struct pvr_instruction * 775bf215546Sopenharmony_cipvr_pds_disassemble_instruction_ddmad(void *context, 776bf215546Sopenharmony_ci PVR_ERR_CALLBACK err_callback, 777bf215546Sopenharmony_ci struct pvr_dissassembler_error error, 778bf215546Sopenharmony_ci uint32_t instruction) 779bf215546Sopenharmony_ci{ 780bf215546Sopenharmony_ci struct pvr_ddmad *ddmad = malloc(sizeof(*ddmad)); 781bf215546Sopenharmony_ci assert(ddmad); 782bf215546Sopenharmony_ci 783bf215546Sopenharmony_ci ddmad->instruction.next = NULL; 784bf215546Sopenharmony_ci ddmad->instruction.type = INS_DDMAD; 785bf215546Sopenharmony_ci 786bf215546Sopenharmony_ci ddmad->cc = instruction & PVR_ROGUE_PDSINST_DDMAD_CC_ENABLE; 787bf215546Sopenharmony_ci ddmad->END = instruction & PVR_ROGUE_PDSINST_DDMAD_END_ENABLE; 788bf215546Sopenharmony_ci 789bf215546Sopenharmony_ci ddmad->src0 = pvr_pds_disassemble_regs32( 790bf215546Sopenharmony_ci context, 791bf215546Sopenharmony_ci err_callback, 792bf215546Sopenharmony_ci error, 793bf215546Sopenharmony_ci instruction >> PVR_ROGUE_PDSINST_DDMAD_SRC0_SHIFT, 794bf215546Sopenharmony_ci 1); 795bf215546Sopenharmony_ci ddmad->src0->instruction = &ddmad->instruction; 796bf215546Sopenharmony_ci 797bf215546Sopenharmony_ci ddmad->src1 = pvr_pds_disassemble_regs32t( 798bf215546Sopenharmony_ci context, 799bf215546Sopenharmony_ci err_callback, 800bf215546Sopenharmony_ci error, 801bf215546Sopenharmony_ci instruction >> PVR_ROGUE_PDSINST_DDMAD_SRC1_SHIFT, 802bf215546Sopenharmony_ci 2); 803bf215546Sopenharmony_ci ddmad->src1->instruction = &ddmad->instruction; 804bf215546Sopenharmony_ci 805bf215546Sopenharmony_ci ddmad->src2 = pvr_pds_disassemble_regs64( 806bf215546Sopenharmony_ci context, 807bf215546Sopenharmony_ci err_callback, 808bf215546Sopenharmony_ci error, 809bf215546Sopenharmony_ci instruction >> PVR_ROGUE_PDSINST_DDMAD_SRC2_SHIFT, 810bf215546Sopenharmony_ci 3); 811bf215546Sopenharmony_ci ddmad->src2->instruction = &ddmad->instruction; 812bf215546Sopenharmony_ci 813bf215546Sopenharmony_ci ddmad->src3 = pvr_pds_disassemble_regs64C( 814bf215546Sopenharmony_ci context, 815bf215546Sopenharmony_ci err_callback, 816bf215546Sopenharmony_ci error, 817bf215546Sopenharmony_ci instruction >> PVR_ROGUE_PDSINST_DDMAD_SRC3_SHIFT, 818bf215546Sopenharmony_ci 4); 819bf215546Sopenharmony_ci ddmad->src3->instruction = &ddmad->instruction; 820bf215546Sopenharmony_ci 821bf215546Sopenharmony_ci return &ddmad->instruction; 822bf215546Sopenharmony_ci} 823bf215546Sopenharmony_ci 824bf215546Sopenharmony_cistatic struct pvr_instruction * 825bf215546Sopenharmony_cipvr_pds_disassemble_instruction_mad(void *context, 826bf215546Sopenharmony_ci PVR_ERR_CALLBACK err_callback, 827bf215546Sopenharmony_ci struct pvr_dissassembler_error error, 828bf215546Sopenharmony_ci uint32_t instruction) 829bf215546Sopenharmony_ci{ 830bf215546Sopenharmony_ci struct pvr_mad *mad = malloc(sizeof(*mad)); 831bf215546Sopenharmony_ci assert(mad); 832bf215546Sopenharmony_ci 833bf215546Sopenharmony_ci mad->instruction.next = NULL; 834bf215546Sopenharmony_ci mad->instruction.type = INS_MAD; 835bf215546Sopenharmony_ci 836bf215546Sopenharmony_ci mad->cc = instruction & PVR_ROGUE_PDSINST_MAD_CC_ENABLE; 837bf215546Sopenharmony_ci mad->sna = instruction & PVR_ROGUE_PDSINST_MAD_SNA_SUB; 838bf215546Sopenharmony_ci mad->alum = (instruction & PVR_ROGUE_PDSINST_MAD_ALUM_SIGNED); 839bf215546Sopenharmony_ci 840bf215546Sopenharmony_ci mad->src0 = pvr_pds_disassemble_regs32(context, 841bf215546Sopenharmony_ci err_callback, 842bf215546Sopenharmony_ci error, 843bf215546Sopenharmony_ci instruction >> 844bf215546Sopenharmony_ci PVR_ROGUE_PDSINST_MAD_SRC0_SHIFT, 845bf215546Sopenharmony_ci 1); 846bf215546Sopenharmony_ci mad->src0->instruction = &mad->instruction; 847bf215546Sopenharmony_ci 848bf215546Sopenharmony_ci mad->src1 = pvr_pds_disassemble_regs32(context, 849bf215546Sopenharmony_ci err_callback, 850bf215546Sopenharmony_ci error, 851bf215546Sopenharmony_ci instruction >> 852bf215546Sopenharmony_ci PVR_ROGUE_PDSINST_MAD_SRC1_SHIFT, 853bf215546Sopenharmony_ci 2); 854bf215546Sopenharmony_ci mad->src1->instruction = &mad->instruction; 855bf215546Sopenharmony_ci 856bf215546Sopenharmony_ci mad->src2 = pvr_pds_disassemble_regs64(context, 857bf215546Sopenharmony_ci err_callback, 858bf215546Sopenharmony_ci error, 859bf215546Sopenharmony_ci instruction >> 860bf215546Sopenharmony_ci PVR_ROGUE_PDSINST_MAD_SRC2_SHIFT, 861bf215546Sopenharmony_ci 3); 862bf215546Sopenharmony_ci mad->src2->instruction = &mad->instruction; 863bf215546Sopenharmony_ci 864bf215546Sopenharmony_ci mad->dst = pvr_pds_disassemble_regs64t(context, 865bf215546Sopenharmony_ci err_callback, 866bf215546Sopenharmony_ci error, 867bf215546Sopenharmony_ci instruction >> 868bf215546Sopenharmony_ci PVR_ROGUE_PDSINST_MAD_DST_SHIFT, 869bf215546Sopenharmony_ci 0); 870bf215546Sopenharmony_ci mad->dst->instruction = &mad->instruction; 871bf215546Sopenharmony_ci 872bf215546Sopenharmony_ci return &mad->instruction; 873bf215546Sopenharmony_ci} 874bf215546Sopenharmony_ci 875bf215546Sopenharmony_cistatic struct pvr_instruction * 876bf215546Sopenharmony_cipvr_pds_disassemble_instruction_dout(void *context, 877bf215546Sopenharmony_ci PVR_ERR_CALLBACK err_callback, 878bf215546Sopenharmony_ci struct pvr_dissassembler_error error, 879bf215546Sopenharmony_ci uint32_t instruction) 880bf215546Sopenharmony_ci{ 881bf215546Sopenharmony_ci struct pvr_dout *dout = malloc(sizeof(*dout)); 882bf215546Sopenharmony_ci assert(dout); 883bf215546Sopenharmony_ci 884bf215546Sopenharmony_ci dout->instruction.next = NULL; 885bf215546Sopenharmony_ci dout->instruction.type = INS_DOUT; 886bf215546Sopenharmony_ci 887bf215546Sopenharmony_ci dout->END = instruction & PVR_ROGUE_PDSINST_DOUT_END_ENABLE; 888bf215546Sopenharmony_ci dout->cc = instruction & PVR_ROGUE_PDSINST_DOUT_CC_ENABLE; 889bf215546Sopenharmony_ci dout->dst = (instruction >> PVR_ROGUE_PDSINST_DOUT_DST_SHIFT) & 890bf215546Sopenharmony_ci PVR_ROGUE_PDSINST_DSTDOUT_MASK; 891bf215546Sopenharmony_ci 892bf215546Sopenharmony_ci dout->src0 = pvr_pds_disassemble_regs64(context, 893bf215546Sopenharmony_ci err_callback, 894bf215546Sopenharmony_ci error, 895bf215546Sopenharmony_ci instruction >> 896bf215546Sopenharmony_ci PVR_ROGUE_PDSINST_DOUT_SRC0_SHIFT, 897bf215546Sopenharmony_ci 1); 898bf215546Sopenharmony_ci dout->src0->instruction = &dout->instruction; 899bf215546Sopenharmony_ci 900bf215546Sopenharmony_ci dout->src1 = pvr_pds_disassemble_regs32(context, 901bf215546Sopenharmony_ci err_callback, 902bf215546Sopenharmony_ci error, 903bf215546Sopenharmony_ci instruction >> 904bf215546Sopenharmony_ci PVR_ROGUE_PDSINST_DOUT_SRC1_SHIFT, 905bf215546Sopenharmony_ci 2); 906bf215546Sopenharmony_ci dout->src1->instruction = &dout->instruction; 907bf215546Sopenharmony_ci 908bf215546Sopenharmony_ci return &dout->instruction; 909bf215546Sopenharmony_ci} 910bf215546Sopenharmony_ci 911bf215546Sopenharmony_cistatic void pvr_pds_free_instruction_limm(struct pvr_limm *inst) 912bf215546Sopenharmony_ci{ 913bf215546Sopenharmony_ci free(inst->dst); 914bf215546Sopenharmony_ci free(inst->src0); 915bf215546Sopenharmony_ci free(inst); 916bf215546Sopenharmony_ci} 917bf215546Sopenharmony_ci 918bf215546Sopenharmony_cistatic void pvr_pds_free_instruction_add(struct pvr_add *inst) 919bf215546Sopenharmony_ci{ 920bf215546Sopenharmony_ci free(inst->dst); 921bf215546Sopenharmony_ci free(inst->src0); 922bf215546Sopenharmony_ci free(inst->src1); 923bf215546Sopenharmony_ci free(inst); 924bf215546Sopenharmony_ci} 925bf215546Sopenharmony_ci 926bf215546Sopenharmony_cistatic void pvr_pds_free_instruction_cmp(struct pvr_cmp *inst) 927bf215546Sopenharmony_ci{ 928bf215546Sopenharmony_ci free(inst->src0); 929bf215546Sopenharmony_ci free(inst->src1); 930bf215546Sopenharmony_ci free(inst); 931bf215546Sopenharmony_ci} 932bf215546Sopenharmony_ci 933bf215546Sopenharmony_cistatic void pvr_pds_free_instruction_mad(struct pvr_mad *inst) 934bf215546Sopenharmony_ci{ 935bf215546Sopenharmony_ci free(inst->dst); 936bf215546Sopenharmony_ci free(inst->src0); 937bf215546Sopenharmony_ci free(inst->src1); 938bf215546Sopenharmony_ci free(inst->src2); 939bf215546Sopenharmony_ci free(inst); 940bf215546Sopenharmony_ci} 941bf215546Sopenharmony_ci 942bf215546Sopenharmony_cistatic void pvr_pds_free_instruction_bra(struct pvr_bra *inst) 943bf215546Sopenharmony_ci{ 944bf215546Sopenharmony_ci free(inst->setc); 945bf215546Sopenharmony_ci free(inst->srcc); 946bf215546Sopenharmony_ci free(inst); 947bf215546Sopenharmony_ci} 948bf215546Sopenharmony_ci 949bf215546Sopenharmony_cistatic void pvr_pds_free_instruction_ddmad(struct pvr_ddmad *inst) 950bf215546Sopenharmony_ci{ 951bf215546Sopenharmony_ci free(inst->src0); 952bf215546Sopenharmony_ci free(inst->src1); 953bf215546Sopenharmony_ci free(inst->src2); 954bf215546Sopenharmony_ci free(inst->src3); 955bf215546Sopenharmony_ci free(inst); 956bf215546Sopenharmony_ci} 957bf215546Sopenharmony_ci 958bf215546Sopenharmony_cistatic void pvr_pds_free_instruction_dout(struct pvr_dout *inst) 959bf215546Sopenharmony_ci{ 960bf215546Sopenharmony_ci free(inst->src0); 961bf215546Sopenharmony_ci free(inst->src1); 962bf215546Sopenharmony_ci free(inst); 963bf215546Sopenharmony_ci} 964bf215546Sopenharmony_ci 965bf215546Sopenharmony_cistatic void pvr_pds_free_instruction_ldst(struct pvr_ldst *inst) 966bf215546Sopenharmony_ci{ 967bf215546Sopenharmony_ci free(inst->src0); 968bf215546Sopenharmony_ci free(inst); 969bf215546Sopenharmony_ci} 970bf215546Sopenharmony_ci 971bf215546Sopenharmony_cistatic void pvr_pds_free_instruction_simple(struct pvr_simple *inst) 972bf215546Sopenharmony_ci{ 973bf215546Sopenharmony_ci free(inst); 974bf215546Sopenharmony_ci} 975bf215546Sopenharmony_ci 976bf215546Sopenharmony_cistatic void pvr_pds_free_instruction_sfltp(struct pvr_sftlp *inst) 977bf215546Sopenharmony_ci{ 978bf215546Sopenharmony_ci free(inst->dst); 979bf215546Sopenharmony_ci free(inst->src0); 980bf215546Sopenharmony_ci free(inst->src1); 981bf215546Sopenharmony_ci free(inst->src2); 982bf215546Sopenharmony_ci free(inst); 983bf215546Sopenharmony_ci} 984bf215546Sopenharmony_ci 985bf215546Sopenharmony_cistatic void pvr_pds_free_instruction_stm(struct pvr_stm *inst) 986bf215546Sopenharmony_ci{ 987bf215546Sopenharmony_ci free(inst->src0); 988bf215546Sopenharmony_ci free(inst->src1); 989bf215546Sopenharmony_ci free(inst->src2); 990bf215546Sopenharmony_ci free(inst->src3); 991bf215546Sopenharmony_ci free(inst); 992bf215546Sopenharmony_ci} 993bf215546Sopenharmony_ci 994bf215546Sopenharmony_cistatic void pvr_pds_free_instruction_stmc(struct pvr_stmc *inst) 995bf215546Sopenharmony_ci{ 996bf215546Sopenharmony_ci free(inst->src0); 997bf215546Sopenharmony_ci free(inst); 998bf215546Sopenharmony_ci} 999bf215546Sopenharmony_ci 1000bf215546Sopenharmony_civoid pvr_pds_free_instruction(struct pvr_instruction *instruction) 1001bf215546Sopenharmony_ci{ 1002bf215546Sopenharmony_ci if (!instruction) 1003bf215546Sopenharmony_ci return; 1004bf215546Sopenharmony_ci 1005bf215546Sopenharmony_ci switch (instruction->type) { 1006bf215546Sopenharmony_ci case INS_LIMM: 1007bf215546Sopenharmony_ci pvr_pds_free_instruction_limm((struct pvr_limm *)instruction); 1008bf215546Sopenharmony_ci break; 1009bf215546Sopenharmony_ci case INS_ADD64: 1010bf215546Sopenharmony_ci case INS_ADD32: 1011bf215546Sopenharmony_ci pvr_pds_free_instruction_add((struct pvr_add *)instruction); 1012bf215546Sopenharmony_ci break; 1013bf215546Sopenharmony_ci case INS_CMP: 1014bf215546Sopenharmony_ci pvr_pds_free_instruction_cmp((struct pvr_cmp *)instruction); 1015bf215546Sopenharmony_ci break; 1016bf215546Sopenharmony_ci case INS_MAD: 1017bf215546Sopenharmony_ci pvr_pds_free_instruction_mad((struct pvr_mad *)instruction); 1018bf215546Sopenharmony_ci break; 1019bf215546Sopenharmony_ci case INS_BRA: 1020bf215546Sopenharmony_ci pvr_pds_free_instruction_bra((struct pvr_bra *)instruction); 1021bf215546Sopenharmony_ci break; 1022bf215546Sopenharmony_ci case INS_DDMAD: 1023bf215546Sopenharmony_ci pvr_pds_free_instruction_ddmad((struct pvr_ddmad *)instruction); 1024bf215546Sopenharmony_ci break; 1025bf215546Sopenharmony_ci case INS_DOUT: 1026bf215546Sopenharmony_ci pvr_pds_free_instruction_dout((struct pvr_dout *)instruction); 1027bf215546Sopenharmony_ci break; 1028bf215546Sopenharmony_ci case INS_LD: 1029bf215546Sopenharmony_ci case INS_ST: 1030bf215546Sopenharmony_ci pvr_pds_free_instruction_ldst((struct pvr_ldst *)instruction); 1031bf215546Sopenharmony_ci break; 1032bf215546Sopenharmony_ci case INS_WDF: 1033bf215546Sopenharmony_ci case INS_LOCK: 1034bf215546Sopenharmony_ci case INS_RELEASE: 1035bf215546Sopenharmony_ci case INS_HALT: 1036bf215546Sopenharmony_ci case INS_NOP: 1037bf215546Sopenharmony_ci pvr_pds_free_instruction_simple((struct pvr_simple *)instruction); 1038bf215546Sopenharmony_ci break; 1039bf215546Sopenharmony_ci case INS_SFTLP64: 1040bf215546Sopenharmony_ci case INS_SFTLP32: 1041bf215546Sopenharmony_ci pvr_pds_free_instruction_sfltp((struct pvr_sftlp *)instruction); 1042bf215546Sopenharmony_ci break; 1043bf215546Sopenharmony_ci case INS_STM: 1044bf215546Sopenharmony_ci pvr_pds_free_instruction_stm((struct pvr_stm *)instruction); 1045bf215546Sopenharmony_ci break; 1046bf215546Sopenharmony_ci case INS_STMC: 1047bf215546Sopenharmony_ci pvr_pds_free_instruction_stmc((struct pvr_stmc *)instruction); 1048bf215546Sopenharmony_ci break; 1049bf215546Sopenharmony_ci } 1050bf215546Sopenharmony_ci} 1051bf215546Sopenharmony_ci 1052bf215546Sopenharmony_cistruct pvr_instruction * 1053bf215546Sopenharmony_cipvr_pds_disassemble_instruction2(void *context, 1054bf215546Sopenharmony_ci PVR_ERR_CALLBACK err_callback, 1055bf215546Sopenharmony_ci uint32_t instruction) 1056bf215546Sopenharmony_ci{ 1057bf215546Sopenharmony_ci struct pvr_dissassembler_error error = { .context = context }; 1058bf215546Sopenharmony_ci 1059bf215546Sopenharmony_ci /* First we need to find out what type of OPCODE we are dealing with. */ 1060bf215546Sopenharmony_ci if (instruction & PVR_TYPE_OPCODE) { 1061bf215546Sopenharmony_ci uint32_t opcode_C = (instruction >> PVR_TYPE_OPCODE_SHIFT) & 1062bf215546Sopenharmony_ci PVR_ROGUE_PDSINST_OPCODEC_MASK; 1063bf215546Sopenharmony_ci switch (opcode_C) { 1064bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_OPCODEC_ADD64: 1065bf215546Sopenharmony_ci error.instruction = INS_ADD64; 1066bf215546Sopenharmony_ci return pvr_pds_disassemble_instruction_add64(context, 1067bf215546Sopenharmony_ci err_callback, 1068bf215546Sopenharmony_ci error, 1069bf215546Sopenharmony_ci instruction); 1070bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_OPCODEC_ADD32: 1071bf215546Sopenharmony_ci error.instruction = INS_ADD32; 1072bf215546Sopenharmony_ci return pvr_pds_disassemble_instruction_add32(context, 1073bf215546Sopenharmony_ci err_callback, 1074bf215546Sopenharmony_ci error, 1075bf215546Sopenharmony_ci instruction); 1076bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_OPCODEC_SFTLP64: 1077bf215546Sopenharmony_ci error.instruction = INS_SFTLP64; 1078bf215546Sopenharmony_ci return pvr_pds_disassemble_instruction_sftlp64(context, 1079bf215546Sopenharmony_ci err_callback, 1080bf215546Sopenharmony_ci error, 1081bf215546Sopenharmony_ci instruction); 1082bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_OPCODEC_CMP: 1083bf215546Sopenharmony_ci error.instruction = INS_CMP; 1084bf215546Sopenharmony_ci return pvr_pds_disassemble_instruction_cmp(context, 1085bf215546Sopenharmony_ci err_callback, 1086bf215546Sopenharmony_ci error, 1087bf215546Sopenharmony_ci instruction); 1088bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_OPCODEC_BRA: 1089bf215546Sopenharmony_ci error.instruction = INS_BRA; 1090bf215546Sopenharmony_ci return pvr_pds_disassemble_instruction_bra(instruction); 1091bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_OPCODEC_SP: 1092bf215546Sopenharmony_ci return pvr_pds_disassemble_instruction_sp(context, 1093bf215546Sopenharmony_ci err_callback, 1094bf215546Sopenharmony_ci error, 1095bf215546Sopenharmony_ci instruction); 1096bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_OPCODEC_DDMAD: 1097bf215546Sopenharmony_ci error.instruction = INS_DDMAD; 1098bf215546Sopenharmony_ci return pvr_pds_disassemble_instruction_ddmad(context, 1099bf215546Sopenharmony_ci err_callback, 1100bf215546Sopenharmony_ci error, 1101bf215546Sopenharmony_ci instruction); 1102bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_OPCODEC_DOUT: 1103bf215546Sopenharmony_ci error.instruction = INS_DOUT; 1104bf215546Sopenharmony_ci return pvr_pds_disassemble_instruction_dout(context, 1105bf215546Sopenharmony_ci err_callback, 1106bf215546Sopenharmony_ci error, 1107bf215546Sopenharmony_ci instruction); 1108bf215546Sopenharmony_ci } 1109bf215546Sopenharmony_ci } else if (instruction & PVR_TYPE_OPCODEB) { 1110bf215546Sopenharmony_ci uint32_t opcode_B = (instruction >> PVR_TYPE_OPCODEB_SHIFT) & 1111bf215546Sopenharmony_ci PVR_ROGUE_PDSINST_OPCODEB_MASK; 1112bf215546Sopenharmony_ci switch (opcode_B) { 1113bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_OPCODEB_SFTLP32: 1114bf215546Sopenharmony_ci error.instruction = INS_SFTLP32; 1115bf215546Sopenharmony_ci return pvr_pds_disassemble_instruction_sftlp32(context, 1116bf215546Sopenharmony_ci err_callback, 1117bf215546Sopenharmony_ci error, 1118bf215546Sopenharmony_ci instruction); 1119bf215546Sopenharmony_ci case PVR_ROGUE_PDSINST_OPCODEB_STM: 1120bf215546Sopenharmony_ci error.instruction = INS_STM; 1121bf215546Sopenharmony_ci return pvr_pds_disassemble_instruction_stm(context, 1122bf215546Sopenharmony_ci err_callback, 1123bf215546Sopenharmony_ci error, 1124bf215546Sopenharmony_ci instruction); 1125bf215546Sopenharmony_ci } 1126bf215546Sopenharmony_ci } else { /* Opcode A - MAD instruction. */ 1127bf215546Sopenharmony_ci error.instruction = INS_MAD; 1128bf215546Sopenharmony_ci return pvr_pds_disassemble_instruction_mad(context, 1129bf215546Sopenharmony_ci err_callback, 1130bf215546Sopenharmony_ci error, 1131bf215546Sopenharmony_ci instruction); 1132bf215546Sopenharmony_ci } 1133bf215546Sopenharmony_ci return NULL; 1134bf215546Sopenharmony_ci} 1135