1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright (c) 2016 Etnaviv Project 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sub license, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 12bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 13bf215546Sopenharmony_ci * of the 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 NON-INFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE 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 20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 22bf215546Sopenharmony_ci * 23bf215546Sopenharmony_ci * Authors: 24bf215546Sopenharmony_ci * Christian Gmeiner <christian.gmeiner@gmail.com> 25bf215546Sopenharmony_ci */ 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ci#include "etnaviv_disasm.h" 28bf215546Sopenharmony_ci#include "etnaviv_asm.h" 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci#include <assert.h> 31bf215546Sopenharmony_ci#include <stdbool.h> 32bf215546Sopenharmony_ci#include <stdio.h> 33bf215546Sopenharmony_ci#include <stdlib.h> 34bf215546Sopenharmony_ci 35bf215546Sopenharmony_ci#include "hw/isa.xml.h" 36bf215546Sopenharmony_ci#include "util/u_math.h" 37bf215546Sopenharmony_ci#include "util/half_float.h" 38bf215546Sopenharmony_ci 39bf215546Sopenharmony_cistruct instr { 40bf215546Sopenharmony_ci /* dword0: */ 41bf215546Sopenharmony_ci uint32_t opc : 6; 42bf215546Sopenharmony_ci uint32_t cond : 5; 43bf215546Sopenharmony_ci uint32_t sat : 1; 44bf215546Sopenharmony_ci uint32_t dst_use : 1; 45bf215546Sopenharmony_ci uint32_t dst_amode : 3; 46bf215546Sopenharmony_ci uint32_t dst_reg : 7; 47bf215546Sopenharmony_ci uint32_t dst_comps : 4; 48bf215546Sopenharmony_ci uint32_t tex_id : 5; 49bf215546Sopenharmony_ci 50bf215546Sopenharmony_ci /* dword1: */ 51bf215546Sopenharmony_ci uint32_t tex_amode : 3; 52bf215546Sopenharmony_ci uint32_t tex_swiz : 8; 53bf215546Sopenharmony_ci uint32_t src0_use : 1; 54bf215546Sopenharmony_ci uint32_t src0_reg : 9; 55bf215546Sopenharmony_ci uint32_t type_bit2 : 1; 56bf215546Sopenharmony_ci uint32_t src0_swiz : 8; 57bf215546Sopenharmony_ci uint32_t src0_neg : 1; 58bf215546Sopenharmony_ci uint32_t src0_abs : 1; 59bf215546Sopenharmony_ci 60bf215546Sopenharmony_ci /* dword2: */ 61bf215546Sopenharmony_ci uint32_t src0_amode : 3; 62bf215546Sopenharmony_ci uint32_t src0_rgroup : 3; 63bf215546Sopenharmony_ci uint32_t src1_use : 1; 64bf215546Sopenharmony_ci uint32_t src1_reg : 9; 65bf215546Sopenharmony_ci uint32_t opcode_bit6 : 1; 66bf215546Sopenharmony_ci uint32_t src1_swiz : 8; 67bf215546Sopenharmony_ci uint32_t src1_neg : 1; 68bf215546Sopenharmony_ci uint32_t src1_abs : 1; 69bf215546Sopenharmony_ci uint32_t src1_amode : 3; 70bf215546Sopenharmony_ci uint32_t type_bit01 : 2; 71bf215546Sopenharmony_ci 72bf215546Sopenharmony_ci /* dword3: */ 73bf215546Sopenharmony_ci union { 74bf215546Sopenharmony_ci struct { 75bf215546Sopenharmony_ci uint32_t src1_rgroup : 3; 76bf215546Sopenharmony_ci uint32_t src2_use : 1; 77bf215546Sopenharmony_ci uint32_t src2_reg : 9; 78bf215546Sopenharmony_ci uint32_t sel_0 : 1; 79bf215546Sopenharmony_ci uint32_t src2_swiz : 8; 80bf215546Sopenharmony_ci uint32_t src2_neg : 1; 81bf215546Sopenharmony_ci uint32_t src2_abs : 1; 82bf215546Sopenharmony_ci uint32_t sel_1 : 1; 83bf215546Sopenharmony_ci uint32_t src2_amode : 3; 84bf215546Sopenharmony_ci uint32_t src2_rgroup : 3; 85bf215546Sopenharmony_ci uint32_t dst_full : 1; 86bf215546Sopenharmony_ci }; 87bf215546Sopenharmony_ci uint32_t dword3; 88bf215546Sopenharmony_ci }; 89bf215546Sopenharmony_ci}; 90bf215546Sopenharmony_cistruct opc_operands { 91bf215546Sopenharmony_ci struct etna_inst_dst *dst; 92bf215546Sopenharmony_ci struct etna_inst_tex *tex; 93bf215546Sopenharmony_ci struct etna_inst_src *src0; 94bf215546Sopenharmony_ci struct etna_inst_src *src1; 95bf215546Sopenharmony_ci struct etna_inst_src *src2; 96bf215546Sopenharmony_ci 97bf215546Sopenharmony_ci int imm; 98bf215546Sopenharmony_ci}; 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_cistatic void 101bf215546Sopenharmony_ciprintf_type(uint8_t type) 102bf215546Sopenharmony_ci{ 103bf215546Sopenharmony_ci switch(type) { 104bf215546Sopenharmony_ci case INST_TYPE_F32: 105bf215546Sopenharmony_ci /* as f32 is the default print nothing */ 106bf215546Sopenharmony_ci break; 107bf215546Sopenharmony_ci 108bf215546Sopenharmony_ci case INST_TYPE_S32: 109bf215546Sopenharmony_ci printf(".s32"); 110bf215546Sopenharmony_ci break; 111bf215546Sopenharmony_ci 112bf215546Sopenharmony_ci case INST_TYPE_S8: 113bf215546Sopenharmony_ci printf(".s8"); 114bf215546Sopenharmony_ci break; 115bf215546Sopenharmony_ci 116bf215546Sopenharmony_ci case INST_TYPE_U16: 117bf215546Sopenharmony_ci printf(".u16"); 118bf215546Sopenharmony_ci break; 119bf215546Sopenharmony_ci 120bf215546Sopenharmony_ci case INST_TYPE_F16: 121bf215546Sopenharmony_ci printf(".f16"); 122bf215546Sopenharmony_ci break; 123bf215546Sopenharmony_ci 124bf215546Sopenharmony_ci case INST_TYPE_S16: 125bf215546Sopenharmony_ci printf(".s16"); 126bf215546Sopenharmony_ci break; 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_ci case INST_TYPE_U32: 129bf215546Sopenharmony_ci printf(".u32"); 130bf215546Sopenharmony_ci break; 131bf215546Sopenharmony_ci 132bf215546Sopenharmony_ci case INST_TYPE_U8: 133bf215546Sopenharmony_ci printf(".u8"); 134bf215546Sopenharmony_ci break; 135bf215546Sopenharmony_ci 136bf215546Sopenharmony_ci default: 137bf215546Sopenharmony_ci abort(); 138bf215546Sopenharmony_ci break; 139bf215546Sopenharmony_ci } 140bf215546Sopenharmony_ci} 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_cistatic void 143bf215546Sopenharmony_ciprint_condition(uint8_t condition) 144bf215546Sopenharmony_ci{ 145bf215546Sopenharmony_ci switch (condition) { 146bf215546Sopenharmony_ci case INST_CONDITION_TRUE: 147bf215546Sopenharmony_ci break; 148bf215546Sopenharmony_ci 149bf215546Sopenharmony_ci case INST_CONDITION_GT: 150bf215546Sopenharmony_ci printf(".GT"); 151bf215546Sopenharmony_ci break; 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_ci case INST_CONDITION_LT: 154bf215546Sopenharmony_ci printf(".LT"); 155bf215546Sopenharmony_ci break; 156bf215546Sopenharmony_ci 157bf215546Sopenharmony_ci case INST_CONDITION_GE: 158bf215546Sopenharmony_ci printf(".GE"); 159bf215546Sopenharmony_ci break; 160bf215546Sopenharmony_ci 161bf215546Sopenharmony_ci case INST_CONDITION_LE: 162bf215546Sopenharmony_ci printf(".LE"); 163bf215546Sopenharmony_ci break; 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ci case INST_CONDITION_EQ: 166bf215546Sopenharmony_ci printf(".EQ"); 167bf215546Sopenharmony_ci break; 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_ci case INST_CONDITION_NE: 170bf215546Sopenharmony_ci printf(".NE"); 171bf215546Sopenharmony_ci break; 172bf215546Sopenharmony_ci 173bf215546Sopenharmony_ci case INST_CONDITION_AND: 174bf215546Sopenharmony_ci printf(".AND"); 175bf215546Sopenharmony_ci break; 176bf215546Sopenharmony_ci 177bf215546Sopenharmony_ci case INST_CONDITION_OR: 178bf215546Sopenharmony_ci printf(".OR"); 179bf215546Sopenharmony_ci break; 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ci case INST_CONDITION_XOR: 182bf215546Sopenharmony_ci printf(".XOR"); 183bf215546Sopenharmony_ci break; 184bf215546Sopenharmony_ci 185bf215546Sopenharmony_ci case INST_CONDITION_NOT: 186bf215546Sopenharmony_ci printf(".NOT"); 187bf215546Sopenharmony_ci break; 188bf215546Sopenharmony_ci 189bf215546Sopenharmony_ci case INST_CONDITION_NZ: 190bf215546Sopenharmony_ci printf(".NZ"); 191bf215546Sopenharmony_ci break; 192bf215546Sopenharmony_ci 193bf215546Sopenharmony_ci case INST_CONDITION_GEZ: 194bf215546Sopenharmony_ci printf(".GEZ"); 195bf215546Sopenharmony_ci break; 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_ci case INST_CONDITION_GZ: 198bf215546Sopenharmony_ci printf(".GZ"); 199bf215546Sopenharmony_ci break; 200bf215546Sopenharmony_ci 201bf215546Sopenharmony_ci case INST_CONDITION_LEZ: 202bf215546Sopenharmony_ci printf(".LEZ"); 203bf215546Sopenharmony_ci break; 204bf215546Sopenharmony_ci 205bf215546Sopenharmony_ci case INST_CONDITION_LZ: 206bf215546Sopenharmony_ci printf(".LZ"); 207bf215546Sopenharmony_ci break; 208bf215546Sopenharmony_ci 209bf215546Sopenharmony_ci default: 210bf215546Sopenharmony_ci abort(); 211bf215546Sopenharmony_ci break; 212bf215546Sopenharmony_ci } 213bf215546Sopenharmony_ci} 214bf215546Sopenharmony_ci 215bf215546Sopenharmony_cistatic void 216bf215546Sopenharmony_ciprint_rgroup(uint8_t rgoup) 217bf215546Sopenharmony_ci{ 218bf215546Sopenharmony_ci switch (rgoup) { 219bf215546Sopenharmony_ci case INST_RGROUP_TEMP: 220bf215546Sopenharmony_ci printf("t"); 221bf215546Sopenharmony_ci break; 222bf215546Sopenharmony_ci 223bf215546Sopenharmony_ci case INST_RGROUP_INTERNAL: 224bf215546Sopenharmony_ci printf("i"); 225bf215546Sopenharmony_ci break; 226bf215546Sopenharmony_ci 227bf215546Sopenharmony_ci case INST_RGROUP_UNIFORM_0: 228bf215546Sopenharmony_ci case INST_RGROUP_UNIFORM_1: 229bf215546Sopenharmony_ci printf("u"); 230bf215546Sopenharmony_ci break; 231bf215546Sopenharmony_ci case 4: 232bf215546Sopenharmony_ci printf("th"); 233bf215546Sopenharmony_ci break; 234bf215546Sopenharmony_ci } 235bf215546Sopenharmony_ci} 236bf215546Sopenharmony_ci 237bf215546Sopenharmony_cistatic void 238bf215546Sopenharmony_ciprint_components(uint8_t components) 239bf215546Sopenharmony_ci{ 240bf215546Sopenharmony_ci if (components == 15) 241bf215546Sopenharmony_ci return; 242bf215546Sopenharmony_ci 243bf215546Sopenharmony_ci printf("."); 244bf215546Sopenharmony_ci if (components & INST_COMPS_X) 245bf215546Sopenharmony_ci printf("x"); 246bf215546Sopenharmony_ci else 247bf215546Sopenharmony_ci printf("_"); 248bf215546Sopenharmony_ci 249bf215546Sopenharmony_ci if (components & INST_COMPS_Y) 250bf215546Sopenharmony_ci printf("y"); 251bf215546Sopenharmony_ci else 252bf215546Sopenharmony_ci printf("_"); 253bf215546Sopenharmony_ci 254bf215546Sopenharmony_ci if (components & INST_COMPS_Z) 255bf215546Sopenharmony_ci printf("z"); 256bf215546Sopenharmony_ci else 257bf215546Sopenharmony_ci printf("_"); 258bf215546Sopenharmony_ci 259bf215546Sopenharmony_ci if (components & INST_COMPS_W) 260bf215546Sopenharmony_ci printf("w"); 261bf215546Sopenharmony_ci else 262bf215546Sopenharmony_ci printf("_"); 263bf215546Sopenharmony_ci} 264bf215546Sopenharmony_ci 265bf215546Sopenharmony_cistatic inline void 266bf215546Sopenharmony_ciprint_swiz_comp(uint8_t swiz_comp) 267bf215546Sopenharmony_ci{ 268bf215546Sopenharmony_ci switch (swiz_comp) { 269bf215546Sopenharmony_ci case INST_SWIZ_COMP_X: 270bf215546Sopenharmony_ci printf("x"); 271bf215546Sopenharmony_ci break; 272bf215546Sopenharmony_ci 273bf215546Sopenharmony_ci case INST_SWIZ_COMP_Y: 274bf215546Sopenharmony_ci printf("y"); 275bf215546Sopenharmony_ci break; 276bf215546Sopenharmony_ci 277bf215546Sopenharmony_ci case INST_SWIZ_COMP_Z: 278bf215546Sopenharmony_ci printf("z"); 279bf215546Sopenharmony_ci break; 280bf215546Sopenharmony_ci 281bf215546Sopenharmony_ci case INST_SWIZ_COMP_W: 282bf215546Sopenharmony_ci printf("w"); 283bf215546Sopenharmony_ci break; 284bf215546Sopenharmony_ci 285bf215546Sopenharmony_ci default: 286bf215546Sopenharmony_ci abort(); 287bf215546Sopenharmony_ci break; 288bf215546Sopenharmony_ci } 289bf215546Sopenharmony_ci} 290bf215546Sopenharmony_ci 291bf215546Sopenharmony_cistatic void 292bf215546Sopenharmony_ciprint_swiz(uint8_t swiz) 293bf215546Sopenharmony_ci{ 294bf215546Sopenharmony_ci // if a null swizzle 295bf215546Sopenharmony_ci if (swiz == 0xe4) 296bf215546Sopenharmony_ci return; 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_ci const unsigned x = swiz & 0x3; 299bf215546Sopenharmony_ci const unsigned y = (swiz & 0x0C) >> 2; 300bf215546Sopenharmony_ci const unsigned z = (swiz & 0x30) >> 4; 301bf215546Sopenharmony_ci const unsigned w = (swiz & 0xc0) >> 6; 302bf215546Sopenharmony_ci 303bf215546Sopenharmony_ci printf("."); 304bf215546Sopenharmony_ci print_swiz_comp(x); 305bf215546Sopenharmony_ci print_swiz_comp(y); 306bf215546Sopenharmony_ci print_swiz_comp(z); 307bf215546Sopenharmony_ci print_swiz_comp(w); 308bf215546Sopenharmony_ci} 309bf215546Sopenharmony_ci 310bf215546Sopenharmony_cistatic void 311bf215546Sopenharmony_ciprint_amode(uint8_t amode) 312bf215546Sopenharmony_ci{ 313bf215546Sopenharmony_ci switch (amode) { 314bf215546Sopenharmony_ci case INST_AMODE_DIRECT: 315bf215546Sopenharmony_ci /* nothing to output */ 316bf215546Sopenharmony_ci break; 317bf215546Sopenharmony_ci 318bf215546Sopenharmony_ci case INST_AMODE_ADD_A_X: 319bf215546Sopenharmony_ci printf("[a.x]"); 320bf215546Sopenharmony_ci break; 321bf215546Sopenharmony_ci 322bf215546Sopenharmony_ci case INST_AMODE_ADD_A_Y: 323bf215546Sopenharmony_ci printf("[a.y]"); 324bf215546Sopenharmony_ci break; 325bf215546Sopenharmony_ci 326bf215546Sopenharmony_ci case INST_AMODE_ADD_A_Z: 327bf215546Sopenharmony_ci printf("[a.z]"); 328bf215546Sopenharmony_ci break; 329bf215546Sopenharmony_ci 330bf215546Sopenharmony_ci case INST_AMODE_ADD_A_W: 331bf215546Sopenharmony_ci printf("[a.w]"); 332bf215546Sopenharmony_ci break; 333bf215546Sopenharmony_ci 334bf215546Sopenharmony_ci default: 335bf215546Sopenharmony_ci abort(); 336bf215546Sopenharmony_ci break; 337bf215546Sopenharmony_ci } 338bf215546Sopenharmony_ci} 339bf215546Sopenharmony_ci 340bf215546Sopenharmony_cistatic void 341bf215546Sopenharmony_ciprint_dst(struct etna_inst_dst *dst, bool sep) 342bf215546Sopenharmony_ci{ 343bf215546Sopenharmony_ci if (dst->use) { 344bf215546Sopenharmony_ci printf("t%u", dst->reg); 345bf215546Sopenharmony_ci print_amode(dst->amode); 346bf215546Sopenharmony_ci print_components(dst->write_mask); 347bf215546Sopenharmony_ci } else { 348bf215546Sopenharmony_ci printf("void"); 349bf215546Sopenharmony_ci } 350bf215546Sopenharmony_ci 351bf215546Sopenharmony_ci if (sep) 352bf215546Sopenharmony_ci printf(", "); 353bf215546Sopenharmony_ci} 354bf215546Sopenharmony_ci 355bf215546Sopenharmony_cistatic void 356bf215546Sopenharmony_ciprint_tex(struct etna_inst_tex *tex, bool sep) 357bf215546Sopenharmony_ci{ 358bf215546Sopenharmony_ci printf("tex%u", tex->id); 359bf215546Sopenharmony_ci print_amode(tex->amode); 360bf215546Sopenharmony_ci print_swiz(tex->swiz); 361bf215546Sopenharmony_ci 362bf215546Sopenharmony_ci if (sep) 363bf215546Sopenharmony_ci printf(", "); 364bf215546Sopenharmony_ci} 365bf215546Sopenharmony_ci 366bf215546Sopenharmony_cistatic void 367bf215546Sopenharmony_ciprint_src(struct etna_inst_src *src, bool sep) 368bf215546Sopenharmony_ci{ 369bf215546Sopenharmony_ci if (src->use) { 370bf215546Sopenharmony_ci if (src->rgroup == INST_RGROUP_IMMEDIATE) { 371bf215546Sopenharmony_ci switch (src->imm_type) { 372bf215546Sopenharmony_ci case 0: /* float */ 373bf215546Sopenharmony_ci printf("%f", uif(src->imm_val << 12)); 374bf215546Sopenharmony_ci break; 375bf215546Sopenharmony_ci case 1: /* signed */ 376bf215546Sopenharmony_ci printf("%d", ((int) src->imm_val << 12) >> 12); 377bf215546Sopenharmony_ci break; 378bf215546Sopenharmony_ci case 2: /* unsigned */ 379bf215546Sopenharmony_ci printf("%d", src->imm_val); 380bf215546Sopenharmony_ci break; 381bf215546Sopenharmony_ci case 3: /* 16-bit */ 382bf215546Sopenharmony_ci printf("%f/%.5X", _mesa_half_to_float(src->imm_val), src->imm_val); 383bf215546Sopenharmony_ci break; 384bf215546Sopenharmony_ci } 385bf215546Sopenharmony_ci } else { 386bf215546Sopenharmony_ci if (src->neg) 387bf215546Sopenharmony_ci printf("-"); 388bf215546Sopenharmony_ci 389bf215546Sopenharmony_ci if (src->abs) 390bf215546Sopenharmony_ci printf("|"); 391bf215546Sopenharmony_ci 392bf215546Sopenharmony_ci if (src->rgroup == INST_RGROUP_UNIFORM_1) 393bf215546Sopenharmony_ci src->reg += 128; 394bf215546Sopenharmony_ci 395bf215546Sopenharmony_ci print_rgroup(src->rgroup); 396bf215546Sopenharmony_ci printf("%u", src->reg); 397bf215546Sopenharmony_ci print_amode(src->amode); 398bf215546Sopenharmony_ci print_swiz(src->swiz); 399bf215546Sopenharmony_ci 400bf215546Sopenharmony_ci if (src->abs) 401bf215546Sopenharmony_ci printf("|"); 402bf215546Sopenharmony_ci } 403bf215546Sopenharmony_ci } else { 404bf215546Sopenharmony_ci printf("void"); 405bf215546Sopenharmony_ci } 406bf215546Sopenharmony_ci 407bf215546Sopenharmony_ci if (sep) 408bf215546Sopenharmony_ci printf(", "); 409bf215546Sopenharmony_ci} 410bf215546Sopenharmony_ci 411bf215546Sopenharmony_cistatic void 412bf215546Sopenharmony_ciprint_opc_default(struct opc_operands *operands) 413bf215546Sopenharmony_ci{ 414bf215546Sopenharmony_ci print_dst(operands->dst, true); 415bf215546Sopenharmony_ci print_src(operands->src0, true); 416bf215546Sopenharmony_ci print_src(operands->src1, true); 417bf215546Sopenharmony_ci print_src(operands->src2, false); 418bf215546Sopenharmony_ci} 419bf215546Sopenharmony_ci 420bf215546Sopenharmony_cistatic void 421bf215546Sopenharmony_ciprint_opc_mov(struct opc_operands *operands) 422bf215546Sopenharmony_ci{ 423bf215546Sopenharmony_ci // dst (areg) 424bf215546Sopenharmony_ci printf("a%u", operands->dst->reg); 425bf215546Sopenharmony_ci print_components(operands->dst->write_mask); 426bf215546Sopenharmony_ci printf(", "); 427bf215546Sopenharmony_ci 428bf215546Sopenharmony_ci print_src(operands->src0, true); 429bf215546Sopenharmony_ci print_src(operands->src1, true); 430bf215546Sopenharmony_ci print_src(operands->src2, false); 431bf215546Sopenharmony_ci} 432bf215546Sopenharmony_ci 433bf215546Sopenharmony_cistatic void 434bf215546Sopenharmony_ciprint_opc_tex(struct opc_operands *operands) 435bf215546Sopenharmony_ci{ 436bf215546Sopenharmony_ci print_dst(operands->dst, true); 437bf215546Sopenharmony_ci print_tex(operands->tex, true); 438bf215546Sopenharmony_ci print_src(operands->src0, true); 439bf215546Sopenharmony_ci print_src(operands->src1, true); 440bf215546Sopenharmony_ci print_src(operands->src2, false); 441bf215546Sopenharmony_ci} 442bf215546Sopenharmony_ci 443bf215546Sopenharmony_cistatic void 444bf215546Sopenharmony_ciprint_opc_imm(struct opc_operands *operands) 445bf215546Sopenharmony_ci{ 446bf215546Sopenharmony_ci print_dst(operands->dst, true); 447bf215546Sopenharmony_ci print_src(operands->src0, true); 448bf215546Sopenharmony_ci print_src(operands->src1, true); 449bf215546Sopenharmony_ci printf("label_%04d", operands->imm); 450bf215546Sopenharmony_ci} 451bf215546Sopenharmony_ci 452bf215546Sopenharmony_ci#define OPC_BITS 7 453bf215546Sopenharmony_ci 454bf215546Sopenharmony_cistatic const struct opc_info { 455bf215546Sopenharmony_ci const char *name; 456bf215546Sopenharmony_ci void (*print)(struct opc_operands *operands); 457bf215546Sopenharmony_ci} opcs[1 << OPC_BITS] = { 458bf215546Sopenharmony_ci#define OPC(opc) [INST_OPCODE_##opc] = {#opc, print_opc_default} 459bf215546Sopenharmony_ci#define OPC_MOV(opc) [INST_OPCODE_##opc] = {#opc, print_opc_mov} 460bf215546Sopenharmony_ci#define OPC_TEX(opc) [INST_OPCODE_##opc] = {#opc, print_opc_tex} 461bf215546Sopenharmony_ci#define OPC_IMM(opc) [INST_OPCODE_##opc] = {#opc, print_opc_imm} 462bf215546Sopenharmony_ci OPC(NOP), 463bf215546Sopenharmony_ci OPC(ADD), 464bf215546Sopenharmony_ci OPC(MAD), 465bf215546Sopenharmony_ci OPC(MUL), 466bf215546Sopenharmony_ci OPC(DST), 467bf215546Sopenharmony_ci OPC(DP3), 468bf215546Sopenharmony_ci OPC(DP4), 469bf215546Sopenharmony_ci OPC(DSX), 470bf215546Sopenharmony_ci OPC(DSY), 471bf215546Sopenharmony_ci OPC(MOV), 472bf215546Sopenharmony_ci OPC_MOV(MOVAR), 473bf215546Sopenharmony_ci OPC_MOV(MOVAF), 474bf215546Sopenharmony_ci OPC_MOV(MOVAI), 475bf215546Sopenharmony_ci OPC(RCP), 476bf215546Sopenharmony_ci OPC(RSQ), 477bf215546Sopenharmony_ci OPC(LITP), 478bf215546Sopenharmony_ci OPC(SELECT), 479bf215546Sopenharmony_ci OPC(SET), 480bf215546Sopenharmony_ci OPC(EXP), 481bf215546Sopenharmony_ci OPC(LOG), 482bf215546Sopenharmony_ci OPC(FRC), 483bf215546Sopenharmony_ci OPC_IMM(CALL), 484bf215546Sopenharmony_ci OPC(RET), 485bf215546Sopenharmony_ci OPC_IMM(BRANCH), 486bf215546Sopenharmony_ci OPC_TEX(TEXKILL), 487bf215546Sopenharmony_ci OPC_TEX(TEXLD), 488bf215546Sopenharmony_ci OPC_TEX(TEXLDB), 489bf215546Sopenharmony_ci OPC_TEX(TEXLDD), 490bf215546Sopenharmony_ci OPC_TEX(TEXLDL), 491bf215546Sopenharmony_ci OPC_TEX(TEXLDPCF), 492bf215546Sopenharmony_ci OPC_TEX(TEXLDLPCF), 493bf215546Sopenharmony_ci OPC_TEX(TEXLDGPCF), 494bf215546Sopenharmony_ci OPC(REP), 495bf215546Sopenharmony_ci OPC(ENDREP), 496bf215546Sopenharmony_ci OPC(LOOP), 497bf215546Sopenharmony_ci OPC(ENDLOOP), 498bf215546Sopenharmony_ci OPC(SQRT), 499bf215546Sopenharmony_ci OPC(SIN), 500bf215546Sopenharmony_ci OPC(COS), 501bf215546Sopenharmony_ci OPC(FLOOR), 502bf215546Sopenharmony_ci OPC(CEIL), 503bf215546Sopenharmony_ci OPC(SIGN), 504bf215546Sopenharmony_ci OPC(I2F), 505bf215546Sopenharmony_ci OPC(F2I), 506bf215546Sopenharmony_ci OPC(CMP), 507bf215546Sopenharmony_ci OPC(LOAD), 508bf215546Sopenharmony_ci OPC(STORE), 509bf215546Sopenharmony_ci OPC(IMULLO0), 510bf215546Sopenharmony_ci OPC(IMULHI0), 511bf215546Sopenharmony_ci OPC(IMADLO0), 512bf215546Sopenharmony_ci OPC(IMADHI0), 513bf215546Sopenharmony_ci OPC(LEADZERO), 514bf215546Sopenharmony_ci OPC(LSHIFT), 515bf215546Sopenharmony_ci OPC(RSHIFT), 516bf215546Sopenharmony_ci OPC(ROTATE), 517bf215546Sopenharmony_ci OPC(OR), 518bf215546Sopenharmony_ci OPC(AND), 519bf215546Sopenharmony_ci OPC(XOR), 520bf215546Sopenharmony_ci OPC(NOT), 521bf215546Sopenharmony_ci OPC(DP2), 522bf215546Sopenharmony_ci OPC(DIV), 523bf215546Sopenharmony_ci OPC(IABS), 524bf215546Sopenharmony_ci}; 525bf215546Sopenharmony_ci 526bf215546Sopenharmony_cistatic void 527bf215546Sopenharmony_ciprint_instr(uint32_t *dwords, int n, enum debug_t debug) 528bf215546Sopenharmony_ci{ 529bf215546Sopenharmony_ci struct instr *instr = (struct instr *)dwords; 530bf215546Sopenharmony_ci const unsigned opc = instr->opc | (instr->opcode_bit6 << 6); 531bf215546Sopenharmony_ci const char *name = opcs[opc].name; 532bf215546Sopenharmony_ci 533bf215546Sopenharmony_ci printf("%04d: ", n); 534bf215546Sopenharmony_ci if (debug & PRINT_RAW) 535bf215546Sopenharmony_ci printf("%08x %08x %08x %08x ", dwords[0], dwords[1], dwords[2], 536bf215546Sopenharmony_ci dwords[3]); 537bf215546Sopenharmony_ci 538bf215546Sopenharmony_ci if (name) { 539bf215546Sopenharmony_ci 540bf215546Sopenharmony_ci struct etna_inst_dst dst = { 541bf215546Sopenharmony_ci .use = instr->dst_use, 542bf215546Sopenharmony_ci .amode = instr->dst_amode, 543bf215546Sopenharmony_ci .reg = instr->dst_reg, 544bf215546Sopenharmony_ci .write_mask = instr->dst_comps 545bf215546Sopenharmony_ci }; 546bf215546Sopenharmony_ci 547bf215546Sopenharmony_ci struct etna_inst_tex tex = { 548bf215546Sopenharmony_ci .id = instr->tex_id, 549bf215546Sopenharmony_ci .amode = instr->tex_amode, 550bf215546Sopenharmony_ci .swiz = instr->tex_swiz, 551bf215546Sopenharmony_ci }; 552bf215546Sopenharmony_ci 553bf215546Sopenharmony_ci struct etna_inst_src src0 = { 554bf215546Sopenharmony_ci .use = instr->src0_use, 555bf215546Sopenharmony_ci .neg = instr->src0_neg, 556bf215546Sopenharmony_ci .abs = instr->src0_abs, 557bf215546Sopenharmony_ci .rgroup = instr->src0_rgroup, 558bf215546Sopenharmony_ci .reg = instr->src0_reg, 559bf215546Sopenharmony_ci .swiz = instr->src0_swiz, 560bf215546Sopenharmony_ci .amode = instr->src0_amode, 561bf215546Sopenharmony_ci }; 562bf215546Sopenharmony_ci 563bf215546Sopenharmony_ci struct etna_inst_src src1 = { 564bf215546Sopenharmony_ci .use = instr->src1_use, 565bf215546Sopenharmony_ci .neg = instr->src1_neg, 566bf215546Sopenharmony_ci .abs = instr->src1_abs, 567bf215546Sopenharmony_ci .rgroup = instr->src1_rgroup, 568bf215546Sopenharmony_ci .reg = instr->src1_reg, 569bf215546Sopenharmony_ci .swiz = instr->src1_swiz, 570bf215546Sopenharmony_ci .amode = instr->src1_amode, 571bf215546Sopenharmony_ci }; 572bf215546Sopenharmony_ci 573bf215546Sopenharmony_ci struct etna_inst_src src2 = { 574bf215546Sopenharmony_ci .use = instr->src2_use, 575bf215546Sopenharmony_ci .neg = instr->src2_neg, 576bf215546Sopenharmony_ci .abs = instr->src2_abs, 577bf215546Sopenharmony_ci .rgroup = instr->src2_rgroup, 578bf215546Sopenharmony_ci .reg = instr->src2_reg, 579bf215546Sopenharmony_ci .swiz = instr->src2_swiz, 580bf215546Sopenharmony_ci .amode = instr->src2_amode, 581bf215546Sopenharmony_ci }; 582bf215546Sopenharmony_ci 583bf215546Sopenharmony_ci int imm = (instr->dword3 & VIV_ISA_WORD_3_SRC2_IMM__MASK) 584bf215546Sopenharmony_ci >> VIV_ISA_WORD_3_SRC2_IMM__SHIFT; 585bf215546Sopenharmony_ci 586bf215546Sopenharmony_ci struct opc_operands operands = { 587bf215546Sopenharmony_ci .dst = &dst, 588bf215546Sopenharmony_ci .tex = &tex, 589bf215546Sopenharmony_ci .src0 = &src0, 590bf215546Sopenharmony_ci .src1 = &src1, 591bf215546Sopenharmony_ci .src2 = &src2, 592bf215546Sopenharmony_ci .imm = imm, 593bf215546Sopenharmony_ci }; 594bf215546Sopenharmony_ci 595bf215546Sopenharmony_ci uint8_t type = instr->type_bit01 | (instr->type_bit2 << 2); 596bf215546Sopenharmony_ci 597bf215546Sopenharmony_ci printf("%s", name); 598bf215546Sopenharmony_ci printf_type(type); 599bf215546Sopenharmony_ci if (instr->sat) 600bf215546Sopenharmony_ci printf(".SAT"); 601bf215546Sopenharmony_ci print_condition(instr->cond); 602bf215546Sopenharmony_ci printf(" "); 603bf215546Sopenharmony_ci if (instr->sel_0) 604bf215546Sopenharmony_ci printf("SEL_0 "); 605bf215546Sopenharmony_ci if (instr->sel_1) 606bf215546Sopenharmony_ci printf("SEL_1 "); 607bf215546Sopenharmony_ci if (instr->dst_full) 608bf215546Sopenharmony_ci printf("DST_FULL "); 609bf215546Sopenharmony_ci opcs[opc].print(&operands); 610bf215546Sopenharmony_ci } else { 611bf215546Sopenharmony_ci printf("unknown (%d)", instr->opc); 612bf215546Sopenharmony_ci } 613bf215546Sopenharmony_ci 614bf215546Sopenharmony_ci printf("\n"); 615bf215546Sopenharmony_ci} 616bf215546Sopenharmony_ci 617bf215546Sopenharmony_civoid 618bf215546Sopenharmony_cietna_disasm(uint32_t *dwords, int sizedwords, enum debug_t debug) 619bf215546Sopenharmony_ci{ 620bf215546Sopenharmony_ci unsigned i; 621bf215546Sopenharmony_ci 622bf215546Sopenharmony_ci assert((sizedwords % 2) == 0); 623bf215546Sopenharmony_ci 624bf215546Sopenharmony_ci for (i = 0; i < sizedwords; i += 4) 625bf215546Sopenharmony_ci print_instr(&dwords[i], i / 4, debug); 626bf215546Sopenharmony_ci} 627