pan/bifrost: Style format the disassembler

$ astyle *.c *.h --style=linux -s8

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
This commit is contained in:
Alyssa Rosenzweig 2019-08-14 12:28:01 -07:00
parent fca491c0e1
commit d8d8b08fe5
4 changed files with 2265 additions and 1079 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,69 @@
/*
* Copyright (C) 2018 Ryan Houdek <Sonicadvance1@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __bifrost_compile_h__
#define __bifrost_compile_h__
#include "compiler/nir/nir.h"
#include "util/u_dynarray.h"
struct bifrost_program {
struct util_dynarray compiled;
};
int
bifrost_compile_shader_nir(nir_shader *nir, struct bifrost_program *program);
static const nir_shader_compiler_options bifrost_nir_options = {
.fuse_ffma = true,
.lower_flrp16 = true,
.lower_flrp32 = true,
.lower_flrp64 = true,
.lower_fmod = true,
.lower_bitfield_extract = true,
.lower_bitfield_extract_to_shifts = true,
.lower_bitfield_insert = true,
.lower_bitfield_insert_to_shifts = true,
.lower_bitfield_reverse = true,
.lower_idiv = true,
.lower_isign = true,
.lower_fsign = true,
.lower_ffract = true,
.lower_pack_half_2x16 = true,
.lower_pack_unorm_2x16 = true,
.lower_pack_snorm_2x16 = true,
.lower_pack_unorm_4x8 = true,
.lower_pack_snorm_4x8 = true,
.lower_unpack_half_2x16 = true,
.lower_unpack_unorm_2x16 = true,
.lower_unpack_snorm_2x16 = true,
.lower_unpack_unorm_4x8 = true,
.lower_unpack_snorm_4x8 = true,
.lower_extract_byte = true,
.lower_extract_word = true,
.lower_all_io_to_temps = true,
.lower_all_io_to_elements = true,
.vertex_id_zero_based = true,
};
#endif

View File

@ -30,6 +30,8 @@
#include "compiler/nir_types.h" #include "compiler/nir_types.h"
#include "util/u_dynarray.h" #include "util/u_dynarray.h"
#include "bifrost_compile.h"
static void static void
compile_shader(char **argv) compile_shader(char **argv)
{ {
@ -100,8 +102,7 @@ main(int argc, char **argv)
} }
if (strcmp(argv[1], "compile") == 0) { if (strcmp(argv[1], "compile") == 0) {
compile_shader(&argv[2]); compile_shader(&argv[2]);
} } else if (strcmp(argv[1], "disasm") == 0) {
else if (strcmp(argv[1], "disasm") == 0) {
disassemble(argv[2]); disassemble(argv[2]);
} }
return 0; return 0;

View File

@ -81,7 +81,7 @@ enum bifrost_reg_write_unit {
}; };
// this represents the decoded version of the ctrl register field. // this represents the decoded version of the ctrl register field.
struct bifrost_reg_ctrl{ struct bifrost_reg_ctrl {
bool read_reg0; bool read_reg0;
bool read_reg1; bool read_reg1;
bool read_reg3; bool read_reg3;
@ -192,7 +192,8 @@ void dump_instr(const struct bifrost_alu_inst *instr, struct bifrost_regs next_r
unsigned data_reg, unsigned offset, bool verbose); unsigned data_reg, unsigned offset, bool verbose);
bool dump_clause(uint32_t *words, unsigned *size, unsigned offset, bool verbose); bool dump_clause(uint32_t *words, unsigned *size, unsigned offset, bool verbose);
void dump_header(struct bifrost_header header, bool verbose) { void dump_header(struct bifrost_header header, bool verbose)
{
if (header.clause_type != 0) { if (header.clause_type != 0) {
printf("id(%du) ", header.scoreboard_index); printf("id(%du) ", header.scoreboard_index);
} }
@ -373,13 +374,27 @@ static uint64_t get_const(uint64_t *consts, struct bifrost_regs srcs)
unsigned low_bits = srcs.uniform_const & 0xf; unsigned low_bits = srcs.uniform_const & 0xf;
uint64_t imm; uint64_t imm;
switch (srcs.uniform_const >> 4) { switch (srcs.uniform_const >> 4) {
case 4: imm = consts[0]; break; case 4:
case 5: imm = consts[1]; break; imm = consts[0];
case 6: imm = consts[2]; break; break;
case 7: imm = consts[3]; break; case 5:
case 2: imm = consts[4]; break; imm = consts[1];
case 3: imm = consts[5]; break; break;
default: assert(0); break; case 6:
imm = consts[2];
break;
case 7:
imm = consts[3];
break;
case 2:
imm = consts[4];
break;
case 3:
imm = consts[5];
break;
default:
assert(0);
break;
} }
return imm | low_bits; return imm | low_bits;
} }
@ -397,9 +412,15 @@ static void dump_uniform_const_src(struct bifrost_regs srcs, uint64_t *consts, b
dump_const_imm(imm); dump_const_imm(imm);
} else { } else {
switch (srcs.uniform_const) { switch (srcs.uniform_const) {
case 0: printf("0"); break; case 0:
case 5: printf("atest-data"); break; printf("0");
case 6: printf("sample-ptr"); break; break;
case 5:
printf("atest-data");
break;
case 6:
printf("sample-ptr");
break;
case 8: case 8:
case 9: case 9:
case 10: case 10:
@ -425,9 +446,15 @@ static void dump_uniform_const_src(struct bifrost_regs srcs, uint64_t *consts, b
static void dump_src(unsigned src, struct bifrost_regs srcs, uint64_t *consts, bool isFMA) static void dump_src(unsigned src, struct bifrost_regs srcs, uint64_t *consts, bool isFMA)
{ {
switch (src) { switch (src) {
case 0: printf("R%d", get_reg0(srcs)); break; case 0:
case 1: printf("R%d", get_reg1(srcs)); break; printf("R%d", get_reg0(srcs));
case 2: printf("R%d", srcs.reg3); break; break;
case 1:
printf("R%d", get_reg1(srcs));
break;
case 2:
printf("R%d", srcs.reg3);
break;
case 3: case 3:
if (isFMA) if (isFMA)
printf("0"); printf("0");
@ -440,8 +467,12 @@ static void dump_src(unsigned src, struct bifrost_regs srcs, uint64_t *consts, b
case 5: case 5:
dump_uniform_const_src(srcs, consts, true); dump_uniform_const_src(srcs, consts, true);
break; break;
case 6: printf("T0"); break; case 6:
case 7: printf("T1"); break; printf("T0");
break;
case 7:
printf("T1");
break;
} }
} }
@ -451,11 +482,14 @@ static void dump_output_mod(unsigned mod)
case 0: case 0:
break; break;
case 1: case 1:
printf(".clamp_0_inf"); break; // max(out, 0) printf(".clamp_0_inf");
break; // max(out, 0)
case 2: case 2:
printf(".clamp_m1_1"); break; // clamp(out, -1, 1) printf(".clamp_m1_1");
break; // clamp(out, -1, 1)
case 3: case 3:
printf(".clamp_0_1"); break; // clamp(out, 0, 1) printf(".clamp_0_1");
break; // clamp(out, 0, 1)
default: default:
break; break;
} }
@ -475,7 +509,8 @@ static void dump_minmax_mode(unsigned mod)
* "greater"/"lesser" NaN is always returned, first by checking the * "greater"/"lesser" NaN is always returned, first by checking the
* sign and then the mantissa bits. * sign and then the mantissa bits.
*/ */
printf(".nan_wins"); break; printf(".nan_wins");
break;
case 2: case 2:
/* For max, implement src0 > src1 ? src0 : src1 /* For max, implement src0 > src1 ? src0 : src1
* For min, implement src0 < src1 ? src0 : src1 * For min, implement src0 < src1 ? src0 : src1
@ -485,12 +520,14 @@ static void dump_minmax_mode(unsigned mod)
* return false for NaN's. As a result, this mode is *not* * return false for NaN's. As a result, this mode is *not*
* commutative. * commutative.
*/ */
printf(".src1_wins"); break; printf(".src1_wins");
break;
case 3: case 3:
/* For max, implement src0 < src1 ? src1 : src0 /* For max, implement src0 < src1 ? src1 : src0
* For min, implement src0 > src1 ? src1 : src0 * For min, implement src0 > src1 ? src1 : src0
*/ */
printf(".src0_wins"); break; printf(".src0_wins");
break;
default: default:
break; break;
} }
@ -504,13 +541,16 @@ static void dump_round_mode(unsigned mod)
break; break;
case 1: case 1:
/* roundTowardPositive in the IEEE spec. */ /* roundTowardPositive in the IEEE spec. */
printf(".round_pos"); break; printf(".round_pos");
break;
case 2: case 2:
/* roundTowardNegative in the IEEE spec. */ /* roundTowardNegative in the IEEE spec. */
printf(".round_neg"); break; printf(".round_neg");
break;
case 3: case 3:
/* roundTowardZero in the IEEE spec. */ /* roundTowardZero in the IEEE spec. */
printf(".round_zero"); break; printf(".round_zero");
break;
default: default:
break; break;
} }
@ -1417,18 +1457,29 @@ static void dump_add(uint64_t word, struct bifrost_regs regs, struct bifrost_reg
printf(".v2f16"); printf(".v2f16");
} else if (info.src_type == ADD_FADDMscale) { } else if (info.src_type == ADD_FADDMscale) {
switch ((ADD.op >> 6) & 0x7) { switch ((ADD.op >> 6) & 0x7) {
case 0: break; case 0:
break;
// causes GPU hangs on G71 // causes GPU hangs on G71
case 1: printf(".invalid"); break; case 1:
printf(".invalid");
break;
// Same as usual outmod value. // Same as usual outmod value.
case 2: printf(".clamp_0_1"); break; case 2:
printf(".clamp_0_1");
break;
// If src0 is infinite or NaN, flush it to zero so that the other // If src0 is infinite or NaN, flush it to zero so that the other
// source is passed through unmodified. // source is passed through unmodified.
case 3: printf(".flush_src0_inf_nan"); break; case 3:
printf(".flush_src0_inf_nan");
break;
// Vice versa. // Vice versa.
case 4: printf(".flush_src1_inf_nan"); break; case 4:
printf(".flush_src1_inf_nan");
break;
// Every other case seems to behave the same as the above? // Every other case seems to behave the same as the above?
default: printf(".unk%d", (ADD.op >> 6) & 0x7); break; default:
printf(".unk%d", (ADD.op >> 6) & 0x7);
break;
} }
} else if (info.src_type == ADD_VARYING_INTERP) { } else if (info.src_type == ADD_VARYING_INTERP) {
if (ADD.op & 0x200) if (ADD.op & 0x200)
@ -1436,10 +1487,17 @@ static void dump_add(uint64_t word, struct bifrost_regs regs, struct bifrost_reg
if (ADD.op & 0x400) if (ADD.op & 0x400)
printf(".flat"); printf(".flat");
switch ((ADD.op >> 7) & 0x3) { switch ((ADD.op >> 7) & 0x3) {
case 0: printf(".per_frag"); break; case 0:
case 1: printf(".centroid"); break; printf(".per_frag");
case 2: break; break;
case 3: printf(".explicit"); break; case 1:
printf(".centroid");
break;
case 2:
break;
case 3:
printf(".explicit");
break;
} }
printf(".v%d", ((ADD.op >> 5) & 0x3) + 1); printf(".v%d", ((ADD.op >> 5) & 0x3) + 1);
} else if (info.src_type == ADD_BRANCH) { } else if (info.src_type == ADD_BRANCH) {
@ -1615,24 +1673,31 @@ static void dump_add(uint64_t word, struct bifrost_regs regs, struct bifrost_reg
switch (ctrl.result_type) { switch (ctrl.result_type) {
case 0x4: case 0x4:
printf("f32 "); break; printf("f32 ");
break;
case 0xe: case 0xe:
printf("i32 "); break; printf("i32 ");
break;
case 0xf: case 0xf:
printf("u32 "); break; printf("u32 ");
break;
default: default:
printf("unktype(%x) ", ctrl.result_type); printf("unktype(%x) ", ctrl.result_type);
} }
switch (ctrl.tex_type) { switch (ctrl.tex_type) {
case 0: case 0:
printf("cube "); break; printf("cube ");
break;
case 1: case 1:
printf("buffer "); break; printf("buffer ");
break;
case 2: case 2:
printf("2D "); break; printf("2D ");
break;
case 3: case 3:
printf("3D "); break; printf("3D ");
break;
} }
if (ctrl.is_shadow) if (ctrl.is_shadow)
@ -1981,7 +2046,8 @@ void dump_instr(const struct bifrost_alu_inst *instr, struct bifrost_regs next_r
dump_add(instr->add_bits, regs, next_regs, consts, data_reg, offset, verbose); dump_add(instr->add_bits, regs, next_regs, consts, data_reg, offset, verbose);
} }
bool dump_clause(uint32_t *words, unsigned *size, unsigned offset, bool verbose) { bool dump_clause(uint32_t *words, unsigned *size, unsigned offset, bool verbose)
{
// State for a decoded clause // State for a decoded clause
struct bifrost_alu_inst instrs[8] = {}; struct bifrost_alu_inst instrs[8] = {};
uint64_t consts[6] = {}; uint64_t consts[6] = {};
@ -2198,8 +2264,7 @@ void disassemble_bifrost(uint8_t *code, size_t size, bool verbose)
uint32_t *words_end = words + (size / 4); uint32_t *words_end = words + (size / 4);
// used for displaying branch targets // used for displaying branch targets
unsigned offset = 0; unsigned offset = 0;
while (words != words_end) while (words != words_end) {
{
// we don't know what the program-end bit is quite yet, so for now just // we don't know what the program-end bit is quite yet, so for now just
// assume that an all-0 quadword is padding // assume that an all-0 quadword is padding
uint32_t zero[4] = {}; uint32_t zero[4] = {};