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:
parent
fca491c0e1
commit
d8d8b08fe5
File diff suppressed because it is too large
Load Diff
|
@ -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
|
|
@ -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;
|
||||||
|
|
|
@ -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] = {};
|
||||||
|
|
Loading…
Reference in New Issue