101e04c3fSmrg/* 201e04c3fSmrg * Copyright (c) 2016 Etnaviv Project 301e04c3fSmrg * 401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 501e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 601e04c3fSmrg * to deal in the Software without restriction, including without limitation 701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sub license, 801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the 901e04c3fSmrg * Software is furnished to do so, subject to the following conditions: 1001e04c3fSmrg * 1101e04c3fSmrg * The above copyright notice and this permission notice (including the 1201e04c3fSmrg * next paragraph) shall be included in all copies or substantial portions 1301e04c3fSmrg * of the Software. 1401e04c3fSmrg * 1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 2101e04c3fSmrg * DEALINGS IN THE SOFTWARE. 2201e04c3fSmrg * 2301e04c3fSmrg * Authors: 2401e04c3fSmrg * Christian Gmeiner <christian.gmeiner@gmail.com> 2501e04c3fSmrg */ 2601e04c3fSmrg 2701e04c3fSmrg#include "etnaviv_disasm.h" 287ec681f3Smrg#include "etnaviv_asm.h" 2901e04c3fSmrg 3001e04c3fSmrg#include <assert.h> 3101e04c3fSmrg#include <stdbool.h> 3201e04c3fSmrg#include <stdio.h> 3301e04c3fSmrg#include <stdlib.h> 3401e04c3fSmrg 3501e04c3fSmrg#include "hw/isa.xml.h" 367ec681f3Smrg#include "util/u_math.h" 377ec681f3Smrg#include "util/half_float.h" 3801e04c3fSmrg 3901e04c3fSmrgstruct instr { 4001e04c3fSmrg /* dword0: */ 4101e04c3fSmrg uint32_t opc : 6; 4201e04c3fSmrg uint32_t cond : 5; 4301e04c3fSmrg uint32_t sat : 1; 4401e04c3fSmrg uint32_t dst_use : 1; 4501e04c3fSmrg uint32_t dst_amode : 3; 4601e04c3fSmrg uint32_t dst_reg : 7; 4701e04c3fSmrg uint32_t dst_comps : 4; 4801e04c3fSmrg uint32_t tex_id : 5; 4901e04c3fSmrg 5001e04c3fSmrg /* dword1: */ 5101e04c3fSmrg uint32_t tex_amode : 3; 5201e04c3fSmrg uint32_t tex_swiz : 8; 5301e04c3fSmrg uint32_t src0_use : 1; 5401e04c3fSmrg uint32_t src0_reg : 9; 5501e04c3fSmrg uint32_t type_bit2 : 1; 5601e04c3fSmrg uint32_t src0_swiz : 8; 5701e04c3fSmrg uint32_t src0_neg : 1; 5801e04c3fSmrg uint32_t src0_abs : 1; 5901e04c3fSmrg 6001e04c3fSmrg /* dword2: */ 6101e04c3fSmrg uint32_t src0_amode : 3; 6201e04c3fSmrg uint32_t src0_rgroup : 3; 6301e04c3fSmrg uint32_t src1_use : 1; 6401e04c3fSmrg uint32_t src1_reg : 9; 6501e04c3fSmrg uint32_t opcode_bit6 : 1; 6601e04c3fSmrg uint32_t src1_swiz : 8; 6701e04c3fSmrg uint32_t src1_neg : 1; 6801e04c3fSmrg uint32_t src1_abs : 1; 6901e04c3fSmrg uint32_t src1_amode : 3; 7001e04c3fSmrg uint32_t type_bit01 : 2; 7101e04c3fSmrg 7201e04c3fSmrg /* dword3: */ 7301e04c3fSmrg union { 7401e04c3fSmrg struct { 7501e04c3fSmrg uint32_t src1_rgroup : 3; 7601e04c3fSmrg uint32_t src2_use : 1; 7701e04c3fSmrg uint32_t src2_reg : 9; 787ec681f3Smrg uint32_t sel_0 : 1; 7901e04c3fSmrg uint32_t src2_swiz : 8; 8001e04c3fSmrg uint32_t src2_neg : 1; 8101e04c3fSmrg uint32_t src2_abs : 1; 827ec681f3Smrg uint32_t sel_1 : 1; 8301e04c3fSmrg uint32_t src2_amode : 3; 8401e04c3fSmrg uint32_t src2_rgroup : 3; 857ec681f3Smrg uint32_t dst_full : 1; 8601e04c3fSmrg }; 8701e04c3fSmrg uint32_t dword3; 8801e04c3fSmrg }; 8901e04c3fSmrg}; 9001e04c3fSmrgstruct opc_operands { 917ec681f3Smrg struct etna_inst_dst *dst; 927ec681f3Smrg struct etna_inst_tex *tex; 937ec681f3Smrg struct etna_inst_src *src0; 947ec681f3Smrg struct etna_inst_src *src1; 957ec681f3Smrg struct etna_inst_src *src2; 9601e04c3fSmrg 9701e04c3fSmrg int imm; 9801e04c3fSmrg}; 9901e04c3fSmrg 10001e04c3fSmrgstatic void 10101e04c3fSmrgprintf_type(uint8_t type) 10201e04c3fSmrg{ 10301e04c3fSmrg switch(type) { 10401e04c3fSmrg case INST_TYPE_F32: 10501e04c3fSmrg /* as f32 is the default print nothing */ 10601e04c3fSmrg break; 10701e04c3fSmrg 10801e04c3fSmrg case INST_TYPE_S32: 10901e04c3fSmrg printf(".s32"); 11001e04c3fSmrg break; 11101e04c3fSmrg 11201e04c3fSmrg case INST_TYPE_S8: 11301e04c3fSmrg printf(".s8"); 11401e04c3fSmrg break; 11501e04c3fSmrg 11601e04c3fSmrg case INST_TYPE_U16: 11701e04c3fSmrg printf(".u16"); 11801e04c3fSmrg break; 11901e04c3fSmrg 12001e04c3fSmrg case INST_TYPE_F16: 12101e04c3fSmrg printf(".f16"); 12201e04c3fSmrg break; 12301e04c3fSmrg 12401e04c3fSmrg case INST_TYPE_S16: 12501e04c3fSmrg printf(".s16"); 12601e04c3fSmrg break; 12701e04c3fSmrg 12801e04c3fSmrg case INST_TYPE_U32: 12901e04c3fSmrg printf(".u32"); 13001e04c3fSmrg break; 13101e04c3fSmrg 13201e04c3fSmrg case INST_TYPE_U8: 13301e04c3fSmrg printf(".u8"); 13401e04c3fSmrg break; 13501e04c3fSmrg 13601e04c3fSmrg default: 13701e04c3fSmrg abort(); 13801e04c3fSmrg break; 13901e04c3fSmrg } 14001e04c3fSmrg} 14101e04c3fSmrg 14201e04c3fSmrgstatic void 14301e04c3fSmrgprint_condition(uint8_t condition) 14401e04c3fSmrg{ 14501e04c3fSmrg switch (condition) { 14601e04c3fSmrg case INST_CONDITION_TRUE: 14701e04c3fSmrg break; 14801e04c3fSmrg 14901e04c3fSmrg case INST_CONDITION_GT: 15001e04c3fSmrg printf(".GT"); 15101e04c3fSmrg break; 15201e04c3fSmrg 15301e04c3fSmrg case INST_CONDITION_LT: 15401e04c3fSmrg printf(".LT"); 15501e04c3fSmrg break; 15601e04c3fSmrg 15701e04c3fSmrg case INST_CONDITION_GE: 15801e04c3fSmrg printf(".GE"); 15901e04c3fSmrg break; 16001e04c3fSmrg 16101e04c3fSmrg case INST_CONDITION_LE: 16201e04c3fSmrg printf(".LE"); 16301e04c3fSmrg break; 16401e04c3fSmrg 16501e04c3fSmrg case INST_CONDITION_EQ: 16601e04c3fSmrg printf(".EQ"); 16701e04c3fSmrg break; 16801e04c3fSmrg 16901e04c3fSmrg case INST_CONDITION_NE: 17001e04c3fSmrg printf(".NE"); 17101e04c3fSmrg break; 17201e04c3fSmrg 17301e04c3fSmrg case INST_CONDITION_AND: 17401e04c3fSmrg printf(".AND"); 17501e04c3fSmrg break; 17601e04c3fSmrg 17701e04c3fSmrg case INST_CONDITION_OR: 17801e04c3fSmrg printf(".OR"); 17901e04c3fSmrg break; 18001e04c3fSmrg 18101e04c3fSmrg case INST_CONDITION_XOR: 18201e04c3fSmrg printf(".XOR"); 18301e04c3fSmrg break; 18401e04c3fSmrg 18501e04c3fSmrg case INST_CONDITION_NOT: 18601e04c3fSmrg printf(".NOT"); 18701e04c3fSmrg break; 18801e04c3fSmrg 18901e04c3fSmrg case INST_CONDITION_NZ: 19001e04c3fSmrg printf(".NZ"); 19101e04c3fSmrg break; 19201e04c3fSmrg 19301e04c3fSmrg case INST_CONDITION_GEZ: 19401e04c3fSmrg printf(".GEZ"); 19501e04c3fSmrg break; 19601e04c3fSmrg 19701e04c3fSmrg case INST_CONDITION_GZ: 19801e04c3fSmrg printf(".GZ"); 19901e04c3fSmrg break; 20001e04c3fSmrg 20101e04c3fSmrg case INST_CONDITION_LEZ: 20201e04c3fSmrg printf(".LEZ"); 20301e04c3fSmrg break; 20401e04c3fSmrg 20501e04c3fSmrg case INST_CONDITION_LZ: 20601e04c3fSmrg printf(".LZ"); 20701e04c3fSmrg break; 20801e04c3fSmrg 20901e04c3fSmrg default: 21001e04c3fSmrg abort(); 21101e04c3fSmrg break; 21201e04c3fSmrg } 21301e04c3fSmrg} 21401e04c3fSmrg 21501e04c3fSmrgstatic void 21601e04c3fSmrgprint_rgroup(uint8_t rgoup) 21701e04c3fSmrg{ 21801e04c3fSmrg switch (rgoup) { 21901e04c3fSmrg case INST_RGROUP_TEMP: 22001e04c3fSmrg printf("t"); 22101e04c3fSmrg break; 22201e04c3fSmrg 22301e04c3fSmrg case INST_RGROUP_INTERNAL: 22401e04c3fSmrg printf("i"); 22501e04c3fSmrg break; 22601e04c3fSmrg 22701e04c3fSmrg case INST_RGROUP_UNIFORM_0: 22801e04c3fSmrg case INST_RGROUP_UNIFORM_1: 22901e04c3fSmrg printf("u"); 23001e04c3fSmrg break; 2317ec681f3Smrg case 4: 2327ec681f3Smrg printf("th"); 2337ec681f3Smrg break; 23401e04c3fSmrg } 23501e04c3fSmrg} 23601e04c3fSmrg 23701e04c3fSmrgstatic void 23801e04c3fSmrgprint_components(uint8_t components) 23901e04c3fSmrg{ 24001e04c3fSmrg if (components == 15) 24101e04c3fSmrg return; 24201e04c3fSmrg 24301e04c3fSmrg printf("."); 24401e04c3fSmrg if (components & INST_COMPS_X) 24501e04c3fSmrg printf("x"); 24601e04c3fSmrg else 24701e04c3fSmrg printf("_"); 24801e04c3fSmrg 24901e04c3fSmrg if (components & INST_COMPS_Y) 25001e04c3fSmrg printf("y"); 25101e04c3fSmrg else 25201e04c3fSmrg printf("_"); 25301e04c3fSmrg 25401e04c3fSmrg if (components & INST_COMPS_Z) 25501e04c3fSmrg printf("z"); 25601e04c3fSmrg else 25701e04c3fSmrg printf("_"); 25801e04c3fSmrg 25901e04c3fSmrg if (components & INST_COMPS_W) 26001e04c3fSmrg printf("w"); 26101e04c3fSmrg else 26201e04c3fSmrg printf("_"); 26301e04c3fSmrg} 26401e04c3fSmrg 26501e04c3fSmrgstatic inline void 26601e04c3fSmrgprint_swiz_comp(uint8_t swiz_comp) 26701e04c3fSmrg{ 26801e04c3fSmrg switch (swiz_comp) { 26901e04c3fSmrg case INST_SWIZ_COMP_X: 27001e04c3fSmrg printf("x"); 27101e04c3fSmrg break; 27201e04c3fSmrg 27301e04c3fSmrg case INST_SWIZ_COMP_Y: 27401e04c3fSmrg printf("y"); 27501e04c3fSmrg break; 27601e04c3fSmrg 27701e04c3fSmrg case INST_SWIZ_COMP_Z: 27801e04c3fSmrg printf("z"); 27901e04c3fSmrg break; 28001e04c3fSmrg 28101e04c3fSmrg case INST_SWIZ_COMP_W: 28201e04c3fSmrg printf("w"); 28301e04c3fSmrg break; 28401e04c3fSmrg 28501e04c3fSmrg default: 28601e04c3fSmrg abort(); 28701e04c3fSmrg break; 28801e04c3fSmrg } 28901e04c3fSmrg} 29001e04c3fSmrg 29101e04c3fSmrgstatic void 29201e04c3fSmrgprint_swiz(uint8_t swiz) 29301e04c3fSmrg{ 29401e04c3fSmrg // if a null swizzle 29501e04c3fSmrg if (swiz == 0xe4) 29601e04c3fSmrg return; 29701e04c3fSmrg 29801e04c3fSmrg const unsigned x = swiz & 0x3; 29901e04c3fSmrg const unsigned y = (swiz & 0x0C) >> 2; 30001e04c3fSmrg const unsigned z = (swiz & 0x30) >> 4; 30101e04c3fSmrg const unsigned w = (swiz & 0xc0) >> 6; 30201e04c3fSmrg 30301e04c3fSmrg printf("."); 30401e04c3fSmrg print_swiz_comp(x); 30501e04c3fSmrg print_swiz_comp(y); 30601e04c3fSmrg print_swiz_comp(z); 30701e04c3fSmrg print_swiz_comp(w); 30801e04c3fSmrg} 30901e04c3fSmrg 31001e04c3fSmrgstatic void 31101e04c3fSmrgprint_amode(uint8_t amode) 31201e04c3fSmrg{ 31301e04c3fSmrg switch (amode) { 31401e04c3fSmrg case INST_AMODE_DIRECT: 31501e04c3fSmrg /* nothing to output */ 31601e04c3fSmrg break; 31701e04c3fSmrg 31801e04c3fSmrg case INST_AMODE_ADD_A_X: 31901e04c3fSmrg printf("[a.x]"); 32001e04c3fSmrg break; 32101e04c3fSmrg 32201e04c3fSmrg case INST_AMODE_ADD_A_Y: 32301e04c3fSmrg printf("[a.y]"); 32401e04c3fSmrg break; 32501e04c3fSmrg 32601e04c3fSmrg case INST_AMODE_ADD_A_Z: 32701e04c3fSmrg printf("[a.z]"); 32801e04c3fSmrg break; 32901e04c3fSmrg 33001e04c3fSmrg case INST_AMODE_ADD_A_W: 33101e04c3fSmrg printf("[a.w]"); 33201e04c3fSmrg break; 33301e04c3fSmrg 33401e04c3fSmrg default: 33501e04c3fSmrg abort(); 33601e04c3fSmrg break; 33701e04c3fSmrg } 33801e04c3fSmrg} 33901e04c3fSmrg 34001e04c3fSmrgstatic void 3417ec681f3Smrgprint_dst(struct etna_inst_dst *dst, bool sep) 34201e04c3fSmrg{ 34301e04c3fSmrg if (dst->use) { 34401e04c3fSmrg printf("t%u", dst->reg); 34501e04c3fSmrg print_amode(dst->amode); 3467ec681f3Smrg print_components(dst->write_mask); 34701e04c3fSmrg } else { 34801e04c3fSmrg printf("void"); 34901e04c3fSmrg } 35001e04c3fSmrg 35101e04c3fSmrg if (sep) 35201e04c3fSmrg printf(", "); 35301e04c3fSmrg} 35401e04c3fSmrg 35501e04c3fSmrgstatic void 3567ec681f3Smrgprint_tex(struct etna_inst_tex *tex, bool sep) 35701e04c3fSmrg{ 35801e04c3fSmrg printf("tex%u", tex->id); 35901e04c3fSmrg print_amode(tex->amode); 36001e04c3fSmrg print_swiz(tex->swiz); 36101e04c3fSmrg 36201e04c3fSmrg if (sep) 36301e04c3fSmrg printf(", "); 36401e04c3fSmrg} 36501e04c3fSmrg 36601e04c3fSmrgstatic void 3677ec681f3Smrgprint_src(struct etna_inst_src *src, bool sep) 36801e04c3fSmrg{ 36901e04c3fSmrg if (src->use) { 3707ec681f3Smrg if (src->rgroup == INST_RGROUP_IMMEDIATE) { 3717ec681f3Smrg switch (src->imm_type) { 3727ec681f3Smrg case 0: /* float */ 3737ec681f3Smrg printf("%f", uif(src->imm_val << 12)); 3747ec681f3Smrg break; 3757ec681f3Smrg case 1: /* signed */ 3767ec681f3Smrg printf("%d", ((int) src->imm_val << 12) >> 12); 3777ec681f3Smrg break; 3787ec681f3Smrg case 2: /* unsigned */ 3797ec681f3Smrg printf("%d", src->imm_val); 3807ec681f3Smrg break; 3817ec681f3Smrg case 3: /* 16-bit */ 3827ec681f3Smrg printf("%f/%.5X", _mesa_half_to_float(src->imm_val), src->imm_val); 3837ec681f3Smrg break; 3847ec681f3Smrg } 3857ec681f3Smrg } else { 3867ec681f3Smrg if (src->neg) 3877ec681f3Smrg printf("-"); 3887ec681f3Smrg 3897ec681f3Smrg if (src->abs) 3907ec681f3Smrg printf("|"); 3917ec681f3Smrg 3927ec681f3Smrg if (src->rgroup == INST_RGROUP_UNIFORM_1) 3937ec681f3Smrg src->reg += 128; 3947ec681f3Smrg 3957ec681f3Smrg print_rgroup(src->rgroup); 3967ec681f3Smrg printf("%u", src->reg); 3977ec681f3Smrg print_amode(src->amode); 3987ec681f3Smrg print_swiz(src->swiz); 3997ec681f3Smrg 4007ec681f3Smrg if (src->abs) 4017ec681f3Smrg printf("|"); 4027ec681f3Smrg } 40301e04c3fSmrg } else { 40401e04c3fSmrg printf("void"); 40501e04c3fSmrg } 40601e04c3fSmrg 40701e04c3fSmrg if (sep) 40801e04c3fSmrg printf(", "); 40901e04c3fSmrg} 41001e04c3fSmrg 41101e04c3fSmrgstatic void 41201e04c3fSmrgprint_opc_default(struct opc_operands *operands) 41301e04c3fSmrg{ 41401e04c3fSmrg print_dst(operands->dst, true); 41501e04c3fSmrg print_src(operands->src0, true); 41601e04c3fSmrg print_src(operands->src1, true); 41701e04c3fSmrg print_src(operands->src2, false); 41801e04c3fSmrg} 41901e04c3fSmrg 42001e04c3fSmrgstatic void 42101e04c3fSmrgprint_opc_mov(struct opc_operands *operands) 42201e04c3fSmrg{ 42301e04c3fSmrg // dst (areg) 42401e04c3fSmrg printf("a%u", operands->dst->reg); 4257ec681f3Smrg print_components(operands->dst->write_mask); 42601e04c3fSmrg printf(", "); 42701e04c3fSmrg 42801e04c3fSmrg print_src(operands->src0, true); 42901e04c3fSmrg print_src(operands->src1, true); 43001e04c3fSmrg print_src(operands->src2, false); 43101e04c3fSmrg} 43201e04c3fSmrg 43301e04c3fSmrgstatic void 43401e04c3fSmrgprint_opc_tex(struct opc_operands *operands) 43501e04c3fSmrg{ 43601e04c3fSmrg print_dst(operands->dst, true); 43701e04c3fSmrg print_tex(operands->tex, true); 43801e04c3fSmrg print_src(operands->src0, true); 43901e04c3fSmrg print_src(operands->src1, true); 44001e04c3fSmrg print_src(operands->src2, false); 44101e04c3fSmrg} 44201e04c3fSmrg 44301e04c3fSmrgstatic void 44401e04c3fSmrgprint_opc_imm(struct opc_operands *operands) 44501e04c3fSmrg{ 44601e04c3fSmrg print_dst(operands->dst, true); 44701e04c3fSmrg print_src(operands->src0, true); 44801e04c3fSmrg print_src(operands->src1, true); 44901e04c3fSmrg printf("label_%04d", operands->imm); 45001e04c3fSmrg} 45101e04c3fSmrg 45201e04c3fSmrg#define OPC_BITS 7 45301e04c3fSmrg 45401e04c3fSmrgstatic const struct opc_info { 45501e04c3fSmrg const char *name; 45601e04c3fSmrg void (*print)(struct opc_operands *operands); 45701e04c3fSmrg} opcs[1 << OPC_BITS] = { 45801e04c3fSmrg#define OPC(opc) [INST_OPCODE_##opc] = {#opc, print_opc_default} 45901e04c3fSmrg#define OPC_MOV(opc) [INST_OPCODE_##opc] = {#opc, print_opc_mov} 46001e04c3fSmrg#define OPC_TEX(opc) [INST_OPCODE_##opc] = {#opc, print_opc_tex} 46101e04c3fSmrg#define OPC_IMM(opc) [INST_OPCODE_##opc] = {#opc, print_opc_imm} 46201e04c3fSmrg OPC(NOP), 46301e04c3fSmrg OPC(ADD), 46401e04c3fSmrg OPC(MAD), 46501e04c3fSmrg OPC(MUL), 46601e04c3fSmrg OPC(DST), 46701e04c3fSmrg OPC(DP3), 46801e04c3fSmrg OPC(DP4), 46901e04c3fSmrg OPC(DSX), 47001e04c3fSmrg OPC(DSY), 47101e04c3fSmrg OPC(MOV), 47201e04c3fSmrg OPC_MOV(MOVAR), 47301e04c3fSmrg OPC_MOV(MOVAF), 4747ec681f3Smrg OPC_MOV(MOVAI), 47501e04c3fSmrg OPC(RCP), 47601e04c3fSmrg OPC(RSQ), 47701e04c3fSmrg OPC(LITP), 47801e04c3fSmrg OPC(SELECT), 47901e04c3fSmrg OPC(SET), 48001e04c3fSmrg OPC(EXP), 48101e04c3fSmrg OPC(LOG), 48201e04c3fSmrg OPC(FRC), 48301e04c3fSmrg OPC_IMM(CALL), 48401e04c3fSmrg OPC(RET), 48501e04c3fSmrg OPC_IMM(BRANCH), 48601e04c3fSmrg OPC_TEX(TEXKILL), 48701e04c3fSmrg OPC_TEX(TEXLD), 48801e04c3fSmrg OPC_TEX(TEXLDB), 48901e04c3fSmrg OPC_TEX(TEXLDD), 49001e04c3fSmrg OPC_TEX(TEXLDL), 49101e04c3fSmrg OPC_TEX(TEXLDPCF), 4927ec681f3Smrg OPC_TEX(TEXLDLPCF), 4937ec681f3Smrg OPC_TEX(TEXLDGPCF), 49401e04c3fSmrg OPC(REP), 49501e04c3fSmrg OPC(ENDREP), 49601e04c3fSmrg OPC(LOOP), 49701e04c3fSmrg OPC(ENDLOOP), 49801e04c3fSmrg OPC(SQRT), 49901e04c3fSmrg OPC(SIN), 50001e04c3fSmrg OPC(COS), 50101e04c3fSmrg OPC(FLOOR), 50201e04c3fSmrg OPC(CEIL), 50301e04c3fSmrg OPC(SIGN), 50401e04c3fSmrg OPC(I2F), 5057ec681f3Smrg OPC(F2I), 50601e04c3fSmrg OPC(CMP), 50701e04c3fSmrg OPC(LOAD), 50801e04c3fSmrg OPC(STORE), 50901e04c3fSmrg OPC(IMULLO0), 51001e04c3fSmrg OPC(IMULHI0), 5117ec681f3Smrg OPC(IMADLO0), 5127ec681f3Smrg OPC(IMADHI0), 51301e04c3fSmrg OPC(LEADZERO), 51401e04c3fSmrg OPC(LSHIFT), 51501e04c3fSmrg OPC(RSHIFT), 51601e04c3fSmrg OPC(ROTATE), 51701e04c3fSmrg OPC(OR), 51801e04c3fSmrg OPC(AND), 51901e04c3fSmrg OPC(XOR), 52001e04c3fSmrg OPC(NOT), 52101e04c3fSmrg OPC(DP2), 5227ec681f3Smrg OPC(DIV), 5237ec681f3Smrg OPC(IABS), 52401e04c3fSmrg}; 52501e04c3fSmrg 52601e04c3fSmrgstatic void 52701e04c3fSmrgprint_instr(uint32_t *dwords, int n, enum debug_t debug) 52801e04c3fSmrg{ 52901e04c3fSmrg struct instr *instr = (struct instr *)dwords; 53001e04c3fSmrg const unsigned opc = instr->opc | (instr->opcode_bit6 << 6); 53101e04c3fSmrg const char *name = opcs[opc].name; 53201e04c3fSmrg 53301e04c3fSmrg printf("%04d: ", n); 53401e04c3fSmrg if (debug & PRINT_RAW) 53501e04c3fSmrg printf("%08x %08x %08x %08x ", dwords[0], dwords[1], dwords[2], 53601e04c3fSmrg dwords[3]); 53701e04c3fSmrg 53801e04c3fSmrg if (name) { 53901e04c3fSmrg 5407ec681f3Smrg struct etna_inst_dst dst = { 54101e04c3fSmrg .use = instr->dst_use, 54201e04c3fSmrg .amode = instr->dst_amode, 54301e04c3fSmrg .reg = instr->dst_reg, 5447ec681f3Smrg .write_mask = instr->dst_comps 54501e04c3fSmrg }; 54601e04c3fSmrg 5477ec681f3Smrg struct etna_inst_tex tex = { 54801e04c3fSmrg .id = instr->tex_id, 54901e04c3fSmrg .amode = instr->tex_amode, 55001e04c3fSmrg .swiz = instr->tex_swiz, 55101e04c3fSmrg }; 55201e04c3fSmrg 5537ec681f3Smrg struct etna_inst_src src0 = { 55401e04c3fSmrg .use = instr->src0_use, 55501e04c3fSmrg .neg = instr->src0_neg, 55601e04c3fSmrg .abs = instr->src0_abs, 55701e04c3fSmrg .rgroup = instr->src0_rgroup, 55801e04c3fSmrg .reg = instr->src0_reg, 55901e04c3fSmrg .swiz = instr->src0_swiz, 56001e04c3fSmrg .amode = instr->src0_amode, 56101e04c3fSmrg }; 56201e04c3fSmrg 5637ec681f3Smrg struct etna_inst_src src1 = { 56401e04c3fSmrg .use = instr->src1_use, 56501e04c3fSmrg .neg = instr->src1_neg, 56601e04c3fSmrg .abs = instr->src1_abs, 56701e04c3fSmrg .rgroup = instr->src1_rgroup, 56801e04c3fSmrg .reg = instr->src1_reg, 56901e04c3fSmrg .swiz = instr->src1_swiz, 57001e04c3fSmrg .amode = instr->src1_amode, 57101e04c3fSmrg }; 57201e04c3fSmrg 5737ec681f3Smrg struct etna_inst_src src2 = { 57401e04c3fSmrg .use = instr->src2_use, 57501e04c3fSmrg .neg = instr->src2_neg, 57601e04c3fSmrg .abs = instr->src2_abs, 57701e04c3fSmrg .rgroup = instr->src2_rgroup, 57801e04c3fSmrg .reg = instr->src2_reg, 57901e04c3fSmrg .swiz = instr->src2_swiz, 58001e04c3fSmrg .amode = instr->src2_amode, 58101e04c3fSmrg }; 58201e04c3fSmrg 58301e04c3fSmrg int imm = (instr->dword3 & VIV_ISA_WORD_3_SRC2_IMM__MASK) 58401e04c3fSmrg >> VIV_ISA_WORD_3_SRC2_IMM__SHIFT; 58501e04c3fSmrg 58601e04c3fSmrg struct opc_operands operands = { 58701e04c3fSmrg .dst = &dst, 58801e04c3fSmrg .tex = &tex, 58901e04c3fSmrg .src0 = &src0, 59001e04c3fSmrg .src1 = &src1, 59101e04c3fSmrg .src2 = &src2, 59201e04c3fSmrg .imm = imm, 59301e04c3fSmrg }; 59401e04c3fSmrg 59501e04c3fSmrg uint8_t type = instr->type_bit01 | (instr->type_bit2 << 2); 59601e04c3fSmrg 59701e04c3fSmrg printf("%s", name); 59801e04c3fSmrg printf_type(type); 59901e04c3fSmrg if (instr->sat) 60001e04c3fSmrg printf(".SAT"); 60101e04c3fSmrg print_condition(instr->cond); 60201e04c3fSmrg printf(" "); 6037ec681f3Smrg if (instr->sel_0) 6047ec681f3Smrg printf("SEL_0 "); 6057ec681f3Smrg if (instr->sel_1) 6067ec681f3Smrg printf("SEL_1 "); 6077ec681f3Smrg if (instr->dst_full) 6087ec681f3Smrg printf("DST_FULL "); 60901e04c3fSmrg opcs[opc].print(&operands); 61001e04c3fSmrg } else { 61101e04c3fSmrg printf("unknown (%d)", instr->opc); 61201e04c3fSmrg } 61301e04c3fSmrg 61401e04c3fSmrg printf("\n"); 61501e04c3fSmrg} 61601e04c3fSmrg 61701e04c3fSmrgvoid 61801e04c3fSmrgetna_disasm(uint32_t *dwords, int sizedwords, enum debug_t debug) 61901e04c3fSmrg{ 62001e04c3fSmrg unsigned i; 62101e04c3fSmrg 62201e04c3fSmrg assert((sizedwords % 2) == 0); 62301e04c3fSmrg 62401e04c3fSmrg for (i = 0; i < sizedwords; i += 4) 62501e04c3fSmrg print_instr(&dwords[i], i / 4, debug); 62601e04c3fSmrg} 627